mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 04:57:44 +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/StylePainter.h>
|
||||||
#include <SharedGraphics/CharacterBitmap.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))
|
: on_click(move(on_click_handler))
|
||||||
, m_frame(frame)
|
, m_frame(frame)
|
||||||
, m_bitmap(move(bitmap))
|
, m_bitmap(move(bitmap))
|
||||||
|
@ -47,7 +47,7 @@ void WSButton::on_mouse_event(const WSMouseEvent& event)
|
||||||
m_pressed = false;
|
m_pressed = false;
|
||||||
if (rect().contains(event.position())) {
|
if (rect().contains(event.position())) {
|
||||||
if (on_click)
|
if (on_click)
|
||||||
on_click();
|
on_click(*this);
|
||||||
}
|
}
|
||||||
if (old_pressed != m_pressed)
|
if (old_pressed != m_pressed)
|
||||||
wm.invalidate(screen_rect());
|
wm.invalidate(screen_rect());
|
||||||
|
|
|
@ -12,7 +12,7 @@ class WSWindowFrame;
|
||||||
|
|
||||||
class WSButton : public Weakable<WSButton> {
|
class WSButton : public Weakable<WSButton> {
|
||||||
public:
|
public:
|
||||||
WSButton(WSWindowFrame&, Retained<CharacterBitmap>&&, Function<void()>&& on_click_handler);
|
WSButton(WSWindowFrame&, Retained<CharacterBitmap>&&, Function<void(WSButton&)>&& on_click_handler);
|
||||||
~WSButton();
|
~WSButton();
|
||||||
|
|
||||||
Rect relative_rect() const { return m_relative_rect; }
|
Rect relative_rect() const { return m_relative_rect; }
|
||||||
|
@ -25,10 +25,12 @@ public:
|
||||||
|
|
||||||
void on_mouse_event(const WSMouseEvent&);
|
void on_mouse_event(const WSMouseEvent&);
|
||||||
|
|
||||||
Function<void()> on_click;
|
Function<void(WSButton&)> on_click;
|
||||||
|
|
||||||
bool is_visible() const { return m_visible; }
|
bool is_visible() const { return m_visible; }
|
||||||
|
|
||||||
|
void set_bitmap(const CharacterBitmap& bitmap) { m_bitmap = bitmap; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
WSWindowFrame& m_frame;
|
WSWindowFrame& m_frame;
|
||||||
Rect m_relative_rect;
|
Rect m_relative_rect;
|
||||||
|
|
|
@ -134,6 +134,21 @@ void WSWindow::set_minimized(bool minimized)
|
||||||
WSWindowManager::the().notify_minimization_state_changed(*this);
|
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)
|
void WSWindow::event(CEvent& event)
|
||||||
{
|
{
|
||||||
if (m_internal_owner)
|
if (m_internal_owner)
|
||||||
|
|
|
@ -29,6 +29,9 @@ public:
|
||||||
bool is_minimized() const { return m_minimized; }
|
bool is_minimized() const { return m_minimized; }
|
||||||
void set_minimized(bool);
|
void set_minimized(bool);
|
||||||
|
|
||||||
|
bool is_maximized() const { return m_maximized; }
|
||||||
|
void set_maximized(bool);
|
||||||
|
|
||||||
WSWindowFrame& frame() { return m_frame; }
|
WSWindowFrame& frame() { return m_frame; }
|
||||||
const WSWindowFrame& frame() const { return m_frame; }
|
const WSWindowFrame& frame() const { return m_frame; }
|
||||||
|
|
||||||
|
@ -152,6 +155,7 @@ private:
|
||||||
bool m_resizable { false };
|
bool m_resizable { false };
|
||||||
bool m_listens_to_wm_events { false };
|
bool m_listens_to_wm_events { false };
|
||||||
bool m_minimized { false };
|
bool m_minimized { false };
|
||||||
|
bool m_maximized { false };
|
||||||
RetainPtr<GraphicsBitmap> m_backing_store;
|
RetainPtr<GraphicsBitmap> m_backing_store;
|
||||||
RetainPtr<GraphicsBitmap> m_last_backing_store;
|
RetainPtr<GraphicsBitmap> m_last_backing_store;
|
||||||
int m_window_id { -1 };
|
int m_window_id { -1 };
|
||||||
|
@ -165,4 +169,5 @@ private:
|
||||||
Color m_background_color { Color::LightGray };
|
Color m_background_color { Color::LightGray };
|
||||||
unsigned m_wm_event_mask { 0 };
|
unsigned m_wm_event_mask { 0 };
|
||||||
DisjointRectSet m_pending_paint_rects;
|
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_width = 8;
|
||||||
static const int s_minimize_button_bitmap_height = 9;
|
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)
|
WSWindowFrame::WSWindowFrame(WSWindow& window)
|
||||||
: m_window(window)
|
: m_window(window)
|
||||||
{
|
{
|
||||||
|
@ -51,14 +83,25 @@ WSWindowFrame::WSWindowFrame(WSWindow& window)
|
||||||
if (!s_minimize_button_bitmap)
|
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();
|
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);
|
WSEvent close_request(WSEvent::WindowCloseRequest);
|
||||||
m_window.event(close_request);
|
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_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()
|
WSWindowFrame::~WSWindowFrame()
|
||||||
|
|
|
@ -20,11 +20,11 @@ public:
|
||||||
void notify_window_rect_changed(const Rect& old_rect, const Rect& new_rect);
|
void notify_window_rect_changed(const Rect& old_rect, const Rect& new_rect);
|
||||||
void invalidate_title_bar();
|
void invalidate_title_bar();
|
||||||
|
|
||||||
private:
|
|
||||||
Rect title_bar_rect() const;
|
Rect title_bar_rect() const;
|
||||||
Rect title_bar_icon_rect() const;
|
Rect title_bar_icon_rect() const;
|
||||||
Rect title_bar_text_rect() const;
|
Rect title_bar_text_rect() const;
|
||||||
|
|
||||||
|
private:
|
||||||
WSWindow& m_window;
|
WSWindow& m_window;
|
||||||
Vector<OwnPtr<WSButton>> m_buttons;
|
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_candidate = window.make_weak_ptr();
|
||||||
m_resize_direction = direction;
|
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_minimization_state_changed(WSWindow&);
|
||||||
void notify_client_changed_app_menubar(WSClientConnection&);
|
void notify_client_changed_app_menubar(WSClientConnection&);
|
||||||
|
|
||||||
|
Rect maximized_window_rect(const WSWindow&) const;
|
||||||
|
|
||||||
WSWindow* active_window() { return m_active_window.ptr(); }
|
WSWindow* active_window() { return m_active_window.ptr(); }
|
||||||
const WSClientConnection* active_client() const;
|
const WSClientConnection* active_client() const;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue