diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index af2a7a5c2..2dd5b4fc0 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -300,7 +300,7 @@ add_library(aseprite-library
widgets/fileview.cpp
widgets/groupbut.cpp
widgets/hex_color_entry.cpp
- widgets/menuitem.cpp
+ widgets/menuitem2.cpp
widgets/palette_view.cpp
widgets/popup_frame_pin.cpp
widgets/statebar.cpp
diff --git a/src/app.cpp b/src/app.cpp
index c3d29158f..33962d950 100644
--- a/src/app.cpp
+++ b/src/app.cpp
@@ -54,7 +54,7 @@
#include "widgets/color_bar.h"
#include "widgets/editor/editor.h"
#include "widgets/editor/editor_view.h"
-#include "widgets/menuitem.h"
+#include "widgets/menuitem2.h"
#include "widgets/statebar.h"
#include "widgets/tabs.h"
#include "widgets/toolbar.h"
@@ -101,7 +101,7 @@ static Widget* box_colorbar = NULL; /* box where the color bar is */
static Widget* box_toolbar = NULL; /* box where the tools bar is */
static Widget* box_statusbar = NULL; /* box where the status bar is */
static Widget* box_tabsbar = NULL; /* box where the tabs bar is */
-static Widget* menubar = NULL; /* the menu bar widget */
+static MenuBar* menubar = NULL; /* the menu bar widget */
static StatusBar* statusbar = NULL; /* the status bar widget */
static ColorBar* colorbar = NULL; /* the color bar widget */
static Widget* toolbar = NULL; /* the tool bar widget */
@@ -180,7 +180,7 @@ int App::run()
box_statusbar = top_window->findChild("statusbar");
box_tabsbar = top_window->findChild("tabsbar");
- menubar = jmenubar_new();
+ menubar = new MenuBar();
statusbar = new StatusBar();
colorbar = new ColorBar(box_colorbar->getAlign());
toolbar = toolbar_new();
@@ -200,7 +200,7 @@ int App::run()
view->attachToView(editor);
/* setup the menus */
- jmenubar_set_menu(menubar, get_root_menu());
+ menubar->setMenu(get_root_menu());
/* start text of status bar */
app_default_statusbar_message();
@@ -288,7 +288,7 @@ int App::run()
// Remove the root-menu from the menu-bar (because the rootmenu
// module should destroy it).
- jmenubar_set_menu(menubar, NULL);
+ menubar->setMenu(NULL);
// Destroy the top-window
jwidget_free(top_window);
@@ -402,25 +402,25 @@ void app_update_document_tab(const Document* document)
*/
bool app_realloc_recent_list()
{
- Widget* list_menuitem = get_recent_list_menuitem();
- Widget* menuitem;
+ MenuItem* list_menuitem = get_recent_list_menuitem();
+ MenuItem* menuitem;
/* update the recent file list menu item */
if (list_menuitem) {
- if (jmenuitem_has_submenu_opened(list_menuitem))
+ if (list_menuitem->hasSubmenuOpened())
return false;
Command* cmd_open_file = CommandsModule::instance()->getCommandByName(CommandId::OpenFile);
- Widget* submenu = jmenuitem_get_submenu(list_menuitem);
+ Menu* submenu = list_menuitem->getSubmenu();
if (submenu) {
- jmenuitem_set_submenu(list_menuitem, NULL);
+ list_menuitem->setSubmenu(NULL);
jwidget_free(submenu);
}
// Build the menu of recent files
- submenu = jmenu_new();
- jmenuitem_set_submenu(list_menuitem, submenu);
+ submenu = new Menu();
+ list_menuitem->setSubmenu(submenu);
RecentFiles::const_iterator it = App::instance()->getRecentFiles()->begin();
RecentFiles::const_iterator end = App::instance()->getRecentFiles()->end();
@@ -433,12 +433,12 @@ bool app_realloc_recent_list()
params.set("filename", filename);
- menuitem = menuitem_new(get_filename(filename), cmd_open_file, ¶ms);
+ menuitem = new MenuItem2(get_filename(filename), cmd_open_file, ¶ms);
submenu->addChild(menuitem);
}
}
else {
- menuitem = menuitem_new("Nothing", NULL, NULL);
+ menuitem = new MenuItem2("Nothing", NULL, NULL);
menuitem->setEnabled(false);
submenu->addChild(menuitem);
}
@@ -462,7 +462,7 @@ int app_get_current_image_type()
}
Frame* app_get_top_window() { return top_window; }
-Widget* app_get_menubar() { return menubar; }
+MenuBar* app_get_menubar() { return menubar; }
StatusBar* app_get_statusbar() { return statusbar; }
ColorBar* app_get_colorbar() { return colorbar; }
Widget* app_get_toolbar() { return toolbar; }
diff --git a/src/app.h b/src/app.h
index 47979982f..2e0bc05ff 100644
--- a/src/app.h
+++ b/src/app.h
@@ -34,6 +34,7 @@ class Frame;
class Layer;
class LegacyModules;
class LoggerModule;
+class MenuBar;
class Params;
class RecentFiles;
class StatusBar;
@@ -96,7 +97,7 @@ bool app_realloc_recent_list();
int app_get_current_image_type();
Frame* app_get_top_window();
-Widget* app_get_menubar();
+MenuBar* app_get_menubar();
StatusBar* app_get_statusbar();
ColorBar* app_get_colorbar();
Widget* app_get_toolbar();
diff --git a/src/dialogs/aniedit.cpp b/src/dialogs/aniedit.cpp
index 23194ff74..2f20f27b0 100644
--- a/src/dialogs/aniedit.cpp
+++ b/src/dialogs/aniedit.cpp
@@ -529,9 +529,9 @@ bool AnimationEditor::onProcessMessage(Message* msg)
// Show the frame pop-up menu.
if (msg->mouse.right) {
if (m_clk_frame == m_hot_frame) {
- JWidget popup_menu = get_frame_popup_menu();
+ Menu* popup_menu = get_frame_popup_menu();
if (popup_menu != NULL) {
- jmenu_popup(popup_menu, msg->mouse.x, msg->mouse.y);
+ popup_menu->showPopup(msg->mouse.x, msg->mouse.y);
destroy_thumbnails();
invalidate();
@@ -571,9 +571,9 @@ bool AnimationEditor::onProcessMessage(Message* msg)
// Show the layer pop-up menu.
if (msg->mouse.right) {
if (m_clk_layer == m_hot_layer) {
- JWidget popup_menu = get_layer_popup_menu();
+ Menu* popup_menu = get_layer_popup_menu();
if (popup_menu != NULL) {
- jmenu_popup(popup_menu, msg->mouse.x, msg->mouse.y);
+ popup_menu->showPopup(msg->mouse.x, msg->mouse.y);
destroy_thumbnails();
invalidate();
@@ -654,10 +654,10 @@ bool AnimationEditor::onProcessMessage(Message* msg)
// Show the cel pop-up menu.
if (msg->mouse.right) {
- JWidget popup_menu = movement ? get_cel_movement_popup_menu():
- get_cel_popup_menu();
+ Menu* popup_menu = movement ? get_cel_movement_popup_menu():
+ get_cel_popup_menu();
if (popup_menu != NULL) {
- jmenu_popup(popup_menu, msg->mouse.x, msg->mouse.y);
+ popup_menu->showPopup(msg->mouse.x, msg->mouse.y);
destroy_thumbnails();
regenerateLayers();
diff --git a/src/gui/menu.cpp b/src/gui/menu.cpp
index 5262734f6..8f3959751 100644
--- a/src/gui/menu.cpp
+++ b/src/gui/menu.cpp
@@ -44,28 +44,8 @@ JM_MESSAGE(exe_menuitem);
#define JM_EXE_MENUITEM jm_exe_menuitem()
-//////////////////////////////////////////////////////////////////////
-// Some auxiliar matros
-
-#define MOUSE_IN(pos) \
- ((jmouse_x(0) >= pos->x1) && (jmouse_x(0) < pos->x2) && \
- (jmouse_y(0) >= pos->y1) && (jmouse_y(0) < pos->y2))
-
-#define MBOX(widget) \
- ((MenuBox*)jwidget_get_data((widget), JI_MENUBOX))
-
-#define MENU(widget) \
- ((Menu*)jwidget_get_data((widget), JI_MENU))
-
-#define MITEM(widget) \
- ((MenuItem*)jwidget_get_data((widget), JI_MENUITEM))
-
-#define HAS_SUBMENU(menuitem) \
- ((MITEM(menuitem)->submenu) && \
- (!jlist_empty(MITEM(menuitem)->submenu->children)))
-
// Data for the main jmenubar or the first popuped-jmenubox
-struct Base
+struct MenuBaseData
{
// True when the menu-items must be opened with the cursor movement
bool was_clicked : 1;
@@ -79,200 +59,145 @@ struct Base
bool is_filtering : 1;
bool close_all : 1;
+
+ MenuBaseData()
+ {
+ was_clicked = false;
+ is_filtering = false;
+ is_processing = false;
+ close_all = false;
+ }
+
};
-// Data for a jmenu
-struct Menu
-{
- Widget* menuitem; // From where the menu was open
-};
+static MenuBox* get_base_menubox(Widget* widget);
+static MenuBaseData* get_base(Widget* widget);
-// Data for a jmenubox
-struct MenuBox
-{
- Base *base;
-};
-
-// Data for a jmenuitem
-struct MenuItem
-{
- JAccel accel; // Hot-key
- bool highlight : 1; // Is it highlighted?
- Widget* submenu; // The sub-menu
- Widget* submenu_menubox; // The opened menubox for this menu-item
- int submenu_timer; // Timer to open the submenu
-};
-
-static bool menu_msg_proc(Widget* widget, Message* msg);
-static void menu_request_size(Widget* widget, int *w, int *h);
-static void menu_set_position(Widget* widget, JRect rect);
-
-static bool menubox_msg_proc(Widget* widget, Message* msg);
-static void menubox_request_size(Widget* widget, int *w, int *h);
-static void menubox_set_position(Widget* widget, JRect rect);
-
-static bool menuitem_msg_proc(Widget* widget, Message* msg);
-static void menuitem_request_size(Widget* widget, int *w, int *h);
-
-static Widget* get_base_menubox(Widget* widget);
-static Base *get_base(Widget* widget);
-static Base *create_base(Widget* widget);
-
-static Widget* get_highlight(Widget* menu);
-static void set_highlight(Widget* menu, Widget* menuitem, bool click, bool open_submenu, bool select_first_child);
-static void unhighlight(Widget* menu);
-
-static void open_menuitem(Widget* menuitem, bool select_first);
-static void close_menuitem(Widget* menuitem, bool last_of_close_chain);
-static void close_popup(Widget* menubox);
-static void close_all(Widget* menu);
-static void exe_menuitem(Widget* menuitem);
static bool window_msg_proc(Widget* widget, Message* msg);
-static Widget* check_for_letter(Widget* menu, int ascii);
-static Widget* check_for_accel(Widget* menu, Message* msg);
+static MenuItem* check_for_letter(Menu* menu, int ascii);
+static MenuItem* check_for_accel(Menu* menu, Message* msg);
-static Widget* find_nextitem(Widget* menu, Widget* menuitem);
-static Widget* find_previtem(Widget* menu, Widget* menuitem);
+static MenuItem* find_nextitem(Menu* menu, MenuItem* menuitem);
+static MenuItem* find_previtem(Menu* menu, MenuItem* menuitem);
-Widget* jmenu_new()
+Menu::Menu()
+ : Widget(JI_MENU)
+ , m_menuitem(NULL)
{
- Widget* widget = new Widget(JI_MENU);
- Menu* menu = new Menu;
-
- menu->menuitem = NULL;
-
- jwidget_add_hook(widget, JI_MENU, menu_msg_proc, menu);
- widget->initTheme();
-
- return widget;
+ initTheme();
}
-Widget* jmenubar_new()
+Menu::~Menu()
{
- Widget* widget = jmenubox_new();
-
- create_base(widget);
-
- widget->type = JI_MENUBAR;
- widget->initTheme();
-
- return widget;
-}
-
-Widget* jmenubox_new()
-{
- Widget* widget = new Widget(JI_MENUBOX);
- MenuBox* menubox = new MenuBox;
-
- menubox->base = NULL;
-
- jwidget_add_hook(widget, JI_MENUBOX, menubox_msg_proc, menubox);
- jwidget_focusrest(widget, true);
- widget->initTheme();
-
- return widget;
-}
-
-Widget* jmenuitem_new(const char *text)
-{
- Widget* widget = new Widget(JI_MENUITEM);
- MenuItem* menuitem = new MenuItem;
-
- menuitem->accel = NULL;
- menuitem->highlight = false;
- menuitem->submenu = NULL;
- menuitem->submenu_menubox = NULL;
- menuitem->submenu_timer = -1;
-
- jwidget_add_hook(widget, JI_MENUITEM, menuitem_msg_proc, menuitem);
- widget->setText(text);
- widget->initTheme();
-
- return widget;
-}
-
-Widget* jmenubox_get_menu(Widget* widget)
-{
- ASSERT_VALID_WIDGET(widget);
-
- if (jlist_empty(widget->children))
- return NULL;
- else
- return (Widget*)jlist_first(widget->children)->data;
-}
-
-Widget* jmenubar_get_menu(Widget* widget)
-{
- ASSERT_VALID_WIDGET(widget);
-
- return jmenubox_get_menu(widget);
-}
-
-Widget* jmenuitem_get_submenu(Widget* widget)
-{
- MenuItem *menuitem;
-
- ASSERT_VALID_WIDGET(widget);
-
- menuitem = MITEM(widget);
-
- return menuitem->submenu ? menuitem->submenu: NULL;
-}
-
-JAccel jmenuitem_get_accel(Widget* widget)
-{
- ASSERT_VALID_WIDGET(widget);
-
- return MITEM(widget)->accel;
-}
-
-bool jmenuitem_has_submenu_opened(Widget* widget)
-{
- ASSERT_VALID_WIDGET(widget);
-
- return MITEM(widget)->submenu_menubox != NULL;
-}
-
-void jmenubox_set_menu(Widget* widget, Widget* widget_menu)
-{
- Widget* old_menu;
-
- ASSERT_VALID_WIDGET(widget);
-
- old_menu = jmenubox_get_menu(widget);
- if (old_menu)
- widget->removeChild(old_menu);
-
- if (widget_menu) {
- ASSERT_VALID_WIDGET(widget_menu);
- widget->addChild(widget_menu);
+ if (m_menuitem) {
+ if (m_menuitem->getSubmenu() == this) {
+ m_menuitem->setSubmenu(NULL);
+ }
+ else {
+ ASSERT(m_menuitem->getSubmenu() == NULL);
+ }
}
}
-void jmenubar_set_menu(Widget* widget, Widget* widget_menu)
+MenuBox::MenuBox(int type)
+ : Widget(type)
+ , m_base(NULL)
{
- ASSERT_VALID_WIDGET(widget);
-
- jmenubox_set_menu(widget, widget_menu);
+ jwidget_focusrest(this, true);
+ initTheme();
}
-void jmenuitem_set_submenu(Widget* widget, Widget* widget_menu)
+MenuBox::~MenuBox()
{
- MenuItem *menuitem;
+ if (m_base && m_base->is_filtering) {
+ m_base->is_filtering = false;
+ jmanager_remove_msg_filter(JM_BUTTONPRESSED, this);
+ }
- ASSERT_VALID_WIDGET(widget);
+ delete m_base;
+}
- menuitem = MITEM(widget);
+MenuBar::MenuBar()
+ : MenuBox(JI_MENUBAR)
+{
+ createBase();
+}
- if (menuitem->submenu)
- MENU(menuitem->submenu)->menuitem = NULL;
+MenuItem::MenuItem(const char *text)
+ : Widget(JI_MENUITEM)
+{
+ m_accel = NULL;
+ m_highlighted = false;
+ m_submenu = NULL;
+ m_submenu_menubox = NULL;
+ m_submenu_timer = -1;
- menuitem->submenu = widget_menu;
+ setText(text);
+ initTheme();
+}
- if (menuitem->submenu) {
- ASSERT_VALID_WIDGET(widget_menu);
- MENU(menuitem->submenu)->menuitem = widget;
+MenuItem::~MenuItem()
+{
+ if (m_accel)
+ jaccel_free(m_accel);
+
+ if (m_submenu)
+ jwidget_free(m_submenu);
+
+ // Stop timer to open the popup
+ if (m_submenu_timer >= 0) {
+ jmanager_remove_timer(m_submenu_timer);
+ m_submenu_timer = -1;
+ }
+}
+
+Menu* MenuBox::getMenu()
+{
+ if (jlist_empty(children))
+ return NULL;
+ else
+ return static_cast