From 5f288014d4d0ed8ecae6196c7495550a770e48a6 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Mon, 11 Feb 2019 10:08:37 +0100 Subject: WindowServer: More work on menus. --- Applications/Clock/ClockWidget.cpp | 2 +- Applications/FileManager/DirectoryView.cpp | 4 +-- LibGUI/GButton.cpp | 4 +-- LibGUI/GCheckBox.cpp | 2 +- LibGUI/GLabel.cpp | 2 +- LibGUI/GListBox.cpp | 2 +- SharedGraphics/Painter.h | 3 +- Userland/guitest.cpp | 2 +- WindowServer/WSMenu.cpp | 49 ++++++++++++++++++------------ WindowServer/WSMenu.h | 3 ++ WindowServer/WSWindowManager.cpp | 11 ++++--- 11 files changed, 51 insertions(+), 33 deletions(-) diff --git a/Applications/Clock/ClockWidget.cpp b/Applications/Clock/ClockWidget.cpp index 94cf55cb35..97001edbb5 100644 --- a/Applications/Clock/ClockWidget.cpp +++ b/Applications/Clock/ClockWidget.cpp @@ -24,7 +24,7 @@ void ClockWidget::paint_event(GPaintEvent&) Painter painter(*this); painter.fill_rect(rect(), Color::LightGray); - painter.draw_text(rect(), timeBuf, Painter::TextAlignment::Center, Color::Black); + painter.draw_text(rect(), timeBuf, TextAlignment::Center, Color::Black); } void ClockWidget::timer_event(GTimerEvent&) diff --git a/Applications/FileManager/DirectoryView.cpp b/Applications/FileManager/DirectoryView.cpp index 85dbcb55a7..a50fb4b41b 100644 --- a/Applications/FileManager/DirectoryView.cpp +++ b/Applications/FileManager/DirectoryView.cpp @@ -143,9 +143,9 @@ void DirectoryView::paint_event(GPaintEvent&) Rect size_rect(name_rect.right() + horizontal_padding, y, 64, item_height()); painter.fill_rect(row_rect(painted_item_index), i % 2 ? Color(210, 210, 210) : Color::White); painter.blit_with_alpha(icon_rect.location(), icon_for(entry), { 0, 0, icon_size, icon_size }); - painter.draw_text(name_rect, entry.name, Painter::TextAlignment::CenterLeft, Color::Black); + painter.draw_text(name_rect, entry.name, TextAlignment::CenterLeft, Color::Black); if (should_show_size_for(entry)) - painter.draw_text(size_rect, pretty_byte_size(entry.size), Painter::TextAlignment::CenterRight, Color::Black); + painter.draw_text(size_rect, pretty_byte_size(entry.size), TextAlignment::CenterRight, Color::Black); } }; diff --git a/LibGUI/GButton.cpp b/LibGUI/GButton.cpp index 775a187af7..8d117ea178 100644 --- a/LibGUI/GButton.cpp +++ b/LibGUI/GButton.cpp @@ -37,9 +37,9 @@ void GButton::paint_event(GPaintEvent&) } if (m_icon) { painter.blit_with_alpha(icon_location, *m_icon, m_icon->rect()); - painter.draw_text(content_rect, caption(), Painter::TextAlignment::Center, Color::Black); + painter.draw_text(content_rect, caption(), TextAlignment::Center, Color::Black); } else { - painter.draw_text(content_rect, caption(), Painter::TextAlignment::Center, Color::Black); + painter.draw_text(content_rect, caption(), TextAlignment::Center, Color::Black); } } } diff --git a/LibGUI/GCheckBox.cpp b/LibGUI/GCheckBox.cpp index 57158a90f1..d19fabd9f3 100644 --- a/LibGUI/GCheckBox.cpp +++ b/LibGUI/GCheckBox.cpp @@ -75,7 +75,7 @@ void GCheckBox::paint_event(GPaintEvent&) painter.draw_bitmap(box_rect.shrunken(2, 2).location(), *s_checked_bitmap, foreground_color()); if (!caption().is_empty()) - painter.draw_text(text_rect, caption(), Painter::TextAlignment::TopLeft, foreground_color()); + painter.draw_text(text_rect, caption(), TextAlignment::TopLeft, foreground_color()); if (is_focused()) { // NOTE: Painter::draw_focus_rect() will shrink(2,2) the passed rect. diff --git a/LibGUI/GLabel.cpp b/LibGUI/GLabel.cpp index d99cdd569c..dde70f1fc4 100644 --- a/LibGUI/GLabel.cpp +++ b/LibGUI/GLabel.cpp @@ -24,5 +24,5 @@ void GLabel::paint_event(GPaintEvent& event) if (fill_with_background_color()) painter.fill_rect({ 0, 0, width(), height() }, background_color()); if (!text().is_empty()) - painter.draw_text({ 4, 4, width(), height() }, text(), Painter::TextAlignment::TopLeft, foreground_color()); + painter.draw_text({ 4, 4, width(), height() }, text(), TextAlignment::TopLeft, foreground_color()); } diff --git a/LibGUI/GListBox.cpp b/LibGUI/GListBox.cpp index b5a5e738c1..ba627ab4c3 100644 --- a/LibGUI/GListBox.cpp +++ b/LibGUI/GListBox.cpp @@ -39,7 +39,7 @@ void GListBox::paint_event(GPaintEvent&) painter.fill_rect(item_rect, Color(96, 96, 96)); item_text_color = Color::White; } - painter.draw_text(item_rect, m_items[i], Painter::TextAlignment::TopLeft, item_text_color); + painter.draw_text(item_rect, m_items[i], TextAlignment::TopLeft, item_text_color); } } diff --git a/SharedGraphics/Painter.h b/SharedGraphics/Painter.h index e3e2cb8188..646bf4ee1b 100644 --- a/SharedGraphics/Painter.h +++ b/SharedGraphics/Painter.h @@ -16,6 +16,8 @@ class GWidget; class GWindow; #endif +enum class TextAlignment { TopLeft, CenterLeft, Center, CenterRight }; + class Painter { public: #ifndef KERNEL @@ -34,7 +36,6 @@ public: void blit(const Point&, const GraphicsBitmap&, const Rect& src_rect); void blit_with_alpha(const Point&, const GraphicsBitmap&, const Rect& src_rect); - enum class TextAlignment { TopLeft, CenterLeft, Center, CenterRight }; void draw_text(const Rect&, const String&, TextAlignment = TextAlignment::TopLeft, Color = Color()); void draw_glyph(const Point&, char, Color); diff --git a/Userland/guitest.cpp b/Userland/guitest.cpp index 314c999c12..b9fc6f82d0 100644 --- a/Userland/guitest.cpp +++ b/Userland/guitest.cpp @@ -90,5 +90,5 @@ void paint(GraphicsBitmap& bitmap, int width, int height) Color color(r, g, b); Painter painter(bitmap); painter.fill_rect({0, 0, width, height}, color); - painter.draw_text({0, 0, width, height}, "Hello World!", Painter::TextAlignment::Center, Color::Black); + painter.draw_text({0, 0, width, height}, "Hello World!", TextAlignment::Center, Color::Black); } diff --git a/WindowServer/WSMenu.cpp b/WindowServer/WSMenu.cpp index bc77860611..00c4c39241 100644 --- a/WindowServer/WSMenu.cpp +++ b/WindowServer/WSMenu.cpp @@ -43,6 +43,13 @@ int WSMenu::height() const return (m_items.last()->rect().bottom() - 1) + padding(); } +void WSMenu::redraw() +{ + ASSERT(menu_window()); + draw(); + menu_window()->invalidate(); +} + WSWindow& WSMenu::ensure_menu_window() { if (!m_menu_window) { @@ -59,21 +66,20 @@ WSWindow& WSMenu::ensure_menu_window() auto window = make(*this); window->set_rect(0, 0, width(), height()); - dbgprintf("Created menu window for menu '%s' (%u items) with rect %s\n", name().characters(), m_items.size(), window->rect().to_string().characters()); m_menu_window = move(window); draw(); } return *m_menu_window; } + void WSMenu::draw() { - ASSERT(m_menu_window); - ASSERT(m_menu_window->backing()); - Painter painter(*m_menu_window->backing()); - - Rect rect { { }, m_menu_window->size() }; + ASSERT(menu_window()); + ASSERT(menu_window()->backing()); + Painter painter(*menu_window()->backing()); + Rect rect { { }, menu_window()->size() }; painter.draw_rect(rect, Color::White); painter.fill_rect(rect.shrunken(2, 2), Color::LightGray); @@ -81,10 +87,10 @@ void WSMenu::draw() if (item->type() == WSMenuItem::Text) { Color text_color = Color::Black; if (item.ptr() == m_hovered_item) { - painter.fill_rect(item->rect(), Color(0, 0, 128)); + painter.fill_rect(item->rect(), Color(0, 0, 104)); text_color = Color::White; } - painter.draw_text(item->rect(), item->text(), Painter::TextAlignment::CenterLeft, text_color); + painter.draw_text(item->rect(), item->text(), TextAlignment::CenterLeft, text_color); } else if (item->type() == WSMenuItem::Separator) { Point p1(padding(), item->rect().center().y()); Point p2(width() - padding(), item->rect().center().y()); @@ -95,17 +101,22 @@ void WSMenu::draw() void WSMenu::on_window_message(WSMessage& message) { - dbgprintf("WSMenu::on_window_message: %u\n", message.type()); + ASSERT(menu_window()); if (message.type() == WSMessage::MouseMove) { - auto& mouse_event = static_cast(message); - for (auto& item : m_items) { - if (item->rect().contains(mouse_event.position())) { - if (m_hovered_item == item.ptr()) - return; - m_hovered_item = item.ptr(); - draw(); - menu_window()->invalidate(); - } - } + auto* item = item_at(static_cast(message).position()); + if (!item || m_hovered_item == item) + return; + m_hovered_item = item; + redraw(); + } +} + +WSMenuItem* WSMenu::item_at(const Point& position) +{ + for (auto& item : m_items) { + if (!item->rect().contains(position)) + continue; + return item.ptr(); } + return nullptr; } diff --git a/WindowServer/WSMenu.h b/WindowServer/WSMenu.h index bb4376a536..959dbfdf50 100644 --- a/WindowServer/WSMenu.h +++ b/WindowServer/WSMenu.h @@ -54,6 +54,9 @@ public: void draw(); const Font& font() const; + WSMenuItem* item_at(const Point&); + void redraw(); + private: String m_name; Rect m_rect_in_menubar; diff --git a/WindowServer/WSWindowManager.cpp b/WindowServer/WSWindowManager.cpp index 16e44b8505..215b8a0285 100644 --- a/WindowServer/WSWindowManager.cpp +++ b/WindowServer/WSWindowManager.cpp @@ -302,7 +302,7 @@ void WSWindowManager::paint_window_frame(WSWindow& window) m_back_painter->draw_rect(border_rect, middle_border_color); m_back_painter->draw_rect(outer_rect, border_color); m_back_painter->draw_rect(inner_border_rect, border_color); - m_back_painter->draw_text(titlebar_title_rect, window.title(), Painter::TextAlignment::CenterLeft, title_color); + m_back_painter->draw_text(titlebar_title_rect, window.title(), TextAlignment::CenterLeft, title_color); if (!s_close_button_bitmap) s_close_button_bitmap = CharacterBitmap::create_from_ascii(s_close_button_bitmap_data, s_close_button_bitmap_width, s_close_button_bitmap_height).leak_ref(); @@ -319,7 +319,7 @@ void WSWindowManager::paint_window_frame(WSWindow& window) m_back_painter->draw_text( titlebar_inner_rect, String::format("%d:%d", window.pid(), window.window_id()), - Painter::TextAlignment::CenterRight, + TextAlignment::CenterRight, metadata_color ); #endif @@ -476,8 +476,11 @@ void WSWindowManager::process_mouse_event(WSMouseEvent& event) return; } + // FIXME: Figure out an automatic menu dismissal logic that feels right. +#if 0 if (m_current_menu && event.type() == WSMouseEvent::MouseUp && event.button() == MouseButton::Left) close_current_menu(); +#endif for (auto* window = m_windows_in_order.tail(); window; window = window->prev()) { if (!window->is_visible()) @@ -610,10 +613,10 @@ void WSWindowManager::draw_menubar() m_current_menubar->for_each_menu([&] (WSMenu& menu) { Color text_color = Color::Black; if (&menu == m_current_menu) { - m_back_painter->fill_rect(menu.rect_in_menubar(), Color(0, 0, 128)); + m_back_painter->fill_rect(menu.rect_in_menubar(), Color(0, 0, 104)); text_color = Color::White; } - m_back_painter->draw_text(menu.text_rect_in_menubar(), menu.name(), Painter::TextAlignment::CenterLeft, text_color); + m_back_painter->draw_text(menu.text_rect_in_menubar(), menu.name(), TextAlignment::CenterLeft, text_color); return true; }); } -- cgit v1.2.3