Skip to content

Commit

Permalink
Implement menubar on Windows
Browse files Browse the repository at this point in the history
  • Loading branch information
dpjudas committed May 26, 2024
1 parent da787e4 commit 47188e6
Show file tree
Hide file tree
Showing 11 changed files with 307 additions and 47 deletions.
11 changes: 9 additions & 2 deletions include/zwidget/core/widget.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,12 @@ class Widget : DisplayWindowHost
void LockCursor();
void UnlockCursor();
void SetCursor(StandardCursor cursor);
void CaptureMouse();
void ReleaseMouseCapture();

void SetPointerCapture();
void ReleasePointerCapture();

void SetModalCapture();
void ReleaseModalCapture();

bool GetKeyState(InputKey key);

Expand All @@ -126,6 +130,9 @@ class Widget : DisplayWindowHost
Widget* ChildAt(double x, double y) { return ChildAt(Point(x, y)); }
Widget* ChildAt(const Point& pos);

bool IsParent(const Widget* w) const;
bool IsChild(const Widget* w) const;

Widget* Parent() const { return ParentObj; }
Widget* PrevSibling() const { return PrevSiblingObj; }
Widget* NextSibling() const { return NextSiblingObj; }
Expand Down
24 changes: 23 additions & 1 deletion include/zwidget/widgets/menubar/menubar.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,22 @@ class Menubar : public Widget

protected:
void OnGeometryChanged() override;
bool OnMouseDown(const Point& pos, InputKey key) override;
bool OnMouseUp(const Point& pos, InputKey key) override;
void OnMouseMove(const Point& pos) override;
void OnKeyDown(InputKey key) override;

private:
void ShowMenu(MenubarItem* item);
void CloseMenu();

MenubarItem* GetMenubarItemAt(const Point& pos);
int GetItemIndex(MenubarItem* item);

std::vector<MenubarItem*> menuItems;
int currentMenubarItem = -1;
Menu* openMenu = nullptr;
bool modalMode = false;

friend class MenubarItem;
};
Expand Down Expand Up @@ -70,30 +79,43 @@ class Menu : public Widget
double GetPreferredWidth() const;
double GetPreferredHeight() const;

void SetSelected(MenuItem* item);

protected:
void OnGeometryChanged() override;

std::function<void()> onCloseMenu;
MenuItem* selectedItem = nullptr;

friend class Menubar;
};

class MenuItem : public Widget
{
public:
MenuItem(Widget* parent);
MenuItem(Menu* menu, std::function<void()> onClick);

void Click();

Menu* menu = nullptr;
ImageBox* icon = nullptr;
TextLabel* text = nullptr;

protected:
bool OnMouseUp(const Point& pos, InputKey key) override;
void OnMouseMove(const Point& pos) override;
void OnMouseLeave() override;
void OnGeometryChanged() override;

private:
std::function<void()> onClick;
};

