diff --git a/TODO.md b/TODO.md index bd794757c..9ac1d6df7 100644 --- a/TODO.md +++ b/TODO.md @@ -13,7 +13,6 @@ * MovingPixelsState: Add undo information in each transformation step. * Add IntEntry class in src/gui/ with spin-buttons. * Add feedback to "Shift+S" shortcut to switch "snap to grid". -* Convert jaccel::key_list to std::vector<> * Add color swatches bar. * Sort palette entries. * Add "Remap" button to palette editor after a palette entry is modified: @@ -38,7 +37,6 @@ then cloned, and finally filled with params. * About Signals/Slots: Add some field in slots to avoid disconnecting them from dead signals. -* Eradicate JList. * Replace JRect & jrect with gfx::Rect. * Create gfx::Region to replace JRegion & jregion. * editors_ -> MultiEditors class widget @@ -47,7 +45,6 @@ * move all functions (jwidget_*) to methods in Widget class. * the same for each widget (e.g. jbutton_* to Button widget) * AppHooks to Vaca::Signals - * Convert all JI_SIGNAL to base::Signals * all member functions should be named verbNoun instead of verb_noun or noun_verb. * all functions to handle an object should be converted to member functions: * e.g. jwidget_set_text -> Widget::setText diff --git a/src/app_menus.cpp b/src/app_menus.cpp index f7f9a22a3..09c716763 100644 --- a/src/app_menus.cpp +++ b/src/app_menus.cpp @@ -129,7 +129,7 @@ void AppMenus::reload() PRINTF(" - Shortcut for command `%s' <%s>\n", command_name, command_key); // add the keyboard shortcut to the command - JAccel accel = + Accelerator* accel = add_keyboard_shortcut_to_execute_command(command_key, command_name, ¶ms); // add the shortcut to the menuitems with this @@ -364,13 +364,10 @@ Widget* AppMenus::createInvalidVersionMenuitem() return menuitem; } -void AppMenus::applyShortcutToMenuitemsWithCommand(Menu* menu, Command *command, Params* params, JAccel accel) +void AppMenus::applyShortcutToMenuitemsWithCommand(Menu* menu, Command *command, Params* params, Accelerator* accel) { - JList children = menu->getChildren(); - JLink link; - - JI_LIST_FOR_EACH(children, link) { - Widget* child = (Widget*)link->data; + UI_FOREACH_WIDGET(menu->getChildren(), it) { + Widget* child = *it; if (child->getType() == JI_MENUITEM) { ASSERT(dynamic_cast(child) != NULL); @@ -384,13 +381,11 @@ void AppMenus::applyShortcutToMenuitemsWithCommand(Menu* menu, Command *command, ((mi_params && *mi_params == *params) || (Params() == *params))) { // Set the accelerator to be shown in this menu-item - menuitem->setAccel(jaccel_new_copy(accel)); + menuitem->setAccel(new Accelerator(*accel)); } if (Menu* submenu = menuitem->getSubmenu()) applyShortcutToMenuitemsWithCommand(submenu, command, params, accel); } } - - jlist_free(children); } diff --git a/src/app_menus.h b/src/app_menus.h index e914fcbd3..ab9d8d8c8 100644 --- a/src/app_menus.h +++ b/src/app_menus.h @@ -29,6 +29,8 @@ class Params; class TiXmlElement; class TiXmlHandle; +namespace ui { class Accelerator; } + // Class to handle/get/reload available menus in gui.xml file. class AppMenus { @@ -56,7 +58,7 @@ private: ui::Menu* convertXmlelemToMenu(TiXmlElement* elem); ui::Widget* convertXmlelemToMenuitem(TiXmlElement* elem); ui::Widget* createInvalidVersionMenuitem(); - void applyShortcutToMenuitemsWithCommand(ui::Menu* menu, Command* command, Params* params, ui::JAccel accel); + void applyShortcutToMenuitemsWithCommand(ui::Menu* menu, Command* command, Params* params, ui::Accelerator* accel); UniquePtr m_rootMenu; ui::MenuItem* m_recentListMenuitem; diff --git a/src/commands/cmd_advanced_mode.cpp b/src/commands/cmd_advanced_mode.cpp index bb3b8bdf9..4975146a8 100644 --- a/src/commands/cmd_advanced_mode.cpp +++ b/src/commands/cmd_advanced_mode.cpp @@ -74,10 +74,9 @@ void AdvancedModeCommand::onExecute(Context* context) if (advanced_mode && get_config_bool("AdvancedMode", "Warning", true)) { - JAccel accel = get_accel_to_execute_command(short_name()); + Accelerator* accel = get_accel_to_execute_command(short_name()); if (accel != NULL) { char warning[1024]; - char key[1024]; char buf[1024]; UniquePtr window(app::load_widget("advanced_mode.xml", "advanced_mode_warning")); @@ -85,8 +84,7 @@ void AdvancedModeCommand::onExecute(Context* context) Widget* donot_show = app::find_widget(window, "donot_show"); strcpy(warning, "You can back pressing the \"%s\" key."); - jaccel_to_string(accel, key); - std::sprintf(buf, warning, key); + std::sprintf(buf, warning, accel->toString().c_str()); warning_label->setText(buf); diff --git a/src/commands/filters/cmd_convolution_matrix.cpp b/src/commands/filters/cmd_convolution_matrix.cpp index 2cccecb1a..485ad1fd6 100644 --- a/src/commands/filters/cmd_convolution_matrix.cpp +++ b/src/commands/filters/cmd_convolution_matrix.cpp @@ -34,7 +34,6 @@ #include "raster/sprite.h" #include "ui/button.h" #include "ui/label.h" -#include "ui/list.h" #include "ui/listbox.h" #include "ui/slider.h" #include "ui/view.h" @@ -88,11 +87,10 @@ private: void fillStockListBox() { const char* oldSelected = (m_filter.getMatrix() ? m_filter.getMatrix()->getName(): NULL); - JLink link, next; // Clean the list - JI_LIST_FOR_EACH_SAFE(m_stockListBox->children, link, next) { - Widget* listitem = reinterpret_cast(link->data); + while (!m_stockListBox->getChildren().empty()) { + Widget* listitem = m_stockListBox->getChildren().front(); m_stockListBox->removeChild(listitem); delete listitem; } @@ -109,12 +107,11 @@ private: void selectMatrixByName(const char* oldSelected) { - Widget* select_this = reinterpret_cast(jlist_first_data(m_stockListBox->children)); + Widget* select_this = UI_FIRST_WIDGET(m_stockListBox->getChildren()); if (oldSelected) { - JLink link; - JI_LIST_FOR_EACH(m_stockListBox->children, link) { - Widget* child = reinterpret_cast(link->data); + UI_FOREACH_WIDGET(m_stockListBox->getChildren(), it) { + Widget* child = *it; if (strcmp(child->getText(), oldSelected) == 0) { select_this = child; diff --git a/src/file/ase_format.cpp b/src/file/ase_format.cpp index 06a6ce8e0..c13b57bc9 100644 --- a/src/file/ase_format.cpp +++ b/src/file/ase_format.cpp @@ -25,7 +25,6 @@ #include "file/file_handle.h" #include "file/format_options.h" #include "raster/raster.h" -#include "ui/list.h" #include "zlib.h" #include diff --git a/src/modules/editors.cpp b/src/modules/editors.cpp index 48a9e45f9..45e4e9674 100644 --- a/src/modules/editors.cpp +++ b/src/modules/editors.cpp @@ -123,41 +123,41 @@ public: } bool isCopySelectionKeyPressed() OVERRIDE { - JAccel accel = get_accel_to_copy_selection(); + Accelerator* accel = get_accel_to_copy_selection(); if (accel) - return jaccel_check_from_key(accel); + return accel->checkFromAllegroKeyArray(); else return false; } bool isSnapToGridKeyPressed() OVERRIDE { - JAccel accel = get_accel_to_snap_to_grid(); + Accelerator* accel = get_accel_to_snap_to_grid(); if (accel) - return jaccel_check_from_key(accel); + return accel->checkFromAllegroKeyArray(); else return false; } bool isAngleSnapKeyPressed() OVERRIDE { - JAccel accel = get_accel_to_angle_snap(); + Accelerator* accel = get_accel_to_angle_snap(); if (accel) - return jaccel_check_from_key(accel); + return accel->checkFromAllegroKeyArray(); else return false; } bool isMaintainAspectRatioKeyPressed() OVERRIDE { - JAccel accel = get_accel_to_maintain_aspect_ratio(); + Accelerator* accel = get_accel_to_maintain_aspect_ratio(); if (accel) - return jaccel_check_from_key(accel); + return accel->checkFromAllegroKeyArray(); else return false; } bool isLockAxisKeyPressed() OVERRIDE { - JAccel accel = get_accel_to_lock_axis(); + Accelerator* accel = get_accel_to_lock_axis(); if (accel) - return jaccel_check_from_key(accel); + return accel->checkFromAllegroKeyArray(); else return false; } @@ -515,7 +515,7 @@ void close_editor(Editor* editor) delete view; // Fixup the parent. - other_widget = reinterpret_cast(jlist_first_data(parent_box->children)); + other_widget = UI_FIRST_WIDGET(parent_box->getChildren()); parent_box->removeChild(other_widget); parent_box->getParent()->replaceChild(parent_box, other_widget); @@ -544,8 +544,6 @@ void close_editor(Editor* editor) void make_unique_editor(Editor* editor) { View* view = View::getView(editor); - JLink link, next; - Widget* child; // It's the unique editor. if (editors.size() == 1) @@ -555,9 +553,8 @@ void make_unique_editor(Editor* editor) view->getParent()->removeChild(view); // Remove all children of main_editor_box. - JI_LIST_FOR_EACH_SAFE(box_editors->children, link, next) { - child = (Widget*)link->data; - + while (!box_editors->getChildren().empty()) { + Widget* child = box_editors->getChildren().front(); box_editors->removeChild(child); delete child; // widget } @@ -617,14 +614,13 @@ static Document* get_more_reliable_document() static Widget* find_next_editor(Widget* widget) { Widget* editor = NULL; - JLink link; if (widget->type == JI_VIEW) { - editor = reinterpret_cast(jlist_first_data(static_cast(widget)->getViewport()->children)); + editor = UI_FIRST_WIDGET(static_cast(widget)->getViewport()->getChildren()); } else { - JI_LIST_FOR_EACH(widget->children, link) - if ((editor = find_next_editor(reinterpret_cast(link->data)))) + UI_FOREACH_WIDGET(widget->getChildren(), it) + if ((editor = find_next_editor(*it))) break; } diff --git a/src/modules/gui.cpp b/src/modules/gui.cpp index 664c7fb7e..6ca1df5a5 100644 --- a/src/modules/gui.cpp +++ b/src/modules/gui.cpp @@ -99,7 +99,7 @@ enum ShortcutType { Shortcut_ExecuteCommand, struct Shortcut { - JAccel accel; + Accelerator* accel; ShortcutType type; union { Command* command; @@ -666,7 +666,7 @@ CheckBox* check_button_new(const char *text, int b1, int b2, int b3, int b4) // Keyboard shortcuts ////////////////////////////////////////////////////////////////////// -JAccel add_keyboard_shortcut_to_execute_command(const char* shortcut_string, const char* command_name, Params* params) +Accelerator* add_keyboard_shortcut_to_execute_command(const char* shortcut_string, const char* command_name, Params* params) { Shortcut* shortcut = get_keyboard_shortcut_for_command(command_name, params); if (!shortcut) { @@ -681,7 +681,7 @@ JAccel add_keyboard_shortcut_to_execute_command(const char* shortcut_string, con return shortcut->accel; } -JAccel add_keyboard_shortcut_to_change_tool(const char* shortcut_string, tools::Tool* tool) +Accelerator* add_keyboard_shortcut_to_change_tool(const char* shortcut_string, tools::Tool* tool) { Shortcut* shortcut = get_keyboard_shortcut_for_tool(tool); if (!shortcut) { @@ -695,7 +695,7 @@ JAccel add_keyboard_shortcut_to_change_tool(const char* shortcut_string, tools:: return shortcut->accel; } -JAccel add_keyboard_shortcut_to_quicktool(const char* shortcut_string, tools::Tool* tool) +Accelerator* add_keyboard_shortcut_to_quicktool(const char* shortcut_string, tools::Tool* tool) { Shortcut* shortcut = get_keyboard_shortcut_for_quicktool(tool); if (!shortcut) { @@ -709,7 +709,7 @@ JAccel add_keyboard_shortcut_to_quicktool(const char* shortcut_string, tools::To return shortcut->accel; } -JAccel add_keyboard_shortcut_to_spriteeditor(const char* shortcut_string, const char* action_name) +Accelerator* add_keyboard_shortcut_to_spriteeditor(const char* shortcut_string, const char* action_name) { Shortcut* shortcut = get_keyboard_shortcut_for_spriteeditor(action_name); if (!shortcut) { @@ -738,7 +738,7 @@ bool get_command_from_key_message(Message* msg, Command** command, Params** para return false; } -JAccel get_accel_to_execute_command(const char* command_name, Params* params) +Accelerator* get_accel_to_execute_command(const char* command_name, Params* params) { Shortcut* shortcut = get_keyboard_shortcut_for_command(command_name, params); if (shortcut) @@ -747,7 +747,7 @@ JAccel get_accel_to_execute_command(const char* command_name, Params* params) return NULL; } -JAccel get_accel_to_change_tool(tools::Tool* tool) +Accelerator* get_accel_to_change_tool(tools::Tool* tool) { Shortcut* shortcut = get_keyboard_shortcut_for_tool(tool); if (shortcut) @@ -756,7 +756,7 @@ JAccel get_accel_to_change_tool(tools::Tool* tool) return NULL; } -JAccel get_accel_to_copy_selection() +Accelerator* get_accel_to_copy_selection() { Shortcut* shortcut = get_keyboard_shortcut_for_spriteeditor(SPRITEDITOR_ACTION_COPYSELECTION); if (shortcut) @@ -765,7 +765,7 @@ JAccel get_accel_to_copy_selection() return NULL; } -JAccel get_accel_to_snap_to_grid() +Accelerator* get_accel_to_snap_to_grid() { Shortcut* shortcut = get_keyboard_shortcut_for_spriteeditor(SPRITEDITOR_ACTION_SNAPTOGRID); if (shortcut) @@ -774,7 +774,7 @@ JAccel get_accel_to_snap_to_grid() return NULL; } -JAccel get_accel_to_angle_snap() +Accelerator* get_accel_to_angle_snap() { Shortcut* shortcut = get_keyboard_shortcut_for_spriteeditor(SPRITEDITOR_ACTION_ANGLESNAP); if (shortcut) @@ -783,7 +783,7 @@ JAccel get_accel_to_angle_snap() return NULL; } -JAccel get_accel_to_maintain_aspect_ratio() +Accelerator* get_accel_to_maintain_aspect_ratio() { Shortcut* shortcut = get_keyboard_shortcut_for_spriteeditor(SPRITEDITOR_ACTION_MAINTAINASPECTRATIO); if (shortcut) @@ -792,7 +792,7 @@ JAccel get_accel_to_maintain_aspect_ratio() return NULL; } -JAccel get_accel_to_lock_axis() +Accelerator* get_accel_to_lock_axis() { Shortcut* shortcut = get_keyboard_shortcut_for_spriteeditor(SPRITEDITOR_ACTION_LOCKAXIS); if (shortcut) @@ -804,8 +804,8 @@ JAccel get_accel_to_lock_axis() tools::Tool* get_selected_quicktool(tools::Tool* currentTool) { if (currentTool && currentTool->getInk(0)->isSelection()) { - JAccel copyselection_accel = get_accel_to_copy_selection(); - if (copyselection_accel && jaccel_check_from_key(copyselection_accel)) + Accelerator* copyselection_accel = get_accel_to_copy_selection(); + if (copyselection_accel && copyselection_accel->checkFromAllegroKeyArray()) return NULL; } @@ -827,7 +827,7 @@ tools::Tool* get_selected_quicktool(tools::Tool* currentTool) Shortcut::Shortcut(ShortcutType type) { this->type = type; - this->accel = jaccel_new(); + this->accel = new Accelerator; this->command = NULL; this->tool = NULL; this->params = NULL; @@ -838,21 +838,20 @@ Shortcut::~Shortcut() delete params; if (type == Shortcut_SpriteEditor) base_free(action); - jaccel_free(accel); + delete accel; } void Shortcut::add_shortcut(const char* shortcut_string) { char buf[256]; usprintf(buf, "<%s>", shortcut_string); - jaccel_add_keys_from_string(this->accel, buf); + this->accel->addKeysFromString(buf); } bool Shortcut::is_pressed(Message* msg) { if (accel) { - return jaccel_check(accel, - msg->any.shifts, + return accel->check(msg->any.shifts, msg->key.ascii, msg->key.scancode); } @@ -862,7 +861,7 @@ bool Shortcut::is_pressed(Message* msg) bool Shortcut::is_pressed_from_key_array() { if (accel) { - return jaccel_check_from_key(accel); + return accel->checkFromAllegroKeyArray(); } return false; } @@ -1022,9 +1021,8 @@ bool CustomizedGuiManager::onProcessMessage(Message* msg) // Commands are executed only when the main window is // the current window running at foreground. - JLink link; - JI_LIST_FOR_EACH(this->children, link) { - Window* child = reinterpret_cast(link->data); + UI_FOREACH_WIDGET(getChildren(), it) { + Window* child = static_cast(*it); // There are a foreground window executing? if (child->is_foreground()) { diff --git a/src/modules/gui.h b/src/modules/gui.h index 55211400d..0868702ae 100644 --- a/src/modules/gui.h +++ b/src/modules/gui.h @@ -21,7 +21,7 @@ #include "base/exception.h" #include "skin/skin_property.h" -#include "ui/accel.h" +#include "ui/accelerator.h" #include "ui/base.h" #include #include @@ -71,19 +71,19 @@ ui::CheckBox* check_button_new(const char* text, int b1, int b2, int b3, int b4) ////////////////////////////////////////////////////////////////////// // Keyboard shortcuts -ui::JAccel add_keyboard_shortcut_to_execute_command(const char* shortcut, const char* command_name, Params* params); -ui::JAccel add_keyboard_shortcut_to_change_tool(const char* shortcut, tools::Tool* tool); -ui::JAccel add_keyboard_shortcut_to_quicktool(const char* shortcut, tools::Tool* tool); -ui::JAccel add_keyboard_shortcut_to_spriteeditor(const char* shortcut, const char* action_name); +ui::Accelerator* add_keyboard_shortcut_to_execute_command(const char* shortcut, const char* command_name, Params* params); +ui::Accelerator* add_keyboard_shortcut_to_change_tool(const char* shortcut, tools::Tool* tool); +ui::Accelerator* add_keyboard_shortcut_to_quicktool(const char* shortcut, tools::Tool* tool); +ui::Accelerator* add_keyboard_shortcut_to_spriteeditor(const char* shortcut, const char* action_name); bool get_command_from_key_message(ui::Message* msg, Command** command, Params** params); -ui::JAccel get_accel_to_execute_command(const char* command, Params* params = NULL); -ui::JAccel get_accel_to_change_tool(tools::Tool* tool); -ui::JAccel get_accel_to_copy_selection(); -ui::JAccel get_accel_to_snap_to_grid(); -ui::JAccel get_accel_to_angle_snap(); -ui::JAccel get_accel_to_maintain_aspect_ratio(); -ui::JAccel get_accel_to_lock_axis(); +ui::Accelerator* get_accel_to_execute_command(const char* command, Params* params = NULL); +ui::Accelerator* get_accel_to_change_tool(tools::Tool* tool); +ui::Accelerator* get_accel_to_copy_selection(); +ui::Accelerator* get_accel_to_snap_to_grid(); +ui::Accelerator* get_accel_to_angle_snap(); +ui::Accelerator* get_accel_to_maintain_aspect_ratio(); +ui::Accelerator* get_accel_to_lock_axis(); tools::Tool* get_selected_quicktool(tools::Tool* currentTool); diff --git a/src/modules/palettes.cpp b/src/modules/palettes.cpp index 971903d09..db8185733 100644 --- a/src/modules/palettes.cpp +++ b/src/modules/palettes.cpp @@ -21,8 +21,6 @@ #include #include -#include "ui/list.h" - #include "app.h" #include "modules/palettes.h" #include "raster/blend.h" diff --git a/src/skin/skin_theme.cpp b/src/skin/skin_theme.cpp index 47ab893a0..dc8211edd 100644 --- a/src/skin/skin_theme.cpp +++ b/src/skin/skin_theme.cpp @@ -731,7 +731,7 @@ JRegion SkinTheme::get_window_mask(Widget* widget) void SkinTheme::map_decorative_widget(Widget* widget) { if (widget->getId() == kThemeCloseButtonId) { - Widget* window = widget->parent; + Widget* window = widget->getParent(); JRect rect = jrect_new(0, 0, 0, 0); rect->x2 = m_part[PART_WINDOW_CLOSE_BUTTON_NORMAL]->w; @@ -1092,10 +1092,10 @@ void SkinTheme::draw_menuitem(MenuItem* widget, JRect clip) JRect pos; /* TODO ASSERT? */ - if (!widget->parent->parent) + if (!widget->getParent()->getParent()) return; - bar = (widget->parent->parent->type == JI_MENUBAR); + bar = (widget->getParent()->getParent()->type == JI_MENUBAR); /* colors */ if (!widget->isEnabled()) { @@ -1178,18 +1178,17 @@ void SkinTheme::draw_menuitem(MenuItem* widget, JRect clip) (widget->rc->y1+widget->rc->y2)/2+c, COLOR_DISABLED); } } - /* draw the keyboard shortcut */ + // Draw the keyboard shortcut else if (widget->getAccel()) { int old_align = widget->getAlign(); - char buf[256]; pos = jwidget_get_rect(widget); pos->x2 -= widget->child_spacing/4; - jaccel_to_string(widget->getAccel(), buf); + std::string buf = widget->getAccel()->toString(); widget->setAlign(JI_RIGHT | JI_MIDDLE); - draw_textstring(buf, fg, bg, false, widget, pos, 0); + draw_textstring(buf.c_str(), fg, bg, false, widget, pos, 0); widget->setAlign(old_align); jrect_free(pos); diff --git a/src/ui/CMakeLists.txt b/src/ui/CMakeLists.txt index 6719d64f8..122ff475f 100644 --- a/src/ui/CMakeLists.txt +++ b/src/ui/CMakeLists.txt @@ -2,7 +2,7 @@ # Copyright (C) 2001-2012 David Capello add_library(ui-lib - accel.cpp + accelerator.cpp alert.cpp box.cpp button.cpp @@ -22,7 +22,6 @@ add_library(ui-lib intern.cpp label.cpp link_label.cpp - list.cpp listbox.cpp manager.cpp menu.cpp diff --git a/src/ui/accel.h b/src/ui/accel.h deleted file mode 100644 index e788178d0..000000000 --- a/src/ui/accel.h +++ /dev/null @@ -1,29 +0,0 @@ -// ASEPRITE gui library -// Copyright (C) 2001-2012 David Capello -// -// This source file is ditributed under a BSD-like license, please -// read LICENSE.txt for more information. - -#ifndef UI_ACCEL_H_INCLUDED -#define UI_ACCEL_H_INCLUDED - -#include "ui/base.h" - -namespace ui { - - JAccel jaccel_new(); - JAccel jaccel_new_copy(JAccel accel); - void jaccel_free(JAccel accel); - - void jaccel_add_key(JAccel accel, int shifts, int ascii, int scancode); - void jaccel_add_keys_from_string(JAccel accel, const char *string); - - bool jaccel_is_empty(JAccel accel); - void jaccel_to_string(JAccel accel, char *buf); - - bool jaccel_check(JAccel accel, int shifts, int ascii, int scancode); - bool jaccel_check_from_key(JAccel accel); - -} // namespace ui - -#endif diff --git a/src/ui/accel.cpp b/src/ui/accelerator.cpp similarity index 75% rename from src/ui/accel.cpp rename to src/ui/accelerator.cpp index 94fc349c6..1e3366d5e 100644 --- a/src/ui/accel.cpp +++ b/src/ui/accelerator.cpp @@ -6,77 +6,31 @@ #include "config.h" +#include "ui/accelerator.h" + +#include "base/unique_ptr.h" + #include #include #include -#include "ui/accel.h" -#include "ui/list.h" - /* #define REPORT_KEYS */ #define PREPROCESS_KEYS namespace ui { -struct jaccel +void Accelerator::addKey(int shifts, int ascii, int scancode) { - JList key_list; -}; + KeyCombo key; -struct KeyCombo -{ - int shifts; - int ascii; - int scancode; -}; + key.shifts = shifts & (KB_SHIFT_FLAG | KB_CTRL_FLAG | KB_ALT_FLAG); + key.ascii = ascii; + key.scancode = scancode; -JAccel jaccel_new() -{ - JAccel accel = new jaccel; - - accel->key_list = jlist_new(); - - return accel; + m_combos.push_back(key); } -JAccel jaccel_new_copy(JAccel accel) -{ - KeyCombo *key; - JAccel copy; - JLink link; - - copy = jaccel_new(); - - JI_LIST_FOR_EACH(accel->key_list, link) { - key = (KeyCombo *)link->data; - jaccel_add_key(copy, key->shifts, key->ascii, key->scancode); - } - - return copy; -} - -void jaccel_free(JAccel accel) -{ - JLink link; - JI_LIST_FOR_EACH(accel->key_list, link) { - delete (KeyCombo*)link->data; - } - jlist_free(accel->key_list); - delete accel; -} - -void jaccel_add_key(JAccel accel, int shifts, int ascii, int scancode) -{ - KeyCombo *key = new KeyCombo; - - key->shifts = shifts & (KB_SHIFT_FLAG | KB_CTRL_FLAG | KB_ALT_FLAG); - key->ascii = ascii; - key->scancode = scancode; - - jlist_append(accel->key_list, key); -} - -static void proc_one_word(JAccel accel, char* word) +static void process_one_word(Accelerator* accel, char* word) { int shifts = 0; int ascii = 0; @@ -85,7 +39,7 @@ static void proc_one_word(JAccel accel, char* word) // Special case: plus sign if (word[0] == '+' && word[1] == 0) { - jaccel_add_key(accel, 0, '+', 0); + accel->addKey(0, '+', 0); return; } @@ -215,11 +169,10 @@ static void proc_one_word(JAccel accel, char* word) } } - jaccel_add_key(accel, shifts, ascii, scancode); + accel->addKey(shifts, ascii, scancode); } -/* process strings like " " */ -void jaccel_add_keys_from_string(JAccel accel, const char *string) +void Accelerator::addKeysFromString(const char* string) { char *s, *begin, buf[256]; int backup; @@ -235,7 +188,7 @@ void jaccel_add_keys_from_string(JAccel accel, const char *string) backup = *s; *s = 0; - proc_one_word(accel, begin); + process_one_word(this, begin); *s = backup; } @@ -245,12 +198,7 @@ void jaccel_add_keys_from_string(JAccel accel, const char *string) } } -bool jaccel_is_empty(JAccel accel) -{ - return jlist_empty(accel->key_list); -} - -static void keycombo_get_string(KeyCombo *key, char *buf) +std::string Accelerator::KeyCombo::toString() { /* same order that Allegro scancodes */ static const char *table[] = { @@ -359,42 +307,41 @@ static void keycombo_get_string(KeyCombo *key, char *buf) "Kanji", }; + char buf[256]; ustrcpy(buf, ""); - if (!key) - return; - - /* shifts */ - if (key->shifts & KB_CTRL_FLAG) + // Shifts + if (this->shifts & KB_CTRL_FLAG) ustrcat(buf, "Ctrl+"); - if (key->shifts & KB_ALT_FLAG) + if (this->shifts & KB_ALT_FLAG) ustrcat(buf, "Alt+"); - if (key->shifts & KB_SHIFT_FLAG) + if (this->shifts & KB_SHIFT_FLAG) ustrcat(buf, "Shift+"); - /* key */ - if (key->ascii) - usprintf(buf+ustrlen(buf), "%c", toupper(key->ascii)); - else if (key->scancode) - ustrcat(buf, table[key->scancode]); + // Key + if (this->ascii) + usprintf(buf+ustrlen(buf), "%c", toupper(this->ascii)); + else if (this->scancode) + ustrcat(buf, table[this->scancode]); else ustrcat(buf, "Unknown"); + + return buf; } -void jaccel_to_string(JAccel accel, char *buf) +std::string Accelerator::toString() { - keycombo_get_string(reinterpret_cast(jlist_first(accel->key_list)->data), buf); + ASSERT(!m_combos.empty()); + return m_combos.front().toString(); } -bool jaccel_check(JAccel accel, int shifts, int ascii, int scancode) +bool Accelerator::check(int shifts, int ascii, int scancode) { - KeyCombo *key; - JLink link; #ifdef REPORT_KEYS char buf[256]; - char buf2[256]; + std::string buf2; #endif /* preprocess the character to be compared with the accelerator */ @@ -450,25 +397,23 @@ bool jaccel_check(JAccel accel, int shifts, int ascii, int scancode) #ifdef REPORT_KEYS { - JAccel *a2 = jaccel_new(); - jaccel_add_key(a2, shifts, ascii, scancode); - jaccel_get_string(a2, buf2); - jaccel_free(a2); + UniquePtr a2(new Accelerator); + a2->addKey(shifts, ascii, scancode); + buf2 = a2->getString(); } #endif - JI_LIST_FOR_EACH(accel->key_list, link) { - key = (KeyCombo *)link->data; - + for (KeyCombos::iterator it = m_combos.begin(), end = m_combos.end(); + it != end; ++it) { #ifdef REPORT_KEYS - keycombo_get_string(key, buf); printf("%3d==%3d %3d==%3d %s==%s ", - key->scancode, scancode, key->ascii, ascii, buf, buf2); + it->scancode, scancode, it->ascii, ascii, + it->getString().c_str(), buf2.c_str(); #endif - if (((key->scancode && key->scancode == scancode) - || (key->ascii && key->ascii == ascii)) - && (key->shifts == (shifts & (KB_SHIFT_FLAG | KB_CTRL_FLAG | KB_ALT_FLAG)))) { + if (((it->scancode && it->scancode == scancode) + || (it->ascii && it->ascii == ascii)) + && (it->shifts == (shifts & (KB_SHIFT_FLAG | KB_CTRL_FLAG | KB_ALT_FLAG)))) { #ifdef REPORT_KEYS printf("true\n"); @@ -484,7 +429,7 @@ bool jaccel_check(JAccel accel, int shifts, int ascii, int scancode) return false; } -bool jaccel_check_from_key(JAccel accel) +bool Accelerator::checkFromAllegroKeyArray() { int shifts = 0; @@ -494,12 +439,10 @@ bool jaccel_check_from_key(JAccel accel) if (key[KEY_RCONTROL]) shifts |= KB_CTRL_FLAG; if (key[KEY_ALT]) shifts |= KB_ALT_FLAG; - JLink link; - JI_LIST_FOR_EACH(accel->key_list, link) { - KeyCombo* keyCombo = (KeyCombo*)link->data; - - if ((keyCombo->scancode == 0 || key[keyCombo->scancode]) && - (keyCombo->shifts == (shifts & (KB_SHIFT_FLAG | KB_CTRL_FLAG | KB_ALT_FLAG)))) { + for (KeyCombos::iterator it = m_combos.begin(), end = m_combos.end(); + it != end; ++it) { + if ((it->scancode == 0 || key[it->scancode]) && + (it->shifts == (shifts & (KB_SHIFT_FLAG | KB_CTRL_FLAG | KB_ALT_FLAG)))) { return true; } } diff --git a/src/ui/accelerator.h b/src/ui/accelerator.h new file mode 100644 index 000000000..e978e02f5 --- /dev/null +++ b/src/ui/accelerator.h @@ -0,0 +1,43 @@ +// ASEPRITE gui library +// Copyright (C) 2001-2012 David Capello +// +// This source file is ditributed under a BSD-like license, please +// read LICENSE.txt for more information. + +#ifndef UI_ACCELERATOR_H_INCLUDED +#define UI_ACCELERATOR_H_INCLUDED + +#include +#include + +namespace ui { + + class Accelerator + { + public: + void addKey(int shifts, int ascii, int scancode); + + // Adds keys from strings like " " + void addKeysFromString(const char* string); + + bool isEmpty() const { return m_combos.empty(); } + std::string toString(); + + bool check(int shifts, int ascii, int scancode); + bool checkFromAllegroKeyArray(); + + private: + struct KeyCombo { + int shifts; + int ascii; + int scancode; + std::string toString(); + }; + + typedef std::vector KeyCombos; + KeyCombos m_combos; + }; + +} // namespace ui + +#endif diff --git a/src/ui/base.h b/src/ui/base.h index c828c202d..ade717d0b 100644 --- a/src/ui/base.h +++ b/src/ui/base.h @@ -31,9 +31,6 @@ namespace ui { - struct jaccel; - struct jlink; - struct jlist; struct jrect; struct jregion; @@ -144,11 +141,6 @@ namespace ui { typedef unsigned int JID; - typedef void* JThread; - - typedef struct jaccel* JAccel; - typedef struct jlink* JLink; - typedef struct jlist* JList; typedef struct jrect* JRect; typedef struct jregion* JRegion; diff --git a/src/ui/box.cpp b/src/ui/box.cpp index df2ac4f46..78ce1616d 100644 --- a/src/ui/box.cpp +++ b/src/ui/box.cpp @@ -10,7 +10,6 @@ #include "gfx/size.h" #include "ui/box.h" -#include "ui/list.h" #include "ui/message.h" #include "ui/preferred_size_event.h" #include "ui/rect.h" @@ -61,20 +60,18 @@ void Box::onPreferredSize(PreferredSizeEvent& ev) } int w, h, nvis_children; - Widget* child; - JLink link; nvis_children = 0; - JI_LIST_FOR_EACH(this->children, link) { - child = (Widget*)link->data; + UI_FOREACH_WIDGET(getChildren(), it) { + Widget* child = *it; if (!(child->flags & JI_HIDDEN)) nvis_children++; } w = h = 0; - JI_LIST_FOR_EACH(this->children, link) { - child = (Widget*)link->data; + UI_FOREACH_WIDGET(getChildren(), it) { + Widget* child = *it; if (child->flags & JI_HIDDEN) continue; @@ -136,8 +133,8 @@ void Box::layoutBox(JRect rect) - this->border_width.t \ - this->border_width.b); \ \ - JI_LIST_FOR_EACH(this->children, link) { \ - child = (Widget*)link->data; \ + UI_FOREACH_WIDGET(getChildren(), it) { \ + child = *it; \ \ if (!(child->flags & JI_HIDDEN)) { \ if (this->getAlign() & JI_HOMOGENEOUS) { \ @@ -185,15 +182,14 @@ void Box::layoutBox(JRect rect) int nvis_children = 0; int nexpand_children = 0; int child_width; - JLink link; int width; int extra; int x, y, w, h; jrect_copy(this->rc, rect); - JI_LIST_FOR_EACH(this->children, link) { - child = (Widget*)link->data; + UI_FOREACH_WIDGET(getChildren(), it) { + child = *it; if (!(child->flags & JI_HIDDEN)) { nvis_children++; diff --git a/src/ui/button.cpp b/src/ui/button.cpp index a6ced7f38..832ea61a3 100644 --- a/src/ui/button.cpp +++ b/src/ui/button.cpp @@ -7,7 +7,6 @@ #include "config.h" #include "ui/button.h" -#include "ui/list.h" #include "ui/manager.h" #include "ui/message.h" #include "ui/preferred_size_event.h" @@ -359,9 +358,8 @@ void RadioButton::deselectRadioGroup() radioButton->setSelected(false); } - JLink link; - JI_LIST_FOR_EACH(widget->children, link) { - allChildrens.push((Widget*)link->data); + UI_FOREACH_WIDGET(widget->getChildren(), it) { + allChildrens.push(*it); } } } diff --git a/src/ui/draw.cpp b/src/ui/draw.cpp index 3cdaa285f..79f524aa8 100644 --- a/src/ui/draw.cpp +++ b/src/ui/draw.cpp @@ -13,7 +13,6 @@ #include "ui/draw.h" #include "ui/font.h" #include "ui/intern.h" -#include "ui/list.h" #include "ui/rect.h" #include "ui/region.h" #include "ui/system.h" diff --git a/src/ui/grid.cpp b/src/ui/grid.cpp index be6309eb4..61f6d21ac 100644 --- a/src/ui/grid.cpp +++ b/src/ui/grid.cpp @@ -13,7 +13,6 @@ #include "base/memory.h" #include "gfx/size.h" #include "ui/grid.h" -#include "ui/list.h" #include "ui/message.h" #include "ui/preferred_size_event.h" #include "ui/rect.h" diff --git a/src/ui/gui.h b/src/ui/gui.h index fe3ef4536..ba9cbb1de 100644 --- a/src/ui/gui.h +++ b/src/ui/gui.h @@ -7,7 +7,7 @@ #ifndef UI_GUI_H_INCLUDED #define UI_GUI_H_INCLUDED -#include "ui/accel.h" +#include "ui/accelerator.h" #include "ui/alert.h" #include "ui/base.h" #include "ui/box.h" @@ -27,7 +27,6 @@ #include "ui/init_theme_event.h" #include "ui/label.h" #include "ui/link_label.h" -#include "ui/list.h" #include "ui/listbox.h" #include "ui/manager.h" #include "ui/menu.h" diff --git a/src/ui/list.cpp b/src/ui/list.cpp deleted file mode 100644 index 885bf1e00..000000000 --- a/src/ui/list.cpp +++ /dev/null @@ -1,198 +0,0 @@ -// ASEPRITE gui library -// Copyright (C) 2001-2012 David Capello -// -// This source file is ditributed under a BSD-like license, please -// read LICENSE.txt for more information. - -#include "config.h" - -#include "ui/list.h" - -namespace ui { - -JList jlist_new() -{ - JList list = new jlist; - list->end = new jlink(NULL); - list->end->prev = list->end; - list->end->next = list->end; - list->length = 0; - return list; -} - -void jlist_free(JList list) -{ - JLink link, next; - JI_LIST_FOR_EACH_SAFE(list, link, next) - delete link; - delete list->end; - delete list; -} - -void jlist_clear(JList list) -{ - JLink link, next; - JI_LIST_FOR_EACH_SAFE(list, link, next) { - delete link; - } - list->end->prev = list->end; - list->end->next = list->end; - list->length = 0; -} - -void jlist_append(JList list, void *data) -{ - JLink link = new jlink(data); - link->prev = list->end->prev; - link->next = list->end; - link->prev->next = link; - link->next->prev = link; - list->length++; -} - -void jlist_prepend(JList list, void *data) -{ - JLink link = new jlink(data); - link->prev = list->end; - link->next = list->end->next; - link->prev->next = link; - link->next->prev = link; - list->length++; -} - -void jlist_insert(JList list, void *data, int position) -{ - JLink new_link, tmp_link; - - if (position < 0) { - jlist_append(list, data); - return; - } - else if (position == 0) { - jlist_prepend(list, data); - return; - } - - tmp_link = jlist_nth_link(list, position); - if (!tmp_link) { - jlist_append(list, data); - return; - } - - new_link = new jlink(data); - new_link->prev = tmp_link->prev; - new_link->next = tmp_link; - new_link->prev->next = new_link; - new_link->next->prev = new_link; - list->length++; -} - -void jlist_insert_before(JList list, JLink sibling, void *data) -{ - if (jlist_empty(list)) - jlist_prepend(list, data); - else if (sibling) { - JLink new_link; - - new_link = new jlink(data); - new_link->prev = sibling->prev; - new_link->next = sibling; - new_link->prev->next = new_link; - new_link->next->prev = new_link; - list->length++; - } - else - jlist_append(list, data); -} - -void jlist_remove(JList list, const void *data) -{ - JLink link; - JI_LIST_FOR_EACH(list, link) { - if (link->data == data) { - link->prev->next = link->next; - link->next->prev = link->prev; - delete link; - list->length--; - return; - } - } -} - -void jlist_remove_all(JList list, const void *data) -{ - JLink link, next; - JI_LIST_FOR_EACH_SAFE(list, link, next) { - if (link->data == data) { - link->prev->next = link->next; - link->next->prev = link->prev; - delete link; - list->length--; - } - } -} - -void jlist_remove_link(JList list, JLink link) -{ - link->prev->next = link->next; - link->next->prev = link->prev; - list->length--; -} - -void jlist_delete_link(JList list, JLink link) -{ - link->prev->next = link->next; - link->next->prev = link->prev; - delete link; - list->length--; -} - -JList jlist_copy(JList list) -{ - JList new_list = jlist_new(); - JLink new_link, link; - - JI_LIST_FOR_EACH(list, link) { - /* it's like jlist_append(new_list, link->data) */ - new_link = new jlink(link->data); - new_link->prev = new_list->end->prev; - new_link->next = new_list->end; - new_link->prev->next = new_link; - new_link->next->prev = new_link; - } - - new_list->length = list->length; - return new_list; -} - -JLink jlist_nth_link(JList list, unsigned int n) -{ - JLink link; - JI_LIST_FOR_EACH(list, link) { - if (n-- <= 0) - return link; - } - return list->end; -} - -void *jlist_nth_data(JList list, unsigned int n) -{ - JLink link; - JI_LIST_FOR_EACH(list, link) { - if (n-- <= 0) - return link->data; - } - return NULL; -} - -JLink jlist_find(JList list, const void *data) -{ - JLink link; - JI_LIST_FOR_EACH(list, link) { - if (link->data == data) - return link; - } - return list->end; -} - -} // namespace ui diff --git a/src/ui/list.h b/src/ui/list.h deleted file mode 100644 index ca1cb97c4..000000000 --- a/src/ui/list.h +++ /dev/null @@ -1,77 +0,0 @@ -// ASEPRITE gui library -// Copyright (C) 2001-2012 David Capello -// -// This source file is ditributed under a BSD-like license, please -// read LICENSE.txt for more information. - -#ifndef UI_LIST_H_INCLUDED -#define UI_LIST_H_INCLUDED - -#include "ui/base.h" - -namespace ui { - - struct jlink - { - void* data; - JLink prev; - JLink next; - - jlink(void* data) : data(data), prev(0), next(0) { } - }; - - struct jlist - { - JLink end; - unsigned int length; - - jlist() : end(0), length(0) { } - }; - - JList jlist_new(); - void jlist_free(JList list); - void jlist_clear(JList list); - void jlist_append(JList list, void *data); - void jlist_prepend(JList list, void *data); - void jlist_insert(JList list, void *data, int position); - void jlist_insert_before(JList list, JLink sibling, void *data); - void jlist_remove(JList list, const void *data); - void jlist_remove_all(JList list, const void *data); - void jlist_remove_link(JList list, JLink link); - void jlist_delete_link(JList list, JLink link); - JList jlist_copy(JList list); - JLink jlist_nth_link(JList list, unsigned int n); - void *jlist_nth_data(JList list, unsigned int n); - JLink jlist_find(JList list, const void *data); - -#define jlist_first(list) (((JList)(list))->end->next) -#define jlist_last(list) (((JList)(list))->end->prev) -#define jlist_length(list) (((JList)(list))->length) - -#define jlist_first_data(list) (jlist_first(list)->data) -#define jlist_last_data(list) (jlist_last(list)->data) - -#define jlist_empty(list) (((JList)(list))->length == 0) - -#define JI_LIST_FOR_EACH(list, link) \ - for (link=((JList)(list))->end->next; \ - link!=((JList)(list))->end; \ - link=link->next) - -#define JI_LIST_FOR_EACH_BACK(list, link) \ - for (link=((JList)(list))->end->prev; \ - link!=((JList)(list))->end; \ - link=link->prev) - - /** - * Iterator for each item of the list (the body of the "for" can be - * remove elements in the list). - */ -#define JI_LIST_FOR_EACH_SAFE(list, link, next) \ - for (link=((JList)(list))->end->next, next=link->next; \ - link!=((JList)(list))->end; \ - link=next, next=link->next) - -} // namespace ui - -#endif diff --git a/src/ui/list_unittest.cpp b/src/ui/list_unittest.cpp deleted file mode 100644 index 6dd62261b..000000000 --- a/src/ui/list_unittest.cpp +++ /dev/null @@ -1,207 +0,0 @@ -/* ASEPRITE - * Copyright (C) 2001-2012 David Capello - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "ui/list.h" -#include - -using namespace ui; - -TEST(JList, AppendAndClear) -{ - JList q = jlist_new(); - ASSERT_TRUE(q != NULL); - EXPECT_EQ(0, jlist_length(q)); - - jlist_append(q, (void*)10); - EXPECT_EQ(1, jlist_length(q)); - - jlist_append(q, (void*)20); - jlist_append(q, (void*)30); - ASSERT_EQ(3, jlist_length(q)); - EXPECT_EQ((void*)10, jlist_nth_data(q, 0)); - EXPECT_EQ((void*)20, jlist_nth_data(q, 1)); - EXPECT_EQ((void*)30, jlist_nth_data(q, 2)); - - jlist_clear(q); - EXPECT_EQ(0, jlist_length(q)); - - jlist_free(q); -} - -TEST(JList, Prepend) -{ - JList q = jlist_new(); - jlist_prepend(q, (void*)30); - jlist_prepend(q, (void*)20); - jlist_prepend(q, (void*)10); - ASSERT_EQ(3, jlist_length(q)); - EXPECT_EQ((void*)10, jlist_nth_data(q, 0)); - EXPECT_EQ((void*)20, jlist_nth_data(q, 1)); - EXPECT_EQ((void*)30, jlist_nth_data(q, 2)); - - jlist_free(q); -} - -TEST(JList, Insert) -{ - JList q = jlist_new(); - jlist_append(q, (void*)10); - jlist_append(q, (void*)30); - jlist_insert(q, (void*)20, 1); - jlist_insert(q, (void*)50, 3); - jlist_insert(q, (void*)40, 3); - ASSERT_EQ(5, jlist_length(q)); - EXPECT_EQ((void*)10, jlist_nth_data(q, 0)); - EXPECT_EQ((void*)20, jlist_nth_data(q, 1)); - EXPECT_EQ((void*)30, jlist_nth_data(q, 2)); - EXPECT_EQ((void*)40, jlist_nth_data(q, 3)); - EXPECT_EQ((void*)50, jlist_nth_data(q, 4)); - - jlist_free(q); -} - -TEST(JList, NthLink) -{ - JLink a, b, c; - - JList q = jlist_new(); - jlist_append(q, (void*)10); - jlist_append(q, (void*)20); - jlist_append(q, (void*)30); - - a = jlist_nth_link(q, 0); - b = jlist_nth_link(q, 1); - c = jlist_nth_link(q, 2); - EXPECT_EQ((void*)10, a->data); - EXPECT_EQ((void*)20, b->data); - EXPECT_EQ((void*)30, c->data); - - jlist_free(q); -} - -TEST(JList, InsertBefore) -{ - JLink a, b, c; - - JList q = jlist_new(); - jlist_append(q, (void*)20); - jlist_append(q, (void*)40); - jlist_append(q, (void*)60); - - a = jlist_nth_link(q, 0); - b = jlist_nth_link(q, 1); - c = jlist_nth_link(q, 2); - - jlist_insert_before(q, a, (void*)10); - jlist_insert_before(q, b, (void*)30); - jlist_insert_before(q, c, (void*)50); - jlist_insert_before(q, NULL, (void*)70); - ASSERT_EQ(7, jlist_length(q)); - EXPECT_EQ((void*)10, jlist_nth_data(q, 0)); - EXPECT_EQ((void*)20, jlist_nth_data(q, 1)); - EXPECT_EQ((void*)30, jlist_nth_data(q, 2)); - EXPECT_EQ((void*)40, jlist_nth_data(q, 3)); - EXPECT_EQ((void*)50, jlist_nth_data(q, 4)); - EXPECT_EQ((void*)60, jlist_nth_data(q, 5)); - EXPECT_EQ((void*)70, jlist_nth_data(q, 6)); - - jlist_free(q); -} - -TEST(JList, RemoveAndRemoveAll) -{ - JList q = jlist_new(); - jlist_append(q, (void*)10); - jlist_append(q, (void*)20); - jlist_append(q, (void*)30); - - jlist_remove(q, (void*)20); - ASSERT_EQ(2, jlist_length(q)); - EXPECT_EQ((void*)10, jlist_nth_data(q, 0)); - EXPECT_EQ((void*)30, jlist_nth_data(q, 1)); - - jlist_append(q, (void*)10); - jlist_remove_all(q, (void*)10); - ASSERT_EQ(1, jlist_length(q)); - EXPECT_EQ((void*)30, jlist_nth_data(q, 0)); - - jlist_free(q); -} - -TEST(JList, RemoveLinkAndDeleteLink) -{ - JList q; - JLink b; - - q = jlist_new(); - jlist_append(q, (void*)10); - jlist_append(q, (void*)20); - jlist_append(q, (void*)30); - - b = jlist_nth_link(q, 1); - jlist_remove_link(q, b); - EXPECT_EQ(2, jlist_length(q)); - - jlist_delete_link(q, jlist_nth_link(q, 0)); - jlist_delete_link(q, jlist_nth_link(q, 0)); - EXPECT_EQ(0, jlist_length(q)); - - delete b; - jlist_free(q); -} - -TEST(JList, Copy) -{ - JList q, r; - - q = jlist_new(); - jlist_append(q, (void*)10); - jlist_append(q, (void*)20); - jlist_append(q, (void*)30); - ASSERT_EQ(3, jlist_length(q)); - EXPECT_EQ((void*)10, jlist_nth_data(q, 0)); - EXPECT_EQ((void*)20, jlist_nth_data(q, 1)); - EXPECT_EQ((void*)30, jlist_nth_data(q, 2)); - - r = jlist_copy(q); - ASSERT_EQ(3, jlist_length(r)); - EXPECT_EQ((void*)10, jlist_nth_data(r, 0)); - EXPECT_EQ((void*)20, jlist_nth_data(r, 1)); - EXPECT_EQ((void*)30, jlist_nth_data(r, 2)); - - jlist_free(q); - jlist_free(r); -} - -TEST(JList, Find) -{ - JList q = jlist_new(); - jlist_append(q, (void*)10); - jlist_append(q, (void*)20); - jlist_append(q, (void*)30); - - EXPECT_EQ(jlist_nth_link(q, 0), jlist_find(q, (void*)10)); - EXPECT_EQ(jlist_nth_link(q, 1), jlist_find(q, (void*)20)); - EXPECT_EQ(jlist_nth_link(q, 2), jlist_find(q, (void*)30)); -} - -int main(int argc, char** argv) -{ - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} diff --git a/src/ui/listbox.cpp b/src/ui/listbox.cpp index ea571ceaa..7ae24c1c4 100644 --- a/src/ui/listbox.cpp +++ b/src/ui/listbox.cpp @@ -8,7 +8,6 @@ #include "ui/listbox.h" -#include "ui/list.h" #include "ui/message.h" #include "ui/preferred_size_event.h" #include "ui/system.h" @@ -38,21 +37,21 @@ ListBox::Item::Item(const char* text) ListBox::Item* ListBox::getSelectedChild() { - JLink link; - JI_LIST_FOR_EACH(this->children, link) { - if (((Item*)link->data)->isSelected()) - return (Item*)link->data; + UI_FOREACH_WIDGET(getChildren(), it) { + ASSERT(dynamic_cast(*it) != NULL); + + if (static_cast(*it)->isSelected()) + return static_cast(*it); } return 0; } int ListBox::getSelectedIndex() { - JLink link; int i = 0; - JI_LIST_FOR_EACH(this->children, link) { - if (((Item*)link->data)->isSelected()) + UI_FOREACH_WIDGET(getChildren(), it) { + if (static_cast(*it)->isSelected()) return i; i++; } @@ -62,11 +61,8 @@ int ListBox::getSelectedIndex() void ListBox::selectChild(Item* item) { - Item* child; - JLink link; - - JI_LIST_FOR_EACH(this->children, link) { - child = (Item*)link->data; + UI_FOREACH_WIDGET(getChildren(), it) { + Item* child = static_cast(*it); if (child->isSelected()) { if (item && child == item) @@ -100,14 +96,18 @@ void ListBox::selectChild(Item* item) void ListBox::selectIndex(int index) { - Item* child = reinterpret_cast(jlist_nth_data(this->children, index)); - if (child) - selectChild(child); + const WidgetsList& children = getChildren(); + if (index < 0 || index >= (int)children.size()) + return; + + Item* child = static_cast(children[index]); + ASSERT(child); + selectChild(child); } -int ListBox::getItemsCount() +size_t ListBox::getItemsCount() const { - return jlist_length(this->children); + return getChildren().size(); } /* setup the scroll to center the selected item in the viewport */ @@ -207,10 +207,10 @@ bool ListBox::onProcessMessage(Message* msg) } case JM_KEYPRESSED: - if (this->hasFocus() && !jlist_empty(this->children)) { + if (hasFocus() && !getChildren().empty()) { int select = getSelectedIndex(); View* view = View::getView(this); - int bottom = MAX(0, jlist_length(this->children)-1); + int bottom = MAX(0, getChildren().size()-1); switch (msg->key.scancode) { case KEY_UP: @@ -272,16 +272,13 @@ bool ListBox::onProcessMessage(Message* msg) void ListBox::onPreferredSize(PreferredSizeEvent& ev) { - Size reqSize; - JLink link; - int w = 0, h = 0; - JI_LIST_FOR_EACH(this->children, link) { - reqSize = reinterpret_cast(link->data)->getPreferredSize(); + UI_FOREACH_WIDGET_WITH_END(getChildren(), it, end) { + Size reqSize = static_cast(*it)->getPreferredSize(); w = MAX(w, reqSize.w); - h += reqSize.h + ((link->next)? this->child_spacing: 0); + h += reqSize.h + (it+1 != end ? this->child_spacing: 0); } w += this->border_width.l + this->border_width.r; @@ -303,15 +300,13 @@ void ListBox::onDoubleClickItem() void ListBox::layoutListBox(JRect rect) { Size reqSize; - Widget* child; JRect cpos; - JLink link; jrect_copy(this->rc, rect); cpos = jwidget_get_child_rect(this); - JI_LIST_FOR_EACH(this->children, link) { - child = (Widget*)link->data; + UI_FOREACH_WIDGET(getChildren(), it) { + Widget* child = *it; reqSize = child->getPreferredSize(); @@ -327,18 +322,15 @@ void ListBox::layoutListBox(JRect rect) void ListBox::dirtyChildren() { View* view = View::getView(this); - Item* child; - JLink link; - if (!view) { - JI_LIST_FOR_EACH(this->children, link) - reinterpret_cast(link->data)->invalidate(); + UI_FOREACH_WIDGET(getChildren(), it) + static_cast(*it)->invalidate(); } else { gfx::Rect vp = view->getViewportBounds(); - JI_LIST_FOR_EACH(this->children, link) { - child = reinterpret_cast(link->data); + UI_FOREACH_WIDGET(getChildren(), it) { + Item* child = static_cast(*it); if (child->rc->y2 <= vp.y) continue; @@ -356,13 +348,12 @@ bool ListBox::Item::onProcessMessage(Message* msg) case JM_SETPOS: { JRect crect; - JLink link; jrect_copy(this->rc, &msg->setpos.rect); crect = jwidget_get_child_rect(this); - JI_LIST_FOR_EACH(this->children, link) - jwidget_set_rect(reinterpret_cast(link->data), crect); + UI_FOREACH_WIDGET(getChildren(), it) + jwidget_set_rect(*it, crect); jrect_free(crect); return true; @@ -380,8 +371,6 @@ void ListBox::Item::onPreferredSize(PreferredSizeEvent& ev) { int w = 0, h = 0; Size maxSize; - Size reqSize; - JLink link; if (hasText()) { maxSize.w = jwidget_get_text_length(this); @@ -390,8 +379,8 @@ void ListBox::Item::onPreferredSize(PreferredSizeEvent& ev) else maxSize.w = maxSize.h = 0; - JI_LIST_FOR_EACH(this->children, link) { - reqSize = reinterpret_cast(link->data)->getPreferredSize(); + UI_FOREACH_WIDGET(getChildren(), it) { + Size reqSize = (*it)->getPreferredSize(); maxSize.w = MAX(maxSize.w, reqSize.w); maxSize.h = MAX(maxSize.h, reqSize.h); diff --git a/src/ui/listbox.h b/src/ui/listbox.h index 6bce42738..d760ebc5b 100644 --- a/src/ui/listbox.h +++ b/src/ui/listbox.h @@ -34,7 +34,7 @@ namespace ui { void selectChild(Item* item); void selectIndex(int index); - int getItemsCount(); + size_t getItemsCount() const; void centerScroll(); diff --git a/src/ui/manager.cpp b/src/ui/manager.cpp index 9efb61969..b35044f3f 100644 --- a/src/ui/manager.cpp +++ b/src/ui/manager.cpp @@ -15,10 +15,11 @@ #include "ui/intern.h" #ifdef REPORT_EVENTS -#include +#include #endif #include #include +#include namespace ui { @@ -55,6 +56,9 @@ struct Filter , widget(widget) { } }; +typedef std::list Messages; +typedef std::list Filters; + static int double_click_level; static int double_click_buttons; static int double_click_ticks; @@ -65,10 +69,10 @@ static int want_close_stage; /* variable to handle the external Manager* Manager::m_defaultManager = NULL; -static JList new_windows; // Windows that we should show +static WidgetsList new_windows; // Windows that we should show static WidgetsList mouse_widgets_list; // List of widgets to send mouse events -static JList msg_queue; // Messages queue -static JList msg_filters[NFILTERS]; // Filters for every enqueued message +static Messages msg_queue; // Messages queue +static Filters msg_filters[NFILTERS]; // Filters for every enqueued message static Widget* focus_widget; // The widget with the focus static Widget* mouse_widget; // The widget with the mouse @@ -116,13 +120,10 @@ Manager::Manager() set_close_button_callback(allegro_window_close_hook); // Empty lists - msg_queue = jlist_new(); - new_windows = jlist_new(); + ASSERT(msg_queue.empty()); + ASSERT(new_windows.empty()); mouse_widgets_list.clear(); - for (int c=0; c(link->data); - } - jlist_free(msg_filters[c]); - msg_filters[c] = NULL; + for (Filters::iterator it=msg_filters[c].begin(), end=msg_filters[c].end(); + it != end; ++it) + delete *it; + msg_filters[c].clear(); } // No more default manager m_defaultManager = NULL; // Shutdown system - jlist_free(msg_queue); - jlist_free(new_windows); + ASSERT(msg_queue.empty()); + ASSERT(new_windows.empty()); mouse_widgets_list.clear(); } } @@ -186,7 +184,7 @@ void Manager::run() { MessageLoop loop(this); - while (!jlist_empty(this->children)) + while (!getChildren().empty()) loop.pumpMessages(); } @@ -194,9 +192,7 @@ bool Manager::generateMessages() { Widget* widget; Widget* window; - int mousemove; Message* msg; - JLink link; int c; // Poll keyboard @@ -210,15 +206,13 @@ bool Manager::generateMessages() } // First check: there are windows to manage? - if (jlist_empty(this->children)) + if (getChildren().empty()) return false; // New windows to show? - if (!jlist_empty(new_windows)) { - Widget* magnet; - - JI_LIST_FOR_EACH(new_windows, link) { - window = reinterpret_cast(link->data); + if (!new_windows.empty()) { + UI_FOREACH_WIDGET(new_windows, it) { + window = *it; // Relayout window->layout(); @@ -229,7 +223,7 @@ bool Manager::generateMessages() // Attract the focus to the magnetic widget... // 1) get the magnetic widget - magnet = findMagneticWidget(window->getRoot()); + Widget* magnet = findMagneticWidget(window->getRoot()); // 2) if magnetic widget exists and it doesn't have the focus if (magnet && !magnet->hasFocus()) setFocus(magnet); @@ -238,11 +232,11 @@ bool Manager::generateMessages() focusFirstChild(window); } - jlist_clear(new_windows); + new_windows.clear(); } // Update mouse status - mousemove = jmouse_poll(); + bool mousemove = jmouse_poll(); if (mousemove || !mouse_widget) { // Get the list of widgets to send mouse messages. mouse_widgets_list.clear(); @@ -251,9 +245,7 @@ bool Manager::generateMessages() // Get the widget under the mouse widget = NULL; - for (WidgetsList::iterator - it = mouse_widgets_list.begin(), - end = mouse_widgets_list.end(); it != end; ++it) { + UI_FOREACH_WIDGET(mouse_widgets_list, it) { widget = (*it)->pick(jmouse_x(0), jmouse_y(0)); if (widget) break; @@ -374,18 +366,19 @@ bool Manager::generateMessages() // If the window is not already the top window of the manager. (window != win_manager->getTopWindow())) { // Put it in the top of the list - jlist_remove(win_manager->children, window); + win_manager->removeChild(window); if (window->is_ontop()) - jlist_prepend(win_manager->children, window); + win_manager->insertChild(0, window); else { - int pos = jlist_length(win_manager->children); - JI_LIST_FOR_EACH_BACK(win_manager->children, link) { - if (((Window*)link->data)->is_ontop()) + int pos = (int)win_manager->getChildren().size(); + UI_FOREACH_WIDGET_BACKWARD(win_manager->getChildren(), it) { + if (static_cast(*it)->is_ontop()) break; - pos--; + + --pos; } - jlist_insert(win_manager->children, window, pos); + win_manager->insertChild(pos, window); } window->invalidate(); @@ -457,7 +450,7 @@ bool Manager::generateMessages() // Generate redraw events. flushRedraw(); - if (!jlist_empty(msg_queue)) + if (!msg_queue.empty()) return true; else return false; @@ -486,42 +479,39 @@ void Manager::enqueueMessage(Message* msg) { int c; - ASSERT(msg_queue != NULL); ASSERT(msg != NULL); - /* check if this message must be filtered by some widget before */ + // Check if this message must be filtered by some widget before c = msg->type; if (c >= JM_REGISTERED_MESSAGES) c = JM_REGISTERED_MESSAGES; - if (!jlist_empty(msg_filters[c])) { /* ok, so are filters to add ... */ - JLink link; - - /* add all the filters in the destination list of the message */ - JI_LIST_FOR_EACH_BACK(msg_filters[c], link) { - Filter* filter = reinterpret_cast(link->data); + if (!msg_filters[c].empty()) { // OK, so are filters to add... + // Add all the filters in the destination list of the message + for (Filters::reverse_iterator it=msg_filters[c].rbegin(), + end=msg_filters[c].rend(); it != end; ++it) { + Filter* filter = *it; if (msg->type == filter->message) jmessage_add_pre_dest(msg, filter->widget); } } - /* there are a destination widget at least? */ - if (!jlist_empty(msg->any.widgets)) - jlist_append(msg_queue, msg); + // There are a destination widget at least? + if (!msg->any.widgets->empty()) + msg_queue.push_back(msg); else jmessage_free(msg); } Window* Manager::getTopWindow() { - return reinterpret_cast(jlist_first_data(this->children)); + return static_cast(UI_FIRST_WIDGET(getChildren())); } Window* Manager::getForegroundWindow() { - JLink link; - JI_LIST_FOR_EACH(this->children, link) { - Window* window = (Window*)link->data; + UI_FOREACH_WIDGET(getChildren(), it) { + Window* window = static_cast(*it); if (window->is_foreground() || window->is_desktop()) return window; @@ -552,27 +542,24 @@ void Manager::setFocus(Widget* widget) && !(widget->flags & JI_HIDDEN) && !(widget->flags & JI_DECORATIVE) && someParentIsFocusStop(widget)))) { - JList widget_parents = NULL; + WidgetsList widget_parents; Widget* common_parent = NULL; - JLink link, link2; Message* msg; if (widget) - widget_parents = widget->getParents(false); - else - widget_parents = jlist_new(); - - /* fetch the focus */ + widget->getParents(false, widget_parents); + // Fetch the focus if (focus_widget) { - JList focus_parents = focus_widget->getParents(true); + WidgetsList focus_parents; + focus_widget->getParents(true, focus_parents); msg = jmessage_new(JM_FOCUSLEAVE); - JI_LIST_FOR_EACH(focus_parents, link) { + UI_FOREACH_WIDGET(focus_parents, it) { if (widget) { - JI_LIST_FOR_EACH(widget_parents, link2) { - if (link->data == link2->data) { - common_parent = reinterpret_cast(link->data); + UI_FOREACH_WIDGET(widget_parents, it2) { + if (*it == *it2) { + common_parent = *it; break; } } @@ -580,30 +567,34 @@ void Manager::setFocus(Widget* widget) break; } - if (reinterpret_cast(link->data)->hasFocus()) { - ((Widget*)link->data)->flags &= ~JI_HASFOCUS; - jmessage_add_dest(msg, reinterpret_cast(link->data)); + if ((*it)->hasFocus()) { + (*it)->flags &= ~JI_HASFOCUS; + jmessage_add_dest(msg, *it); } } enqueueMessage(msg); - jlist_free(focus_parents); } - /* put the focus */ - + // Put the focus focus_widget = widget; - if (widget) { - if (common_parent) - link = jlist_find(widget_parents, common_parent)->next; + WidgetsList::iterator it; + + if (common_parent) { + it = std::find(widget_parents.begin(), + widget_parents.end(), + common_parent); + ASSERT(it != widget_parents.end()); + ++it; + } else - link = jlist_first(widget_parents); + it = widget_parents.begin(); msg = jmessage_new(JM_FOCUSENTER); - for (; link != widget_parents->end; link=link->next) { - Widget* w = (Widget*)link->data; + for (; it != widget_parents.end(); ++it) { + Widget* w = *it; if (w->flags & JI_FOCUSSTOP) { w->flags |= JI_HASFOCUS; @@ -614,35 +605,30 @@ void Manager::setFocus(Widget* widget) enqueueMessage(msg); } - - jlist_free(widget_parents); } } void Manager::setMouse(Widget* widget) { if ((mouse_widget != widget) && (!capture_widget)) { - JList widget_parents = NULL; + WidgetsList widget_parents; Widget* common_parent = NULL; - JLink link, link2; Message* msg; if (widget) - widget_parents = widget->getParents(false); - else - widget_parents = jlist_new(); - - /* fetch the mouse */ + widget->getParents(false, widget_parents); + // Fetch the mouse if (mouse_widget) { - JList mouse_parents = mouse_widget->getParents(true); + WidgetsList mouse_parents; + mouse_widget->getParents(true, mouse_parents); msg = jmessage_new(JM_MOUSELEAVE); - JI_LIST_FOR_EACH(mouse_parents, link) { + UI_FOREACH_WIDGET(mouse_parents, it) { if (widget) { - JI_LIST_FOR_EACH(widget_parents, link2) { - if (link->data == link2->data) { - common_parent = reinterpret_cast(link->data); + UI_FOREACH_WIDGET(widget_parents, it2) { + if (*it == *it2) { + common_parent = *it; break; } } @@ -650,38 +636,40 @@ void Manager::setMouse(Widget* widget) break; } - if (reinterpret_cast(link->data)->hasMouse()) { - ((Widget*)link->data)->flags &= ~JI_HASMOUSE; - jmessage_add_dest(msg, reinterpret_cast(link->data)); + if ((*it)->hasMouse()) { + (*it)->flags &= ~JI_HASMOUSE; + jmessage_add_dest(msg, *it); } } enqueueMessage(msg); - jlist_free(mouse_parents); } - /* put the mouse */ - + // Put the mouse mouse_widget = widget; - if (widget) { - if (common_parent) - link = jlist_find(widget_parents, common_parent)->next; + WidgetsList::iterator it; + + if (common_parent) { + it = std::find(widget_parents.begin(), + widget_parents.end(), + common_parent); + ASSERT(it != widget_parents.end()); + ++it; + } else - link = jlist_first(widget_parents); + it = widget_parents.begin(); msg = jmessage_new(JM_MOUSEENTER); - for (; link != widget_parents->end; link=link->next) { - reinterpret_cast(link->data)->flags |= JI_HASMOUSE; - jmessage_add_dest(msg, reinterpret_cast(link->data)); + for (; it != widget_parents.end(); ++it) { + (*it)->flags |= JI_HASMOUSE; + jmessage_add_dest(msg, *it); } enqueueMessage(msg); generateSetCursorMessage(); } - - jlist_free(widget_parents); } } @@ -691,13 +679,13 @@ void Manager::setCapture(Widget* widget) capture_widget = widget; } -/* sets the focus to the "magnetic" widget inside the window */ +// Sets the focus to the "magnetic" widget inside the window void Manager::attractFocus(Widget* widget) { - /* get the magnetic widget */ + // Get the magnetic widget Widget* magnet = findMagneticWidget(widget->getRoot()); - /* if magnetic widget exists and it doesn't have the focus */ + // If magnetic widget exists and it doesn't have the focus if (magnet && !magnet->hasFocus()) setFocus(magnet); } @@ -746,28 +734,30 @@ void Manager::freeWidget(Widget* widget) void Manager::removeMessage(Message* msg) { - jlist_remove(msg_queue, msg); + Messages::iterator it = std::find(msg_queue.begin(), msg_queue.end(), msg); + ASSERT(it != msg_queue.end()); + msg_queue.erase(it); } void Manager::removeMessagesFor(Widget* widget) { - JLink link; - JI_LIST_FOR_EACH(msg_queue, link) - removeWidgetFromDests(widget, reinterpret_cast(link->data)); + for (Messages::iterator it=msg_queue.begin(), end=msg_queue.end(); + it != end; ++it) + removeWidgetFromDests(widget, *it); } void Manager::removeMessagesForTimer(Timer* timer) { - JLink link, next; - - JI_LIST_FOR_EACH_SAFE(msg_queue, link, next) { - Message* message = reinterpret_cast(link->data); + for (Messages::iterator it=msg_queue.begin(); it != msg_queue.end(); ) { + Message* message = *it; if (!message->any.used && message->any.type == JM_TIMER && message->timer.timer == timer) { - jmessage_free(reinterpret_cast(link->data)); - jlist_delete_link(msg_queue, link); + jmessage_free(message); + it = msg_queue.erase(it); } + else + ++it; } } @@ -777,37 +767,37 @@ void Manager::addMessageFilter(int message, Widget* widget) if (c >= JM_REGISTERED_MESSAGES) c = JM_REGISTERED_MESSAGES; - jlist_append(msg_filters[c], new Filter(message, widget)); + msg_filters[c].push_back(new Filter(message, widget)); } void Manager::removeMessageFilter(int message, Widget* widget) { - JLink link, next; int c = message; if (c >= JM_REGISTERED_MESSAGES) c = JM_REGISTERED_MESSAGES; - JI_LIST_FOR_EACH_SAFE(msg_filters[c], link, next) { - Filter* filter = reinterpret_cast(link->data); + for (Filters::iterator it=msg_filters[c].begin(); it != msg_filters[c].end(); ) { + Filter* filter = *it; if (filter->widget == widget) { delete filter; - jlist_delete_link(msg_filters[c], link); + it = msg_filters[c].erase(it); } + else + ++it; } } void Manager::removeMessageFilterFor(Widget* widget) { - JLink link, next; - int c; - - for (c=0; c(link->data); + for (int c=0; cwidget == widget) { delete filter; - jlist_delete_link(msg_filters[c], link); + it = msg_filters[c].erase(it); } + else + ++it; } } } @@ -823,8 +813,7 @@ void Manager::_openWindow(Window* window) } // Add the window to manager. - jlist_prepend(this->children, window); - window->parent = this; + insertChild(0, window); // Broadcast the open message. Message* msg = jmessage_new(JM_OPEN); @@ -832,7 +821,7 @@ void Manager::_openWindow(Window* window) enqueueMessage(msg); // Update the new windows list to show. - jlist_append(new_windows, window); + new_windows.push_back(window); } void Manager::_closeWindow(Window* window, bool redraw_background) @@ -848,19 +837,18 @@ void Manager::_closeWindow(Window* window, bool redraw_background) else reg1 = NULL; - /* close all windows to this desktop */ + // Close all windows to this desktop if (window->is_desktop()) { - JLink link, next; - - JI_LIST_FOR_EACH_SAFE(this->children, link, next) { - if (link->data == window) + while (!getChildren().empty()) { + Window* child = static_cast(getChildren().front()); + if (child == window) break; else { JRegion reg2 = jwidget_get_region(window); jregion_union(reg1, reg1, reg2); jregion_free(reg2); - _closeWindow(reinterpret_cast(link->data), false); + _closeWindow(child, false); } } } @@ -884,8 +872,7 @@ void Manager::_closeWindow(Window* window, bool redraw_background) enqueueMessage(msg); // Update manager list stuff. - jlist_remove(this->children, window); - window->parent = NULL; + removeChild(window); // Redraw background. if (reg1) { @@ -894,7 +881,10 @@ void Manager::_closeWindow(Window* window, bool redraw_background) } // Maybe the window is in the "new_windows" list. - jlist_remove(new_windows, window); + WidgetsList::iterator it = + std::find(new_windows.begin(), new_windows.end(), window); + if (it != new_windows.end()) + new_windows.erase(it); } bool Manager::onProcessMessage(Message* msg) @@ -911,19 +901,17 @@ bool Manager::onProcessMessage(Message* msg) case JM_KEYPRESSED: case JM_KEYRELEASED: { - JLink link, link2; - msg->key.propagate_to_children = true; msg->key.propagate_to_parent = false; // Continue sending the message to the children of all windows // (until a desktop or foreground window). - JI_LIST_FOR_EACH(this->children, link) { - Window* w = (Window*)link->data; + UI_FOREACH_WIDGET(getChildren(), it) { + Window* w = static_cast(*it); // Send to the window. - JI_LIST_FOR_EACH(w->children, link2) - if (reinterpret_cast(link2->data)->sendMessage(msg)) + UI_FOREACH_WIDGET(w->getChildren(), it2) + if ((*it2)->sendMessage(msg)) return true; if (w->is_foreground() || @@ -947,7 +935,7 @@ void Manager::onBroadcastMouseMessage(WidgetsList& targets) { // Ask to the first window in the "children" list to know how to // propagate mouse messages. - Widget* widget = reinterpret_cast(jlist_first_data(children)); + Widget* widget = UI_FIRST_WIDGET(getChildren()); if (widget) widget->broadcastMouseMessage(targets); } @@ -956,16 +944,15 @@ void Manager::onPreferredSize(PreferredSizeEvent& ev) { int w = 0, h = 0; - if (!this->parent) { /* hasn't parent? */ + if (!getParent()) { // hasn' parent? w = jrect_w(this->rc); h = jrect_h(this->rc); } else { - JRect cpos, pos = jwidget_get_child_rect(this->parent); - JLink link; + JRect cpos, pos = jwidget_get_child_rect(this->getParent()); - JI_LIST_FOR_EACH(this->children, link) { - cpos = jwidget_get_rect(reinterpret_cast(link->data)); + UI_FOREACH_WIDGET(getChildren(), it) { + cpos = jwidget_get_rect(*it); jrect_union(pos, cpos); jrect_free(cpos); } @@ -981,19 +968,17 @@ void Manager::onPreferredSize(PreferredSizeEvent& ev) void Manager::layoutManager(JRect rect) { JRect cpos, old_pos; - Widget* child; - JLink link; int x, y; old_pos = jrect_new_copy(this->rc); jrect_copy(this->rc, rect); - /* offset for all windows */ + // Offset for all windows x = this->rc->x1 - old_pos->x1; y = this->rc->y1 - old_pos->y1; - JI_LIST_FOR_EACH(this->children, link) { - child = (Widget*)link->data; + UI_FOREACH_WIDGET(getChildren(), it) { + Widget* child = *it; cpos = jwidget_get_rect(child); jrect_displace(cpos, x, y); @@ -1006,35 +991,29 @@ void Manager::layoutManager(JRect rect) void Manager::pumpQueue() { - Message* msg, *first_msg; - JLink link, link2, next; - Widget* widget; - bool done; #ifdef LIMIT_DISPATCH_TIME int t = ji_clock; #endif - ASSERT(msg_queue != NULL); - - link = jlist_first(msg_queue); - while (link != msg_queue->end) { + Messages::iterator it = msg_queue.begin(); + while (it != msg_queue.end()) { #ifdef LIMIT_DISPATCH_TIME if (ji_clock-t > 250) break; #endif - /* the message to process */ - msg = reinterpret_cast(link->data); + // The message to process + Message* msg = *it; - /* go to next message */ + // Go to next message if (msg->any.used) { - link = link->next; + ++it; continue; } - /* this message is in use */ + // This message is in use msg->any.used = true; - first_msg = msg; + Message* first_msg = msg; // Call Timer::tick() if this is a tick message. if (msg->type == JM_TIMER) { @@ -1042,9 +1021,11 @@ void Manager::pumpQueue() msg->timer.timer->tick(); } - done = false; - JI_LIST_FOR_EACH(msg->any.widgets, link2) { - widget = reinterpret_cast(link2->data); + bool done = false; + UI_FOREACH_WIDGET(*msg->any.widgets, it2) { + Widget* widget = *it2; + if (!widget) + continue; #ifdef REPORT_EVENTS { @@ -1128,12 +1109,10 @@ void Manager::pumpQueue() break; } - /* remove the message from the msg_queue */ - next = link->next; - jlist_delete_link(msg_queue, link); - link = next; + // Remove the message from the msg_queue + it = msg_queue.erase(it); - /* destroy the message */ + // Destroy the message jmessage_free(first_msg); } } @@ -1143,21 +1122,23 @@ void Manager::invalidateDisplayRegion(const JRegion region) JRegion reg1 = jregion_new(NULL, 0); JRegion reg2 = jregion_new(this->rc, 0); JRegion reg3; - JLink link; // TODO intersect with jwidget_get_drawable_region()??? jregion_intersect(reg1, region, reg2); // Redraw windows from top to background. - JI_LIST_FOR_EACH(this->children, link) { - Window* window = (Window*)link->data; + bool withDesktop = false; + UI_FOREACH_WIDGET(getChildren(), it) { + Window* window = static_cast(*it); // Invalidate regions of this window window->invalidateRegion(reg1); // There is desktop? - if (window->is_desktop()) + if (window->is_desktop()) { + withDesktop = true; break; // Work done + } // Clip this window area for the next window. reg3 = jwidget_get_region(window); @@ -1168,7 +1149,7 @@ void Manager::invalidateDisplayRegion(const JRegion region) // Invalidate areas outside windows (only when there are not a // desktop window). - if (link == children->end) + if (!withDesktop) Widget::invalidateRegion(reg1); jregion_free(reg1); @@ -1214,11 +1195,11 @@ void Manager::generateSetCursorMessage() // static void Manager::removeWidgetFromDests(Widget* widget, Message* msg) { - JLink link, next; - - JI_LIST_FOR_EACH_SAFE(msg->any.widgets, link, next) { - if (link->data == widget) - jlist_delete_link(msg->any.widgets, link); + for (WidgetsList::iterator + it = msg->any.widgets->begin(), + end = msg->any.widgets->end(); it != end; ++it) { + if (*it == widget) + *it = NULL; } } @@ -1228,8 +1209,8 @@ bool Manager::someParentIsFocusStop(Widget* widget) if (widget->isFocusStop()) return true; - if (widget->parent) - return someParentIsFocusStop(widget->parent); + if (widget->getParent()) + return someParentIsFocusStop(widget->getParent()); else return false; } @@ -1238,10 +1219,9 @@ bool Manager::someParentIsFocusStop(Widget* widget) Widget* Manager::findMagneticWidget(Widget* widget) { Widget* found; - JLink link; - JI_LIST_FOR_EACH(widget->children, link) { - found = findMagneticWidget(reinterpret_cast(link->data)); + UI_FOREACH_WIDGET(widget->getChildren(), it) { + found = findMagneticWidget(*it); if (found) return found; } @@ -1307,7 +1287,7 @@ static bool move_focus(Manager* manager, Message* msg) if (focus_widget) { window = focus_widget->getRoot(); } - else if (!jlist_empty(manager->children)) { + else if (!manager->getChildren().empty()) { window = manager->getTopWindow(); } @@ -1406,10 +1386,9 @@ static int count_widgets_accept_focus(Widget* widget) ASSERT(widget != NULL); int count = 0; - JLink link; - JI_LIST_FOR_EACH(widget->children, link) - count += count_widgets_accept_focus(reinterpret_cast(link->data)); + UI_FOREACH_WIDGET(widget->getChildren(), it) + count += count_widgets_accept_focus(*it); if ((count == 0) && (ACCEPT_FOCUS(widget))) count++; @@ -1419,10 +1398,8 @@ static int count_widgets_accept_focus(Widget* widget) static bool childs_accept_focus(Widget* widget, bool first) { - JLink link; - - JI_LIST_FOR_EACH(widget->children, link) - if (childs_accept_focus(reinterpret_cast(link->data), false)) + UI_FOREACH_WIDGET(widget->getChildren(), it) + if (childs_accept_focus(*it, false)) return true; return first ? false: ACCEPT_FOCUS(widget); @@ -1430,15 +1407,20 @@ static bool childs_accept_focus(Widget* widget, bool first) static Widget* next_widget(Widget* widget) { - if (!jlist_empty(widget->children)) - return reinterpret_cast(jlist_first(widget->children)->data); + if (!widget->getChildren().empty()) + return UI_FIRST_WIDGET(widget->getChildren()); - while (widget->parent->type != JI_MANAGER) { - JLink link = jlist_find(widget->parent->children, widget); - if (link->next != widget->parent->children->end) - return reinterpret_cast(link->next->data); + while (widget->getParent()->type != JI_MANAGER) { + WidgetsList::const_iterator begin = widget->getParent()->getChildren().begin(); + WidgetsList::const_iterator end = widget->getParent()->getChildren().end(); + WidgetsList::const_iterator it = std::find(begin, end, widget); + + ASSERT(it != end); + + if ((it+1) != end) + return *(it+1); else - widget = widget->parent; + widget = widget->getParent(); } return NULL; diff --git a/src/ui/menu.cpp b/src/ui/menu.cpp index c8680b472..3ce2b3d9c 100644 --- a/src/ui/menu.cpp +++ b/src/ui/menu.cpp @@ -167,7 +167,7 @@ MenuItem::MenuItem(const char *text) MenuItem::~MenuItem() { if (m_accel) - jaccel_free(m_accel); + delete m_accel; if (m_submenu) delete m_submenu; @@ -175,10 +175,10 @@ MenuItem::~MenuItem() Menu* MenuBox::getMenu() { - if (jlist_empty(children)) + if (getChildren().empty()) return NULL; else - return static_cast(jlist_first(children)->data); + return static_cast(getChildren().front()); } MenuBaseData* MenuBox::createBase() @@ -193,7 +193,7 @@ Menu* MenuItem::getSubmenu() return m_submenu; } -JAccel MenuItem::getAccel() +Accelerator* MenuItem::getAccel() { return m_accel; } @@ -229,10 +229,10 @@ void MenuItem::setSubmenu(Menu* menu) * @warning The specified @a accel will be freed automatically when * the menu-item is deleted. */ -void MenuItem::setAccel(JAccel accel) +void MenuItem::setAccel(Accelerator* accel) { if (m_accel) - jaccel_free(m_accel); + delete m_accel; m_accel = accel; } @@ -249,7 +249,7 @@ void MenuItem::setHighlighted(bool state) bool MenuItem::hasSubmenu() const { - return (m_submenu && !jlist_empty(m_submenu->children)); + return (m_submenu && !m_submenu->getChildren().empty()); } void Menu::showPopup(int x, int y) @@ -319,22 +319,19 @@ bool Menu::onProcessMessage(Message* msg) void Menu::requestSize(int *w, int *h) { Size reqSize; - JLink link; *w = *h = 0; - JI_LIST_FOR_EACH(this->children, link) { - reqSize = ((Widget*)link->data)->getPreferredSize(); + UI_FOREACH_WIDGET_WITH_END(getChildren(), it, end) { + reqSize = (*it)->getPreferredSize(); - if (this->parent->type == JI_MENUBAR) { - *w += reqSize.w + ((link->next != this->children->end) ? - this->child_spacing: 0); + if (this->getParent()->type == JI_MENUBAR) { + *w += reqSize.w + ((it+1 != end) ? this->child_spacing: 0); *h = MAX(*h, reqSize.h); } else { *w = MAX(*w, reqSize.w); - *h += reqSize.h + ((link->next != this->children->end) ? - this->child_spacing: 0); + *h += reqSize.h + ((it+1 != end) ? this->child_spacing: 0); } } @@ -347,24 +344,23 @@ void Menu::set_position(JRect rect) Size reqSize; Widget* child; JRect cpos; - JLink link; jrect_copy(this->rc, rect); cpos = jwidget_get_child_rect(this); - JI_LIST_FOR_EACH(this->children, link) { - child = (Widget*)link->data; + UI_FOREACH_WIDGET(getChildren(), it) { + child = *it; reqSize = child->getPreferredSize(); - if (this->parent->type == JI_MENUBAR) + if (this->getParent()->type == JI_MENUBAR) cpos->x2 = cpos->x1+reqSize.w; else cpos->y2 = cpos->y1+reqSize.h; jwidget_set_rect(child, cpos); - if (this->parent->type == JI_MENUBAR) + if (this->getParent()->type == JI_MENUBAR) cpos->x1 += jrect_w(cpos); else cpos->y1 += jrect_h(cpos); @@ -510,12 +506,11 @@ bool MenuBox::onProcessMessage(Message* msg) if (this->hasFocus()) { MenuItem* highlight = menu->getHighlightedItem(); MenuItem* child_with_submenu_opened = NULL; - JLink link; bool used = false; // Search a child with highlight or the submenu opened - JI_LIST_FOR_EACH(menu->children, link) { - Widget* child = (Widget*)link->data; + UI_FOREACH_WIDGET(menu->getChildren(), it) { + Widget* child = *it; if (child->type != JI_MENUITEM) continue; @@ -592,7 +587,7 @@ bool MenuBox::onProcessMessage(Message* msg) else { // Go to parent if (menu->m_menuitem) { - Widget* parent = menu->m_menuitem->parent->parent; + Widget* parent = menu->m_menuitem->getParent()->getParent(); // Go to the previous item in the parent @@ -741,7 +736,7 @@ bool MenuItem::onProcessMessage(Message* msg) ASSERT(base->is_processing); ASSERT(hasSubmenu()); - JRect old_pos = jwidget_get_rect(this->parent->parent); + JRect old_pos = jwidget_get_rect(this->getParent()->getParent()); MenuBox* menubox = new MenuBox(); m_submenu_menubox = menubox; @@ -753,7 +748,7 @@ bool MenuItem::onProcessMessage(Message* msg) // Menubox position pos = jwidget_get_rect(window); - if (this->parent->parent->type == JI_MENUBAR) { + if (this->getParent()->getParent()->type == JI_MENUBAR) { jrect_moveto(pos, MID(0, this->rc->x1, JI_SCREEN_W-jrect_w(pos)), MID(0, this->rc->y2, JI_SCREEN_H-jrect_h(pos))); @@ -800,12 +795,10 @@ bool MenuItem::onProcessMessage(Message* msg) // Setup the highlight of the new menubox if (select_first) { // Select the first child - Widget* child; MenuItem* first_child = NULL; - JLink link; - JI_LIST_FOR_EACH(m_submenu->children, link) { - child = (Widget*)link->data; + UI_FOREACH_WIDGET(m_submenu->getChildren(), it) { + Widget* child = *it; if (child->type != JI_MENUITEM) continue; @@ -845,7 +838,7 @@ bool MenuItem::onProcessMessage(Message* msg) ASSERT(menubox != NULL); - window = (Window*)menubox->parent; + window = (Window*)menubox->getParent(); ASSERT(window && window->type == JI_WINDOW); // Fetch the "menu" to avoid destroy it with 'delete'. @@ -858,7 +851,7 @@ bool MenuItem::onProcessMessage(Message* msg) if (base->close_all) getManager()->freeFocus(); else - getManager()->setFocus(this->parent->parent); + getManager()->setFocus(this->getParent()->getParent()); // It is not necessary to delete this window because it's // automatically destroyed by the manager @@ -907,7 +900,7 @@ void MenuItem::onClick() void MenuItem::requestSize(int *w, int *h) { - int bar = (this->parent->parent->type == JI_MENUBAR); + int bar = (this->getParent()->getParent()->type == JI_MENUBAR); if (this->hasText()) { *w = @@ -921,10 +914,8 @@ void MenuItem::requestSize(int *w, int *h) + jwidget_get_text_height(this) + this->border_width.b; - if (m_accel) { - char buf[256]; - jaccel_to_string(m_accel, buf); - *w += ji_font_text_len(this->getFont(), buf); + if (m_accel && !m_accel->isEmpty()) { + *w += ji_font_text_len(this->getFont(), m_accel->toString().c_str()); } } else { @@ -955,10 +946,10 @@ static MenuBox* get_base_menubox(Widget* widget) // We are in a menuitem else { ASSERT(widget->type == JI_MENUITEM); - ASSERT(widget->parent != NULL); - ASSERT(widget->parent->type == JI_MENU); + ASSERT(widget->getParent() != NULL); + ASSERT(widget->getParent()->type == JI_MENU); - widget = widget->parent->parent; + widget = widget->getParent()->getParent(); } } @@ -974,9 +965,8 @@ static MenuBaseData* get_base(Widget* widget) MenuItem* Menu::getHighlightedItem() { - JLink link; - JI_LIST_FOR_EACH(this->children, link) { - Widget* child = (Widget*)link->data; + UI_FOREACH_WIDGET(getChildren(), it) { + Widget* child = *it; if (child->type != JI_MENUITEM) continue; @@ -989,13 +979,9 @@ MenuItem* Menu::getHighlightedItem() void Menu::highlightItem(MenuItem* menuitem, bool click, bool open_submenu, bool select_first_child) { - Menu* menu = this; - Widget* child; - JLink link; - // Find the menuitem with the highlight - JI_LIST_FOR_EACH(menu->children, link) { - child = (Widget*)link->data; + UI_FOREACH_WIDGET(getChildren(), it) { + Widget* child = *it; if (child->type != JI_MENUITEM) continue; @@ -1015,9 +1001,9 @@ void Menu::highlightItem(MenuItem* menuitem, bool click, bool open_submenu, bool } // Highlight parents - if (menu->getOwnerMenuItem() != NULL) { - static_cast(menu->getOwnerMenuItem()->parent) - ->highlightItem(menu->getOwnerMenuItem(), false, false, false); + if (getOwnerMenuItem() != NULL) { + static_cast(getOwnerMenuItem()->getParent()) + ->highlightItem(getOwnerMenuItem(), false, false, false); } // Open submenu of the menitem @@ -1033,7 +1019,7 @@ void Menu::highlightItem(MenuItem* menuitem, bool click, bool open_submenu, bool } // Execute menuitem action else if (click) { - menu->closeAll(); + closeAll(); menuitem->executeClick(); } } @@ -1047,13 +1033,11 @@ void Menu::unhighlightItem() void MenuItem::openSubmenu(bool select_first) { Widget* menu; - Widget* child; Message* msg; - JLink link; ASSERT(hasSubmenu()); - menu = this->parent; + menu = this->getParent(); // The menu item is already opened? ASSERT(m_submenu_menubox == NULL); @@ -1061,9 +1045,9 @@ void MenuItem::openSubmenu(bool select_first) ASSERT_VALID_WIDGET(menu); // Close all siblings of 'menuitem' - if (menu->parent) { - JI_LIST_FOR_EACH(menu->children, link) { - child = reinterpret_cast(link->data); + if (menu->getParent()) { + UI_FOREACH_WIDGET(menu->getChildren(), it) { + Widget* child = *it; if (child->type != JI_MENUITEM) continue; @@ -1100,9 +1084,8 @@ void MenuItem::openSubmenu(bool select_first) void MenuItem::closeSubmenu(bool last_of_close_chain) { - Widget* menu, *child; + Widget* menu; Message* msg; - JLink link; MenuBaseData* base; ASSERT(m_submenu_menubox != NULL); @@ -1111,8 +1094,8 @@ void MenuItem::closeSubmenu(bool last_of_close_chain) menu = m_submenu_menubox->getMenu(); ASSERT(menu != NULL); - JI_LIST_FOR_EACH(menu->children, link) { - child = reinterpret_cast(link->data); + UI_FOREACH_WIDGET(menu->getChildren(), it) { + Widget* child = *it; if (child->type != JI_MENUITEM) continue; @@ -1160,10 +1143,10 @@ void Menu::closeAll() MenuItem* menuitem = NULL; while (menu->m_menuitem) { menuitem = menu->m_menuitem; - menu = static_cast(menuitem->parent); + menu = static_cast(menuitem->getParent()); } - MenuBox* base_menubox = get_base_menubox(menu->parent); + MenuBox* base_menubox = get_base_menubox(menu->getParent()); MenuBaseData* base = base_menubox->getBase(); base->close_all = true; base->was_clicked = false; @@ -1179,9 +1162,8 @@ void Menu::closeAll() menuitem->closeSubmenu(true); } else { - JLink link; - JI_LIST_FOR_EACH(menu->children, link) { - Widget* child = reinterpret_cast(link->data); + UI_FOREACH_WIDGET(menu->getChildren(), it) { + Widget* child = *it; if (child->type != JI_MENUITEM) continue; @@ -1223,9 +1205,8 @@ void MenuItem::executeClick() static MenuItem* check_for_letter(Menu* menu, int ascii) { - JLink link; - JI_LIST_FOR_EACH(menu->children, link) { - Widget* child = (Widget*)link->data; + UI_FOREACH_WIDGET(menu->getChildren(), it) { + Widget* child = *it; if (child->type != JI_MENUITEM) continue; @@ -1238,9 +1219,8 @@ static MenuItem* check_for_letter(Menu* menu, int ascii) static MenuItem* check_for_accel(Menu* menu, Message* msg) { - JLink link; - JI_LIST_FOR_EACH(menu->children, link) { - Widget* child = (Widget*)link->data; + UI_FOREACH_WIDGET(menu->getChildren(), it) { + Widget* child = *it; if (child->type != JI_MENUITEM) continue; @@ -1252,10 +1232,9 @@ static MenuItem* check_for_accel(Menu* menu, Message* msg) } else if (menuitem->getAccel()) { if ((menuitem->isEnabled()) && - (jaccel_check(menuitem->getAccel(), - msg->any.shifts, - msg->key.ascii, - msg->key.scancode))) + (menuitem->getAccel()->check(msg->any.shifts, + msg->key.ascii, + msg->key.scancode))) return menuitem; } } @@ -1266,16 +1245,19 @@ static MenuItem* check_for_accel(Menu* menu, Message* msg) // from the first item in `menu' static MenuItem* find_nextitem(Menu* menu, MenuItem* menuitem) { - Widget* nextitem; - JLink link; + WidgetsList::const_iterator begin = menu->getChildren().begin(); + WidgetsList::const_iterator it, end = menu->getChildren().end(); - if (menuitem) - link = jlist_find(menu->children, menuitem)->next; + if (menuitem) { + it = std::find(begin, end, menuitem); + if (it != end) + ++it; + } else - link = jlist_first(menu->children); + it = begin; - for (; link != menu->children->end; link=link->next) { - nextitem = (Widget*)link->data; + for (; it != end; ++it) { + Widget* nextitem = *it; if ((nextitem->type == JI_MENUITEM) && nextitem->isEnabled()) return static_cast(nextitem); } @@ -1288,16 +1270,19 @@ static MenuItem* find_nextitem(Menu* menu, MenuItem* menuitem) static MenuItem* find_previtem(Menu* menu, MenuItem* menuitem) { - Widget* nextitem; - JLink link; + WidgetsList::const_reverse_iterator begin = menu->getChildren().rbegin(); + WidgetsList::const_reverse_iterator it, end = menu->getChildren().rend(); - if (menuitem) - link = jlist_find(menu->children, menuitem)->prev; + if (menuitem) { + it = std::find(begin, end, menuitem); + if (it != end) + ++it; + } else - link = jlist_last(menu->children); + it = begin; - for (; link != menu->children->end; link=link->prev) { - nextitem = (Widget*)link->data; + for (; it != end; ++it) { + Widget* nextitem = *it; if ((nextitem->type == JI_MENUITEM) && nextitem->isEnabled()) return static_cast(nextitem); } diff --git a/src/ui/menu.h b/src/ui/menu.h index 3912aa725..17f35e80d 100644 --- a/src/ui/menu.h +++ b/src/ui/menu.h @@ -14,9 +14,10 @@ namespace ui { + class Accelerator; class MenuItem; - struct MenuBaseData; class Timer; + struct MenuBaseData; class Menu : public Widget { @@ -99,8 +100,8 @@ namespace ui { Menu* getSubmenu(); void setSubmenu(Menu* submenu); - JAccel getAccel(); - void setAccel(JAccel accel); + Accelerator* getAccel(); + void setAccel(Accelerator* accel); bool isHighlighted() const; void setHighlighted(bool state); @@ -134,7 +135,7 @@ namespace ui { void stopTimer(); void executeClick(); - JAccel m_accel; // Hot-key + Accelerator* m_accel; // Hot-key bool m_highlighted; // Is it highlighted? Menu* m_submenu; // The sub-menu MenuBox* m_submenu_menubox; // The opened menubox for this menu-item diff --git a/src/ui/message.cpp b/src/ui/message.cpp index 51bb4c56d..f1926c19a 100644 --- a/src/ui/message.cpp +++ b/src/ui/message.cpp @@ -10,7 +10,6 @@ #include #include "base/memory.h" -#include "ui/list.h" #include "ui/manager.h" #include "ui/message.h" #include "ui/rect.h" @@ -27,12 +26,12 @@ int ji_register_message_type() Message* jmessage_new(int type) { - Message* msg = (Message*)base_malloc0(sizeof(Message)); - if (!msg) - return NULL; + Message* msg = new Message; + + memset(msg, 0, sizeof(Message)); msg->type = type; - msg->any.widgets = jlist_new(); + msg->any.widgets = new WidgetsList; msg->any.shifts = (key[KEY_LSHIFT] || key[KEY_RSHIFT] ? KB_SHIFT_FLAG: 0) | (key[KEY_LCONTROL] || key[KEY_RCONTROL] ? KB_CTRL_FLAG: 0) | @@ -73,13 +72,13 @@ Message* jmessage_new_copy(const Message* msg) ASSERT(msg != NULL); - copy = (Message*)base_malloc(sizeof(Message)); + copy = new Message; if (!copy) return NULL; memcpy(copy, msg, sizeof(Message)); - copy->any.widgets = jlist_copy(msg->any.widgets); + copy->any.widgets = new WidgetsList(*msg->any.widgets); copy->any.used = false; return copy; @@ -89,13 +88,13 @@ Message* jmessage_new_copy_without_dests(const Message* msg) { ASSERT(msg != NULL); - Message* copy = (Message*)base_malloc(sizeof(Message)); + Message* copy = new Message; if (!copy) return NULL; memcpy(copy, msg, sizeof(Message)); - copy->any.widgets = jlist_new(); + copy->any.widgets = new WidgetsList; copy->any.used = false; return copy; @@ -105,8 +104,8 @@ void jmessage_free(Message* msg) { ASSERT(msg != NULL); - jlist_free(msg->any.widgets); - base_free(msg); + delete msg->any.widgets; + delete msg; } void jmessage_add_dest(Message* msg, Widget* widget) @@ -114,7 +113,7 @@ void jmessage_add_dest(Message* msg, Widget* widget) ASSERT(msg != NULL); ASSERT_VALID_WIDGET(widget); - jlist_append(msg->any.widgets, widget); + msg->any.widgets->push_back(widget); } void jmessage_add_pre_dest(Message* msg, Widget* widget) @@ -122,18 +121,16 @@ void jmessage_add_pre_dest(Message* msg, Widget* widget) ASSERT(msg != NULL); ASSERT_VALID_WIDGET(widget); - jlist_prepend(msg->any.widgets, widget); + msg->any.widgets->insert(msg->any.widgets->begin(), widget); } void jmessage_broadcast_to_children(Message* msg, Widget* widget) { - JLink link; - ASSERT(msg != NULL); ASSERT_VALID_WIDGET(widget); - JI_LIST_FOR_EACH(widget->children, link) - jmessage_broadcast_to_children(msg, reinterpret_cast(link->data)); + UI_FOREACH_WIDGET(widget->getChildren(), it) + jmessage_broadcast_to_children(msg, *it); jmessage_add_dest(msg, widget); } diff --git a/src/ui/message.h b/src/ui/message.h index 3679677b3..bfae14277 100644 --- a/src/ui/message.h +++ b/src/ui/message.h @@ -9,6 +9,7 @@ #include "ui/base.h" #include "ui/rect.h" +#include "ui/widgets_list.h" namespace ui { @@ -27,10 +28,10 @@ namespace ui { struct MessageAny { - int type; /* type of message */ - JList widgets; /* destination widgets */ - bool used : 1; /* was used */ - int shifts; /* key shifts pressed when message was created */ + int type; // Type of message + WidgetsList* widgets; // Destination widgets + bool used : 1; // Was used + int shifts; // Key shifts pressed when message was created }; struct MessageKey diff --git a/src/ui/popup_window.cpp b/src/ui/popup_window.cpp index fb04eb415..078f0875f 100644 --- a/src/ui/popup_window.cpp +++ b/src/ui/popup_window.cpp @@ -31,10 +31,7 @@ PopupWindow::PopupWindow(const char* text, bool close_on_buttonpressed) set_wantfocus(false); setAlign(JI_LEFT | JI_TOP); - // remove decorative widgets - JLink link, next; - JI_LIST_FOR_EACH_SAFE(this->children, link, next) - delete reinterpret_cast(link->data); + removeDecorativeWidgets(); initTheme(); jwidget_noborders(this); @@ -152,14 +149,12 @@ void PopupWindow::onPreferredSize(PreferredSizeEvent& ev) resultSize.w += border_width.l + border_width.r; resultSize.h += border_width.t + border_width.b; - if (!jlist_empty(this->children)) { + if (!getChildren().empty()) { Size maxSize(0, 0); Size reqSize; - Widget* child; - JLink link; - JI_LIST_FOR_EACH(this->children, link) { - child = (Widget*)link->data; + UI_FOREACH_WIDGET(getChildren(), it) { + Widget* child = *it; reqSize = child->getPreferredSize(); diff --git a/src/ui/separator.cpp b/src/ui/separator.cpp index d333c8dcf..b4563a0da 100644 --- a/src/ui/separator.cpp +++ b/src/ui/separator.cpp @@ -9,7 +9,6 @@ #include "ui/separator.h" #include "gfx/size.h" -#include "ui/list.h" #include "ui/message.h" #include "ui/preferred_size_event.h" #include "ui/theme.h" @@ -41,11 +40,9 @@ bool Separator::onProcessMessage(Message* msg) void Separator::onPreferredSize(PreferredSizeEvent& ev) { Size maxSize(0, 0); - JLink link; - - JI_LIST_FOR_EACH(this->children, link) { - Widget* child = (Widget*)link->data; + UI_FOREACH_WIDGET(getChildren(), it) { + Widget* child = *it; Size reqSize = child->getPreferredSize(); maxSize.w = MAX(maxSize.w, reqSize.w); maxSize.h = MAX(maxSize.h, reqSize.h); diff --git a/src/ui/splitter.cpp b/src/ui/splitter.cpp index a65c3bfc3..a5245ee03 100644 --- a/src/ui/splitter.cpp +++ b/src/ui/splitter.cpp @@ -8,7 +8,6 @@ #include "ui/splitter.h" -#include "ui/list.h" #include "ui/message.h" #include "ui/preferred_size_event.h" #include "ui/system.h" @@ -54,14 +53,13 @@ bool Splitter::onProcessMessage(Message* msg) Widget* c1, *c2; int x1, y1, x2, y2; int bar, click_bar; - JLink link; bar = click_bar = 0; - JI_LIST_FOR_EACH(this->children, link) { - if (link->next != this->children->end) { - c1 = reinterpret_cast(link->data); - c2 = reinterpret_cast(link->next->data); + UI_FOREACH_WIDGET_WITH_END(getChildren(), it, end) { + if (it+1 != end) { + c1 = *it; + c2 = *(it+1); ++bar; @@ -120,14 +118,13 @@ bool Splitter::onProcessMessage(Message* msg) case JM_SETCURSOR: if (isEnabled()) { Widget* c1, *c2; - JLink link; int x1, y1, x2, y2; bool change_cursor = false; - JI_LIST_FOR_EACH(this->children, link) { - if (link->next != this->children->end) { - c1 = reinterpret_cast(link->data); - c2 = reinterpret_cast(link->next->data); + UI_FOREACH_WIDGET_WITH_END(getChildren(), it, end) { + if (it+1 != end) { + c1 = *it; + c2 = *(it+1); if (this->getAlign() & JI_HORIZONTAL) { x1 = c1->rc->x2; @@ -183,12 +180,10 @@ void Splitter::onPreferredSize(PreferredSizeEvent& ev) int visibleChildren; Size reqSize; - Widget* child; - JLink link; visibleChildren = 0; - JI_LIST_FOR_EACH(this->children, link) { - child = (Widget*)link->data; + UI_FOREACH_WIDGET(getChildren(), it) { + Widget* child = *it; if (!(child->flags & JI_HIDDEN)) visibleChildren++; } @@ -196,8 +191,8 @@ void Splitter::onPreferredSize(PreferredSizeEvent& ev) int w, h; w = h = 0; - JI_LIST_FOR_EACH(this->children, link) { - child = (Widget*)link->data; + UI_FOREACH_WIDGET(getChildren(), it) { + Widget* child = *it; if (child->flags & JI_HIDDEN) continue; @@ -252,11 +247,9 @@ void Splitter::layoutMembers(JRect rect) jrect_copy(this->rc, rect); - if (jlist_length(this->children) == 2) { - Widget* child1 = reinterpret_cast(jlist_first(this->children)->data); - Widget* child2 = reinterpret_cast(jlist_first(this->children)->next->data); - //Size reqSize1 = child1->getPreferredSize(); - //Size reqSize2 = child2->getPreferredSize(); + if (getChildren().size() == 2) { + Widget* child1 = getChildren()[0]; + Widget* child2 = getChildren()[1]; if (this->getAlign() & JI_HORIZONTAL) FIXUP(x, y, w, h, l, t, r, b); diff --git a/src/ui/tooltips.cpp b/src/ui/tooltips.cpp index 012633928..b374fec90 100644 --- a/src/ui/tooltips.cpp +++ b/src/ui/tooltips.cpp @@ -51,9 +51,8 @@ bool TooltipManager::onProcessMessage(Message* msg) switch (msg->type) { case JM_MOUSEENTER: { - JLink link; - JI_LIST_FOR_EACH_BACK(msg->any.widgets, link) { - Tips::iterator it = m_tips.find((Widget*)link->data); + UI_FOREACH_WIDGET(*msg->any.widgets, itWidget) { + Tips::iterator it = m_tips.find(*itWidget); if (it != m_tips.end()) { m_target.widget = it->first; m_target.tipInfo = it->second; @@ -153,8 +152,6 @@ void TooltipManager::onTick() TipWindow::TipWindow(const char *text, bool close_on_buttonpressed) : Window(false, text) { - JLink link, next; - m_close_on_buttonpressed = close_on_buttonpressed; m_hot_region = NULL; m_filtering = false; @@ -165,9 +162,7 @@ TipWindow::TipWindow(const char *text, bool close_on_buttonpressed) set_wantfocus(false); setAlign(JI_LEFT | JI_TOP); - // remove decorative widgets - JI_LIST_FOR_EACH_SAFE(this->children, link, next) - delete reinterpret_cast(link->data); + removeDecorativeWidgets(); initTheme(); } @@ -283,14 +278,12 @@ void TipWindow::onPreferredSize(PreferredSizeEvent& ev) resultSize.w += this->border_width.l + this->border_width.r; resultSize.h += this->border_width.t + this->border_width.b; - if (!jlist_empty(this->children)) { + if (!getChildren().empty()) { Size maxSize(0, 0); Size reqSize; - Widget* child; - JLink link; - JI_LIST_FOR_EACH(this->children, link) { - child = (Widget*)link->data; + UI_FOREACH_WIDGET(getChildren(), it) { + Widget* child = *it; reqSize = child->getPreferredSize(); diff --git a/src/ui/view.cpp b/src/ui/view.cpp index c2981372f..fecc4e62c 100644 --- a/src/ui/view.cpp +++ b/src/ui/view.cpp @@ -8,7 +8,6 @@ #include "gfx/size.h" #include "ui/intern.h" -#include "ui/list.h" #include "ui/message.h" #include "ui/rect.h" #include "ui/region.h" @@ -45,8 +44,6 @@ bool View::hasScrollBars() void View::attachToView(Widget* viewable_widget) { m_viewport.addChild(viewable_widget); - /* TODO */ - /* jwidget_emit_signal(this, JI_SIGNAL_VIEW_ATTACH); */ } void View::makeVisibleAllScrollableArea() @@ -195,7 +192,7 @@ void View::setViewScroll(const Point& pt) void View::updateView() { - Widget* vw = reinterpret_cast(jlist_first_data(m_viewport.children)); + Widget* vw = UI_FIRST_WIDGET(m_viewport.getChildren()); Point scroll = getViewScroll(); // Set minimum (remove scroll-bars) @@ -279,12 +276,10 @@ bool View::onProcessMessage(Message* msg) // static void View::displaceWidgets(Widget* widget, int x, int y) { - JLink link; - jrect_displace(widget->rc, x, y); - JI_LIST_FOR_EACH(widget->children, link) - displaceWidgets(reinterpret_cast(link->data), x, y); + UI_FOREACH_WIDGET(widget->getChildren(), it) + displaceWidgets(*it, x, y); } } // namespace ui diff --git a/src/ui/viewport.cpp b/src/ui/viewport.cpp index 7b8ee7a98..4a74f938b 100644 --- a/src/ui/viewport.cpp +++ b/src/ui/viewport.cpp @@ -8,7 +8,6 @@ #include "gfx/point.h" #include "gfx/size.h" -#include "ui/list.h" #include "ui/message.h" #include "ui/theme.h" #include "ui/view.h" @@ -49,10 +48,9 @@ Size Viewport::calculateNeededSize() { Size maxSize(0, 0); Size reqSize; - JLink link; - JI_LIST_FOR_EACH(this->children, link) { - reqSize = ((Widget*)link->data)->getPreferredSize(); + UI_FOREACH_WIDGET(getChildren(), it) { + reqSize = (*it)->getPreferredSize(); maxSize.w = MAX(maxSize.w, reqSize.w); maxSize.h = MAX(maxSize.h, reqSize.h); } @@ -63,9 +61,7 @@ Size Viewport::calculateNeededSize() void Viewport::set_position(JRect rect) { Size reqSize; - Widget* child; JRect cpos; - JLink link; jrect_copy(this->rc, rect); @@ -75,8 +71,8 @@ void Viewport::set_position(JRect rect) cpos->x1 = this->rc->x1 + this->border_width.l - scroll.x; cpos->y1 = this->rc->y1 + this->border_width.t - scroll.y; - JI_LIST_FOR_EACH(this->children, link) { - child = (Widget*)link->data; + UI_FOREACH_WIDGET(getChildren(), it) { + Widget* child = *it; reqSize = child->getPreferredSize(); cpos->x2 = cpos->x1 + MAX(reqSize.w, jrect_w(this->rc) diff --git a/src/ui/widget.cpp b/src/ui/widget.cpp index 8a92031c4..f63a4ef50 100644 --- a/src/ui/widget.cpp +++ b/src/ui/widget.cpp @@ -28,7 +28,7 @@ static inline void mark_dirty_flag(Widget* widget) { while (widget) { widget->flags |= JI_DIRTY; - widget = widget->parent; + widget = widget->getParent(); } } @@ -54,8 +54,7 @@ Widget::Widget(int type) this->min_h = 0; this->max_w = INT_MAX; this->max_h = INT_MAX; - this->children = jlist_new(); - this->parent = NULL; + this->m_parent = NULL; this->m_theme = CurrentTheme::get(); this->m_align = 0; @@ -81,8 +80,6 @@ Widget::Widget(int type) Widget::~Widget() { - JLink link, next; - // Break relationship with the manager. if (this->type != JI_MANAGER) { Manager* manager = getManager(); @@ -92,13 +89,13 @@ Widget::~Widget() } // Remove from parent - if (this->parent) - this->parent->removeChild(this); + if (m_parent) + m_parent->removeChild(this); - /* remove children */ - JI_LIST_FOR_EACH_SAFE(this->children, link, next) - delete reinterpret_cast(link->data); - jlist_free(this->children); + // Remove children. The ~Widget dtor modifies the parent's + // m_children. + while (!m_children.empty()) + delete m_children.front(); /* destroy the update region */ if (m_update_region) @@ -295,7 +292,7 @@ bool Widget::isVisible() const if (widget->flags & JI_HIDDEN) return false; - widget = widget->parent; + widget = widget->m_parent; } while (widget); return true; @@ -309,7 +306,7 @@ bool Widget::isEnabled() const if (widget->flags & JI_DISABLED) return false; - widget = widget->parent; + widget = widget->m_parent; } while (widget); return true; @@ -352,17 +349,12 @@ Window* Widget::getRoot() if (widget->type == JI_WINDOW) return dynamic_cast(widget); - widget = widget->parent; + widget = widget->m_parent; } return NULL; } -Widget* Widget::getParent() -{ - return this->parent; -} - Manager* Widget::getManager() { Widget* widget = this; @@ -371,76 +363,67 @@ Manager* Widget::getManager() if (widget->type == JI_MANAGER) return static_cast(widget); - widget = widget->parent; + widget = widget->m_parent; } return Manager::getDefault(); } -JList Widget::getParents(bool ascendant) +void Widget::getParents(bool ascendant, WidgetsList& parents) { - JList list = jlist_new(); - - for (Widget* widget=this; widget; widget=widget->parent) { + for (Widget* widget=this; widget; widget=widget->m_parent) { // append parents in tail if (ascendant) - jlist_append(list, widget); + parents.push_back(widget); // append parents in head else - jlist_prepend(list, widget); + parents.insert(parents.begin(), widget); } - - return list; -} - -JList Widget::getChildren() -{ - return jlist_copy(this->children); } Widget* Widget::getNextSibling() { - if (!parent) + if (!m_parent) return NULL; - JLink link = jlist_find(parent->children, this); - ASSERT(link != NULL); - if (!link) + WidgetsList::iterator begin = m_parent->m_children.begin(); + WidgetsList::iterator end = m_parent->m_children.end(); + WidgetsList::iterator it = std::find(begin, end, this); + + if (it == end) return NULL; - if (link == jlist_last(parent->children)) + if (++it == end) return NULL; - return reinterpret_cast(link->next->data); + return *it; } Widget* Widget::getPreviousSibling() { - if (!parent) + if (!m_parent) return NULL; - JLink link = jlist_find(parent->children, this); - ASSERT(link != NULL); - if (!link) + WidgetsList::iterator begin = m_parent->m_children.begin(); + WidgetsList::iterator end = m_parent->m_children.end(); + WidgetsList::iterator it = std::find(begin, end, this); + + if (it == begin || it == end) return NULL; - if (link == jlist_first(parent->children)) - return NULL; - - return reinterpret_cast(link->prev->data); + return *(++it); } Widget* Widget::pick(int x, int y) { Widget* inside, *picked = NULL; - JLink link; if (!(this->flags & JI_HIDDEN) && /* is visible */ jrect_point_in(this->rc, x, y)) { /* the point is inside the bounds */ picked = this; - JI_LIST_FOR_EACH(this->children, link) { - inside = reinterpret_cast(link->data)->pick(x, y); + UI_FOREACH_WIDGET(m_children, it) { + inside = (*it)->pick(x, y); if (inside) { picked = inside; break; @@ -455,26 +438,25 @@ bool Widget::hasChild(Widget* child) { ASSERT_VALID_WIDGET(child); - return jlist_find(this->children, child) != this->children->end ? true: false; + return std::find(m_children.begin(), m_children.end(), child) != m_children.end(); } Widget* Widget::findChild(const char* id) { Widget* child; - JLink link; - JI_LIST_FOR_EACH(this->children, link) { - child = (Widget*)link->data; + UI_FOREACH_WIDGET(m_children, it) { + child = *it; if (child->getId() == id) return child; } - JI_LIST_FOR_EACH(this->children, link) { - if ((child = ((Widget*)link->data)->findChild(id))) + UI_FOREACH_WIDGET(m_children, it) { + if ((child = (*it)->findChild(id))) return child; } - return 0; + return NULL; } Widget* Widget::findSibling(const char* id) @@ -487,8 +469,8 @@ void Widget::addChild(Widget* child) ASSERT_VALID_WIDGET(this); ASSERT_VALID_WIDGET(child); - jlist_append(children, child); - child->parent = this; + m_children.push_back(child); + child->m_parent = this; } void Widget::removeChild(Widget* child) @@ -496,8 +478,11 @@ void Widget::removeChild(Widget* child) ASSERT_VALID_WIDGET(this); ASSERT_VALID_WIDGET(child); - jlist_remove(children, child); - child->parent = NULL; + WidgetsList::iterator it = std::find(m_children.begin(), m_children.end(), child); + if (it != m_children.end()) + m_children.erase(it); + + child->m_parent = NULL; } void Widget::replaceChild(Widget* oldChild, Widget* newChild) @@ -505,16 +490,18 @@ void Widget::replaceChild(Widget* oldChild, Widget* newChild) ASSERT_VALID_WIDGET(oldChild); ASSERT_VALID_WIDGET(newChild); - JLink before = jlist_find(children, oldChild); - if (!before) + WidgetsList::iterator before = + std::find(m_children.begin(), m_children.end(), oldChild); + if (before == m_children.end()) { + ASSERT(false); return; - - before = before->next; + } + int index = before - m_children.begin(); removeChild(oldChild); - jlist_insert_before(children, before, newChild); - newChild->parent = this; + m_children.insert(m_children.begin()+index, newChild); + newChild->m_parent = this; } void Widget::insertChild(int index, Widget* child) @@ -522,8 +509,8 @@ void Widget::insertChild(int index, Widget* child) ASSERT_VALID_WIDGET(this); ASSERT_VALID_WIDGET(child); - jlist_insert(children, child, index); - child->parent = this; + m_children.insert(m_children.begin()+index, child); + child->m_parent = this; } // =============================================================== @@ -604,31 +591,30 @@ JRegion jwidget_get_region(Widget* widget) /* gets the region to be able to draw in */ JRegion jwidget_get_drawable_region(Widget* widget, int flags) { - Widget* window, *manager, *view, *child; + Widget* window, *manager, *view; JRegion region, reg1, reg2, reg3; - JList windows_list; - JLink link; JRect cpos; ASSERT_VALID_WIDGET(widget); region = jwidget_get_region(widget); - /* cut the top windows areas */ + // Cut the top windows areas if (flags & JI_GDR_CUTTOPWINDOWS) { window = widget->getRoot(); manager = window ? window->getManager(): NULL; while (manager) { - windows_list = manager->children; - link = jlist_find(windows_list, window); + const WidgetsList& windows_list = manager->getChildren(); + WidgetsList::const_reverse_iterator it = + std::find(windows_list.rbegin(), windows_list.rend(), window); - if (!jlist_empty(windows_list) && - window != jlist_first(windows_list)->data && - link != windows_list->end) { - /* subtract the rectangles */ - for (link=link->prev; link != windows_list->end; link=link->prev) { - reg1 = jwidget_get_region(reinterpret_cast(link->data)); + if (!windows_list.empty() && + window != windows_list.front() && + it != windows_list.rend()) { + // Subtract the rectangles + for (++it; it != windows_list.rend(); ++it) { + reg1 = jwidget_get_region(*it); jregion_subtract(region, region, reg1); jregion_free(reg1); } @@ -639,13 +625,14 @@ JRegion jwidget_get_drawable_region(Widget* widget, int flags) } } - /* clip the areas where are children */ - if (!(flags & JI_GDR_USECHILDAREA) && !jlist_empty(widget->children)) { + // Clip the areas where are children + if (!(flags & JI_GDR_USECHILDAREA) && !widget->getChildren().empty()) { cpos = jwidget_get_child_rect(widget); reg1 = jregion_new(NULL, 0); reg2 = jregion_new(cpos, 1); - JI_LIST_FOR_EACH(widget->children, link) { - child = reinterpret_cast(link->data); + + UI_FOREACH_WIDGET(widget->getChildren(), it) { + Widget* child = *it; if (child->isVisible()) { reg3 = jwidget_get_region(child); if (child->flags & JI_DECORATIVE) { @@ -664,9 +651,9 @@ JRegion jwidget_get_drawable_region(Widget* widget, int flags) jrect_free(cpos); } - /* intersect with the parent area */ + // Intersect with the parent area if (!(widget->flags & JI_DECORATIVE)) { - Widget* parent = widget->parent; + Widget* parent = widget->getParent(); reg1 = jregion_new(NULL, 0); @@ -676,14 +663,13 @@ JRegion jwidget_get_drawable_region(Widget* widget, int flags) jregion_intersect(region, region, reg1); jrect_free(cpos); - parent = parent->parent; + parent = parent->getParent(); } jregion_free(reg1); } else { - Widget* parent = widget->parent; - + Widget* parent = widget->getParent(); if (parent) { cpos = jwidget_get_rect(parent); reg1 = jregion_new(cpos, 1); @@ -693,7 +679,7 @@ JRegion jwidget_get_drawable_region(Widget* widget, int flags) } } - /* limit to the manager area */ + // Limit to the manager area window = widget->getRoot(); manager = window ? window->getManager(): NULL; @@ -924,7 +910,6 @@ void Widget::flushRedraw() std::queue processing; int c, nrects; Message* msg; - JLink link; JRect rc; if (this->flags & JI_DIRTY) { @@ -942,8 +927,8 @@ void Widget::flushRedraw() if (!widget->isVisible()) continue; - JI_LIST_FOR_EACH(widget->children, link) { - Widget* child = (Widget*)link->data; + UI_FOREACH_WIDGET(widget->getChildren(), it) { + Widget* child = *it; if (child->flags & JI_DIRTY) { child->flags ^= JI_DIRTY; processing.push(child); @@ -993,15 +978,14 @@ void Widget::invalidate() { if (isVisible()) { JRegion reg1 = jwidget_get_drawable_region(this, JI_GDR_CUTTOPWINDOWS); - JLink link; jregion_copy(this->m_update_region, reg1); jregion_free(reg1); mark_dirty_flag(this); - JI_LIST_FOR_EACH(this->children, link) - reinterpret_cast(link->data)->invalidate(); + UI_FOREACH_WIDGET(getChildren(), it) + (*it)->invalidate(); } } @@ -1242,23 +1226,17 @@ bool Widget::isScancodeMnemonic(int scancode) const bool Widget::onProcessMessage(Message* msg) { - Widget* widget = this; - ASSERT(msg != NULL); - ASSERT_VALID_WIDGET(widget); switch (msg->type) { case JM_OPEN: case JM_CLOSE: - case JM_WINMOVE: { - JLink link; - + case JM_WINMOVE: // Broadcast the message to the children. - JI_LIST_FOR_EACH(widget->children, link) - reinterpret_cast(link->data)->sendMessage(msg); + UI_FOREACH_WIDGET(getChildren(), it) + (*it)->sendMessage(msg); break; - } case JM_DRAW: // With double-buffering we create a temporary bitmap to draw @@ -1299,47 +1277,38 @@ bool Widget::onProcessMessage(Message* msg) } case JM_REQSIZE: - msg->reqsize.w = widget->min_w; - msg->reqsize.h = widget->min_h; + msg->reqsize.w = this->min_w; + msg->reqsize.h = this->min_h; return true; case JM_SETPOS: { - JRect cpos; - JLink link; - - jrect_copy(widget->rc, &msg->setpos.rect); - cpos = jwidget_get_child_rect(widget); + jrect_copy(this->rc, &msg->setpos.rect); + JRect cpos = jwidget_get_child_rect(this); // Set all the children to the same "cpos". - JI_LIST_FOR_EACH(widget->children, link) - jwidget_set_rect(reinterpret_cast(link->data), cpos); + UI_FOREACH_WIDGET(getChildren(), it) + jwidget_set_rect(*it, cpos); jrect_free(cpos); return true; } - case JM_DIRTYCHILDREN: { - JLink link; - - JI_LIST_FOR_EACH(widget->children, link) - reinterpret_cast(link->data)->invalidate(); - + case JM_DIRTYCHILDREN: + UI_FOREACH_WIDGET(getChildren(), it) + (*it)->invalidate(); return true; - } case JM_KEYPRESSED: case JM_KEYRELEASED: if (msg->key.propagate_to_children) { - JLink link; - // Broadcast the message to the children. - JI_LIST_FOR_EACH(widget->children, link) - reinterpret_cast(link->data)->sendMessage(msg); + UI_FOREACH_WIDGET(getChildren(), it) + (*it)->sendMessage(msg); } // Propagate the message to the parent. - if (msg->key.propagate_to_parent && widget->parent != NULL) - return widget->parent->sendMessage(msg); + if (msg->key.propagate_to_parent && getParent() != NULL) + return getParent()->sendMessage(msg); else break; @@ -1349,15 +1318,15 @@ bool Widget::onProcessMessage(Message* msg) case JM_MOTION: case JM_WHEEL: // Propagate the message to the parent. - if (widget->parent != NULL) - return widget->parent->sendMessage(msg); + if (getParent() != NULL) + return getParent()->sendMessage(msg); else break; case JM_SETCURSOR: // Propagate the message to the parent. - if (widget->parent != NULL) - return widget->parent->sendMessage(msg); + if (getParent() != NULL) + return getParent()->sendMessage(msg); else { jmouse_set_cursor(JI_CURSOR_NORMAL); return true; @@ -1377,9 +1346,7 @@ void Widget::onInvalidateRegion(const JRegion region) if (isVisible() && jregion_rect_in(region, this->rc) != JI_RGNOUT) { JRegion reg1 = jregion_new(NULL, 0); - JRegion reg2 = jwidget_get_drawable_region(this, - JI_GDR_CUTTOPWINDOWS); - JLink link; + JRegion reg2 = jwidget_get_drawable_region(this, JI_GDR_CUTTOPWINDOWS); jregion_union(reg1, this->m_update_region, region); jregion_intersect(this->m_update_region, reg1, reg2); @@ -1389,8 +1356,8 @@ void Widget::onInvalidateRegion(const JRegion region) mark_dirty_flag(this); - JI_LIST_FOR_EACH(this->children, link) - reinterpret_cast(link->data)->invalidateRegion(reg1); + UI_FOREACH_WIDGET(getChildren(), it) + (*it)->invalidateRegion(reg1); jregion_free(reg1); } diff --git a/src/ui/widget.h b/src/ui/widget.h index de9d709a5..135d09243 100644 --- a/src/ui/widget.h +++ b/src/ui/widget.h @@ -14,7 +14,6 @@ #include "gfx/size.h" #include "ui/base.h" #include "ui/component.h" -#include "ui/list.h" #include "ui/rect.h" #include "ui/widgets_list.h" @@ -77,10 +76,6 @@ namespace ui { int min_w, min_h; int max_w, max_h; - /* structures */ - JList children; /* sub-objects */ - Widget* parent; /* who is the parent? */ - private: std::string m_id; // Widget's id Theme* m_theme; // Widget's theme @@ -89,6 +84,8 @@ namespace ui { struct FONT *m_font; // Text font type int m_bg_color; // Background color JRegion m_update_region; // Region to be redrawed. + WidgetsList m_children; // Sub-widgets + Widget* m_parent; // Who is the parent? public: // Extra data for the theme @@ -176,8 +173,8 @@ namespace ui { // Gets the background color of the widget. int getBgColor() const { - if (m_bg_color < 0 && parent) - return parent->getBgColor(); + if (m_bg_color < 0 && m_parent) + return m_parent->getBgColor(); else return m_bg_color; } @@ -197,16 +194,16 @@ namespace ui { // =============================================================== Window* getRoot(); - Widget* getParent(); + Widget* getParent() { return m_parent; } Manager* getManager(); // Returns a list of parents (you must free the list), if // "ascendant" is true the list is build from child to parents, else // the list is from parent to children. - JList getParents(bool ascendant); + void getParents(bool ascendant, WidgetsList& parents); // Returns a list of children (you must free the list). - JList getChildren(); + const WidgetsList& getChildren() const { return m_children; } // Returns the next or previous siblings. Widget* getNextSibling(); @@ -228,9 +225,8 @@ namespace ui { template T* findFirstChildByType() { - JLink link; - JI_LIST_FOR_EACH(children, link) { - Widget* child = (Widget*)link->data; + UI_FOREACH_WIDGET(m_children, it) { + Widget* child = *it; if (T* specificChild = dynamic_cast(child)) return specificChild; } diff --git a/src/ui/widgets_list.h b/src/ui/widgets_list.h index 4f9d5b36a..880fa45cd 100644 --- a/src/ui/widgets_list.h +++ b/src/ui/widgets_list.h @@ -9,6 +9,30 @@ #include +#define UI_FOREACH_WIDGET(list_name, iterator_name) \ + for (WidgetsList::const_iterator \ + iterator_name = (list_name).begin(), \ + __end = (list_name).end(); \ + iterator_name != __end; \ + ++iterator_name) + +#define UI_FOREACH_WIDGET_BACKWARD(list_name, iterator_name) \ + for (WidgetsList::const_reverse_iterator \ + iterator_name = (list_name).rbegin(), \ + __end=(list_name).rend(); \ + iterator_name != __end; \ + ++iterator_name) + +#define UI_FOREACH_WIDGET_WITH_END(list_name, iterator_name, end_name) \ + for (WidgetsList::const_iterator \ + iterator_name = (list_name).begin(), \ + end_name = (list_name).end(); \ + iterator_name != end_name; \ + ++iterator_name) + +#define UI_FIRST_WIDGET(list_name) \ + ((list_name).empty() ? NULL: (list_name).front()) + namespace ui { class Widget; diff --git a/src/ui/window.cpp b/src/ui/window.cpp index c61bc2665..92c51981a 100644 --- a/src/ui/window.cpp +++ b/src/ui/window.cpp @@ -94,6 +94,12 @@ HitTest Window::hitTest(const gfx::Point& point) return ev.getHit(); } +void Window::removeDecorativeWidgets() +{ + while (!getChildren().empty()) + delete getChildren().front(); +} + void Window::onClose(CloseEvent& ev) { // Fire Close signal @@ -221,7 +227,7 @@ void Window::move_window(JRect rect) void Window::openWindow() { - if (!this->parent) { + if (!getParent()) { if (m_is_autoremap) center_window(); @@ -257,9 +263,8 @@ void Window::closeWindow(Widget* killer) bool Window::is_toplevel() { Widget* manager = getManager(); - - if (!jlist_empty(manager->children)) - return (this == jlist_first(manager->children)->data); + if (!manager->getChildren().empty()) + return (this == UI_FIRST_WIDGET(manager->getChildren())); else return false; } @@ -456,11 +461,9 @@ void Window::onPreferredSize(PreferredSizeEvent& ev) else { Size maxSize(0, 0); Size reqSize; - Widget* child; - JLink link; - JI_LIST_FOR_EACH(this->children, link) { - child = (Widget*)link->data; + UI_FOREACH_WIDGET(getChildren(), it) { + Widget* child = *it; if (!child->isDecorative()) { reqSize = child->getPreferredSize(); @@ -505,17 +508,13 @@ void Window::onSetText() void Window::window_set_position(JRect rect) { - Widget* child; - JRect cpos; - JLink link; - /* copy the new position rectangle */ jrect_copy(this->rc, rect); - cpos = jwidget_get_child_rect(this); + JRect cpos = jwidget_get_child_rect(this); /* set all the children to the same "child_pos" */ - JI_LIST_FOR_EACH(this->children, link) { - child = (Widget*)link->data; + UI_FOREACH_WIDGET(getChildren(), it) { + Widget* child = *it; if (child->isDecorative()) child->getTheme()->map_decorative_widget(child); @@ -649,12 +648,10 @@ void Window::move_window(JRect rect, bool use_blit) static void displace_widgets(Widget* widget, int x, int y) { - JLink link; - jrect_displace(widget->rc, x, y); - JI_LIST_FOR_EACH(widget->children, link) - displace_widgets(reinterpret_cast(link->data), x, y); + UI_FOREACH_WIDGET(widget->getChildren(), it) + displace_widgets((*it), x, y); } } // namespace ui diff --git a/src/ui/window.h b/src/ui/window.h index afbb6d887..fdc88aba6 100644 --- a/src/ui/window.h +++ b/src/ui/window.h @@ -49,6 +49,8 @@ namespace ui { HitTest hitTest(const gfx::Point& point); + void removeDecorativeWidgets(); + // Signals Signal1 Close; diff --git a/src/util/misc.cpp b/src/util/misc.cpp index 2e2a7fee4..c9853fd61 100644 --- a/src/util/misc.cpp +++ b/src/util/misc.cpp @@ -28,7 +28,6 @@ #include "modules/gui.h" #include "modules/palettes.h" #include "raster/raster.h" -#include "ui/list.h" #include "ui/manager.h" #include "ui/system.h" #include "ui/widget.h" diff --git a/src/util/render.cpp b/src/util/render.cpp index 250037f0f..661501a52 100644 --- a/src/util/render.cpp +++ b/src/util/render.cpp @@ -25,7 +25,6 @@ #include "ini_file.h" #include "raster/raster.h" #include "settings/settings.h" -#include "ui/list.h" #include "ui_context.h" ////////////////////////////////////////////////////////////////////// diff --git a/src/util/thmbnail.cpp b/src/util/thmbnail.cpp index 98c3f3b45..fc0f6e523 100644 --- a/src/util/thmbnail.cpp +++ b/src/util/thmbnail.cpp @@ -30,7 +30,6 @@ #include "raster/palette.h" #include "raster/sprite.h" #include "raster/stock.h" -#include "ui/list.h" #include "util/thmbnail.h" #define THUMBNAIL_W 32 diff --git a/src/widgets/button_set.cpp b/src/widgets/button_set.cpp index a242648bd..fcf14737a 100644 --- a/src/widgets/button_set.cpp +++ b/src/widgets/button_set.cpp @@ -25,7 +25,6 @@ #include "modules/gui.h" #include "ui/box.h" #include "ui/button.h" -#include "ui/list.h" #include "ui/system.h" #include "ui/theme.h" #include "ui/widget.h" diff --git a/src/widgets/color_bar.cpp b/src/widgets/color_bar.cpp index 7deb8cfa7..216ce5d6a 100644 --- a/src/widgets/color_bar.cpp +++ b/src/widgets/color_bar.cpp @@ -29,7 +29,6 @@ #include "modules/gui.h" #include "raster/image.h" #include "skin/skin_theme.h" -#include "ui/list.h" #include "ui/message.h" #include "ui_context.h" #include "widgets/color_bar.h" @@ -57,10 +56,7 @@ bool ColorBar::ScrollableView::onProcessMessage(Message* msg) case JM_DRAW: { - Viewport* viewport = getViewport(); - Widget* child = reinterpret_cast(jlist_first_data(viewport->children)); SkinTheme* theme = static_cast(getTheme()); - theme->draw_bounds_nw(ji_screen, rc->x1, rc->y1, rc->x2-1, rc->y2-1, diff --git a/src/widgets/editor/cursor.cpp b/src/widgets/editor/cursor.cpp index d6995694c..a7624a86c 100644 --- a/src/widgets/editor/cursor.cpp +++ b/src/widgets/editor/cursor.cpp @@ -31,7 +31,6 @@ #include "tools/ink.h" #include "tools/tool.h" #include "ui/base.h" -#include "ui/list.h" #include "ui/rect.h" #include "ui/region.h" #include "ui/system.h" diff --git a/src/widgets/editor/editor_view.cpp b/src/widgets/editor/editor_view.cpp index e45487692..a8cffa4c7 100644 --- a/src/widgets/editor/editor_view.cpp +++ b/src/widgets/editor/editor_view.cpp @@ -22,7 +22,6 @@ #include "modules/editors.h" #include "skin/skin_theme.h" -#include "ui/list.h" #include "ui/message.h" #include "widgets/editor/editor.h" @@ -60,7 +59,7 @@ bool EditorView::onProcessMessage(Message* msg) case JM_DRAW: { Widget* viewport = getViewport(); - Widget* child = reinterpret_cast(jlist_first_data(viewport->children)); + Widget* child = UI_FIRST_WIDGET(viewport->getChildren()); JRect pos = jwidget_get_rect(this); SkinTheme* theme = static_cast(getTheme()); bool selected = false; diff --git a/src/widgets/file_selector.cpp b/src/widgets/file_selector.cpp index 9df7459d5..c37b9358f 100644 --- a/src/widgets/file_selector.cpp +++ b/src/widgets/file_selector.cpp @@ -442,13 +442,12 @@ void FileSelector::updateLocation() { IFileItem* currentFolder = m_fileList->getCurrentFolder(); IFileItem* fileItem = currentFolder; - JList locations = jlist_new(); - JLink link; + std::list locations; int selected_index = -1; int newItem; while (fileItem != NULL) { - jlist_prepend(locations, fileItem); + locations.push_front(fileItem); fileItem = fileItem->getParent(); } @@ -457,8 +456,9 @@ void FileSelector::updateLocation() // Add item by item (from root to the specific current folder) int level = 0; - JI_LIST_FOR_EACH(locations, link) { - fileItem = reinterpret_cast(link->data); + for (std::list::iterator it=locations.begin(), end=locations.end(); + it != end; ++it) { + fileItem = *it; // Indentation base::string buf; @@ -495,8 +495,6 @@ void FileSelector::updateLocation() m_location->getEntryWidget()->setText(currentFolder->getDisplayName().c_str()); m_location->getEntryWidget()->deselectText(); } - - jlist_free(locations); } void FileSelector::updateNavigationButtons() @@ -572,7 +570,7 @@ void FileSelector::onGoBack() void FileSelector::onGoForward() { - if (jlist_length(navigation_history) > 1) { + if (navigation_history->size() > 1) { if (navigation_position.isNull()) navigation_position.setIterator(navigation_history->begin()); diff --git a/src/widgets/status_bar.cpp b/src/widgets/status_bar.cpp index 8dc386243..3354fde30 100644 --- a/src/widgets/status_bar.cpp +++ b/src/widgets/status_bar.cpp @@ -373,12 +373,10 @@ void StatusBar::showTool(int msecs, tools::Tool* tool) std::string text = tool->getText(); // Tool shortcut - JAccel accel = get_accel_to_change_tool(tool); + Accelerator* accel = get_accel_to_change_tool(tool); if (accel) { - char buf[512]; // TODO possible buffer overflow - jaccel_to_string(accel, buf); text += ", Shortcut: "; - text += buf; + text += accel->toString(); } // Set text diff --git a/src/widgets/toolbar.cpp b/src/widgets/toolbar.cpp index 10c0c649d..f3a00c5f1 100644 --- a/src/widgets/toolbar.cpp +++ b/src/widgets/toolbar.cpp @@ -492,12 +492,10 @@ void ToolBar::openTipWindow(int group_index, Tool* tool) } // Tool shortcut - JAccel accel = get_accel_to_change_tool(tool); + Accelerator* accel = get_accel_to_change_tool(tool); if (accel) { - char buf[512]; // TODO possible buffer overflow - jaccel_to_string(accel, buf); tooltip += "\n\nShortcut: "; - tooltip += buf; + tooltip += accel->toString(); } } else if (group_index == ConfigureToolIndex) {