1
Fork 0
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:
Andreas Kling 2019-05-12 21:32:02 +02:00
parent dddf45f563
commit 641893104a
8 changed files with 95 additions and 7 deletions

View file

@ -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());

View file

@ -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;

View file

@ -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)

View file

@ -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;
};

View file

@ -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()

View file

@ -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;
};

View file

@ -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;
}

View file

@ -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;