class MenuItemSeparator : public Widget
{
public:
MenuItemSeparator(Widget* parent);

protected:
void OnPaint(Canvas* canvas) override;
};
8 changes: 4 additions & 4 deletions src/core/canvas.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -509,22 +509,22 @@ void BitmapCanvas::drawLineUnclipped(const Point& p0, const Point& p1, const Col

int BitmapCanvas::getClipMinX() const
{
return clipStack.empty() ? 0 : (int)std::max(clipStack.back().x * uiscale, 0.0);
return clipStack.empty() ? 0 : (int)std::round(std::max(clipStack.back().x * uiscale, 0.0));
}

int BitmapCanvas::getClipMinY() const
{
return clipStack.empty() ? 0 : (int)std::max(clipStack.back().y * uiscale, 0.0);
return clipStack.empty() ? 0 : (int)std::round(std::max(clipStack.back().y * uiscale, 0.0));
}

int BitmapCanvas::getClipMaxX() const
{
return clipStack.empty() ? width : (int)std::min((clipStack.back().x + clipStack.back().width) * uiscale, (double)width);
return clipStack.empty() ? width : (int)std::round(std::min((clipStack.back().x + clipStack.back().width) * uiscale, (double)width));
}

int BitmapCanvas::getClipMaxY() const
{
return clipStack.empty() ? height : (int)std::min((clipStack.back().y + clipStack.back().height) * uiscale, (double)height);
return clipStack.empty() ? height : (int)std::round(std::min((clipStack.back().y + clipStack.back().height) * uiscale, (double)height));
}

void BitmapCanvas::fillTile(float left, float top, float width, float height, Colorf color)
Expand Down
13 changes: 13 additions & 0 deletions src/core/theme.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ DarkWidgetTheme::DarkWidgetTheme()
auto tabbar_tab = RegisterStyle(std::make_unique<BasicWidgetStyle>(widget), "tabbar-tab");
auto tabwidget_stack = RegisterStyle(std::make_unique<BasicWidgetStyle>(widget), "tabwidget-stack");
auto checkbox_label = RegisterStyle(std::make_unique<BasicWidgetStyle>(widget), "checkbox-label");
auto menubar = RegisterStyle(std::make_unique<BasicWidgetStyle>(widget), "menubar");
auto menubaritem = RegisterStyle(std::make_unique<BasicWidgetStyle>(widget), "menubaritem");
auto menu = RegisterStyle(std::make_unique<BasicWidgetStyle>(widget), "menu");
auto menuitem = RegisterStyle(std::make_unique<BasicWidgetStyle>(widget), "menuitem");
Expand Down Expand Up @@ -235,8 +236,13 @@ DarkWidgetTheme::DarkWidgetTheme()
checkbox_label->SetColor("unchecked-outer-border-color", Colorf::fromRgba8(99, 99, 99));
checkbox_label->SetColor("unchecked-inner-border-color", Colorf::fromRgba8(51, 51, 51));

menubar->SetColor("background-color", Colorf::fromRgba8(70, 70, 70));

menubaritem->SetColor("color", Colorf::fromRgba8(226, 223, 219));
menubaritem->SetColor("hover", "background-color", Colorf::fromRgba8(78, 78, 78));
menubaritem->SetColor("hover", "color", Colorf::fromRgba8(0, 0, 0));
menubaritem->SetColor("down", "background-color", Colorf::fromRgba8(88, 88, 88));
menubaritem->SetColor("down", "color", Colorf::fromRgba8(0, 0, 0));

menu->SetDouble("noncontent-left", 5.0);
menu->SetDouble("noncontent-top", 5.0);
Expand Down Expand Up @@ -266,6 +272,7 @@ LightWidgetTheme::LightWidgetTheme()
auto tabbar_tab = RegisterStyle(std::make_unique<BasicWidgetStyle>(widget), "tabbar-tab");
auto tabwidget_stack = RegisterStyle(std::make_unique<BasicWidgetStyle>(widget), "tabwidget-stack");
auto checkbox_label = RegisterStyle(std::make_unique<BasicWidgetStyle>(widget), "checkbox-label");
auto menubar = RegisterStyle(std::make_unique<BasicWidgetStyle>(widget), "menubar");
auto menubaritem = RegisterStyle(std::make_unique<BasicWidgetStyle>(widget), "menubaritem");
auto menu = RegisterStyle(std::make_unique<BasicWidgetStyle>(widget), "menu");
auto menuitem = RegisterStyle(std::make_unique<BasicWidgetStyle>(widget), "menuitem");
Expand Down Expand Up @@ -345,13 +352,19 @@ LightWidgetTheme::LightWidgetTheme()
checkbox_label->SetColor("unchecked-outer-border-color", Colorf::fromRgba8(156, 156, 156));
checkbox_label->SetColor("unchecked-inner-border-color", Colorf::fromRgba8(200, 200, 200));

menubar->SetColor("background-color", Colorf::fromRgba8(70, 70, 70));

menubaritem->SetColor("color", Colorf::fromRgba8(226, 223, 219));
menubaritem->SetColor("hover", "background-color", Colorf::fromRgba8(200, 200, 200));
menubaritem->SetColor("hover", "color", Colorf::fromRgba8(0, 0, 0));
menubaritem->SetColor("down", "background-color", Colorf::fromRgba8(190, 190, 190));
menubaritem->SetColor("down", "color", Colorf::fromRgba8(0, 0, 0));

menu->SetDouble("noncontent-left", 5.0);
menu->SetDouble("noncontent-top", 5.0);
menu->SetDouble("noncontent-right", 5.0);
menu->SetDouble("noncontent-bottom", 5.0);
menu->SetColor("background-color", Colorf::fromRgba8(255, 255, 255));
menu->SetColor("border-left-color", Colorf::fromRgba8(155, 155, 155));
menu->SetColor("border-top-color", Colorf::fromRgba8(155, 155, 155));
menu->SetColor("border-right-color", Colorf::fromRgba8(155, 155, 155));
Expand Down
40 changes: 38 additions & 2 deletions src/core/widget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -429,7 +429,7 @@ void Widget::SetCursor(StandardCursor cursor)
}
}

void Widget::CaptureMouse()
void Widget::SetPointerCapture()
{
Widget* w = Window();
if (w && w->CaptureWidget != this)
Expand All @@ -439,7 +439,7 @@ void Widget::CaptureMouse()
}
}

void Widget::ReleaseMouseCapture()
void Widget::ReleasePointerCapture()
{
Widget* w = Window();
if (w && w->CaptureWidget != nullptr)
Expand All @@ -449,6 +449,24 @@ void Widget::ReleaseMouseCapture()
}
}

void Widget::SetModalCapture()
{
Widget* w = Window();
if (w && w->CaptureWidget != this)
{
w->CaptureWidget = this;
}
}

void Widget::ReleaseModalCapture()
{
Widget* w = Window();
if (w && w->CaptureWidget != nullptr)
{
w->CaptureWidget = nullptr;
}
}

std::string Widget::GetClipboardText()
{
Widget* w = Window();
Expand Down Expand Up @@ -485,6 +503,24 @@ Canvas* Widget::GetCanvas() const
return nullptr;
}

bool Widget::IsParent(const Widget* w) const
{
while (w)
{
w = w->Parent();
if (w == this)
return true;
}
return false;
}

bool Widget::IsChild(const Widget* w) const
{
if (!w)
return false;
return w->IsParent(this);
}

Widget* Widget::ChildAt(const Point& pos)
{
for (Widget* cur = LastChild(); cur != nullptr; cur = cur->PrevSibling())
Expand Down
6 changes: 3 additions & 3 deletions src/widgets/lineedit/lineedit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,7 @@ bool LineEdit::OnMouseDown(const Point& pos, InputKey key)
{
if (HasFocus())
{
CaptureMouse();
SetPointerCapture();
mouse_selecting = true;
cursor_pos = GetCharacterIndex(pos.x);
SetTextSelection(cursor_pos, 0);
Expand All @@ -333,14 +333,14 @@ bool LineEdit::OnMouseUp(const Point& pos, InputKey key)
{
if (ignore_mouse_events) // This prevents text selection from changing from what was set when focus was gained.
{
ReleaseMouseCapture();
ReleasePointerCapture();
ignore_mouse_events = false;
mouse_selecting = false;
}
else
{
scroll_timer->Stop();
ReleaseMouseCapture();
ReleasePointerCapture();
mouse_selecting = false;
int sel_end = GetCharacterIndex(pos.x);
SetSelectionLength(sel_end - selection_start);
Expand Down
Loading

0 comments on commit 47188e6

Please sign in to comment.