|
@@ -79,7 +79,8 @@ static Gfx::IntRect frame_rect_for_window(Window& window, const Gfx::IntRect& re
|
|
{
|
|
{
|
|
if (window.is_frameless())
|
|
if (window.is_frameless())
|
|
return rect;
|
|
return rect;
|
|
- return Gfx::WindowTheme::current().frame_rect_for_window(to_theme_window_type(window.type()), rect, WindowManager::the().palette());
|
|
|
|
|
|
+ int menu_row_count = window.menubar() ? 1 : 0;
|
|
|
|
+ return Gfx::WindowTheme::current().frame_rect_for_window(to_theme_window_type(window.type()), rect, WindowManager::the().palette(), menu_row_count);
|
|
}
|
|
}
|
|
|
|
|
|
WindowFrame::WindowFrame(Window& window)
|
|
WindowFrame::WindowFrame(Window& window)
|
|
@@ -238,6 +239,13 @@ void WindowFrame::did_set_maximized(Badge<Window>, bool maximized)
|
|
m_maximize_button->set_icon(maximized ? *s_restore_icon : *s_maximize_icon);
|
|
m_maximize_button->set_icon(maximized ? *s_restore_icon : *s_maximize_icon);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+Gfx::IntRect WindowFrame::menubar_rect() const
|
|
|
|
+{
|
|
|
|
+ if (!m_window.menubar())
|
|
|
|
+ return {};
|
|
|
|
+ return Gfx::WindowTheme::current().menu_bar_rect(to_theme_window_type(m_window.type()), m_window.rect(), WindowManager::the().palette(), menu_row_count());
|
|
|
|
+}
|
|
|
|
+
|
|
Gfx::IntRect WindowFrame::title_bar_rect() const
|
|
Gfx::IntRect WindowFrame::title_bar_rect() const
|
|
{
|
|
{
|
|
return Gfx::WindowTheme::current().title_bar_rect(to_theme_window_type(m_window.type()), m_window.rect(), WindowManager::the().palette());
|
|
return Gfx::WindowTheme::current().title_bar_rect(to_theme_window_type(m_window.type()), m_window.rect(), WindowManager::the().palette());
|
|
@@ -289,11 +297,46 @@ void WindowFrame::paint_tool_window_frame(Gfx::Painter& painter)
|
|
Gfx::WindowTheme::current().paint_tool_window_frame(painter, window_state_for_theme(), m_window.rect(), compute_title_text(), palette, leftmost_button_rect);
|
|
Gfx::WindowTheme::current().paint_tool_window_frame(painter, window_state_for_theme(), m_window.rect(), compute_title_text(), palette, leftmost_button_rect);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+void WindowFrame::paint_menubar(Gfx::Painter& painter)
|
|
|
|
+{
|
|
|
|
+ auto& wm = WindowManager::the();
|
|
|
|
+ auto& font = wm.font();
|
|
|
|
+ auto palette = wm.palette();
|
|
|
|
+ auto menubar_rect = this->menubar_rect();
|
|
|
|
+
|
|
|
|
+ painter.fill_rect(menubar_rect, palette.window());
|
|
|
|
+
|
|
|
|
+ Gfx::PainterStateSaver saver(painter);
|
|
|
|
+ painter.translate(menubar_rect.location());
|
|
|
|
+
|
|
|
|
+ m_window.menubar()->for_each_menu([&](Menu& menu) {
|
|
|
|
+ auto text_rect = menu.text_rect_in_window_menubar();
|
|
|
|
+ Color text_color = palette.window_text();
|
|
|
|
+ if (MenuManager::the().is_open(menu)) {
|
|
|
|
+ painter.fill_rect(menu.rect_in_window_menubar(), palette.menu_selection());
|
|
|
|
+ text_color = palette.menu_selection_text();
|
|
|
|
+ text_rect.move_by(1, 1);
|
|
|
|
+ }
|
|
|
|
+ if (&menu == MenuManager::the().hovered_menu() || MenuManager::the().is_open(menu))
|
|
|
|
+ Gfx::StylePainter::paint_button(painter, menu.rect_in_window_menubar(), palette, Gfx::ButtonStyle::CoolBar, MenuManager::the().is_open(menu), true);
|
|
|
|
+ painter.draw_text(
|
|
|
|
+ text_rect,
|
|
|
|
+ menu.name(),
|
|
|
|
+ font,
|
|
|
|
+ Gfx::TextAlignment::CenterLeft,
|
|
|
|
+ text_color);
|
|
|
|
+ return IterationDecision::Continue;
|
|
|
|
+ });
|
|
|
|
+}
|
|
|
|
+
|
|
void WindowFrame::paint_normal_frame(Gfx::Painter& painter)
|
|
void WindowFrame::paint_normal_frame(Gfx::Painter& painter)
|
|
{
|
|
{
|
|
auto palette = WindowManager::the().palette();
|
|
auto palette = WindowManager::the().palette();
|
|
auto leftmost_button_rect = m_buttons.is_empty() ? Gfx::IntRect() : m_buttons.last().relative_rect();
|
|
auto leftmost_button_rect = m_buttons.is_empty() ? Gfx::IntRect() : m_buttons.last().relative_rect();
|
|
- Gfx::WindowTheme::current().paint_normal_frame(painter, window_state_for_theme(), m_window.rect(), compute_title_text(), m_window.icon(), palette, leftmost_button_rect);
|
|
|
|
|
|
+ Gfx::WindowTheme::current().paint_normal_frame(painter, window_state_for_theme(), m_window.rect(), compute_title_text(), m_window.icon(), palette, leftmost_button_rect, menu_row_count());
|
|
|
|
+
|
|
|
|
+ if (m_window.menubar())
|
|
|
|
+ paint_menubar(painter);
|
|
}
|
|
}
|
|
|
|
|
|
void WindowFrame::paint(Gfx::Painter& painter, const Gfx::IntRect& rect)
|
|
void WindowFrame::paint(Gfx::Painter& painter, const Gfx::IntRect& rect)
|
|
@@ -509,6 +552,13 @@ void WindowFrame::invalidate_title_bar()
|
|
invalidate(title_bar_rect());
|
|
invalidate(title_bar_rect());
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+void WindowFrame::invalidate()
|
|
|
|
+{
|
|
|
|
+ auto frame_rect = render_rect();
|
|
|
|
+ invalidate(Gfx::IntRect { frame_rect.location() - m_window.position(), frame_rect.size() });
|
|
|
|
+ m_window.invalidate(true, true);
|
|
|
|
+}
|
|
|
|
+
|
|
void WindowFrame::invalidate(Gfx::IntRect relative_rect)
|
|
void WindowFrame::invalidate(Gfx::IntRect relative_rect)
|
|
{
|
|
{
|
|
auto frame_rect = rect();
|
|
auto frame_rect = rect();
|
|
@@ -652,6 +702,13 @@ void WindowFrame::on_mouse_event(const MouseEvent& event)
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ auto menubar_rect = this->menubar_rect();
|
|
|
|
+ if (menubar_rect.contains(event.position())) {
|
|
|
|
+ wm.clear_resize_candidate();
|
|
|
|
+ handle_menubar_mouse_event(event);
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
if (m_window.is_resizable() && event.type() == Event::MouseMove && event.buttons() == 0) {
|
|
if (m_window.is_resizable() && event.type() == Event::MouseMove && event.buttons() == 0) {
|
|
constexpr ResizeDirection direction_for_hot_area[3][3] = {
|
|
constexpr ResizeDirection direction_for_hot_area[3][3] = {
|
|
{ ResizeDirection::UpLeft, ResizeDirection::Up, ResizeDirection::UpRight },
|
|
{ ResizeDirection::UpLeft, ResizeDirection::Up, ResizeDirection::UpRight },
|
|
@@ -673,6 +730,50 @@ void WindowFrame::on_mouse_event(const MouseEvent& event)
|
|
wm.start_window_resize(m_window, event.translated(rect().location()));
|
|
wm.start_window_resize(m_window, event.translated(rect().location()));
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+void WindowFrame::handle_menubar_mouse_event(const MouseEvent& event)
|
|
|
|
+{
|
|
|
|
+ Menu* hovered_menu = nullptr;
|
|
|
|
+ auto menubar_rect = this->menubar_rect();
|
|
|
|
+ auto adjusted_position = event.position().translated(-menubar_rect.location());
|
|
|
|
+ m_window.menubar()->for_each_menu([&](Menu& menu) {
|
|
|
|
+ if (menu.rect_in_window_menubar().contains(adjusted_position)) {
|
|
|
|
+ hovered_menu = &menu;
|
|
|
|
+ handle_menu_mouse_event(menu, event);
|
|
|
|
+ return IterationDecision::Break;
|
|
|
|
+ }
|
|
|
|
+ return IterationDecision::Continue;
|
|
|
|
+ });
|
|
|
|
+ if (!hovered_menu && event.type() == Event::Type::MouseDown)
|
|
|
|
+ MenuManager::the().close_everyone();
|
|
|
|
+ if (hovered_menu != MenuManager::the().hovered_menu()) {
|
|
|
|
+ MenuManager::the().set_hovered_menu(hovered_menu);
|
|
|
|
+ invalidate(menubar_rect);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void WindowFrame::handle_menu_mouse_event(Menu& menu, const MouseEvent& event)
|
|
|
|
+{
|
|
|
|
+ auto menubar_rect = this->menubar_rect();
|
|
|
|
+ bool is_hover_with_any_menu_open = event.type() == MouseEvent::MouseMove && &m_window == WindowManager::the().window_with_active_menu();
|
|
|
|
+ bool is_mousedown_with_left_button = event.type() == MouseEvent::MouseDown && event.button() == MouseButton::Left;
|
|
|
|
+ bool should_open_menu = &menu != MenuManager::the().current_menu() && (is_hover_with_any_menu_open || is_mousedown_with_left_button);
|
|
|
|
+ bool should_close_menu = &menu == MenuManager::the().current_menu() && is_mousedown_with_left_button;
|
|
|
|
+
|
|
|
|
+ if (should_open_menu) {
|
|
|
|
+ MenuManager::the().close_everyone();
|
|
|
|
+ menu.ensure_menu_window().move_to(menu.rect_in_window_menubar().bottom_left().translated(rect().location()).translated(menubar_rect.location()));
|
|
|
|
+ MenuManager::the().open_menu(menu, false);
|
|
|
|
+ WindowManager::the().set_window_with_active_menu(&m_window);
|
|
|
|
+ invalidate(menubar_rect);
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (should_close_menu) {
|
|
|
|
+ invalidate(menubar_rect);
|
|
|
|
+ MenuManager::the().close_everyone();
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
void WindowFrame::start_flash_animation()
|
|
void WindowFrame::start_flash_animation()
|
|
{
|
|
{
|
|
if (!m_flash_timer) {
|
|
if (!m_flash_timer) {
|
|
@@ -774,4 +875,9 @@ void WindowFrame::paint_simple_rect_shadow(Gfx::Painter& painter, const Gfx::Int
|
|
paint_vertical(containing_rect.right() - base_size + 1, 1, 0, horizontal_shift);
|
|
paint_vertical(containing_rect.right() - base_size + 1, 1, 0, horizontal_shift);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+int WindowFrame::menu_row_count() const
|
|
|
|
+{
|
|
|
|
+ return m_window.menubar() ? 1 : 0;
|
|
|
|
+}
|
|
|
|
+
|
|
}
|
|
}
|