mirror of
https://github.com/aseprite/aseprite.git
synced 2025-01-16 22:18:30 +00:00
207 lines
5.1 KiB
C++
207 lines
5.1 KiB
C++
// Aseprite UI Library
|
|
// Copyright (C) 2020-2022 Igara Studio S.A.
|
|
// Copyright (C) 2001-2018 David Capello
|
|
//
|
|
// This file is released under the terms of the MIT license.
|
|
// Read LICENSE.txt for more information.
|
|
|
|
#ifndef UI_MENU_H_INCLUDED
|
|
#define UI_MENU_H_INCLUDED
|
|
#pragma once
|
|
|
|
#include "obs/signal.h"
|
|
#include "ui/register_message.h"
|
|
#include "ui/separator.h"
|
|
#include "ui/widget.h"
|
|
#include "ui/window.h"
|
|
|
|
#include <memory>
|
|
|
|
namespace ui {
|
|
|
|
class MenuBoxWindow;
|
|
class MenuItem;
|
|
class Timer;
|
|
struct MenuBaseData;
|
|
|
|
class Menu : public Widget {
|
|
public:
|
|
Menu();
|
|
~Menu();
|
|
|
|
void showPopup(const gfx::Point& pos,
|
|
Display* parentDisplay);
|
|
Widget* findItemById(const char* id) const;
|
|
|
|
// Returns the MenuItem that has as submenu this menu.
|
|
MenuItem* getOwnerMenuItem() {
|
|
return m_menuitem;
|
|
}
|
|
|
|
obs::signal<void()> OpenPopup;
|
|
|
|
protected:
|
|
virtual void onPaint(PaintEvent& ev) override;
|
|
virtual void onResize(ResizeEvent& ev) override;
|
|
virtual void onSizeHint(SizeHintEvent& ev) override;
|
|
virtual void onOpenPopup();
|
|
|
|
private:
|
|
void setOwnerMenuItem(MenuItem* ownerMenuItem) {
|
|
m_menuitem = ownerMenuItem;
|
|
}
|
|
|
|
void closeAll();
|
|
|
|
MenuItem* getHighlightedItem();
|
|
void highlightItem(MenuItem* menuitem, bool click, bool open_submenu, bool select_first_child);
|
|
void unhighlightItem();
|
|
|
|
MenuItem* m_menuitem; // From where the menu was open
|
|
|
|
friend class MenuBox;
|
|
friend class MenuItem;
|
|
};
|
|
|
|
class MenuBox : public Widget {
|
|
public:
|
|
MenuBox(WidgetType type = kMenuBoxWidget);
|
|
~MenuBox();
|
|
|
|
Menu* getMenu();
|
|
void setMenu(Menu* menu);
|
|
|
|
MenuBaseData* getBase() {
|
|
return m_base.get();
|
|
}
|
|
|
|
// Closes all menu-boxes and goes back to the normal state of the
|
|
// menu-bar.
|
|
void cancelMenuLoop();
|
|
|
|
protected:
|
|
virtual bool onProcessMessage(Message* msg) override;
|
|
virtual void onResize(ResizeEvent& ev) override;
|
|
virtual void onSizeHint(SizeHintEvent& ev) override;
|
|
MenuBaseData* createBase();
|
|
|
|
private:
|
|
void closePopup();
|
|
void startFilteringMouseDown();
|
|
void stopFilteringMouseDown();
|
|
|
|
std::unique_ptr<MenuBaseData> m_base;
|
|
|
|
friend class Menu;
|
|
friend class MenuItem;
|
|
};
|
|
|
|
class MenuBar : public MenuBox {
|
|
public:
|
|
enum class ProcessTopLevelShortcuts { kNo, kYes };
|
|
|
|
MenuBar(ProcessTopLevelShortcuts processShortcuts);
|
|
|
|
bool processTopLevelShortcuts() const {
|
|
return m_processTopLevelShortcuts;
|
|
}
|
|
|
|
static bool expandOnMouseover();
|
|
static void setExpandOnMouseover(bool state);
|
|
|
|
private:
|
|
// True if we should open top-level menus with Alt+mnemonic (this
|
|
// flag is not used by Aseprite), top-level menus are opened with
|
|
// the ShowMenu command now.
|
|
bool m_processTopLevelShortcuts;
|
|
static bool m_expandOnMouseover;
|
|
};
|
|
|
|
class MenuItem : public Widget {
|
|
public:
|
|
MenuItem(const std::string& text);
|
|
~MenuItem();
|
|
|
|
Menu* getSubmenu();
|
|
void setSubmenu(Menu* submenu);
|
|
|
|
// Open the submenu of this menu item (the menu item should be
|
|
// positioned in a correct position on the screen).
|
|
void openSubmenu();
|
|
|
|
bool isHighlighted() const;
|
|
void setHighlighted(bool state);
|
|
|
|
// Returns true if the MenuItem has a submenu.
|
|
bool hasSubmenu() const;
|
|
|
|
// Returns true if the submenu is opened.
|
|
bool hasSubmenuOpened() const {
|
|
return (m_submenu_menubox != nullptr);
|
|
}
|
|
|
|
// Returns the menu-box where the sub-menu has been opened, or
|
|
// just nullptr if the sub-menu is closed.
|
|
MenuBox* getSubmenuContainer() const {
|
|
return m_submenu_menubox;
|
|
}
|
|
|
|
void executeClick();
|
|
void validateItem();
|
|
|
|
// Fired when the menu item is clicked.
|
|
obs::signal<void()> Click;
|
|
|
|
protected:
|
|
bool onProcessMessage(Message* msg) override;
|
|
void onInitTheme(InitThemeEvent& ev) override;
|
|
void onPaint(PaintEvent& ev) override;
|
|
void onSizeHint(SizeHintEvent& ev) override;
|
|
virtual void onClick();
|
|
virtual void onValidate();
|
|
|
|
bool inBar() const;
|
|
|
|
private:
|
|
void openSubmenu(bool select_first);
|
|
void closeSubmenu(bool last_of_close_chain);
|
|
void startTimer();
|
|
void stopTimer();
|
|
|
|
bool m_highlighted; // Is it highlighted?
|
|
Menu* m_submenu; // The sub-menu
|
|
MenuBox* m_submenu_menubox; // The opened menubox for this menu-item
|
|
std::unique_ptr<Timer> m_submenu_timer; // Timer to open the submenu
|
|
|
|
friend class Menu;
|
|
friend class MenuBox;
|
|
friend class MenuBoxWindow;
|
|
};
|
|
|
|
class MenuSeparator : public Separator {
|
|
public:
|
|
MenuSeparator() : Separator("", HORIZONTAL) {
|
|
}
|
|
};
|
|
|
|
class MenuBoxWindow : public Window {
|
|
public:
|
|
MenuBoxWindow(MenuItem* menuitem = nullptr);
|
|
~MenuBoxWindow();
|
|
MenuBox* menubox() { return &m_menubox; }
|
|
protected:
|
|
bool onProcessMessage(Message* msg) override;
|
|
private:
|
|
MenuBox m_menubox;
|
|
MenuItem* m_menuitem;
|
|
};
|
|
|
|
extern RegisterMessage kOpenMenuItemMessage;
|
|
extern RegisterMessage kCloseMenuItemMessage;
|
|
extern RegisterMessage kClosePopupMessage;
|
|
extern RegisterMessage kExecuteMenuItemMessage;
|
|
|
|
} // namespace ui
|
|
|
|
#endif
|