mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 05:07:35 +00:00
WindowServer: Add a maximize/unmaximize button to windows.
This commit is contained in:
parent
dddf45f563
commit
641893104a
8 changed files with 95 additions and 7 deletions
|
@ -5,7 +5,7 @@
|
|||
#include <SharedGraphics/StylePainter.h>
|
||||
#include <SharedGraphics/CharacterBitmap.h>
|
||||
|
||||
WSButton::WSButton(WSWindowFrame& frame, Retained<CharacterBitmap>&& bitmap, Function<void()>&& on_click_handler)
|
||||
WSButton::WSButton(WSWindowFrame& frame, Retained<CharacterBitmap>&& bitmap, Function<void(WSButton&)>&& on_click_handler)
|
||||
: on_click(move(on_click_handler))
|
||||
, m_frame(frame)
|
||||
, m_bitmap(move(bitmap))
|
||||
|
@ -47,7 +47,7 @@ void WSButton::on_mouse_event(const WSMouseEvent& event)
|
|||
m_pressed = false;
|
||||
if (rect().contains(event.position())) {
|
||||
if (on_click)
|
||||
on_click();
|
||||
on_click(*this);
|
||||
}
|
||||
if (old_pressed != m_pressed)
|
||||
wm.invalidate(screen_rect());
|
||||
|
|
|
@ -12,7 +12,7 @@ class WSWindowFrame;
|
|||
|
||||
class WSButton : public Weakable<WSButton> {
|
||||
public:
|
||||
WSButton(WSWindowFrame&, Retained<CharacterBitmap>&&, Function<void()>&& on_click_handler);
|
||||
WSButton(WSWindowFrame&, Retained<CharacterBitmap>&&, Function<void(WSButton&)>&& on_click_handler);
|
||||
~WSButton();
|
||||
|
||||
Rect relative_rect() const { return m_relative_rect; }
|
||||
|
@ -25,10 +25,12 @@ public:
|
|||
|
||||
void on_mouse_event(const WSMouseEvent&);
|
||||
|
||||
Function<void()> on_click;
|
||||
Function<void(WSButton&)> on_click;
|
||||
|
||||
bool is_visible() const { return m_visible; }
|
||||
|
||||
void set_bitmap(const CharacterBitmap& bitmap) { m_bitmap = bitmap; }
|
||||
|
||||
private:
|
||||
WSWindowFrame& m_frame;
|
||||
Rect m_relative_rect;
|
||||
|
|
|
@ -134,6 +134,21 @@ void WSWindow::set_minimized(bool minimized)
|
|||
WSWindowManager::the().notify_minimization_state_changed(*this);
|
||||
}
|
||||
|
||||
void WSWindow::set_maximized(bool maximized)
|
||||
{
|
||||
if (m_maximized == maximized)
|
||||
return;
|
||||
m_maximized = maximized;
|
||||
auto old_rect = m_rect;
|
||||
if (maximized) {
|
||||
m_unmaximized_rect = m_rect;
|
||||
set_rect(WSWindowManager::the().maximized_window_rect(*this));
|
||||
} else {
|
||||
set_rect(m_unmaximized_rect);
|
||||
}
|
||||
WSEventLoop::the().post_event(*this, make<WSResizeEvent>(old_rect, m_rect));
|
||||
}
|
||||
|
||||
void WSWindow::event(CEvent& event)
|
||||
{
|
||||
if (m_internal_owner)
|
||||
|
|
|
@ -29,6 +29,9 @@ public:
|
|||
bool is_minimized() const { return m_minimized; }
|
||||
void set_minimized(bool);
|
||||
|
||||
bool is_maximized() const { return m_maximized; }
|
||||
void set_maximized(bool);
|
||||
|
||||
WSWindowFrame& frame() { return m_frame; }
|
||||
const WSWindowFrame& frame() const { return m_frame; }
|
||||
|
||||
|
@ -152,6 +155,7 @@ private:
|
|||
bool m_resizable { false };
|
||||
bool m_listens_to_wm_events { false };
|
||||
bool m_minimized { false };
|
||||
bool m_maximized { false };
|
||||
RetainPtr<GraphicsBitmap> m_backing_store;
|
||||
RetainPtr<GraphicsBitmap> m_last_backing_store;
|
||||
int m_window_id { -1 };
|
||||
|
@ -165,4 +169,5 @@ private:
|
|||
Color m_background_color { Color::LightGray };
|
||||
unsigned m_wm_event_mask { 0 };
|
||||
DisjointRectSet m_pending_paint_rects;
|
||||
Rect m_unmaximized_rect;
|
||||
};
|
||||
|
|
|
@ -42,6 +42,38 @@ static CharacterBitmap* s_minimize_button_bitmap;
|
|||
static const int s_minimize_button_bitmap_width = 8;
|
||||
static const int s_minimize_button_bitmap_height = 9;
|
||||
|
||||
static const char* s_maximize_button_bitmap_data = {
|
||||
" "
|
||||
" "
|
||||
" "
|
||||
" ## "
|
||||
" #### "
|
||||
" ###### "
|
||||
" "
|
||||
" "
|
||||
" "
|
||||
};
|
||||
|
||||
static CharacterBitmap* s_maximize_button_bitmap;
|
||||
static const int s_maximize_button_bitmap_width = 8;
|
||||
static const int s_maximize_button_bitmap_height = 9;
|
||||
|
||||
static const char* s_unmaximize_button_bitmap_data = {
|
||||
" "
|
||||
" ## "
|
||||
" #### "
|
||||
" ###### "
|
||||
" "
|
||||
" ###### "
|
||||
" #### "
|
||||
" ## "
|
||||
" "
|
||||
};
|
||||
|
||||
static CharacterBitmap* s_unmaximize_button_bitmap;
|
||||
static const int s_unmaximize_button_bitmap_width = 8;
|
||||
static const int s_unmaximize_button_bitmap_height = 9;
|
||||
|
||||
WSWindowFrame::WSWindowFrame(WSWindow& window)
|
||||
: m_window(window)
|
||||
{
|
||||
|
@ -51,14 +83,25 @@ WSWindowFrame::WSWindowFrame(WSWindow& window)
|
|||
if (!s_minimize_button_bitmap)
|
||||
s_minimize_button_bitmap = &CharacterBitmap::create_from_ascii(s_minimize_button_bitmap_data, s_minimize_button_bitmap_width, s_minimize_button_bitmap_height).leak_ref();
|
||||
|
||||
m_buttons.append(make<WSButton>(*this, *s_close_button_bitmap, [this] {
|
||||
if (!s_maximize_button_bitmap)
|
||||
s_maximize_button_bitmap = &CharacterBitmap::create_from_ascii(s_maximize_button_bitmap_data, s_maximize_button_bitmap_width, s_maximize_button_bitmap_height).leak_ref();
|
||||
|
||||
if (!s_unmaximize_button_bitmap)
|
||||
s_unmaximize_button_bitmap = &CharacterBitmap::create_from_ascii(s_unmaximize_button_bitmap_data, s_unmaximize_button_bitmap_width, s_unmaximize_button_bitmap_height).leak_ref();
|
||||
|
||||
m_buttons.append(make<WSButton>(*this, *s_close_button_bitmap, [this] (auto&) {
|
||||
WSEvent close_request(WSEvent::WindowCloseRequest);
|
||||
m_window.event(close_request);
|
||||
}));
|
||||
|
||||
m_buttons.append(make<WSButton>(*this, *s_minimize_button_bitmap, [this] {
|
||||
m_buttons.append(make<WSButton>(*this, *s_minimize_button_bitmap, [this] (auto&) {
|
||||
m_window.set_minimized(true);
|
||||
}));
|
||||
|
||||
m_buttons.append(make<WSButton>(*this, *s_maximize_button_bitmap, [this] (auto& button) {
|
||||
m_window.set_maximized(!m_window.is_maximized());
|
||||
button.set_bitmap(m_window.is_maximized() ? *s_unmaximize_button_bitmap : *s_maximize_button_bitmap);
|
||||
}));
|
||||
}
|
||||
|
||||
WSWindowFrame::~WSWindowFrame()
|
||||
|
|
|
@ -20,11 +20,11 @@ public:
|
|||
void notify_window_rect_changed(const Rect& old_rect, const Rect& new_rect);
|
||||
void invalidate_title_bar();
|
||||
|
||||
private:
|
||||
Rect title_bar_rect() const;
|
||||
Rect title_bar_icon_rect() const;
|
||||
Rect title_bar_text_rect() const;
|
||||
|
||||
private:
|
||||
WSWindow& m_window;
|
||||
Vector<OwnPtr<WSButton>> m_buttons;
|
||||
};
|
||||
|
|
|
@ -1218,3 +1218,24 @@ void WSWindowManager::set_resize_candidate(WSWindow& window, ResizeDirection dir
|
|||
m_resize_candidate = window.make_weak_ptr();
|
||||
m_resize_direction = direction;
|
||||
}
|
||||
|
||||
Rect WSWindowManager::maximized_window_rect(const WSWindow& window) const
|
||||
{
|
||||
Rect rect = m_screen_rect;
|
||||
|
||||
// Subtract window title bar (leaving the border)
|
||||
rect.set_y(rect.y() + window.frame().title_bar_rect().height());
|
||||
rect.set_height(rect.height() - window.frame().title_bar_rect().height());
|
||||
|
||||
// Subtract menu bar
|
||||
rect.set_y(rect.y() + menubar_rect().height());
|
||||
rect.set_height(rect.height() - menubar_rect().height());
|
||||
|
||||
// Subtract taskbar window height if present
|
||||
const_cast<WSWindowManager*>(this)->for_each_visible_window_of_type_from_back_to_front(WSWindowType::Taskbar, [&rect] (WSWindow& taskbar_window) {
|
||||
rect.set_height(rect.height() - taskbar_window.height());
|
||||
return IterationDecision::Abort;
|
||||
});
|
||||
|
||||
return rect;
|
||||
}
|
||||
|
|
|
@ -46,6 +46,8 @@ public:
|
|||
void notify_minimization_state_changed(WSWindow&);
|
||||
void notify_client_changed_app_menubar(WSClientConnection&);
|
||||
|
||||
Rect maximized_window_rect(const WSWindow&) const;
|
||||
|
||||
WSWindow* active_window() { return m_active_window.ptr(); }
|
||||
const WSClientConnection* active_client() const;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue