Refactor: replace JList with std::vector<> or std::list<>.

This commit is contained in:
David Capello 2012-07-17 21:42:02 -03:00
parent f8f5b2b515
commit 14f24b1181
52 changed files with 705 additions and 1375 deletions

View File

@ -13,7 +13,6 @@
* MovingPixelsState: Add undo information in each transformation step. * MovingPixelsState: Add undo information in each transformation step.
* Add IntEntry class in src/gui/ with spin-buttons. * Add IntEntry class in src/gui/ with spin-buttons.
* Add feedback to "Shift+S" shortcut to switch "snap to grid". * Add feedback to "Shift+S" shortcut to switch "snap to grid".
* Convert jaccel::key_list to std::vector<>
* Add color swatches bar. * Add color swatches bar.
* Sort palette entries. * Sort palette entries.
* Add "Remap" button to palette editor after a palette entry is modified: * Add "Remap" button to palette editor after a palette entry is modified:
@ -38,7 +37,6 @@
then cloned, and finally filled with params. then cloned, and finally filled with params.
* About Signals/Slots: Add some field in slots to avoid disconnecting * About Signals/Slots: Add some field in slots to avoid disconnecting
them from dead signals. them from dead signals.
* Eradicate JList.
* Replace JRect & jrect with gfx::Rect. * Replace JRect & jrect with gfx::Rect.
* Create gfx::Region to replace JRegion & jregion. * Create gfx::Region to replace JRegion & jregion.
* editors_ -> MultiEditors class widget * editors_ -> MultiEditors class widget
@ -47,7 +45,6 @@
* move all functions (jwidget_*) to methods in Widget class. * move all functions (jwidget_*) to methods in Widget class.
* the same for each widget (e.g. jbutton_* to Button widget) * the same for each widget (e.g. jbutton_* to Button widget)
* AppHooks to Vaca::Signals * 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 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: * all functions to handle an object should be converted to member functions:
* e.g. jwidget_set_text -> Widget::setText * e.g. jwidget_set_text -> Widget::setText

View File

@ -129,7 +129,7 @@ void AppMenus::reload()
PRINTF(" - Shortcut for command `%s' <%s>\n", command_name, command_key); PRINTF(" - Shortcut for command `%s' <%s>\n", command_name, command_key);
// add the keyboard shortcut to the command // add the keyboard shortcut to the command
JAccel accel = Accelerator* accel =
add_keyboard_shortcut_to_execute_command(command_key, command_name, &params); add_keyboard_shortcut_to_execute_command(command_key, command_name, &params);
// add the shortcut to the menuitems with this // add the shortcut to the menuitems with this
@ -364,13 +364,10 @@ Widget* AppMenus::createInvalidVersionMenuitem()
return menuitem; 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(); UI_FOREACH_WIDGET(menu->getChildren(), it) {
JLink link; Widget* child = *it;
JI_LIST_FOR_EACH(children, link) {
Widget* child = (Widget*)link->data;
if (child->getType() == JI_MENUITEM) { if (child->getType() == JI_MENUITEM) {
ASSERT(dynamic_cast<MenuItem2*>(child) != NULL); ASSERT(dynamic_cast<MenuItem2*>(child) != NULL);
@ -384,13 +381,11 @@ void AppMenus::applyShortcutToMenuitemsWithCommand(Menu* menu, Command *command,
((mi_params && *mi_params == *params) || ((mi_params && *mi_params == *params) ||
(Params() == *params))) { (Params() == *params))) {
// Set the accelerator to be shown in this menu-item // 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()) if (Menu* submenu = menuitem->getSubmenu())
applyShortcutToMenuitemsWithCommand(submenu, command, params, accel); applyShortcutToMenuitemsWithCommand(submenu, command, params, accel);
} }
} }
jlist_free(children);
} }

View File

@ -29,6 +29,8 @@ class Params;
class TiXmlElement; class TiXmlElement;
class TiXmlHandle; class TiXmlHandle;
namespace ui { class Accelerator; }
// Class to handle/get/reload available menus in gui.xml file. // Class to handle/get/reload available menus in gui.xml file.
class AppMenus class AppMenus
{ {
@ -56,7 +58,7 @@ private:
ui::Menu* convertXmlelemToMenu(TiXmlElement* elem); ui::Menu* convertXmlelemToMenu(TiXmlElement* elem);
ui::Widget* convertXmlelemToMenuitem(TiXmlElement* elem); ui::Widget* convertXmlelemToMenuitem(TiXmlElement* elem);
ui::Widget* createInvalidVersionMenuitem(); 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<ui::Menu> m_rootMenu; UniquePtr<ui::Menu> m_rootMenu;
ui::MenuItem* m_recentListMenuitem; ui::MenuItem* m_recentListMenuitem;

View File

@ -74,10 +74,9 @@ void AdvancedModeCommand::onExecute(Context* context)
if (advanced_mode && if (advanced_mode &&
get_config_bool("AdvancedMode", "Warning", true)) { 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) { if (accel != NULL) {
char warning[1024]; char warning[1024];
char key[1024];
char buf[1024]; char buf[1024];
UniquePtr<Window> window(app::load_widget<Window>("advanced_mode.xml", "advanced_mode_warning")); UniquePtr<Window> window(app::load_widget<Window>("advanced_mode.xml", "advanced_mode_warning"));
@ -85,8 +84,7 @@ void AdvancedModeCommand::onExecute(Context* context)
Widget* donot_show = app::find_widget<Widget>(window, "donot_show"); Widget* donot_show = app::find_widget<Widget>(window, "donot_show");
strcpy(warning, "You can back pressing the \"%s\" key."); strcpy(warning, "You can back pressing the \"%s\" key.");
jaccel_to_string(accel, key); std::sprintf(buf, warning, accel->toString().c_str());
std::sprintf(buf, warning, key);
warning_label->setText(buf); warning_label->setText(buf);

View File

@ -34,7 +34,6 @@
#include "raster/sprite.h" #include "raster/sprite.h"
#include "ui/button.h" #include "ui/button.h"
#include "ui/label.h" #include "ui/label.h"
#include "ui/list.h"
#include "ui/listbox.h" #include "ui/listbox.h"
#include "ui/slider.h" #include "ui/slider.h"
#include "ui/view.h" #include "ui/view.h"
@ -88,11 +87,10 @@ private:
void fillStockListBox() void fillStockListBox()
{ {
const char* oldSelected = (m_filter.getMatrix() ? m_filter.getMatrix()->getName(): NULL); const char* oldSelected = (m_filter.getMatrix() ? m_filter.getMatrix()->getName(): NULL);
JLink link, next;
// Clean the list // Clean the list
JI_LIST_FOR_EACH_SAFE(m_stockListBox->children, link, next) { while (!m_stockListBox->getChildren().empty()) {
Widget* listitem = reinterpret_cast<Widget*>(link->data); Widget* listitem = m_stockListBox->getChildren().front();
m_stockListBox->removeChild(listitem); m_stockListBox->removeChild(listitem);
delete listitem; delete listitem;
} }
@ -109,12 +107,11 @@ private:
void selectMatrixByName(const char* oldSelected) void selectMatrixByName(const char* oldSelected)
{ {
Widget* select_this = reinterpret_cast<Widget*>(jlist_first_data(m_stockListBox->children)); Widget* select_this = UI_FIRST_WIDGET(m_stockListBox->getChildren());
if (oldSelected) { if (oldSelected) {
JLink link; UI_FOREACH_WIDGET(m_stockListBox->getChildren(), it) {
JI_LIST_FOR_EACH(m_stockListBox->children, link) { Widget* child = *it;
Widget* child = reinterpret_cast<Widget*>(link->data);
if (strcmp(child->getText(), oldSelected) == 0) { if (strcmp(child->getText(), oldSelected) == 0) {
select_this = child; select_this = child;

View File

@ -25,7 +25,6 @@
#include "file/file_handle.h" #include "file/file_handle.h"
#include "file/format_options.h" #include "file/format_options.h"
#include "raster/raster.h" #include "raster/raster.h"
#include "ui/list.h"
#include "zlib.h" #include "zlib.h"
#include <stdio.h> #include <stdio.h>

View File

@ -123,41 +123,41 @@ public:
} }
bool isCopySelectionKeyPressed() OVERRIDE { bool isCopySelectionKeyPressed() OVERRIDE {
JAccel accel = get_accel_to_copy_selection(); Accelerator* accel = get_accel_to_copy_selection();
if (accel) if (accel)
return jaccel_check_from_key(accel); return accel->checkFromAllegroKeyArray();
else else
return false; return false;
} }
bool isSnapToGridKeyPressed() OVERRIDE { bool isSnapToGridKeyPressed() OVERRIDE {
JAccel accel = get_accel_to_snap_to_grid(); Accelerator* accel = get_accel_to_snap_to_grid();
if (accel) if (accel)
return jaccel_check_from_key(accel); return accel->checkFromAllegroKeyArray();
else else
return false; return false;
} }
bool isAngleSnapKeyPressed() OVERRIDE { bool isAngleSnapKeyPressed() OVERRIDE {
JAccel accel = get_accel_to_angle_snap(); Accelerator* accel = get_accel_to_angle_snap();
if (accel) if (accel)
return jaccel_check_from_key(accel); return accel->checkFromAllegroKeyArray();
else else
return false; return false;
} }
bool isMaintainAspectRatioKeyPressed() OVERRIDE { bool isMaintainAspectRatioKeyPressed() OVERRIDE {
JAccel accel = get_accel_to_maintain_aspect_ratio(); Accelerator* accel = get_accel_to_maintain_aspect_ratio();
if (accel) if (accel)
return jaccel_check_from_key(accel); return accel->checkFromAllegroKeyArray();
else else
return false; return false;
} }
bool isLockAxisKeyPressed() OVERRIDE { bool isLockAxisKeyPressed() OVERRIDE {
JAccel accel = get_accel_to_lock_axis(); Accelerator* accel = get_accel_to_lock_axis();
if (accel) if (accel)
return jaccel_check_from_key(accel); return accel->checkFromAllegroKeyArray();
else else
return false; return false;
} }
@ -515,7 +515,7 @@ void close_editor(Editor* editor)
delete view; delete view;
// Fixup the parent. // Fixup the parent.
other_widget = reinterpret_cast<Widget*>(jlist_first_data(parent_box->children)); other_widget = UI_FIRST_WIDGET(parent_box->getChildren());
parent_box->removeChild(other_widget); parent_box->removeChild(other_widget);
parent_box->getParent()->replaceChild(parent_box, 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) void make_unique_editor(Editor* editor)
{ {
View* view = View::getView(editor); View* view = View::getView(editor);
JLink link, next;
Widget* child;
// It's the unique editor. // It's the unique editor.
if (editors.size() == 1) if (editors.size() == 1)
@ -555,9 +553,8 @@ void make_unique_editor(Editor* editor)
view->getParent()->removeChild(view); view->getParent()->removeChild(view);
// Remove all children of main_editor_box. // Remove all children of main_editor_box.
JI_LIST_FOR_EACH_SAFE(box_editors->children, link, next) { while (!box_editors->getChildren().empty()) {
child = (Widget*)link->data; Widget* child = box_editors->getChildren().front();
box_editors->removeChild(child); box_editors->removeChild(child);
delete child; // widget delete child; // widget
} }
@ -617,14 +614,13 @@ static Document* get_more_reliable_document()
static Widget* find_next_editor(Widget* widget) static Widget* find_next_editor(Widget* widget)
{ {
Widget* editor = NULL; Widget* editor = NULL;
JLink link;
if (widget->type == JI_VIEW) { if (widget->type == JI_VIEW) {
editor = reinterpret_cast<Widget*>(jlist_first_data(static_cast<View*>(widget)->getViewport()->children)); editor = UI_FIRST_WIDGET(static_cast<View*>(widget)->getViewport()->getChildren());
} }
else { else {
JI_LIST_FOR_EACH(widget->children, link) UI_FOREACH_WIDGET(widget->getChildren(), it)
if ((editor = find_next_editor(reinterpret_cast<Widget*>(link->data)))) if ((editor = find_next_editor(*it)))
break; break;
} }

View File

@ -99,7 +99,7 @@ enum ShortcutType { Shortcut_ExecuteCommand,
struct Shortcut struct Shortcut
{ {
JAccel accel; Accelerator* accel;
ShortcutType type; ShortcutType type;
union { union {
Command* command; Command* command;
@ -666,7 +666,7 @@ CheckBox* check_button_new(const char *text, int b1, int b2, int b3, int b4)
// Keyboard shortcuts // 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); Shortcut* shortcut = get_keyboard_shortcut_for_command(command_name, params);
if (!shortcut) { if (!shortcut) {
@ -681,7 +681,7 @@ JAccel add_keyboard_shortcut_to_execute_command(const char* shortcut_string, con
return shortcut->accel; 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); Shortcut* shortcut = get_keyboard_shortcut_for_tool(tool);
if (!shortcut) { if (!shortcut) {
@ -695,7 +695,7 @@ JAccel add_keyboard_shortcut_to_change_tool(const char* shortcut_string, tools::
return shortcut->accel; 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); Shortcut* shortcut = get_keyboard_shortcut_for_quicktool(tool);
if (!shortcut) { if (!shortcut) {
@ -709,7 +709,7 @@ JAccel add_keyboard_shortcut_to_quicktool(const char* shortcut_string, tools::To
return shortcut->accel; 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); Shortcut* shortcut = get_keyboard_shortcut_for_spriteeditor(action_name);
if (!shortcut) { if (!shortcut) {
@ -738,7 +738,7 @@ bool get_command_from_key_message(Message* msg, Command** command, Params** para
return false; 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); Shortcut* shortcut = get_keyboard_shortcut_for_command(command_name, params);
if (shortcut) if (shortcut)
@ -747,7 +747,7 @@ JAccel get_accel_to_execute_command(const char* command_name, Params* params)
return NULL; 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); Shortcut* shortcut = get_keyboard_shortcut_for_tool(tool);
if (shortcut) if (shortcut)
@ -756,7 +756,7 @@ JAccel get_accel_to_change_tool(tools::Tool* tool)
return NULL; return NULL;
} }
JAccel get_accel_to_copy_selection() Accelerator* get_accel_to_copy_selection()
{ {
Shortcut* shortcut = get_keyboard_shortcut_for_spriteeditor(SPRITEDITOR_ACTION_COPYSELECTION); Shortcut* shortcut = get_keyboard_shortcut_for_spriteeditor(SPRITEDITOR_ACTION_COPYSELECTION);
if (shortcut) if (shortcut)
@ -765,7 +765,7 @@ JAccel get_accel_to_copy_selection()
return NULL; 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); Shortcut* shortcut = get_keyboard_shortcut_for_spriteeditor(SPRITEDITOR_ACTION_SNAPTOGRID);
if (shortcut) if (shortcut)
@ -774,7 +774,7 @@ JAccel get_accel_to_snap_to_grid()
return NULL; return NULL;
} }
JAccel get_accel_to_angle_snap() Accelerator* get_accel_to_angle_snap()
{ {
Shortcut* shortcut = get_keyboard_shortcut_for_spriteeditor(SPRITEDITOR_ACTION_ANGLESNAP); Shortcut* shortcut = get_keyboard_shortcut_for_spriteeditor(SPRITEDITOR_ACTION_ANGLESNAP);
if (shortcut) if (shortcut)
@ -783,7 +783,7 @@ JAccel get_accel_to_angle_snap()
return NULL; 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); Shortcut* shortcut = get_keyboard_shortcut_for_spriteeditor(SPRITEDITOR_ACTION_MAINTAINASPECTRATIO);
if (shortcut) if (shortcut)
@ -792,7 +792,7 @@ JAccel get_accel_to_maintain_aspect_ratio()
return NULL; return NULL;
} }
JAccel get_accel_to_lock_axis() Accelerator* get_accel_to_lock_axis()
{ {
Shortcut* shortcut = get_keyboard_shortcut_for_spriteeditor(SPRITEDITOR_ACTION_LOCKAXIS); Shortcut* shortcut = get_keyboard_shortcut_for_spriteeditor(SPRITEDITOR_ACTION_LOCKAXIS);
if (shortcut) if (shortcut)
@ -804,8 +804,8 @@ JAccel get_accel_to_lock_axis()
tools::Tool* get_selected_quicktool(tools::Tool* currentTool) tools::Tool* get_selected_quicktool(tools::Tool* currentTool)
{ {
if (currentTool && currentTool->getInk(0)->isSelection()) { if (currentTool && currentTool->getInk(0)->isSelection()) {
JAccel copyselection_accel = get_accel_to_copy_selection(); Accelerator* copyselection_accel = get_accel_to_copy_selection();
if (copyselection_accel && jaccel_check_from_key(copyselection_accel)) if (copyselection_accel && copyselection_accel->checkFromAllegroKeyArray())
return NULL; return NULL;
} }
@ -827,7 +827,7 @@ tools::Tool* get_selected_quicktool(tools::Tool* currentTool)
Shortcut::Shortcut(ShortcutType type) Shortcut::Shortcut(ShortcutType type)
{ {
this->type = type; this->type = type;
this->accel = jaccel_new(); this->accel = new Accelerator;
this->command = NULL; this->command = NULL;
this->tool = NULL; this->tool = NULL;
this->params = NULL; this->params = NULL;
@ -838,21 +838,20 @@ Shortcut::~Shortcut()
delete params; delete params;
if (type == Shortcut_SpriteEditor) if (type == Shortcut_SpriteEditor)
base_free(action); base_free(action);
jaccel_free(accel); delete accel;
} }
void Shortcut::add_shortcut(const char* shortcut_string) void Shortcut::add_shortcut(const char* shortcut_string)
{ {
char buf[256]; char buf[256];
usprintf(buf, "<%s>", shortcut_string); usprintf(buf, "<%s>", shortcut_string);
jaccel_add_keys_from_string(this->accel, buf); this->accel->addKeysFromString(buf);
} }
bool Shortcut::is_pressed(Message* msg) bool Shortcut::is_pressed(Message* msg)
{ {
if (accel) { if (accel) {
return jaccel_check(accel, return accel->check(msg->any.shifts,
msg->any.shifts,
msg->key.ascii, msg->key.ascii,
msg->key.scancode); msg->key.scancode);
} }
@ -862,7 +861,7 @@ bool Shortcut::is_pressed(Message* msg)
bool Shortcut::is_pressed_from_key_array() bool Shortcut::is_pressed_from_key_array()
{ {
if (accel) { if (accel) {
return jaccel_check_from_key(accel); return accel->checkFromAllegroKeyArray();
} }
return false; return false;
} }
@ -1022,9 +1021,8 @@ bool CustomizedGuiManager::onProcessMessage(Message* msg)
// Commands are executed only when the main window is // Commands are executed only when the main window is
// the current window running at foreground. // the current window running at foreground.
JLink link; UI_FOREACH_WIDGET(getChildren(), it) {
JI_LIST_FOR_EACH(this->children, link) { Window* child = static_cast<Window*>(*it);
Window* child = reinterpret_cast<Window*>(link->data);
// There are a foreground window executing? // There are a foreground window executing?
if (child->is_foreground()) { if (child->is_foreground()) {

View File

@ -21,7 +21,7 @@
#include "base/exception.h" #include "base/exception.h"
#include "skin/skin_property.h" #include "skin/skin_property.h"
#include "ui/accel.h" #include "ui/accelerator.h"
#include "ui/base.h" #include "ui/base.h"
#include <list> #include <list>
#include <string> #include <string>
@ -71,19 +71,19 @@ ui::CheckBox* check_button_new(const char* text, int b1, int b2, int b3, int b4)
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
// Keyboard shortcuts // Keyboard shortcuts
ui::JAccel add_keyboard_shortcut_to_execute_command(const char* shortcut, const char* command_name, Params* params); ui::Accelerator* 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::Accelerator* 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::Accelerator* 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_spriteeditor(const char* shortcut, const char* action_name);
bool get_command_from_key_message(ui::Message* msg, Command** command, Params** params); 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::Accelerator* get_accel_to_execute_command(const char* command, Params* params = NULL);
ui::JAccel get_accel_to_change_tool(tools::Tool* tool); ui::Accelerator* get_accel_to_change_tool(tools::Tool* tool);
ui::JAccel get_accel_to_copy_selection(); ui::Accelerator* get_accel_to_copy_selection();
ui::JAccel get_accel_to_snap_to_grid(); ui::Accelerator* get_accel_to_snap_to_grid();
ui::JAccel get_accel_to_angle_snap(); ui::Accelerator* get_accel_to_angle_snap();
ui::JAccel get_accel_to_maintain_aspect_ratio(); ui::Accelerator* get_accel_to_maintain_aspect_ratio();
ui::JAccel get_accel_to_lock_axis(); ui::Accelerator* get_accel_to_lock_axis();
tools::Tool* get_selected_quicktool(tools::Tool* currentTool); tools::Tool* get_selected_quicktool(tools::Tool* currentTool);

View File

@ -21,8 +21,6 @@
#include <allegro.h> #include <allegro.h>
#include <string.h> #include <string.h>
#include "ui/list.h"
#include "app.h" #include "app.h"
#include "modules/palettes.h" #include "modules/palettes.h"
#include "raster/blend.h" #include "raster/blend.h"

View File

@ -731,7 +731,7 @@ JRegion SkinTheme::get_window_mask(Widget* widget)
void SkinTheme::map_decorative_widget(Widget* widget) void SkinTheme::map_decorative_widget(Widget* widget)
{ {
if (widget->getId() == kThemeCloseButtonId) { if (widget->getId() == kThemeCloseButtonId) {
Widget* window = widget->parent; Widget* window = widget->getParent();
JRect rect = jrect_new(0, 0, 0, 0); JRect rect = jrect_new(0, 0, 0, 0);
rect->x2 = m_part[PART_WINDOW_CLOSE_BUTTON_NORMAL]->w; rect->x2 = m_part[PART_WINDOW_CLOSE_BUTTON_NORMAL]->w;
@ -1092,10 +1092,10 @@ void SkinTheme::draw_menuitem(MenuItem* widget, JRect clip)
JRect pos; JRect pos;
/* TODO ASSERT? */ /* TODO ASSERT? */
if (!widget->parent->parent) if (!widget->getParent()->getParent())
return; return;
bar = (widget->parent->parent->type == JI_MENUBAR); bar = (widget->getParent()->getParent()->type == JI_MENUBAR);
/* colors */ /* colors */
if (!widget->isEnabled()) { 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); (widget->rc->y1+widget->rc->y2)/2+c, COLOR_DISABLED);
} }
} }
/* draw the keyboard shortcut */ // Draw the keyboard shortcut
else if (widget->getAccel()) { else if (widget->getAccel()) {
int old_align = widget->getAlign(); int old_align = widget->getAlign();
char buf[256];
pos = jwidget_get_rect(widget); pos = jwidget_get_rect(widget);
pos->x2 -= widget->child_spacing/4; pos->x2 -= widget->child_spacing/4;
jaccel_to_string(widget->getAccel(), buf); std::string buf = widget->getAccel()->toString();
widget->setAlign(JI_RIGHT | JI_MIDDLE); 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); widget->setAlign(old_align);
jrect_free(pos); jrect_free(pos);

View File

@ -2,7 +2,7 @@
# Copyright (C) 2001-2012 David Capello # Copyright (C) 2001-2012 David Capello
add_library(ui-lib add_library(ui-lib
accel.cpp accelerator.cpp
alert.cpp alert.cpp
box.cpp box.cpp
button.cpp button.cpp
@ -22,7 +22,6 @@ add_library(ui-lib
intern.cpp intern.cpp
label.cpp label.cpp
link_label.cpp link_label.cpp
list.cpp
listbox.cpp listbox.cpp
manager.cpp manager.cpp
menu.cpp menu.cpp

View File

@ -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

View File

@ -6,77 +6,31 @@
#include "config.h" #include "config.h"
#include "ui/accelerator.h"
#include "base/unique_ptr.h"
#include <allegro/keyboard.h> #include <allegro/keyboard.h>
#include <allegro/unicode.h> #include <allegro/unicode.h>
#include <ctype.h> #include <ctype.h>
#include "ui/accel.h"
#include "ui/list.h"
/* #define REPORT_KEYS */ /* #define REPORT_KEYS */
#define PREPROCESS_KEYS #define PREPROCESS_KEYS
namespace ui { namespace ui {
struct jaccel void Accelerator::addKey(int shifts, int ascii, int scancode)
{ {
JList key_list; KeyCombo key;
};
struct KeyCombo key.shifts = shifts & (KB_SHIFT_FLAG | KB_CTRL_FLAG | KB_ALT_FLAG);
{ key.ascii = ascii;
int shifts; key.scancode = scancode;
int ascii;
int scancode;
};
JAccel jaccel_new() m_combos.push_back(key);
{
JAccel accel = new jaccel;
accel->key_list = jlist_new();
return accel;
} }
JAccel jaccel_new_copy(JAccel accel) static void process_one_word(Accelerator* accel, char* word)
{
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)
{ {
int shifts = 0; int shifts = 0;
int ascii = 0; int ascii = 0;
@ -85,7 +39,7 @@ static void proc_one_word(JAccel accel, char* word)
// Special case: plus sign // Special case: plus sign
if (word[0] == '+' && word[1] == 0) { if (word[0] == '+' && word[1] == 0) {
jaccel_add_key(accel, 0, '+', 0); accel->addKey(0, '+', 0);
return; 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 "<Ctrl+Q> <ESC>" */ void Accelerator::addKeysFromString(const char* string)
void jaccel_add_keys_from_string(JAccel accel, const char *string)
{ {
char *s, *begin, buf[256]; char *s, *begin, buf[256];
int backup; int backup;
@ -235,7 +188,7 @@ void jaccel_add_keys_from_string(JAccel accel, const char *string)
backup = *s; backup = *s;
*s = 0; *s = 0;
proc_one_word(accel, begin); process_one_word(this, begin);
*s = backup; *s = backup;
} }
@ -245,12 +198,7 @@ void jaccel_add_keys_from_string(JAccel accel, const char *string)
} }
} }
bool jaccel_is_empty(JAccel accel) std::string Accelerator::KeyCombo::toString()
{
return jlist_empty(accel->key_list);
}
static void keycombo_get_string(KeyCombo *key, char *buf)
{ {
/* same order that Allegro scancodes */ /* same order that Allegro scancodes */
static const char *table[] = { static const char *table[] = {
@ -359,42 +307,41 @@ static void keycombo_get_string(KeyCombo *key, char *buf)
"Kanji", "Kanji",
}; };
char buf[256];
ustrcpy(buf, ""); ustrcpy(buf, "");
if (!key) // Shifts
return; if (this->shifts & KB_CTRL_FLAG)
/* shifts */
if (key->shifts & KB_CTRL_FLAG)
ustrcat(buf, "Ctrl+"); ustrcat(buf, "Ctrl+");
if (key->shifts & KB_ALT_FLAG) if (this->shifts & KB_ALT_FLAG)
ustrcat(buf, "Alt+"); ustrcat(buf, "Alt+");
if (key->shifts & KB_SHIFT_FLAG) if (this->shifts & KB_SHIFT_FLAG)
ustrcat(buf, "Shift+"); ustrcat(buf, "Shift+");
/* key */ // Key
if (key->ascii) if (this->ascii)
usprintf(buf+ustrlen(buf), "%c", toupper(key->ascii)); usprintf(buf+ustrlen(buf), "%c", toupper(this->ascii));
else if (key->scancode) else if (this->scancode)
ustrcat(buf, table[key->scancode]); ustrcat(buf, table[this->scancode]);
else else
ustrcat(buf, "Unknown"); ustrcat(buf, "Unknown");
return buf;
} }
void jaccel_to_string(JAccel accel, char *buf) std::string Accelerator::toString()
{ {
keycombo_get_string(reinterpret_cast<KeyCombo*>(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 #ifdef REPORT_KEYS
char buf[256]; char buf[256];
char buf2[256]; std::string buf2;
#endif #endif
/* preprocess the character to be compared with the accelerator */ /* 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 #ifdef REPORT_KEYS
{ {
JAccel *a2 = jaccel_new(); UniquePtr<Accelerator> a2(new Accelerator);
jaccel_add_key(a2, shifts, ascii, scancode); a2->addKey(shifts, ascii, scancode);
jaccel_get_string(a2, buf2); buf2 = a2->getString();
jaccel_free(a2);
} }
#endif #endif
JI_LIST_FOR_EACH(accel->key_list, link) { for (KeyCombos::iterator it = m_combos.begin(), end = m_combos.end();
key = (KeyCombo *)link->data; it != end; ++it) {
#ifdef REPORT_KEYS #ifdef REPORT_KEYS
keycombo_get_string(key, buf);
printf("%3d==%3d %3d==%3d %s==%s ", 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 #endif
if (((key->scancode && key->scancode == scancode) if (((it->scancode && it->scancode == scancode)
|| (key->ascii && key->ascii == ascii)) || (it->ascii && it->ascii == ascii))
&& (key->shifts == (shifts & (KB_SHIFT_FLAG | KB_CTRL_FLAG | KB_ALT_FLAG)))) { && (it->shifts == (shifts & (KB_SHIFT_FLAG | KB_CTRL_FLAG | KB_ALT_FLAG)))) {
#ifdef REPORT_KEYS #ifdef REPORT_KEYS
printf("true\n"); printf("true\n");
@ -484,7 +429,7 @@ bool jaccel_check(JAccel accel, int shifts, int ascii, int scancode)
return false; return false;
} }
bool jaccel_check_from_key(JAccel accel) bool Accelerator::checkFromAllegroKeyArray()
{ {
int shifts = 0; 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_RCONTROL]) shifts |= KB_CTRL_FLAG;
if (key[KEY_ALT]) shifts |= KB_ALT_FLAG; if (key[KEY_ALT]) shifts |= KB_ALT_FLAG;
JLink link; for (KeyCombos::iterator it = m_combos.begin(), end = m_combos.end();
JI_LIST_FOR_EACH(accel->key_list, link) { it != end; ++it) {
KeyCombo* keyCombo = (KeyCombo*)link->data; if ((it->scancode == 0 || key[it->scancode]) &&
(it->shifts == (shifts & (KB_SHIFT_FLAG | KB_CTRL_FLAG | KB_ALT_FLAG)))) {
if ((keyCombo->scancode == 0 || key[keyCombo->scancode]) &&
(keyCombo->shifts == (shifts & (KB_SHIFT_FLAG | KB_CTRL_FLAG | KB_ALT_FLAG)))) {
return true; return true;
} }
} }

43
src/ui/accelerator.h Normal file
View File

@ -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 <string>
#include <vector>
namespace ui {
class Accelerator
{
public:
void addKey(int shifts, int ascii, int scancode);
// Adds keys from strings like "<Ctrl+Q> <ESC>"
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<KeyCombo> KeyCombos;
KeyCombos m_combos;
};
} // namespace ui
#endif

View File

@ -31,9 +31,6 @@
namespace ui { namespace ui {
struct jaccel;
struct jlink;
struct jlist;
struct jrect; struct jrect;
struct jregion; struct jregion;
@ -144,11 +141,6 @@ namespace ui {
typedef unsigned int JID; 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 jrect* JRect;
typedef struct jregion* JRegion; typedef struct jregion* JRegion;

View File

@ -10,7 +10,6 @@
#include "gfx/size.h" #include "gfx/size.h"
#include "ui/box.h" #include "ui/box.h"
#include "ui/list.h"
#include "ui/message.h" #include "ui/message.h"
#include "ui/preferred_size_event.h" #include "ui/preferred_size_event.h"
#include "ui/rect.h" #include "ui/rect.h"
@ -61,20 +60,18 @@ void Box::onPreferredSize(PreferredSizeEvent& ev)
} }
int w, h, nvis_children; int w, h, nvis_children;
Widget* child;
JLink link;
nvis_children = 0; nvis_children = 0;
JI_LIST_FOR_EACH(this->children, link) { UI_FOREACH_WIDGET(getChildren(), it) {
child = (Widget*)link->data; Widget* child = *it;
if (!(child->flags & JI_HIDDEN)) if (!(child->flags & JI_HIDDEN))
nvis_children++; nvis_children++;
} }
w = h = 0; w = h = 0;
JI_LIST_FOR_EACH(this->children, link) { UI_FOREACH_WIDGET(getChildren(), it) {
child = (Widget*)link->data; Widget* child = *it;
if (child->flags & JI_HIDDEN) if (child->flags & JI_HIDDEN)
continue; continue;
@ -136,8 +133,8 @@ void Box::layoutBox(JRect rect)
- this->border_width.t \ - this->border_width.t \
- this->border_width.b); \ - this->border_width.b); \
\ \
JI_LIST_FOR_EACH(this->children, link) { \ UI_FOREACH_WIDGET(getChildren(), it) { \
child = (Widget*)link->data; \ child = *it; \
\ \
if (!(child->flags & JI_HIDDEN)) { \ if (!(child->flags & JI_HIDDEN)) { \
if (this->getAlign() & JI_HOMOGENEOUS) { \ if (this->getAlign() & JI_HOMOGENEOUS) { \
@ -185,15 +182,14 @@ void Box::layoutBox(JRect rect)
int nvis_children = 0; int nvis_children = 0;
int nexpand_children = 0; int nexpand_children = 0;
int child_width; int child_width;
JLink link;
int width; int width;
int extra; int extra;
int x, y, w, h; int x, y, w, h;
jrect_copy(this->rc, rect); jrect_copy(this->rc, rect);
JI_LIST_FOR_EACH(this->children, link) { UI_FOREACH_WIDGET(getChildren(), it) {
child = (Widget*)link->data; child = *it;
if (!(child->flags & JI_HIDDEN)) { if (!(child->flags & JI_HIDDEN)) {
nvis_children++; nvis_children++;

View File

@ -7,7 +7,6 @@
#include "config.h" #include "config.h"
#include "ui/button.h" #include "ui/button.h"
#include "ui/list.h"
#include "ui/manager.h" #include "ui/manager.h"
#include "ui/message.h" #include "ui/message.h"
#include "ui/preferred_size_event.h" #include "ui/preferred_size_event.h"
@ -359,9 +358,8 @@ void RadioButton::deselectRadioGroup()
radioButton->setSelected(false); radioButton->setSelected(false);
} }
JLink link; UI_FOREACH_WIDGET(widget->getChildren(), it) {
JI_LIST_FOR_EACH(widget->children, link) { allChildrens.push(*it);
allChildrens.push((Widget*)link->data);
} }
} }
} }

View File

@ -13,7 +13,6 @@
#include "ui/draw.h" #include "ui/draw.h"
#include "ui/font.h" #include "ui/font.h"
#include "ui/intern.h" #include "ui/intern.h"
#include "ui/list.h"
#include "ui/rect.h" #include "ui/rect.h"
#include "ui/region.h" #include "ui/region.h"
#include "ui/system.h" #include "ui/system.h"

View File

@ -13,7 +13,6 @@
#include "base/memory.h" #include "base/memory.h"
#include "gfx/size.h" #include "gfx/size.h"
#include "ui/grid.h" #include "ui/grid.h"
#include "ui/list.h"
#include "ui/message.h" #include "ui/message.h"
#include "ui/preferred_size_event.h" #include "ui/preferred_size_event.h"
#include "ui/rect.h" #include "ui/rect.h"

View File

@ -7,7 +7,7 @@
#ifndef UI_GUI_H_INCLUDED #ifndef UI_GUI_H_INCLUDED
#define UI_GUI_H_INCLUDED #define UI_GUI_H_INCLUDED
#include "ui/accel.h" #include "ui/accelerator.h"
#include "ui/alert.h" #include "ui/alert.h"
#include "ui/base.h" #include "ui/base.h"
#include "ui/box.h" #include "ui/box.h"
@ -27,7 +27,6 @@
#include "ui/init_theme_event.h" #include "ui/init_theme_event.h"
#include "ui/label.h" #include "ui/label.h"
#include "ui/link_label.h" #include "ui/link_label.h"
#include "ui/list.h"
#include "ui/listbox.h" #include "ui/listbox.h"
#include "ui/manager.h" #include "ui/manager.h"
#include "ui/menu.h" #include "ui/menu.h"

View File

@ -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

View File

@ -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

View File

@ -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 <gtest/gtest.h>
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();
}

View File

@ -8,7 +8,6 @@
#include "ui/listbox.h" #include "ui/listbox.h"
#include "ui/list.h"
#include "ui/message.h" #include "ui/message.h"
#include "ui/preferred_size_event.h" #include "ui/preferred_size_event.h"
#include "ui/system.h" #include "ui/system.h"
@ -38,21 +37,21 @@ ListBox::Item::Item(const char* text)
ListBox::Item* ListBox::getSelectedChild() ListBox::Item* ListBox::getSelectedChild()
{ {
JLink link; UI_FOREACH_WIDGET(getChildren(), it) {
JI_LIST_FOR_EACH(this->children, link) { ASSERT(dynamic_cast<Item*>(*it) != NULL);
if (((Item*)link->data)->isSelected())
return (Item*)link->data; if (static_cast<Item*>(*it)->isSelected())
return static_cast<Item*>(*it);
} }
return 0; return 0;
} }
int ListBox::getSelectedIndex() int ListBox::getSelectedIndex()
{ {
JLink link;
int i = 0; int i = 0;
JI_LIST_FOR_EACH(this->children, link) { UI_FOREACH_WIDGET(getChildren(), it) {
if (((Item*)link->data)->isSelected()) if (static_cast<Item*>(*it)->isSelected())
return i; return i;
i++; i++;
} }
@ -62,11 +61,8 @@ int ListBox::getSelectedIndex()
void ListBox::selectChild(Item* item) void ListBox::selectChild(Item* item)
{ {
Item* child; UI_FOREACH_WIDGET(getChildren(), it) {
JLink link; Item* child = static_cast<Item*>(*it);
JI_LIST_FOR_EACH(this->children, link) {
child = (Item*)link->data;
if (child->isSelected()) { if (child->isSelected()) {
if (item && child == item) if (item && child == item)
@ -100,14 +96,18 @@ void ListBox::selectChild(Item* item)
void ListBox::selectIndex(int index) void ListBox::selectIndex(int index)
{ {
Item* child = reinterpret_cast<Item*>(jlist_nth_data(this->children, index)); const WidgetsList& children = getChildren();
if (child) if (index < 0 || index >= (int)children.size())
selectChild(child); return;
Item* child = static_cast<Item*>(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 */ /* setup the scroll to center the selected item in the viewport */
@ -207,10 +207,10 @@ bool ListBox::onProcessMessage(Message* msg)
} }
case JM_KEYPRESSED: case JM_KEYPRESSED:
if (this->hasFocus() && !jlist_empty(this->children)) { if (hasFocus() && !getChildren().empty()) {
int select = getSelectedIndex(); int select = getSelectedIndex();
View* view = View::getView(this); 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) { switch (msg->key.scancode) {
case KEY_UP: case KEY_UP:
@ -272,16 +272,13 @@ bool ListBox::onProcessMessage(Message* msg)
void ListBox::onPreferredSize(PreferredSizeEvent& ev) void ListBox::onPreferredSize(PreferredSizeEvent& ev)
{ {
Size reqSize;
JLink link;
int w = 0, h = 0; int w = 0, h = 0;
JI_LIST_FOR_EACH(this->children, link) { UI_FOREACH_WIDGET_WITH_END(getChildren(), it, end) {
reqSize = reinterpret_cast<Item*>(link->data)->getPreferredSize(); Size reqSize = static_cast<Item*>(*it)->getPreferredSize();
w = MAX(w, reqSize.w); 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; w += this->border_width.l + this->border_width.r;
@ -303,15 +300,13 @@ void ListBox::onDoubleClickItem()
void ListBox::layoutListBox(JRect rect) void ListBox::layoutListBox(JRect rect)
{ {
Size reqSize; Size reqSize;
Widget* child;
JRect cpos; JRect cpos;
JLink link;
jrect_copy(this->rc, rect); jrect_copy(this->rc, rect);
cpos = jwidget_get_child_rect(this); cpos = jwidget_get_child_rect(this);
JI_LIST_FOR_EACH(this->children, link) { UI_FOREACH_WIDGET(getChildren(), it) {
child = (Widget*)link->data; Widget* child = *it;
reqSize = child->getPreferredSize(); reqSize = child->getPreferredSize();
@ -327,18 +322,15 @@ void ListBox::layoutListBox(JRect rect)
void ListBox::dirtyChildren() void ListBox::dirtyChildren()
{ {
View* view = View::getView(this); View* view = View::getView(this);
Item* child;
JLink link;
if (!view) { if (!view) {
JI_LIST_FOR_EACH(this->children, link) UI_FOREACH_WIDGET(getChildren(), it)
reinterpret_cast<Item*>(link->data)->invalidate(); static_cast<Item*>(*it)->invalidate();
} }
else { else {
gfx::Rect vp = view->getViewportBounds(); gfx::Rect vp = view->getViewportBounds();
JI_LIST_FOR_EACH(this->children, link) { UI_FOREACH_WIDGET(getChildren(), it) {
child = reinterpret_cast<Item*>(link->data); Item* child = static_cast<Item*>(*it);
if (child->rc->y2 <= vp.y) if (child->rc->y2 <= vp.y)
continue; continue;
@ -356,13 +348,12 @@ bool ListBox::Item::onProcessMessage(Message* msg)
case JM_SETPOS: { case JM_SETPOS: {
JRect crect; JRect crect;
JLink link;
jrect_copy(this->rc, &msg->setpos.rect); jrect_copy(this->rc, &msg->setpos.rect);
crect = jwidget_get_child_rect(this); crect = jwidget_get_child_rect(this);
JI_LIST_FOR_EACH(this->children, link) UI_FOREACH_WIDGET(getChildren(), it)
jwidget_set_rect(reinterpret_cast<Widget*>(link->data), crect); jwidget_set_rect(*it, crect);
jrect_free(crect); jrect_free(crect);
return true; return true;
@ -380,8 +371,6 @@ void ListBox::Item::onPreferredSize(PreferredSizeEvent& ev)
{ {
int w = 0, h = 0; int w = 0, h = 0;
Size maxSize; Size maxSize;
Size reqSize;
JLink link;
if (hasText()) { if (hasText()) {
maxSize.w = jwidget_get_text_length(this); maxSize.w = jwidget_get_text_length(this);
@ -390,8 +379,8 @@ void ListBox::Item::onPreferredSize(PreferredSizeEvent& ev)
else else
maxSize.w = maxSize.h = 0; maxSize.w = maxSize.h = 0;
JI_LIST_FOR_EACH(this->children, link) { UI_FOREACH_WIDGET(getChildren(), it) {
reqSize = reinterpret_cast<Widget*>(link->data)->getPreferredSize(); Size reqSize = (*it)->getPreferredSize();
maxSize.w = MAX(maxSize.w, reqSize.w); maxSize.w = MAX(maxSize.w, reqSize.w);
maxSize.h = MAX(maxSize.h, reqSize.h); maxSize.h = MAX(maxSize.h, reqSize.h);

View File

@ -34,7 +34,7 @@ namespace ui {
void selectChild(Item* item); void selectChild(Item* item);
void selectIndex(int index); void selectIndex(int index);
int getItemsCount(); size_t getItemsCount() const;
void centerScroll(); void centerScroll();

View File

@ -15,10 +15,11 @@
#include "ui/intern.h" #include "ui/intern.h"
#ifdef REPORT_EVENTS #ifdef REPORT_EVENTS
#include <stdio.h> #include <cstdio>
#endif #endif
#include <allegro.h> #include <allegro.h>
#include <vector> #include <vector>
#include <list>
namespace ui { namespace ui {
@ -55,6 +56,9 @@ struct Filter
, widget(widget) { } , widget(widget) { }
}; };
typedef std::list<Message*> Messages;
typedef std::list<Filter*> Filters;
static int double_click_level; static int double_click_level;
static int double_click_buttons; static int double_click_buttons;
static int double_click_ticks; static int double_click_ticks;
@ -65,10 +69,10 @@ static int want_close_stage; /* variable to handle the external
Manager* Manager::m_defaultManager = NULL; 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 WidgetsList mouse_widgets_list; // List of widgets to send mouse events
static JList msg_queue; // Messages queue static Messages msg_queue; // Messages queue
static JList msg_filters[NFILTERS]; // Filters for every enqueued message static Filters msg_filters[NFILTERS]; // Filters for every enqueued message
static Widget* focus_widget; // The widget with the focus static Widget* focus_widget; // The widget with the focus
static Widget* mouse_widget; // The widget with the mouse static Widget* mouse_widget; // The widget with the mouse
@ -116,13 +120,10 @@ Manager::Manager()
set_close_button_callback(allegro_window_close_hook); set_close_button_callback(allegro_window_close_hook);
// Empty lists // Empty lists
msg_queue = jlist_new(); ASSERT(msg_queue.empty());
new_windows = jlist_new(); ASSERT(new_windows.empty());
mouse_widgets_list.clear(); mouse_widgets_list.clear();
for (int c=0; c<NFILTERS; ++c)
msg_filters[c] = jlist_new();
// Reset variables // Reset variables
focus_widget = NULL; focus_widget = NULL;
mouse_widget = NULL; mouse_widget = NULL;
@ -149,8 +150,6 @@ Manager::Manager()
Manager::~Manager() Manager::~Manager()
{ {
JLink link;
// There are some messages in queue? Dispatch everything. // There are some messages in queue? Dispatch everything.
dispatchMessages(); dispatchMessages();
collectGarbage(); collectGarbage();
@ -165,19 +164,18 @@ Manager::~Manager()
// Destroy filters // Destroy filters
for (int c=0; c<NFILTERS; ++c) { for (int c=0; c<NFILTERS; ++c) {
JI_LIST_FOR_EACH(msg_filters[c], link) { for (Filters::iterator it=msg_filters[c].begin(), end=msg_filters[c].end();
delete reinterpret_cast<Filter*>(link->data); it != end; ++it)
} delete *it;
jlist_free(msg_filters[c]); msg_filters[c].clear();
msg_filters[c] = NULL;
} }
// No more default manager // No more default manager
m_defaultManager = NULL; m_defaultManager = NULL;
// Shutdown system // Shutdown system
jlist_free(msg_queue); ASSERT(msg_queue.empty());
jlist_free(new_windows); ASSERT(new_windows.empty());
mouse_widgets_list.clear(); mouse_widgets_list.clear();
} }
} }
@ -186,7 +184,7 @@ void Manager::run()
{ {
MessageLoop loop(this); MessageLoop loop(this);
while (!jlist_empty(this->children)) while (!getChildren().empty())
loop.pumpMessages(); loop.pumpMessages();
} }
@ -194,9 +192,7 @@ bool Manager::generateMessages()
{ {
Widget* widget; Widget* widget;
Widget* window; Widget* window;
int mousemove;
Message* msg; Message* msg;
JLink link;
int c; int c;
// Poll keyboard // Poll keyboard
@ -210,15 +206,13 @@ bool Manager::generateMessages()
} }
// First check: there are windows to manage? // First check: there are windows to manage?
if (jlist_empty(this->children)) if (getChildren().empty())
return false; return false;
// New windows to show? // New windows to show?
if (!jlist_empty(new_windows)) { if (!new_windows.empty()) {
Widget* magnet; UI_FOREACH_WIDGET(new_windows, it) {
window = *it;
JI_LIST_FOR_EACH(new_windows, link) {
window = reinterpret_cast<Widget*>(link->data);
// Relayout // Relayout
window->layout(); window->layout();
@ -229,7 +223,7 @@ bool Manager::generateMessages()
// Attract the focus to the magnetic widget... // Attract the focus to the magnetic widget...
// 1) get 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 // 2) if magnetic widget exists and it doesn't have the focus
if (magnet && !magnet->hasFocus()) if (magnet && !magnet->hasFocus())
setFocus(magnet); setFocus(magnet);
@ -238,11 +232,11 @@ bool Manager::generateMessages()
focusFirstChild(window); focusFirstChild(window);
} }
jlist_clear(new_windows); new_windows.clear();
} }
// Update mouse status // Update mouse status
mousemove = jmouse_poll(); bool mousemove = jmouse_poll();
if (mousemove || !mouse_widget) { if (mousemove || !mouse_widget) {
// Get the list of widgets to send mouse messages. // Get the list of widgets to send mouse messages.
mouse_widgets_list.clear(); mouse_widgets_list.clear();
@ -251,9 +245,7 @@ bool Manager::generateMessages()
// Get the widget under the mouse // Get the widget under the mouse
widget = NULL; widget = NULL;
for (WidgetsList::iterator UI_FOREACH_WIDGET(mouse_widgets_list, it) {
it = mouse_widgets_list.begin(),
end = mouse_widgets_list.end(); it != end; ++it) {
widget = (*it)->pick(jmouse_x(0), jmouse_y(0)); widget = (*it)->pick(jmouse_x(0), jmouse_y(0));
if (widget) if (widget)
break; break;
@ -374,18 +366,19 @@ bool Manager::generateMessages()
// If the window is not already the top window of the manager. // If the window is not already the top window of the manager.
(window != win_manager->getTopWindow())) { (window != win_manager->getTopWindow())) {
// Put it in the top of the list // Put it in the top of the list
jlist_remove(win_manager->children, window); win_manager->removeChild(window);
if (window->is_ontop()) if (window->is_ontop())
jlist_prepend(win_manager->children, window); win_manager->insertChild(0, window);
else { else {
int pos = jlist_length(win_manager->children); int pos = (int)win_manager->getChildren().size();
JI_LIST_FOR_EACH_BACK(win_manager->children, link) { UI_FOREACH_WIDGET_BACKWARD(win_manager->getChildren(), it) {
if (((Window*)link->data)->is_ontop()) if (static_cast<Window*>(*it)->is_ontop())
break; break;
pos--;
--pos;
} }
jlist_insert(win_manager->children, window, pos); win_manager->insertChild(pos, window);
} }
window->invalidate(); window->invalidate();
@ -457,7 +450,7 @@ bool Manager::generateMessages()
// Generate redraw events. // Generate redraw events.
flushRedraw(); flushRedraw();
if (!jlist_empty(msg_queue)) if (!msg_queue.empty())
return true; return true;
else else
return false; return false;
@ -486,42 +479,39 @@ void Manager::enqueueMessage(Message* msg)
{ {
int c; int c;
ASSERT(msg_queue != NULL);
ASSERT(msg != 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; c = msg->type;
if (c >= JM_REGISTERED_MESSAGES) if (c >= JM_REGISTERED_MESSAGES)
c = JM_REGISTERED_MESSAGES; c = JM_REGISTERED_MESSAGES;
if (!jlist_empty(msg_filters[c])) { /* ok, so are filters to add ... */ if (!msg_filters[c].empty()) { // OK, so are filters to add...
JLink link; // Add all the filters in the destination list of the message
for (Filters::reverse_iterator it=msg_filters[c].rbegin(),
/* add all the filters in the destination list of the message */ end=msg_filters[c].rend(); it != end; ++it) {
JI_LIST_FOR_EACH_BACK(msg_filters[c], link) { Filter* filter = *it;
Filter* filter = reinterpret_cast<Filter*>(link->data);
if (msg->type == filter->message) if (msg->type == filter->message)
jmessage_add_pre_dest(msg, filter->widget); jmessage_add_pre_dest(msg, filter->widget);
} }
} }
/* there are a destination widget at least? */ // There are a destination widget at least?
if (!jlist_empty(msg->any.widgets)) if (!msg->any.widgets->empty())
jlist_append(msg_queue, msg); msg_queue.push_back(msg);
else else
jmessage_free(msg); jmessage_free(msg);
} }
Window* Manager::getTopWindow() Window* Manager::getTopWindow()
{ {
return reinterpret_cast<Window*>(jlist_first_data(this->children)); return static_cast<Window*>(UI_FIRST_WIDGET(getChildren()));
} }
Window* Manager::getForegroundWindow() Window* Manager::getForegroundWindow()
{ {
JLink link; UI_FOREACH_WIDGET(getChildren(), it) {
JI_LIST_FOR_EACH(this->children, link) { Window* window = static_cast<Window*>(*it);
Window* window = (Window*)link->data;
if (window->is_foreground() || if (window->is_foreground() ||
window->is_desktop()) window->is_desktop())
return window; return window;
@ -552,27 +542,24 @@ void Manager::setFocus(Widget* widget)
&& !(widget->flags & JI_HIDDEN) && !(widget->flags & JI_HIDDEN)
&& !(widget->flags & JI_DECORATIVE) && !(widget->flags & JI_DECORATIVE)
&& someParentIsFocusStop(widget)))) { && someParentIsFocusStop(widget)))) {
JList widget_parents = NULL; WidgetsList widget_parents;
Widget* common_parent = NULL; Widget* common_parent = NULL;
JLink link, link2;
Message* msg; Message* msg;
if (widget) if (widget)
widget_parents = widget->getParents(false); widget->getParents(false, widget_parents);
else
widget_parents = jlist_new();
/* fetch the focus */
// Fetch the focus
if (focus_widget) { if (focus_widget) {
JList focus_parents = focus_widget->getParents(true); WidgetsList focus_parents;
focus_widget->getParents(true, focus_parents);
msg = jmessage_new(JM_FOCUSLEAVE); msg = jmessage_new(JM_FOCUSLEAVE);
JI_LIST_FOR_EACH(focus_parents, link) { UI_FOREACH_WIDGET(focus_parents, it) {
if (widget) { if (widget) {
JI_LIST_FOR_EACH(widget_parents, link2) { UI_FOREACH_WIDGET(widget_parents, it2) {
if (link->data == link2->data) { if (*it == *it2) {
common_parent = reinterpret_cast<Widget*>(link->data); common_parent = *it;
break; break;
} }
} }
@ -580,30 +567,34 @@ void Manager::setFocus(Widget* widget)
break; break;
} }
if (reinterpret_cast<Widget*>(link->data)->hasFocus()) { if ((*it)->hasFocus()) {
((Widget*)link->data)->flags &= ~JI_HASFOCUS; (*it)->flags &= ~JI_HASFOCUS;
jmessage_add_dest(msg, reinterpret_cast<Widget*>(link->data)); jmessage_add_dest(msg, *it);
} }
} }
enqueueMessage(msg); enqueueMessage(msg);
jlist_free(focus_parents);
} }
/* put the focus */ // Put the focus
focus_widget = widget; focus_widget = widget;
if (widget) { if (widget) {
if (common_parent) WidgetsList::iterator it;
link = jlist_find(widget_parents, common_parent)->next;
if (common_parent) {
it = std::find(widget_parents.begin(),
widget_parents.end(),
common_parent);
ASSERT(it != widget_parents.end());
++it;
}
else else
link = jlist_first(widget_parents); it = widget_parents.begin();
msg = jmessage_new(JM_FOCUSENTER); msg = jmessage_new(JM_FOCUSENTER);
for (; link != widget_parents->end; link=link->next) { for (; it != widget_parents.end(); ++it) {
Widget* w = (Widget*)link->data; Widget* w = *it;
if (w->flags & JI_FOCUSSTOP) { if (w->flags & JI_FOCUSSTOP) {
w->flags |= JI_HASFOCUS; w->flags |= JI_HASFOCUS;
@ -614,35 +605,30 @@ void Manager::setFocus(Widget* widget)
enqueueMessage(msg); enqueueMessage(msg);
} }
jlist_free(widget_parents);
} }
} }
void Manager::setMouse(Widget* widget) void Manager::setMouse(Widget* widget)
{ {
if ((mouse_widget != widget) && (!capture_widget)) { if ((mouse_widget != widget) && (!capture_widget)) {
JList widget_parents = NULL; WidgetsList widget_parents;
Widget* common_parent = NULL; Widget* common_parent = NULL;
JLink link, link2;
Message* msg; Message* msg;
if (widget) if (widget)
widget_parents = widget->getParents(false); widget->getParents(false, widget_parents);
else
widget_parents = jlist_new();
/* fetch the mouse */
// Fetch the mouse
if (mouse_widget) { if (mouse_widget) {
JList mouse_parents = mouse_widget->getParents(true); WidgetsList mouse_parents;
mouse_widget->getParents(true, mouse_parents);
msg = jmessage_new(JM_MOUSELEAVE); msg = jmessage_new(JM_MOUSELEAVE);
JI_LIST_FOR_EACH(mouse_parents, link) { UI_FOREACH_WIDGET(mouse_parents, it) {
if (widget) { if (widget) {
JI_LIST_FOR_EACH(widget_parents, link2) { UI_FOREACH_WIDGET(widget_parents, it2) {
if (link->data == link2->data) { if (*it == *it2) {
common_parent = reinterpret_cast<Widget*>(link->data); common_parent = *it;
break; break;
} }
} }
@ -650,38 +636,40 @@ void Manager::setMouse(Widget* widget)
break; break;
} }
if (reinterpret_cast<Widget*>(link->data)->hasMouse()) { if ((*it)->hasMouse()) {
((Widget*)link->data)->flags &= ~JI_HASMOUSE; (*it)->flags &= ~JI_HASMOUSE;
jmessage_add_dest(msg, reinterpret_cast<Widget*>(link->data)); jmessage_add_dest(msg, *it);
} }
} }
enqueueMessage(msg); enqueueMessage(msg);
jlist_free(mouse_parents);
} }
/* put the mouse */ // Put the mouse
mouse_widget = widget; mouse_widget = widget;
if (widget) { if (widget) {
if (common_parent) WidgetsList::iterator it;
link = jlist_find(widget_parents, common_parent)->next;
if (common_parent) {
it = std::find(widget_parents.begin(),
widget_parents.end(),
common_parent);
ASSERT(it != widget_parents.end());
++it;
}
else else
link = jlist_first(widget_parents); it = widget_parents.begin();
msg = jmessage_new(JM_MOUSEENTER); msg = jmessage_new(JM_MOUSEENTER);
for (; link != widget_parents->end; link=link->next) { for (; it != widget_parents.end(); ++it) {
reinterpret_cast<Widget*>(link->data)->flags |= JI_HASMOUSE; (*it)->flags |= JI_HASMOUSE;
jmessage_add_dest(msg, reinterpret_cast<Widget*>(link->data)); jmessage_add_dest(msg, *it);
} }
enqueueMessage(msg); enqueueMessage(msg);
generateSetCursorMessage(); generateSetCursorMessage();
} }
jlist_free(widget_parents);
} }
} }
@ -691,13 +679,13 @@ void Manager::setCapture(Widget* widget)
capture_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) void Manager::attractFocus(Widget* widget)
{ {
/* get the magnetic widget */ // Get the magnetic widget
Widget* magnet = findMagneticWidget(widget->getRoot()); 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()) if (magnet && !magnet->hasFocus())
setFocus(magnet); setFocus(magnet);
} }
@ -746,28 +734,30 @@ void Manager::freeWidget(Widget* widget)
void Manager::removeMessage(Message* msg) 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) void Manager::removeMessagesFor(Widget* widget)
{ {
JLink link; for (Messages::iterator it=msg_queue.begin(), end=msg_queue.end();
JI_LIST_FOR_EACH(msg_queue, link) it != end; ++it)
removeWidgetFromDests(widget, reinterpret_cast<Message*>(link->data)); removeWidgetFromDests(widget, *it);
} }
void Manager::removeMessagesForTimer(Timer* timer) void Manager::removeMessagesForTimer(Timer* timer)
{ {
JLink link, next; for (Messages::iterator it=msg_queue.begin(); it != msg_queue.end(); ) {
Message* message = *it;
JI_LIST_FOR_EACH_SAFE(msg_queue, link, next) {
Message* message = reinterpret_cast<Message*>(link->data);
if (!message->any.used && if (!message->any.used &&
message->any.type == JM_TIMER && message->any.type == JM_TIMER &&
message->timer.timer == timer) { message->timer.timer == timer) {
jmessage_free(reinterpret_cast<Message*>(link->data)); jmessage_free(message);
jlist_delete_link(msg_queue, link); it = msg_queue.erase(it);
} }
else
++it;
} }
} }
@ -777,37 +767,37 @@ void Manager::addMessageFilter(int message, Widget* widget)
if (c >= JM_REGISTERED_MESSAGES) if (c >= JM_REGISTERED_MESSAGES)
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) void Manager::removeMessageFilter(int message, Widget* widget)
{ {
JLink link, next;
int c = message; int c = message;
if (c >= JM_REGISTERED_MESSAGES) if (c >= JM_REGISTERED_MESSAGES)
c = JM_REGISTERED_MESSAGES; c = JM_REGISTERED_MESSAGES;
JI_LIST_FOR_EACH_SAFE(msg_filters[c], link, next) { for (Filters::iterator it=msg_filters[c].begin(); it != msg_filters[c].end(); ) {
Filter* filter = reinterpret_cast<Filter*>(link->data); Filter* filter = *it;
if (filter->widget == widget) { if (filter->widget == widget) {
delete filter; delete filter;
jlist_delete_link(msg_filters[c], link); it = msg_filters[c].erase(it);
} }
else
++it;
} }
} }
void Manager::removeMessageFilterFor(Widget* widget) void Manager::removeMessageFilterFor(Widget* widget)
{ {
JLink link, next; for (int c=0; c<NFILTERS; ++c) {
int c; for (Filters::iterator it=msg_filters[c].begin(); it != msg_filters[c].end(); ) {
Filter* filter = *it;
for (c=0; c<NFILTERS; ++c) {
JI_LIST_FOR_EACH_SAFE(msg_filters[c], link, next) {
Filter* filter = reinterpret_cast<Filter*>(link->data);
if (filter->widget == widget) { if (filter->widget == widget) {
delete filter; 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. // Add the window to manager.
jlist_prepend(this->children, window); insertChild(0, window);
window->parent = this;
// Broadcast the open message. // Broadcast the open message.
Message* msg = jmessage_new(JM_OPEN); Message* msg = jmessage_new(JM_OPEN);
@ -832,7 +821,7 @@ void Manager::_openWindow(Window* window)
enqueueMessage(msg); enqueueMessage(msg);
// Update the new windows list to show. // 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) void Manager::_closeWindow(Window* window, bool redraw_background)
@ -848,19 +837,18 @@ void Manager::_closeWindow(Window* window, bool redraw_background)
else else
reg1 = NULL; reg1 = NULL;
/* close all windows to this desktop */ // Close all windows to this desktop
if (window->is_desktop()) { if (window->is_desktop()) {
JLink link, next; while (!getChildren().empty()) {
Window* child = static_cast<Window*>(getChildren().front());
JI_LIST_FOR_EACH_SAFE(this->children, link, next) { if (child == window)
if (link->data == window)
break; break;
else { else {
JRegion reg2 = jwidget_get_region(window); JRegion reg2 = jwidget_get_region(window);
jregion_union(reg1, reg1, reg2); jregion_union(reg1, reg1, reg2);
jregion_free(reg2); jregion_free(reg2);
_closeWindow(reinterpret_cast<Window*>(link->data), false); _closeWindow(child, false);
} }
} }
} }
@ -884,8 +872,7 @@ void Manager::_closeWindow(Window* window, bool redraw_background)
enqueueMessage(msg); enqueueMessage(msg);
// Update manager list stuff. // Update manager list stuff.
jlist_remove(this->children, window); removeChild(window);
window->parent = NULL;
// Redraw background. // Redraw background.
if (reg1) { if (reg1) {
@ -894,7 +881,10 @@ void Manager::_closeWindow(Window* window, bool redraw_background)
} }
// Maybe the window is in the "new_windows" list. // 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) bool Manager::onProcessMessage(Message* msg)
@ -911,19 +901,17 @@ bool Manager::onProcessMessage(Message* msg)
case JM_KEYPRESSED: case JM_KEYPRESSED:
case JM_KEYRELEASED: { case JM_KEYRELEASED: {
JLink link, link2;
msg->key.propagate_to_children = true; msg->key.propagate_to_children = true;
msg->key.propagate_to_parent = false; msg->key.propagate_to_parent = false;
// Continue sending the message to the children of all windows // Continue sending the message to the children of all windows
// (until a desktop or foreground window). // (until a desktop or foreground window).
JI_LIST_FOR_EACH(this->children, link) { UI_FOREACH_WIDGET(getChildren(), it) {
Window* w = (Window*)link->data; Window* w = static_cast<Window*>(*it);
// Send to the window. // Send to the window.
JI_LIST_FOR_EACH(w->children, link2) UI_FOREACH_WIDGET(w->getChildren(), it2)
if (reinterpret_cast<Widget*>(link2->data)->sendMessage(msg)) if ((*it2)->sendMessage(msg))
return true; return true;
if (w->is_foreground() || 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 // Ask to the first window in the "children" list to know how to
// propagate mouse messages. // propagate mouse messages.
Widget* widget = reinterpret_cast<Widget*>(jlist_first_data(children)); Widget* widget = UI_FIRST_WIDGET(getChildren());
if (widget) if (widget)
widget->broadcastMouseMessage(targets); widget->broadcastMouseMessage(targets);
} }
@ -956,16 +944,15 @@ void Manager::onPreferredSize(PreferredSizeEvent& ev)
{ {
int w = 0, h = 0; int w = 0, h = 0;
if (!this->parent) { /* hasn't parent? */ if (!getParent()) { // hasn' parent?
w = jrect_w(this->rc); w = jrect_w(this->rc);
h = jrect_h(this->rc); h = jrect_h(this->rc);
} }
else { else {
JRect cpos, pos = jwidget_get_child_rect(this->parent); JRect cpos, pos = jwidget_get_child_rect(this->getParent());
JLink link;
JI_LIST_FOR_EACH(this->children, link) { UI_FOREACH_WIDGET(getChildren(), it) {
cpos = jwidget_get_rect(reinterpret_cast<Widget*>(link->data)); cpos = jwidget_get_rect(*it);
jrect_union(pos, cpos); jrect_union(pos, cpos);
jrect_free(cpos); jrect_free(cpos);
} }
@ -981,19 +968,17 @@ void Manager::onPreferredSize(PreferredSizeEvent& ev)
void Manager::layoutManager(JRect rect) void Manager::layoutManager(JRect rect)
{ {
JRect cpos, old_pos; JRect cpos, old_pos;
Widget* child;
JLink link;
int x, y; int x, y;
old_pos = jrect_new_copy(this->rc); old_pos = jrect_new_copy(this->rc);
jrect_copy(this->rc, rect); jrect_copy(this->rc, rect);
/* offset for all windows */ // Offset for all windows
x = this->rc->x1 - old_pos->x1; x = this->rc->x1 - old_pos->x1;
y = this->rc->y1 - old_pos->y1; y = this->rc->y1 - old_pos->y1;
JI_LIST_FOR_EACH(this->children, link) { UI_FOREACH_WIDGET(getChildren(), it) {
child = (Widget*)link->data; Widget* child = *it;
cpos = jwidget_get_rect(child); cpos = jwidget_get_rect(child);
jrect_displace(cpos, x, y); jrect_displace(cpos, x, y);
@ -1006,35 +991,29 @@ void Manager::layoutManager(JRect rect)
void Manager::pumpQueue() void Manager::pumpQueue()
{ {
Message* msg, *first_msg;
JLink link, link2, next;
Widget* widget;
bool done;
#ifdef LIMIT_DISPATCH_TIME #ifdef LIMIT_DISPATCH_TIME
int t = ji_clock; int t = ji_clock;
#endif #endif
ASSERT(msg_queue != NULL); Messages::iterator it = msg_queue.begin();
while (it != msg_queue.end()) {
link = jlist_first(msg_queue);
while (link != msg_queue->end) {
#ifdef LIMIT_DISPATCH_TIME #ifdef LIMIT_DISPATCH_TIME
if (ji_clock-t > 250) if (ji_clock-t > 250)
break; break;
#endif #endif
/* the message to process */ // The message to process
msg = reinterpret_cast<Message*>(link->data); Message* msg = *it;
/* go to next message */ // Go to next message
if (msg->any.used) { if (msg->any.used) {
link = link->next; ++it;
continue; continue;
} }
/* this message is in use */ // This message is in use
msg->any.used = true; msg->any.used = true;
first_msg = msg; Message* first_msg = msg;
// Call Timer::tick() if this is a tick message. // Call Timer::tick() if this is a tick message.
if (msg->type == JM_TIMER) { if (msg->type == JM_TIMER) {
@ -1042,9 +1021,11 @@ void Manager::pumpQueue()
msg->timer.timer->tick(); msg->timer.timer->tick();
} }
done = false; bool done = false;
JI_LIST_FOR_EACH(msg->any.widgets, link2) { UI_FOREACH_WIDGET(*msg->any.widgets, it2) {
widget = reinterpret_cast<Widget*>(link2->data); Widget* widget = *it2;
if (!widget)
continue;
#ifdef REPORT_EVENTS #ifdef REPORT_EVENTS
{ {
@ -1128,12 +1109,10 @@ void Manager::pumpQueue()
break; break;
} }
/* remove the message from the msg_queue */ // Remove the message from the msg_queue
next = link->next; it = msg_queue.erase(it);
jlist_delete_link(msg_queue, link);
link = next;
/* destroy the message */ // Destroy the message
jmessage_free(first_msg); jmessage_free(first_msg);
} }
} }
@ -1143,21 +1122,23 @@ void Manager::invalidateDisplayRegion(const JRegion region)
JRegion reg1 = jregion_new(NULL, 0); JRegion reg1 = jregion_new(NULL, 0);
JRegion reg2 = jregion_new(this->rc, 0); JRegion reg2 = jregion_new(this->rc, 0);
JRegion reg3; JRegion reg3;
JLink link;
// TODO intersect with jwidget_get_drawable_region()??? // TODO intersect with jwidget_get_drawable_region()???
jregion_intersect(reg1, region, reg2); jregion_intersect(reg1, region, reg2);
// Redraw windows from top to background. // Redraw windows from top to background.
JI_LIST_FOR_EACH(this->children, link) { bool withDesktop = false;
Window* window = (Window*)link->data; UI_FOREACH_WIDGET(getChildren(), it) {
Window* window = static_cast<Window*>(*it);
// Invalidate regions of this window // Invalidate regions of this window
window->invalidateRegion(reg1); window->invalidateRegion(reg1);
// There is desktop? // There is desktop?
if (window->is_desktop()) if (window->is_desktop()) {
withDesktop = true;
break; // Work done break; // Work done
}
// Clip this window area for the next window. // Clip this window area for the next window.
reg3 = jwidget_get_region(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 // Invalidate areas outside windows (only when there are not a
// desktop window). // desktop window).
if (link == children->end) if (!withDesktop)
Widget::invalidateRegion(reg1); Widget::invalidateRegion(reg1);
jregion_free(reg1); jregion_free(reg1);
@ -1214,11 +1195,11 @@ void Manager::generateSetCursorMessage()
// static // static
void Manager::removeWidgetFromDests(Widget* widget, Message* msg) void Manager::removeWidgetFromDests(Widget* widget, Message* msg)
{ {
JLink link, next; for (WidgetsList::iterator
it = msg->any.widgets->begin(),
JI_LIST_FOR_EACH_SAFE(msg->any.widgets, link, next) { end = msg->any.widgets->end(); it != end; ++it) {
if (link->data == widget) if (*it == widget)
jlist_delete_link(msg->any.widgets, link); *it = NULL;
} }
} }
@ -1228,8 +1209,8 @@ bool Manager::someParentIsFocusStop(Widget* widget)
if (widget->isFocusStop()) if (widget->isFocusStop())
return true; return true;
if (widget->parent) if (widget->getParent())
return someParentIsFocusStop(widget->parent); return someParentIsFocusStop(widget->getParent());
else else
return false; return false;
} }
@ -1238,10 +1219,9 @@ bool Manager::someParentIsFocusStop(Widget* widget)
Widget* Manager::findMagneticWidget(Widget* widget) Widget* Manager::findMagneticWidget(Widget* widget)
{ {
Widget* found; Widget* found;
JLink link;
JI_LIST_FOR_EACH(widget->children, link) { UI_FOREACH_WIDGET(widget->getChildren(), it) {
found = findMagneticWidget(reinterpret_cast<Widget*>(link->data)); found = findMagneticWidget(*it);
if (found) if (found)
return found; return found;
} }
@ -1307,7 +1287,7 @@ static bool move_focus(Manager* manager, Message* msg)
if (focus_widget) { if (focus_widget) {
window = focus_widget->getRoot(); window = focus_widget->getRoot();
} }
else if (!jlist_empty(manager->children)) { else if (!manager->getChildren().empty()) {
window = manager->getTopWindow(); window = manager->getTopWindow();
} }
@ -1406,10 +1386,9 @@ static int count_widgets_accept_focus(Widget* widget)
ASSERT(widget != NULL); ASSERT(widget != NULL);
int count = 0; int count = 0;
JLink link;
JI_LIST_FOR_EACH(widget->children, link) UI_FOREACH_WIDGET(widget->getChildren(), it)
count += count_widgets_accept_focus(reinterpret_cast<Widget*>(link->data)); count += count_widgets_accept_focus(*it);
if ((count == 0) && (ACCEPT_FOCUS(widget))) if ((count == 0) && (ACCEPT_FOCUS(widget)))
count++; count++;
@ -1419,10 +1398,8 @@ static int count_widgets_accept_focus(Widget* widget)
static bool childs_accept_focus(Widget* widget, bool first) static bool childs_accept_focus(Widget* widget, bool first)
{ {
JLink link; UI_FOREACH_WIDGET(widget->getChildren(), it)
if (childs_accept_focus(*it, false))
JI_LIST_FOR_EACH(widget->children, link)
if (childs_accept_focus(reinterpret_cast<Widget*>(link->data), false))
return true; return true;
return first ? false: ACCEPT_FOCUS(widget); 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) static Widget* next_widget(Widget* widget)
{ {
if (!jlist_empty(widget->children)) if (!widget->getChildren().empty())
return reinterpret_cast<Widget*>(jlist_first(widget->children)->data); return UI_FIRST_WIDGET(widget->getChildren());
while (widget->parent->type != JI_MANAGER) { while (widget->getParent()->type != JI_MANAGER) {
JLink link = jlist_find(widget->parent->children, widget); WidgetsList::const_iterator begin = widget->getParent()->getChildren().begin();
if (link->next != widget->parent->children->end) WidgetsList::const_iterator end = widget->getParent()->getChildren().end();
return reinterpret_cast<Widget*>(link->next->data); WidgetsList::const_iterator it = std::find(begin, end, widget);
ASSERT(it != end);
if ((it+1) != end)
return *(it+1);
else else
widget = widget->parent; widget = widget->getParent();
} }
return NULL; return NULL;

View File

@ -167,7 +167,7 @@ MenuItem::MenuItem(const char *text)
MenuItem::~MenuItem() MenuItem::~MenuItem()
{ {
if (m_accel) if (m_accel)
jaccel_free(m_accel); delete m_accel;
if (m_submenu) if (m_submenu)
delete m_submenu; delete m_submenu;
@ -175,10 +175,10 @@ MenuItem::~MenuItem()
Menu* MenuBox::getMenu() Menu* MenuBox::getMenu()
{ {
if (jlist_empty(children)) if (getChildren().empty())
return NULL; return NULL;
else else
return static_cast<Menu*>(jlist_first(children)->data); return static_cast<Menu*>(getChildren().front());
} }
MenuBaseData* MenuBox::createBase() MenuBaseData* MenuBox::createBase()
@ -193,7 +193,7 @@ Menu* MenuItem::getSubmenu()
return m_submenu; return m_submenu;
} }
JAccel MenuItem::getAccel() Accelerator* MenuItem::getAccel()
{ {
return m_accel; return m_accel;
} }
@ -229,10 +229,10 @@ void MenuItem::setSubmenu(Menu* menu)
* @warning The specified @a accel will be freed automatically when * @warning The specified @a accel will be freed automatically when
* the menu-item is deleted. * the menu-item is deleted.
*/ */
void MenuItem::setAccel(JAccel accel) void MenuItem::setAccel(Accelerator* accel)
{ {
if (m_accel) if (m_accel)
jaccel_free(m_accel); delete m_accel;
m_accel = accel; m_accel = accel;
} }
@ -249,7 +249,7 @@ void MenuItem::setHighlighted(bool state)
bool MenuItem::hasSubmenu() const 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) void Menu::showPopup(int x, int y)
@ -319,22 +319,19 @@ bool Menu::onProcessMessage(Message* msg)
void Menu::requestSize(int *w, int *h) void Menu::requestSize(int *w, int *h)
{ {
Size reqSize; Size reqSize;
JLink link;
*w = *h = 0; *w = *h = 0;
JI_LIST_FOR_EACH(this->children, link) { UI_FOREACH_WIDGET_WITH_END(getChildren(), it, end) {
reqSize = ((Widget*)link->data)->getPreferredSize(); reqSize = (*it)->getPreferredSize();
if (this->parent->type == JI_MENUBAR) { if (this->getParent()->type == JI_MENUBAR) {
*w += reqSize.w + ((link->next != this->children->end) ? *w += reqSize.w + ((it+1 != end) ? this->child_spacing: 0);
this->child_spacing: 0);
*h = MAX(*h, reqSize.h); *h = MAX(*h, reqSize.h);
} }
else { else {
*w = MAX(*w, reqSize.w); *w = MAX(*w, reqSize.w);
*h += reqSize.h + ((link->next != this->children->end) ? *h += reqSize.h + ((it+1 != end) ? this->child_spacing: 0);
this->child_spacing: 0);
} }
} }
@ -347,24 +344,23 @@ void Menu::set_position(JRect rect)
Size reqSize; Size reqSize;
Widget* child; Widget* child;
JRect cpos; JRect cpos;
JLink link;
jrect_copy(this->rc, rect); jrect_copy(this->rc, rect);
cpos = jwidget_get_child_rect(this); cpos = jwidget_get_child_rect(this);
JI_LIST_FOR_EACH(this->children, link) { UI_FOREACH_WIDGET(getChildren(), it) {
child = (Widget*)link->data; child = *it;
reqSize = child->getPreferredSize(); reqSize = child->getPreferredSize();
if (this->parent->type == JI_MENUBAR) if (this->getParent()->type == JI_MENUBAR)
cpos->x2 = cpos->x1+reqSize.w; cpos->x2 = cpos->x1+reqSize.w;
else else
cpos->y2 = cpos->y1+reqSize.h; cpos->y2 = cpos->y1+reqSize.h;
jwidget_set_rect(child, cpos); jwidget_set_rect(child, cpos);
if (this->parent->type == JI_MENUBAR) if (this->getParent()->type == JI_MENUBAR)
cpos->x1 += jrect_w(cpos); cpos->x1 += jrect_w(cpos);
else else
cpos->y1 += jrect_h(cpos); cpos->y1 += jrect_h(cpos);
@ -510,12 +506,11 @@ bool MenuBox::onProcessMessage(Message* msg)
if (this->hasFocus()) { if (this->hasFocus()) {
MenuItem* highlight = menu->getHighlightedItem(); MenuItem* highlight = menu->getHighlightedItem();
MenuItem* child_with_submenu_opened = NULL; MenuItem* child_with_submenu_opened = NULL;
JLink link;
bool used = false; bool used = false;
// Search a child with highlight or the submenu opened // Search a child with highlight or the submenu opened
JI_LIST_FOR_EACH(menu->children, link) { UI_FOREACH_WIDGET(menu->getChildren(), it) {
Widget* child = (Widget*)link->data; Widget* child = *it;
if (child->type != JI_MENUITEM) if (child->type != JI_MENUITEM)
continue; continue;
@ -592,7 +587,7 @@ bool MenuBox::onProcessMessage(Message* msg)
else { else {
// Go to parent // Go to parent
if (menu->m_menuitem) { 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 // Go to the previous item in the parent
@ -741,7 +736,7 @@ bool MenuItem::onProcessMessage(Message* msg)
ASSERT(base->is_processing); ASSERT(base->is_processing);
ASSERT(hasSubmenu()); ASSERT(hasSubmenu());
JRect old_pos = jwidget_get_rect(this->parent->parent); JRect old_pos = jwidget_get_rect(this->getParent()->getParent());
MenuBox* menubox = new MenuBox(); MenuBox* menubox = new MenuBox();
m_submenu_menubox = menubox; m_submenu_menubox = menubox;
@ -753,7 +748,7 @@ bool MenuItem::onProcessMessage(Message* msg)
// Menubox position // Menubox position
pos = jwidget_get_rect(window); pos = jwidget_get_rect(window);
if (this->parent->parent->type == JI_MENUBAR) { if (this->getParent()->getParent()->type == JI_MENUBAR) {
jrect_moveto(pos, jrect_moveto(pos,
MID(0, this->rc->x1, JI_SCREEN_W-jrect_w(pos)), MID(0, this->rc->x1, JI_SCREEN_W-jrect_w(pos)),
MID(0, this->rc->y2, JI_SCREEN_H-jrect_h(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 // Setup the highlight of the new menubox
if (select_first) { if (select_first) {
// Select the first child // Select the first child
Widget* child;
MenuItem* first_child = NULL; MenuItem* first_child = NULL;
JLink link;
JI_LIST_FOR_EACH(m_submenu->children, link) { UI_FOREACH_WIDGET(m_submenu->getChildren(), it) {
child = (Widget*)link->data; Widget* child = *it;
if (child->type != JI_MENUITEM) if (child->type != JI_MENUITEM)
continue; continue;
@ -845,7 +838,7 @@ bool MenuItem::onProcessMessage(Message* msg)
ASSERT(menubox != NULL); ASSERT(menubox != NULL);
window = (Window*)menubox->parent; window = (Window*)menubox->getParent();
ASSERT(window && window->type == JI_WINDOW); ASSERT(window && window->type == JI_WINDOW);
// Fetch the "menu" to avoid destroy it with 'delete'. // Fetch the "menu" to avoid destroy it with 'delete'.
@ -858,7 +851,7 @@ bool MenuItem::onProcessMessage(Message* msg)
if (base->close_all) if (base->close_all)
getManager()->freeFocus(); getManager()->freeFocus();
else else
getManager()->setFocus(this->parent->parent); getManager()->setFocus(this->getParent()->getParent());
// It is not necessary to delete this window because it's // It is not necessary to delete this window because it's
// automatically destroyed by the manager // automatically destroyed by the manager
@ -907,7 +900,7 @@ void MenuItem::onClick()
void MenuItem::requestSize(int *w, int *h) 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()) { if (this->hasText()) {
*w = *w =
@ -921,10 +914,8 @@ void MenuItem::requestSize(int *w, int *h)
+ jwidget_get_text_height(this) + jwidget_get_text_height(this)
+ this->border_width.b; + this->border_width.b;
if (m_accel) { if (m_accel && !m_accel->isEmpty()) {
char buf[256]; *w += ji_font_text_len(this->getFont(), m_accel->toString().c_str());
jaccel_to_string(m_accel, buf);
*w += ji_font_text_len(this->getFont(), buf);
} }
} }
else { else {
@ -955,10 +946,10 @@ static MenuBox* get_base_menubox(Widget* widget)
// We are in a menuitem // We are in a menuitem
else { else {
ASSERT(widget->type == JI_MENUITEM); ASSERT(widget->type == JI_MENUITEM);
ASSERT(widget->parent != NULL); ASSERT(widget->getParent() != NULL);
ASSERT(widget->parent->type == JI_MENU); 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() MenuItem* Menu::getHighlightedItem()
{ {
JLink link; UI_FOREACH_WIDGET(getChildren(), it) {
JI_LIST_FOR_EACH(this->children, link) { Widget* child = *it;
Widget* child = (Widget*)link->data;
if (child->type != JI_MENUITEM) if (child->type != JI_MENUITEM)
continue; continue;
@ -989,13 +979,9 @@ MenuItem* Menu::getHighlightedItem()
void Menu::highlightItem(MenuItem* menuitem, bool click, bool open_submenu, bool select_first_child) 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 // Find the menuitem with the highlight
JI_LIST_FOR_EACH(menu->children, link) { UI_FOREACH_WIDGET(getChildren(), it) {
child = (Widget*)link->data; Widget* child = *it;
if (child->type != JI_MENUITEM) if (child->type != JI_MENUITEM)
continue; continue;
@ -1015,9 +1001,9 @@ void Menu::highlightItem(MenuItem* menuitem, bool click, bool open_submenu, bool
} }
// Highlight parents // Highlight parents
if (menu->getOwnerMenuItem() != NULL) { if (getOwnerMenuItem() != NULL) {
static_cast<Menu*>(menu->getOwnerMenuItem()->parent) static_cast<Menu*>(getOwnerMenuItem()->getParent())
->highlightItem(menu->getOwnerMenuItem(), false, false, false); ->highlightItem(getOwnerMenuItem(), false, false, false);
} }
// Open submenu of the menitem // Open submenu of the menitem
@ -1033,7 +1019,7 @@ void Menu::highlightItem(MenuItem* menuitem, bool click, bool open_submenu, bool
} }
// Execute menuitem action // Execute menuitem action
else if (click) { else if (click) {
menu->closeAll(); closeAll();
menuitem->executeClick(); menuitem->executeClick();
} }
} }
@ -1047,13 +1033,11 @@ void Menu::unhighlightItem()
void MenuItem::openSubmenu(bool select_first) void MenuItem::openSubmenu(bool select_first)
{ {
Widget* menu; Widget* menu;
Widget* child;
Message* msg; Message* msg;
JLink link;
ASSERT(hasSubmenu()); ASSERT(hasSubmenu());
menu = this->parent; menu = this->getParent();
// The menu item is already opened? // The menu item is already opened?
ASSERT(m_submenu_menubox == NULL); ASSERT(m_submenu_menubox == NULL);
@ -1061,9 +1045,9 @@ void MenuItem::openSubmenu(bool select_first)
ASSERT_VALID_WIDGET(menu); ASSERT_VALID_WIDGET(menu);
// Close all siblings of 'menuitem' // Close all siblings of 'menuitem'
if (menu->parent) { if (menu->getParent()) {
JI_LIST_FOR_EACH(menu->children, link) { UI_FOREACH_WIDGET(menu->getChildren(), it) {
child = reinterpret_cast<Widget*>(link->data); Widget* child = *it;
if (child->type != JI_MENUITEM) if (child->type != JI_MENUITEM)
continue; continue;
@ -1100,9 +1084,8 @@ void MenuItem::openSubmenu(bool select_first)
void MenuItem::closeSubmenu(bool last_of_close_chain) void MenuItem::closeSubmenu(bool last_of_close_chain)
{ {
Widget* menu, *child; Widget* menu;
Message* msg; Message* msg;
JLink link;
MenuBaseData* base; MenuBaseData* base;
ASSERT(m_submenu_menubox != NULL); ASSERT(m_submenu_menubox != NULL);
@ -1111,8 +1094,8 @@ void MenuItem::closeSubmenu(bool last_of_close_chain)
menu = m_submenu_menubox->getMenu(); menu = m_submenu_menubox->getMenu();
ASSERT(menu != NULL); ASSERT(menu != NULL);
JI_LIST_FOR_EACH(menu->children, link) { UI_FOREACH_WIDGET(menu->getChildren(), it) {
child = reinterpret_cast<Widget*>(link->data); Widget* child = *it;
if (child->type != JI_MENUITEM) if (child->type != JI_MENUITEM)
continue; continue;
@ -1160,10 +1143,10 @@ void Menu::closeAll()
MenuItem* menuitem = NULL; MenuItem* menuitem = NULL;
while (menu->m_menuitem) { while (menu->m_menuitem) {
menuitem = menu->m_menuitem; menuitem = menu->m_menuitem;
menu = static_cast<Menu*>(menuitem->parent); menu = static_cast<Menu*>(menuitem->getParent());
} }
MenuBox* base_menubox = get_base_menubox(menu->parent); MenuBox* base_menubox = get_base_menubox(menu->getParent());
MenuBaseData* base = base_menubox->getBase(); MenuBaseData* base = base_menubox->getBase();
base->close_all = true; base->close_all = true;
base->was_clicked = false; base->was_clicked = false;
@ -1179,9 +1162,8 @@ void Menu::closeAll()
menuitem->closeSubmenu(true); menuitem->closeSubmenu(true);
} }
else { else {
JLink link; UI_FOREACH_WIDGET(menu->getChildren(), it) {
JI_LIST_FOR_EACH(menu->children, link) { Widget* child = *it;
Widget* child = reinterpret_cast<Widget*>(link->data);
if (child->type != JI_MENUITEM) if (child->type != JI_MENUITEM)
continue; continue;
@ -1223,9 +1205,8 @@ void MenuItem::executeClick()
static MenuItem* check_for_letter(Menu* menu, int ascii) static MenuItem* check_for_letter(Menu* menu, int ascii)
{ {
JLink link; UI_FOREACH_WIDGET(menu->getChildren(), it) {
JI_LIST_FOR_EACH(menu->children, link) { Widget* child = *it;
Widget* child = (Widget*)link->data;
if (child->type != JI_MENUITEM) if (child->type != JI_MENUITEM)
continue; continue;
@ -1238,9 +1219,8 @@ static MenuItem* check_for_letter(Menu* menu, int ascii)
static MenuItem* check_for_accel(Menu* menu, Message* msg) static MenuItem* check_for_accel(Menu* menu, Message* msg)
{ {
JLink link; UI_FOREACH_WIDGET(menu->getChildren(), it) {
JI_LIST_FOR_EACH(menu->children, link) { Widget* child = *it;
Widget* child = (Widget*)link->data;
if (child->type != JI_MENUITEM) if (child->type != JI_MENUITEM)
continue; continue;
@ -1252,10 +1232,9 @@ static MenuItem* check_for_accel(Menu* menu, Message* msg)
} }
else if (menuitem->getAccel()) { else if (menuitem->getAccel()) {
if ((menuitem->isEnabled()) && if ((menuitem->isEnabled()) &&
(jaccel_check(menuitem->getAccel(), (menuitem->getAccel()->check(msg->any.shifts,
msg->any.shifts, msg->key.ascii,
msg->key.ascii, msg->key.scancode)))
msg->key.scancode)))
return menuitem; return menuitem;
} }
} }
@ -1266,16 +1245,19 @@ static MenuItem* check_for_accel(Menu* menu, Message* msg)
// from the first item in `menu' // from the first item in `menu'
static MenuItem* find_nextitem(Menu* menu, MenuItem* menuitem) static MenuItem* find_nextitem(Menu* menu, MenuItem* menuitem)
{ {
Widget* nextitem; WidgetsList::const_iterator begin = menu->getChildren().begin();
JLink link; WidgetsList::const_iterator it, end = menu->getChildren().end();
if (menuitem) if (menuitem) {
link = jlist_find(menu->children, menuitem)->next; it = std::find(begin, end, menuitem);
if (it != end)
++it;
}
else else
link = jlist_first(menu->children); it = begin;
for (; link != menu->children->end; link=link->next) { for (; it != end; ++it) {
nextitem = (Widget*)link->data; Widget* nextitem = *it;
if ((nextitem->type == JI_MENUITEM) && nextitem->isEnabled()) if ((nextitem->type == JI_MENUITEM) && nextitem->isEnabled())
return static_cast<MenuItem*>(nextitem); return static_cast<MenuItem*>(nextitem);
} }
@ -1288,16 +1270,19 @@ static MenuItem* find_nextitem(Menu* menu, MenuItem* menuitem)
static MenuItem* find_previtem(Menu* menu, MenuItem* menuitem) static MenuItem* find_previtem(Menu* menu, MenuItem* menuitem)
{ {
Widget* nextitem; WidgetsList::const_reverse_iterator begin = menu->getChildren().rbegin();
JLink link; WidgetsList::const_reverse_iterator it, end = menu->getChildren().rend();
if (menuitem) if (menuitem) {
link = jlist_find(menu->children, menuitem)->prev; it = std::find(begin, end, menuitem);
if (it != end)
++it;
}
else else
link = jlist_last(menu->children); it = begin;
for (; link != menu->children->end; link=link->prev) { for (; it != end; ++it) {
nextitem = (Widget*)link->data; Widget* nextitem = *it;
if ((nextitem->type == JI_MENUITEM) && nextitem->isEnabled()) if ((nextitem->type == JI_MENUITEM) && nextitem->isEnabled())
return static_cast<MenuItem*>(nextitem); return static_cast<MenuItem*>(nextitem);
} }

View File

@ -14,9 +14,10 @@
namespace ui { namespace ui {
class Accelerator;
class MenuItem; class MenuItem;
struct MenuBaseData;
class Timer; class Timer;
struct MenuBaseData;
class Menu : public Widget class Menu : public Widget
{ {
@ -99,8 +100,8 @@ namespace ui {
Menu* getSubmenu(); Menu* getSubmenu();
void setSubmenu(Menu* submenu); void setSubmenu(Menu* submenu);
JAccel getAccel(); Accelerator* getAccel();
void setAccel(JAccel accel); void setAccel(Accelerator* accel);
bool isHighlighted() const; bool isHighlighted() const;
void setHighlighted(bool state); void setHighlighted(bool state);
@ -134,7 +135,7 @@ namespace ui {
void stopTimer(); void stopTimer();
void executeClick(); void executeClick();
JAccel m_accel; // Hot-key Accelerator* m_accel; // Hot-key
bool m_highlighted; // Is it highlighted? bool m_highlighted; // Is it highlighted?
Menu* m_submenu; // The sub-menu Menu* m_submenu; // The sub-menu
MenuBox* m_submenu_menubox; // The opened menubox for this menu-item MenuBox* m_submenu_menubox; // The opened menubox for this menu-item

View File

@ -10,7 +10,6 @@
#include <string.h> #include <string.h>
#include "base/memory.h" #include "base/memory.h"
#include "ui/list.h"
#include "ui/manager.h" #include "ui/manager.h"
#include "ui/message.h" #include "ui/message.h"
#include "ui/rect.h" #include "ui/rect.h"
@ -27,12 +26,12 @@ int ji_register_message_type()
Message* jmessage_new(int type) Message* jmessage_new(int type)
{ {
Message* msg = (Message*)base_malloc0(sizeof(Message)); Message* msg = new Message;
if (!msg)
return NULL; memset(msg, 0, sizeof(Message));
msg->type = type; msg->type = type;
msg->any.widgets = jlist_new(); msg->any.widgets = new WidgetsList;
msg->any.shifts = msg->any.shifts =
(key[KEY_LSHIFT] || key[KEY_RSHIFT] ? KB_SHIFT_FLAG: 0) | (key[KEY_LSHIFT] || key[KEY_RSHIFT] ? KB_SHIFT_FLAG: 0) |
(key[KEY_LCONTROL] || key[KEY_RCONTROL] ? KB_CTRL_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); ASSERT(msg != NULL);
copy = (Message*)base_malloc(sizeof(Message)); copy = new Message;
if (!copy) if (!copy)
return NULL; return NULL;
memcpy(copy, msg, sizeof(Message)); 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; copy->any.used = false;
return copy; return copy;
@ -89,13 +88,13 @@ Message* jmessage_new_copy_without_dests(const Message* msg)
{ {
ASSERT(msg != NULL); ASSERT(msg != NULL);
Message* copy = (Message*)base_malloc(sizeof(Message)); Message* copy = new Message;
if (!copy) if (!copy)
return NULL; return NULL;
memcpy(copy, msg, sizeof(Message)); memcpy(copy, msg, sizeof(Message));
copy->any.widgets = jlist_new(); copy->any.widgets = new WidgetsList;
copy->any.used = false; copy->any.used = false;
return copy; return copy;
@ -105,8 +104,8 @@ void jmessage_free(Message* msg)
{ {
ASSERT(msg != NULL); ASSERT(msg != NULL);
jlist_free(msg->any.widgets); delete msg->any.widgets;
base_free(msg); delete msg;
} }
void jmessage_add_dest(Message* msg, Widget* widget) void jmessage_add_dest(Message* msg, Widget* widget)
@ -114,7 +113,7 @@ void jmessage_add_dest(Message* msg, Widget* widget)
ASSERT(msg != NULL); ASSERT(msg != NULL);
ASSERT_VALID_WIDGET(widget); 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) 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(msg != NULL);
ASSERT_VALID_WIDGET(widget); 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) void jmessage_broadcast_to_children(Message* msg, Widget* widget)
{ {
JLink link;
ASSERT(msg != NULL); ASSERT(msg != NULL);
ASSERT_VALID_WIDGET(widget); ASSERT_VALID_WIDGET(widget);
JI_LIST_FOR_EACH(widget->children, link) UI_FOREACH_WIDGET(widget->getChildren(), it)
jmessage_broadcast_to_children(msg, reinterpret_cast<Widget*>(link->data)); jmessage_broadcast_to_children(msg, *it);
jmessage_add_dest(msg, widget); jmessage_add_dest(msg, widget);
} }

View File

@ -9,6 +9,7 @@
#include "ui/base.h" #include "ui/base.h"
#include "ui/rect.h" #include "ui/rect.h"
#include "ui/widgets_list.h"
namespace ui { namespace ui {
@ -27,10 +28,10 @@ namespace ui {
struct MessageAny struct MessageAny
{ {
int type; /* type of message */ int type; // Type of message
JList widgets; /* destination widgets */ WidgetsList* widgets; // Destination widgets
bool used : 1; /* was used */ bool used : 1; // Was used
int shifts; /* key shifts pressed when message was created */ int shifts; // Key shifts pressed when message was created
}; };
struct MessageKey struct MessageKey

View File

@ -31,10 +31,7 @@ PopupWindow::PopupWindow(const char* text, bool close_on_buttonpressed)
set_wantfocus(false); set_wantfocus(false);
setAlign(JI_LEFT | JI_TOP); setAlign(JI_LEFT | JI_TOP);
// remove decorative widgets removeDecorativeWidgets();
JLink link, next;
JI_LIST_FOR_EACH_SAFE(this->children, link, next)
delete reinterpret_cast<Widget*>(link->data);
initTheme(); initTheme();
jwidget_noborders(this); jwidget_noborders(this);
@ -152,14 +149,12 @@ void PopupWindow::onPreferredSize(PreferredSizeEvent& ev)
resultSize.w += border_width.l + border_width.r; resultSize.w += border_width.l + border_width.r;
resultSize.h += border_width.t + border_width.b; resultSize.h += border_width.t + border_width.b;
if (!jlist_empty(this->children)) { if (!getChildren().empty()) {
Size maxSize(0, 0); Size maxSize(0, 0);
Size reqSize; Size reqSize;
Widget* child;
JLink link;
JI_LIST_FOR_EACH(this->children, link) { UI_FOREACH_WIDGET(getChildren(), it) {
child = (Widget*)link->data; Widget* child = *it;
reqSize = child->getPreferredSize(); reqSize = child->getPreferredSize();

View File

@ -9,7 +9,6 @@
#include "ui/separator.h" #include "ui/separator.h"
#include "gfx/size.h" #include "gfx/size.h"
#include "ui/list.h"
#include "ui/message.h" #include "ui/message.h"
#include "ui/preferred_size_event.h" #include "ui/preferred_size_event.h"
#include "ui/theme.h" #include "ui/theme.h"
@ -41,11 +40,9 @@ bool Separator::onProcessMessage(Message* msg)
void Separator::onPreferredSize(PreferredSizeEvent& ev) void Separator::onPreferredSize(PreferredSizeEvent& ev)
{ {
Size maxSize(0, 0); 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(); Size reqSize = child->getPreferredSize();
maxSize.w = MAX(maxSize.w, reqSize.w); maxSize.w = MAX(maxSize.w, reqSize.w);
maxSize.h = MAX(maxSize.h, reqSize.h); maxSize.h = MAX(maxSize.h, reqSize.h);

View File

@ -8,7 +8,6 @@
#include "ui/splitter.h" #include "ui/splitter.h"
#include "ui/list.h"
#include "ui/message.h" #include "ui/message.h"
#include "ui/preferred_size_event.h" #include "ui/preferred_size_event.h"
#include "ui/system.h" #include "ui/system.h"
@ -54,14 +53,13 @@ bool Splitter::onProcessMessage(Message* msg)
Widget* c1, *c2; Widget* c1, *c2;
int x1, y1, x2, y2; int x1, y1, x2, y2;
int bar, click_bar; int bar, click_bar;
JLink link;
bar = click_bar = 0; bar = click_bar = 0;
JI_LIST_FOR_EACH(this->children, link) { UI_FOREACH_WIDGET_WITH_END(getChildren(), it, end) {
if (link->next != this->children->end) { if (it+1 != end) {
c1 = reinterpret_cast<Widget*>(link->data); c1 = *it;
c2 = reinterpret_cast<Widget*>(link->next->data); c2 = *(it+1);
++bar; ++bar;
@ -120,14 +118,13 @@ bool Splitter::onProcessMessage(Message* msg)
case JM_SETCURSOR: case JM_SETCURSOR:
if (isEnabled()) { if (isEnabled()) {
Widget* c1, *c2; Widget* c1, *c2;
JLink link;
int x1, y1, x2, y2; int x1, y1, x2, y2;
bool change_cursor = false; bool change_cursor = false;
JI_LIST_FOR_EACH(this->children, link) { UI_FOREACH_WIDGET_WITH_END(getChildren(), it, end) {
if (link->next != this->children->end) { if (it+1 != end) {
c1 = reinterpret_cast<Widget*>(link->data); c1 = *it;
c2 = reinterpret_cast<Widget*>(link->next->data); c2 = *(it+1);
if (this->getAlign() & JI_HORIZONTAL) { if (this->getAlign() & JI_HORIZONTAL) {
x1 = c1->rc->x2; x1 = c1->rc->x2;
@ -183,12 +180,10 @@ void Splitter::onPreferredSize(PreferredSizeEvent& ev)
int visibleChildren; int visibleChildren;
Size reqSize; Size reqSize;
Widget* child;
JLink link;
visibleChildren = 0; visibleChildren = 0;
JI_LIST_FOR_EACH(this->children, link) { UI_FOREACH_WIDGET(getChildren(), it) {
child = (Widget*)link->data; Widget* child = *it;
if (!(child->flags & JI_HIDDEN)) if (!(child->flags & JI_HIDDEN))
visibleChildren++; visibleChildren++;
} }
@ -196,8 +191,8 @@ void Splitter::onPreferredSize(PreferredSizeEvent& ev)
int w, h; int w, h;
w = h = 0; w = h = 0;
JI_LIST_FOR_EACH(this->children, link) { UI_FOREACH_WIDGET(getChildren(), it) {
child = (Widget*)link->data; Widget* child = *it;
if (child->flags & JI_HIDDEN) if (child->flags & JI_HIDDEN)
continue; continue;
@ -252,11 +247,9 @@ void Splitter::layoutMembers(JRect rect)
jrect_copy(this->rc, rect); jrect_copy(this->rc, rect);
if (jlist_length(this->children) == 2) { if (getChildren().size() == 2) {
Widget* child1 = reinterpret_cast<Widget*>(jlist_first(this->children)->data); Widget* child1 = getChildren()[0];
Widget* child2 = reinterpret_cast<Widget*>(jlist_first(this->children)->next->data); Widget* child2 = getChildren()[1];
//Size reqSize1 = child1->getPreferredSize();
//Size reqSize2 = child2->getPreferredSize();
if (this->getAlign() & JI_HORIZONTAL) if (this->getAlign() & JI_HORIZONTAL)
FIXUP(x, y, w, h, l, t, r, b); FIXUP(x, y, w, h, l, t, r, b);

View File

@ -51,9 +51,8 @@ bool TooltipManager::onProcessMessage(Message* msg)
switch (msg->type) { switch (msg->type) {
case JM_MOUSEENTER: { case JM_MOUSEENTER: {
JLink link; UI_FOREACH_WIDGET(*msg->any.widgets, itWidget) {
JI_LIST_FOR_EACH_BACK(msg->any.widgets, link) { Tips::iterator it = m_tips.find(*itWidget);
Tips::iterator it = m_tips.find((Widget*)link->data);
if (it != m_tips.end()) { if (it != m_tips.end()) {
m_target.widget = it->first; m_target.widget = it->first;
m_target.tipInfo = it->second; m_target.tipInfo = it->second;
@ -153,8 +152,6 @@ void TooltipManager::onTick()
TipWindow::TipWindow(const char *text, bool close_on_buttonpressed) TipWindow::TipWindow(const char *text, bool close_on_buttonpressed)
: Window(false, text) : Window(false, text)
{ {
JLink link, next;
m_close_on_buttonpressed = close_on_buttonpressed; m_close_on_buttonpressed = close_on_buttonpressed;
m_hot_region = NULL; m_hot_region = NULL;
m_filtering = false; m_filtering = false;
@ -165,9 +162,7 @@ TipWindow::TipWindow(const char *text, bool close_on_buttonpressed)
set_wantfocus(false); set_wantfocus(false);
setAlign(JI_LEFT | JI_TOP); setAlign(JI_LEFT | JI_TOP);
// remove decorative widgets removeDecorativeWidgets();
JI_LIST_FOR_EACH_SAFE(this->children, link, next)
delete reinterpret_cast<Widget*>(link->data);
initTheme(); initTheme();
} }
@ -283,14 +278,12 @@ void TipWindow::onPreferredSize(PreferredSizeEvent& ev)
resultSize.w += this->border_width.l + this->border_width.r; resultSize.w += this->border_width.l + this->border_width.r;
resultSize.h += this->border_width.t + this->border_width.b; resultSize.h += this->border_width.t + this->border_width.b;
if (!jlist_empty(this->children)) { if (!getChildren().empty()) {
Size maxSize(0, 0); Size maxSize(0, 0);
Size reqSize; Size reqSize;
Widget* child;
JLink link;
JI_LIST_FOR_EACH(this->children, link) { UI_FOREACH_WIDGET(getChildren(), it) {
child = (Widget*)link->data; Widget* child = *it;
reqSize = child->getPreferredSize(); reqSize = child->getPreferredSize();

View File

@ -8,7 +8,6 @@
#include "gfx/size.h" #include "gfx/size.h"
#include "ui/intern.h" #include "ui/intern.h"
#include "ui/list.h"
#include "ui/message.h" #include "ui/message.h"
#include "ui/rect.h" #include "ui/rect.h"
#include "ui/region.h" #include "ui/region.h"
@ -45,8 +44,6 @@ bool View::hasScrollBars()
void View::attachToView(Widget* viewable_widget) void View::attachToView(Widget* viewable_widget)
{ {
m_viewport.addChild(viewable_widget); m_viewport.addChild(viewable_widget);
/* TODO */
/* jwidget_emit_signal(this, JI_SIGNAL_VIEW_ATTACH); */
} }
void View::makeVisibleAllScrollableArea() void View::makeVisibleAllScrollableArea()
@ -195,7 +192,7 @@ void View::setViewScroll(const Point& pt)
void View::updateView() void View::updateView()
{ {
Widget* vw = reinterpret_cast<Widget*>(jlist_first_data(m_viewport.children)); Widget* vw = UI_FIRST_WIDGET(m_viewport.getChildren());
Point scroll = getViewScroll(); Point scroll = getViewScroll();
// Set minimum (remove scroll-bars) // Set minimum (remove scroll-bars)
@ -279,12 +276,10 @@ bool View::onProcessMessage(Message* msg)
// static // static
void View::displaceWidgets(Widget* widget, int x, int y) void View::displaceWidgets(Widget* widget, int x, int y)
{ {
JLink link;
jrect_displace(widget->rc, x, y); jrect_displace(widget->rc, x, y);
JI_LIST_FOR_EACH(widget->children, link) UI_FOREACH_WIDGET(widget->getChildren(), it)
displaceWidgets(reinterpret_cast<Widget*>(link->data), x, y); displaceWidgets(*it, x, y);
} }
} // namespace ui } // namespace ui

View File

@ -8,7 +8,6 @@
#include "gfx/point.h" #include "gfx/point.h"
#include "gfx/size.h" #include "gfx/size.h"
#include "ui/list.h"
#include "ui/message.h" #include "ui/message.h"
#include "ui/theme.h" #include "ui/theme.h"
#include "ui/view.h" #include "ui/view.h"
@ -49,10 +48,9 @@ Size Viewport::calculateNeededSize()
{ {
Size maxSize(0, 0); Size maxSize(0, 0);
Size reqSize; Size reqSize;
JLink link;
JI_LIST_FOR_EACH(this->children, link) { UI_FOREACH_WIDGET(getChildren(), it) {
reqSize = ((Widget*)link->data)->getPreferredSize(); reqSize = (*it)->getPreferredSize();
maxSize.w = MAX(maxSize.w, reqSize.w); maxSize.w = MAX(maxSize.w, reqSize.w);
maxSize.h = MAX(maxSize.h, reqSize.h); maxSize.h = MAX(maxSize.h, reqSize.h);
} }
@ -63,9 +61,7 @@ Size Viewport::calculateNeededSize()
void Viewport::set_position(JRect rect) void Viewport::set_position(JRect rect)
{ {
Size reqSize; Size reqSize;
Widget* child;
JRect cpos; JRect cpos;
JLink link;
jrect_copy(this->rc, rect); 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->x1 = this->rc->x1 + this->border_width.l - scroll.x;
cpos->y1 = this->rc->y1 + this->border_width.t - scroll.y; cpos->y1 = this->rc->y1 + this->border_width.t - scroll.y;
JI_LIST_FOR_EACH(this->children, link) { UI_FOREACH_WIDGET(getChildren(), it) {
child = (Widget*)link->data; Widget* child = *it;
reqSize = child->getPreferredSize(); reqSize = child->getPreferredSize();
cpos->x2 = cpos->x1 + MAX(reqSize.w, jrect_w(this->rc) cpos->x2 = cpos->x1 + MAX(reqSize.w, jrect_w(this->rc)

View File

@ -28,7 +28,7 @@ static inline void mark_dirty_flag(Widget* widget)
{ {
while (widget) { while (widget) {
widget->flags |= JI_DIRTY; widget->flags |= JI_DIRTY;
widget = widget->parent; widget = widget->getParent();
} }
} }
@ -54,8 +54,7 @@ Widget::Widget(int type)
this->min_h = 0; this->min_h = 0;
this->max_w = INT_MAX; this->max_w = INT_MAX;
this->max_h = INT_MAX; this->max_h = INT_MAX;
this->children = jlist_new(); this->m_parent = NULL;
this->parent = NULL;
this->m_theme = CurrentTheme::get(); this->m_theme = CurrentTheme::get();
this->m_align = 0; this->m_align = 0;
@ -81,8 +80,6 @@ Widget::Widget(int type)
Widget::~Widget() Widget::~Widget()
{ {
JLink link, next;
// Break relationship with the manager. // Break relationship with the manager.
if (this->type != JI_MANAGER) { if (this->type != JI_MANAGER) {
Manager* manager = getManager(); Manager* manager = getManager();
@ -92,13 +89,13 @@ Widget::~Widget()
} }
// Remove from parent // Remove from parent
if (this->parent) if (m_parent)
this->parent->removeChild(this); m_parent->removeChild(this);
/* remove children */ // Remove children. The ~Widget dtor modifies the parent's
JI_LIST_FOR_EACH_SAFE(this->children, link, next) // m_children.
delete reinterpret_cast<Widget*>(link->data); while (!m_children.empty())
jlist_free(this->children); delete m_children.front();
/* destroy the update region */ /* destroy the update region */
if (m_update_region) if (m_update_region)
@ -295,7 +292,7 @@ bool Widget::isVisible() const
if (widget->flags & JI_HIDDEN) if (widget->flags & JI_HIDDEN)
return false; return false;
widget = widget->parent; widget = widget->m_parent;
} while (widget); } while (widget);
return true; return true;
@ -309,7 +306,7 @@ bool Widget::isEnabled() const
if (widget->flags & JI_DISABLED) if (widget->flags & JI_DISABLED)
return false; return false;
widget = widget->parent; widget = widget->m_parent;
} while (widget); } while (widget);
return true; return true;
@ -352,17 +349,12 @@ Window* Widget::getRoot()
if (widget->type == JI_WINDOW) if (widget->type == JI_WINDOW)
return dynamic_cast<Window*>(widget); return dynamic_cast<Window*>(widget);
widget = widget->parent; widget = widget->m_parent;
} }
return NULL; return NULL;
} }
Widget* Widget::getParent()
{
return this->parent;
}
Manager* Widget::getManager() Manager* Widget::getManager()
{ {
Widget* widget = this; Widget* widget = this;
@ -371,76 +363,67 @@ Manager* Widget::getManager()
if (widget->type == JI_MANAGER) if (widget->type == JI_MANAGER)
return static_cast<Manager*>(widget); return static_cast<Manager*>(widget);
widget = widget->parent; widget = widget->m_parent;
} }
return Manager::getDefault(); 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->m_parent) {
for (Widget* widget=this; widget; widget=widget->parent) {
// append parents in tail // append parents in tail
if (ascendant) if (ascendant)
jlist_append(list, widget); parents.push_back(widget);
// append parents in head // append parents in head
else else
jlist_prepend(list, widget); parents.insert(parents.begin(), widget);
} }
return list;
}
JList Widget::getChildren()
{
return jlist_copy(this->children);
} }
Widget* Widget::getNextSibling() Widget* Widget::getNextSibling()
{ {
if (!parent) if (!m_parent)
return NULL; return NULL;
JLink link = jlist_find(parent->children, this); WidgetsList::iterator begin = m_parent->m_children.begin();
ASSERT(link != NULL); WidgetsList::iterator end = m_parent->m_children.end();
if (!link) WidgetsList::iterator it = std::find(begin, end, this);
if (it == end)
return NULL; return NULL;
if (link == jlist_last(parent->children)) if (++it == end)
return NULL; return NULL;
return reinterpret_cast<Widget*>(link->next->data); return *it;
} }
Widget* Widget::getPreviousSibling() Widget* Widget::getPreviousSibling()
{ {
if (!parent) if (!m_parent)
return NULL; return NULL;
JLink link = jlist_find(parent->children, this); WidgetsList::iterator begin = m_parent->m_children.begin();
ASSERT(link != NULL); WidgetsList::iterator end = m_parent->m_children.end();
if (!link) WidgetsList::iterator it = std::find(begin, end, this);
if (it == begin || it == end)
return NULL; return NULL;
if (link == jlist_first(parent->children)) return *(++it);
return NULL;
return reinterpret_cast<Widget*>(link->prev->data);
} }
Widget* Widget::pick(int x, int y) Widget* Widget::pick(int x, int y)
{ {
Widget* inside, *picked = NULL; Widget* inside, *picked = NULL;
JLink link;
if (!(this->flags & JI_HIDDEN) && /* is visible */ if (!(this->flags & JI_HIDDEN) && /* is visible */
jrect_point_in(this->rc, x, y)) { /* the point is inside the bounds */ jrect_point_in(this->rc, x, y)) { /* the point is inside the bounds */
picked = this; picked = this;
JI_LIST_FOR_EACH(this->children, link) { UI_FOREACH_WIDGET(m_children, it) {
inside = reinterpret_cast<Widget*>(link->data)->pick(x, y); inside = (*it)->pick(x, y);
if (inside) { if (inside) {
picked = inside; picked = inside;
break; break;
@ -455,26 +438,25 @@ bool Widget::hasChild(Widget* child)
{ {
ASSERT_VALID_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* Widget::findChild(const char* id)
{ {
Widget* child; Widget* child;
JLink link;
JI_LIST_FOR_EACH(this->children, link) { UI_FOREACH_WIDGET(m_children, it) {
child = (Widget*)link->data; child = *it;
if (child->getId() == id) if (child->getId() == id)
return child; return child;
} }
JI_LIST_FOR_EACH(this->children, link) { UI_FOREACH_WIDGET(m_children, it) {
if ((child = ((Widget*)link->data)->findChild(id))) if ((child = (*it)->findChild(id)))
return child; return child;
} }
return 0; return NULL;
} }
Widget* Widget::findSibling(const char* id) Widget* Widget::findSibling(const char* id)
@ -487,8 +469,8 @@ void Widget::addChild(Widget* child)
ASSERT_VALID_WIDGET(this); ASSERT_VALID_WIDGET(this);
ASSERT_VALID_WIDGET(child); ASSERT_VALID_WIDGET(child);
jlist_append(children, child); m_children.push_back(child);
child->parent = this; child->m_parent = this;
} }
void Widget::removeChild(Widget* child) void Widget::removeChild(Widget* child)
@ -496,8 +478,11 @@ void Widget::removeChild(Widget* child)
ASSERT_VALID_WIDGET(this); ASSERT_VALID_WIDGET(this);
ASSERT_VALID_WIDGET(child); ASSERT_VALID_WIDGET(child);
jlist_remove(children, child); WidgetsList::iterator it = std::find(m_children.begin(), m_children.end(), child);
child->parent = NULL; if (it != m_children.end())
m_children.erase(it);
child->m_parent = NULL;
} }
void Widget::replaceChild(Widget* oldChild, Widget* newChild) 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(oldChild);
ASSERT_VALID_WIDGET(newChild); ASSERT_VALID_WIDGET(newChild);
JLink before = jlist_find(children, oldChild); WidgetsList::iterator before =
if (!before) std::find(m_children.begin(), m_children.end(), oldChild);
if (before == m_children.end()) {
ASSERT(false);
return; return;
}
before = before->next; int index = before - m_children.begin();
removeChild(oldChild); removeChild(oldChild);
jlist_insert_before(children, before, newChild); m_children.insert(m_children.begin()+index, newChild);
newChild->parent = this; newChild->m_parent = this;
} }
void Widget::insertChild(int index, Widget* child) 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(this);
ASSERT_VALID_WIDGET(child); ASSERT_VALID_WIDGET(child);
jlist_insert(children, child, index); m_children.insert(m_children.begin()+index, child);
child->parent = this; child->m_parent = this;
} }
// =============================================================== // ===============================================================
@ -604,31 +591,30 @@ JRegion jwidget_get_region(Widget* widget)
/* gets the region to be able to draw in */ /* gets the region to be able to draw in */
JRegion jwidget_get_drawable_region(Widget* widget, int flags) JRegion jwidget_get_drawable_region(Widget* widget, int flags)
{ {
Widget* window, *manager, *view, *child; Widget* window, *manager, *view;
JRegion region, reg1, reg2, reg3; JRegion region, reg1, reg2, reg3;
JList windows_list;
JLink link;
JRect cpos; JRect cpos;
ASSERT_VALID_WIDGET(widget); ASSERT_VALID_WIDGET(widget);
region = jwidget_get_region(widget); region = jwidget_get_region(widget);
/* cut the top windows areas */ // Cut the top windows areas
if (flags & JI_GDR_CUTTOPWINDOWS) { if (flags & JI_GDR_CUTTOPWINDOWS) {
window = widget->getRoot(); window = widget->getRoot();
manager = window ? window->getManager(): NULL; manager = window ? window->getManager(): NULL;
while (manager) { while (manager) {
windows_list = manager->children; const WidgetsList& windows_list = manager->getChildren();
link = jlist_find(windows_list, window); WidgetsList::const_reverse_iterator it =
std::find(windows_list.rbegin(), windows_list.rend(), window);
if (!jlist_empty(windows_list) && if (!windows_list.empty() &&
window != jlist_first(windows_list)->data && window != windows_list.front() &&
link != windows_list->end) { it != windows_list.rend()) {
/* subtract the rectangles */ // Subtract the rectangles
for (link=link->prev; link != windows_list->end; link=link->prev) { for (++it; it != windows_list.rend(); ++it) {
reg1 = jwidget_get_region(reinterpret_cast<Widget*>(link->data)); reg1 = jwidget_get_region(*it);
jregion_subtract(region, region, reg1); jregion_subtract(region, region, reg1);
jregion_free(reg1); jregion_free(reg1);
} }
@ -639,13 +625,14 @@ JRegion jwidget_get_drawable_region(Widget* widget, int flags)
} }
} }
/* clip the areas where are children */ // Clip the areas where are children
if (!(flags & JI_GDR_USECHILDAREA) && !jlist_empty(widget->children)) { if (!(flags & JI_GDR_USECHILDAREA) && !widget->getChildren().empty()) {
cpos = jwidget_get_child_rect(widget); cpos = jwidget_get_child_rect(widget);
reg1 = jregion_new(NULL, 0); reg1 = jregion_new(NULL, 0);
reg2 = jregion_new(cpos, 1); reg2 = jregion_new(cpos, 1);
JI_LIST_FOR_EACH(widget->children, link) {
child = reinterpret_cast<Widget*>(link->data); UI_FOREACH_WIDGET(widget->getChildren(), it) {
Widget* child = *it;
if (child->isVisible()) { if (child->isVisible()) {
reg3 = jwidget_get_region(child); reg3 = jwidget_get_region(child);
if (child->flags & JI_DECORATIVE) { if (child->flags & JI_DECORATIVE) {
@ -664,9 +651,9 @@ JRegion jwidget_get_drawable_region(Widget* widget, int flags)
jrect_free(cpos); jrect_free(cpos);
} }
/* intersect with the parent area */ // Intersect with the parent area
if (!(widget->flags & JI_DECORATIVE)) { if (!(widget->flags & JI_DECORATIVE)) {
Widget* parent = widget->parent; Widget* parent = widget->getParent();
reg1 = jregion_new(NULL, 0); reg1 = jregion_new(NULL, 0);
@ -676,14 +663,13 @@ JRegion jwidget_get_drawable_region(Widget* widget, int flags)
jregion_intersect(region, region, reg1); jregion_intersect(region, region, reg1);
jrect_free(cpos); jrect_free(cpos);
parent = parent->parent; parent = parent->getParent();
} }
jregion_free(reg1); jregion_free(reg1);
} }
else { else {
Widget* parent = widget->parent; Widget* parent = widget->getParent();
if (parent) { if (parent) {
cpos = jwidget_get_rect(parent); cpos = jwidget_get_rect(parent);
reg1 = jregion_new(cpos, 1); 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(); window = widget->getRoot();
manager = window ? window->getManager(): NULL; manager = window ? window->getManager(): NULL;
@ -924,7 +910,6 @@ void Widget::flushRedraw()
std::queue<Widget*> processing; std::queue<Widget*> processing;
int c, nrects; int c, nrects;
Message* msg; Message* msg;
JLink link;
JRect rc; JRect rc;
if (this->flags & JI_DIRTY) { if (this->flags & JI_DIRTY) {
@ -942,8 +927,8 @@ void Widget::flushRedraw()
if (!widget->isVisible()) if (!widget->isVisible())
continue; continue;
JI_LIST_FOR_EACH(widget->children, link) { UI_FOREACH_WIDGET(widget->getChildren(), it) {
Widget* child = (Widget*)link->data; Widget* child = *it;
if (child->flags & JI_DIRTY) { if (child->flags & JI_DIRTY) {
child->flags ^= JI_DIRTY; child->flags ^= JI_DIRTY;
processing.push(child); processing.push(child);
@ -993,15 +978,14 @@ void Widget::invalidate()
{ {
if (isVisible()) { if (isVisible()) {
JRegion reg1 = jwidget_get_drawable_region(this, JI_GDR_CUTTOPWINDOWS); JRegion reg1 = jwidget_get_drawable_region(this, JI_GDR_CUTTOPWINDOWS);
JLink link;
jregion_copy(this->m_update_region, reg1); jregion_copy(this->m_update_region, reg1);
jregion_free(reg1); jregion_free(reg1);
mark_dirty_flag(this); mark_dirty_flag(this);
JI_LIST_FOR_EACH(this->children, link) UI_FOREACH_WIDGET(getChildren(), it)
reinterpret_cast<Widget*>(link->data)->invalidate(); (*it)->invalidate();
} }
} }
@ -1242,23 +1226,17 @@ bool Widget::isScancodeMnemonic(int scancode) const
bool Widget::onProcessMessage(Message* msg) bool Widget::onProcessMessage(Message* msg)
{ {
Widget* widget = this;
ASSERT(msg != NULL); ASSERT(msg != NULL);
ASSERT_VALID_WIDGET(widget);
switch (msg->type) { switch (msg->type) {
case JM_OPEN: case JM_OPEN:
case JM_CLOSE: case JM_CLOSE:
case JM_WINMOVE: { case JM_WINMOVE:
JLink link;
// Broadcast the message to the children. // Broadcast the message to the children.
JI_LIST_FOR_EACH(widget->children, link) UI_FOREACH_WIDGET(getChildren(), it)
reinterpret_cast<Widget*>(link->data)->sendMessage(msg); (*it)->sendMessage(msg);
break; break;
}
case JM_DRAW: case JM_DRAW:
// With double-buffering we create a temporary bitmap to draw // With double-buffering we create a temporary bitmap to draw
@ -1299,47 +1277,38 @@ bool Widget::onProcessMessage(Message* msg)
} }
case JM_REQSIZE: case JM_REQSIZE:
msg->reqsize.w = widget->min_w; msg->reqsize.w = this->min_w;
msg->reqsize.h = widget->min_h; msg->reqsize.h = this->min_h;
return true; return true;
case JM_SETPOS: { case JM_SETPOS: {
JRect cpos; jrect_copy(this->rc, &msg->setpos.rect);
JLink link; JRect cpos = jwidget_get_child_rect(this);
jrect_copy(widget->rc, &msg->setpos.rect);
cpos = jwidget_get_child_rect(widget);
// Set all the children to the same "cpos". // Set all the children to the same "cpos".
JI_LIST_FOR_EACH(widget->children, link) UI_FOREACH_WIDGET(getChildren(), it)
jwidget_set_rect(reinterpret_cast<Widget*>(link->data), cpos); jwidget_set_rect(*it, cpos);
jrect_free(cpos); jrect_free(cpos);
return true; return true;
} }
case JM_DIRTYCHILDREN: { case JM_DIRTYCHILDREN:
JLink link; UI_FOREACH_WIDGET(getChildren(), it)
(*it)->invalidate();
JI_LIST_FOR_EACH(widget->children, link)
reinterpret_cast<Widget*>(link->data)->invalidate();
return true; return true;
}
case JM_KEYPRESSED: case JM_KEYPRESSED:
case JM_KEYRELEASED: case JM_KEYRELEASED:
if (msg->key.propagate_to_children) { if (msg->key.propagate_to_children) {
JLink link;
// Broadcast the message to the children. // Broadcast the message to the children.
JI_LIST_FOR_EACH(widget->children, link) UI_FOREACH_WIDGET(getChildren(), it)
reinterpret_cast<Widget*>(link->data)->sendMessage(msg); (*it)->sendMessage(msg);
} }
// Propagate the message to the parent. // Propagate the message to the parent.
if (msg->key.propagate_to_parent && widget->parent != NULL) if (msg->key.propagate_to_parent && getParent() != NULL)
return widget->parent->sendMessage(msg); return getParent()->sendMessage(msg);
else else
break; break;
@ -1349,15 +1318,15 @@ bool Widget::onProcessMessage(Message* msg)
case JM_MOTION: case JM_MOTION:
case JM_WHEEL: case JM_WHEEL:
// Propagate the message to the parent. // Propagate the message to the parent.
if (widget->parent != NULL) if (getParent() != NULL)
return widget->parent->sendMessage(msg); return getParent()->sendMessage(msg);
else else
break; break;
case JM_SETCURSOR: case JM_SETCURSOR:
// Propagate the message to the parent. // Propagate the message to the parent.
if (widget->parent != NULL) if (getParent() != NULL)
return widget->parent->sendMessage(msg); return getParent()->sendMessage(msg);
else { else {
jmouse_set_cursor(JI_CURSOR_NORMAL); jmouse_set_cursor(JI_CURSOR_NORMAL);
return true; return true;
@ -1377,9 +1346,7 @@ void Widget::onInvalidateRegion(const JRegion region)
if (isVisible() && if (isVisible() &&
jregion_rect_in(region, this->rc) != JI_RGNOUT) { jregion_rect_in(region, this->rc) != JI_RGNOUT) {
JRegion reg1 = jregion_new(NULL, 0); JRegion reg1 = jregion_new(NULL, 0);
JRegion reg2 = jwidget_get_drawable_region(this, JRegion reg2 = jwidget_get_drawable_region(this, JI_GDR_CUTTOPWINDOWS);
JI_GDR_CUTTOPWINDOWS);
JLink link;
jregion_union(reg1, this->m_update_region, region); jregion_union(reg1, this->m_update_region, region);
jregion_intersect(this->m_update_region, reg1, reg2); jregion_intersect(this->m_update_region, reg1, reg2);
@ -1389,8 +1356,8 @@ void Widget::onInvalidateRegion(const JRegion region)
mark_dirty_flag(this); mark_dirty_flag(this);
JI_LIST_FOR_EACH(this->children, link) UI_FOREACH_WIDGET(getChildren(), it)
reinterpret_cast<Widget*>(link->data)->invalidateRegion(reg1); (*it)->invalidateRegion(reg1);
jregion_free(reg1); jregion_free(reg1);
} }

View File

@ -14,7 +14,6 @@
#include "gfx/size.h" #include "gfx/size.h"
#include "ui/base.h" #include "ui/base.h"
#include "ui/component.h" #include "ui/component.h"
#include "ui/list.h"
#include "ui/rect.h" #include "ui/rect.h"
#include "ui/widgets_list.h" #include "ui/widgets_list.h"
@ -77,10 +76,6 @@ namespace ui {
int min_w, min_h; int min_w, min_h;
int max_w, max_h; int max_w, max_h;
/* structures */
JList children; /* sub-objects */
Widget* parent; /* who is the parent? */
private: private:
std::string m_id; // Widget's id std::string m_id; // Widget's id
Theme* m_theme; // Widget's theme Theme* m_theme; // Widget's theme
@ -89,6 +84,8 @@ namespace ui {
struct FONT *m_font; // Text font type struct FONT *m_font; // Text font type
int m_bg_color; // Background color int m_bg_color; // Background color
JRegion m_update_region; // Region to be redrawed. JRegion m_update_region; // Region to be redrawed.
WidgetsList m_children; // Sub-widgets
Widget* m_parent; // Who is the parent?
public: public:
// Extra data for the theme // Extra data for the theme
@ -176,8 +173,8 @@ namespace ui {
// Gets the background color of the widget. // Gets the background color of the widget.
int getBgColor() const { int getBgColor() const {
if (m_bg_color < 0 && parent) if (m_bg_color < 0 && m_parent)
return parent->getBgColor(); return m_parent->getBgColor();
else else
return m_bg_color; return m_bg_color;
} }
@ -197,16 +194,16 @@ namespace ui {
// =============================================================== // ===============================================================
Window* getRoot(); Window* getRoot();
Widget* getParent(); Widget* getParent() { return m_parent; }
Manager* getManager(); Manager* getManager();
// Returns a list of parents (you must free the list), if // Returns a list of parents (you must free the list), if
// "ascendant" is true the list is build from child to parents, else // "ascendant" is true the list is build from child to parents, else
// the list is from parent to children. // 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). // 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. // Returns the next or previous siblings.
Widget* getNextSibling(); Widget* getNextSibling();
@ -228,9 +225,8 @@ namespace ui {
template<class T> template<class T>
T* findFirstChildByType() { T* findFirstChildByType() {
JLink link; UI_FOREACH_WIDGET(m_children, it) {
JI_LIST_FOR_EACH(children, link) { Widget* child = *it;
Widget* child = (Widget*)link->data;
if (T* specificChild = dynamic_cast<T*>(child)) if (T* specificChild = dynamic_cast<T*>(child))
return specificChild; return specificChild;
} }

View File

@ -9,6 +9,30 @@
#include <vector> #include <vector>
#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 { namespace ui {
class Widget; class Widget;

View File

@ -94,6 +94,12 @@ HitTest Window::hitTest(const gfx::Point& point)
return ev.getHit(); return ev.getHit();
} }
void Window::removeDecorativeWidgets()
{
while (!getChildren().empty())
delete getChildren().front();
}
void Window::onClose(CloseEvent& ev) void Window::onClose(CloseEvent& ev)
{ {
// Fire Close signal // Fire Close signal
@ -221,7 +227,7 @@ void Window::move_window(JRect rect)
void Window::openWindow() void Window::openWindow()
{ {
if (!this->parent) { if (!getParent()) {
if (m_is_autoremap) if (m_is_autoremap)
center_window(); center_window();
@ -257,9 +263,8 @@ void Window::closeWindow(Widget* killer)
bool Window::is_toplevel() bool Window::is_toplevel()
{ {
Widget* manager = getManager(); Widget* manager = getManager();
if (!manager->getChildren().empty())
if (!jlist_empty(manager->children)) return (this == UI_FIRST_WIDGET(manager->getChildren()));
return (this == jlist_first(manager->children)->data);
else else
return false; return false;
} }
@ -456,11 +461,9 @@ void Window::onPreferredSize(PreferredSizeEvent& ev)
else { else {
Size maxSize(0, 0); Size maxSize(0, 0);
Size reqSize; Size reqSize;
Widget* child;
JLink link;
JI_LIST_FOR_EACH(this->children, link) { UI_FOREACH_WIDGET(getChildren(), it) {
child = (Widget*)link->data; Widget* child = *it;
if (!child->isDecorative()) { if (!child->isDecorative()) {
reqSize = child->getPreferredSize(); reqSize = child->getPreferredSize();
@ -505,17 +508,13 @@ void Window::onSetText()
void Window::window_set_position(JRect rect) void Window::window_set_position(JRect rect)
{ {
Widget* child;
JRect cpos;
JLink link;
/* copy the new position rectangle */ /* copy the new position rectangle */
jrect_copy(this->rc, rect); 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" */ /* set all the children to the same "child_pos" */
JI_LIST_FOR_EACH(this->children, link) { UI_FOREACH_WIDGET(getChildren(), it) {
child = (Widget*)link->data; Widget* child = *it;
if (child->isDecorative()) if (child->isDecorative())
child->getTheme()->map_decorative_widget(child); 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) static void displace_widgets(Widget* widget, int x, int y)
{ {
JLink link;
jrect_displace(widget->rc, x, y); jrect_displace(widget->rc, x, y);
JI_LIST_FOR_EACH(widget->children, link) UI_FOREACH_WIDGET(widget->getChildren(), it)
displace_widgets(reinterpret_cast<Widget*>(link->data), x, y); displace_widgets((*it), x, y);
} }
} // namespace ui } // namespace ui

View File

@ -49,6 +49,8 @@ namespace ui {
HitTest hitTest(const gfx::Point& point); HitTest hitTest(const gfx::Point& point);
void removeDecorativeWidgets();
// Signals // Signals
Signal1<void, CloseEvent&> Close; Signal1<void, CloseEvent&> Close;

View File

@ -28,7 +28,6 @@
#include "modules/gui.h" #include "modules/gui.h"
#include "modules/palettes.h" #include "modules/palettes.h"
#include "raster/raster.h" #include "raster/raster.h"
#include "ui/list.h"
#include "ui/manager.h" #include "ui/manager.h"
#include "ui/system.h" #include "ui/system.h"
#include "ui/widget.h" #include "ui/widget.h"

View File

@ -25,7 +25,6 @@
#include "ini_file.h" #include "ini_file.h"
#include "raster/raster.h" #include "raster/raster.h"
#include "settings/settings.h" #include "settings/settings.h"
#include "ui/list.h"
#include "ui_context.h" #include "ui_context.h"
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////

View File

@ -30,7 +30,6 @@
#include "raster/palette.h" #include "raster/palette.h"
#include "raster/sprite.h" #include "raster/sprite.h"
#include "raster/stock.h" #include "raster/stock.h"
#include "ui/list.h"
#include "util/thmbnail.h" #include "util/thmbnail.h"
#define THUMBNAIL_W 32 #define THUMBNAIL_W 32

View File

@ -25,7 +25,6 @@
#include "modules/gui.h" #include "modules/gui.h"
#include "ui/box.h" #include "ui/box.h"
#include "ui/button.h" #include "ui/button.h"
#include "ui/list.h"
#include "ui/system.h" #include "ui/system.h"
#include "ui/theme.h" #include "ui/theme.h"
#include "ui/widget.h" #include "ui/widget.h"

View File

@ -29,7 +29,6 @@
#include "modules/gui.h" #include "modules/gui.h"
#include "raster/image.h" #include "raster/image.h"
#include "skin/skin_theme.h" #include "skin/skin_theme.h"
#include "ui/list.h"
#include "ui/message.h" #include "ui/message.h"
#include "ui_context.h" #include "ui_context.h"
#include "widgets/color_bar.h" #include "widgets/color_bar.h"
@ -57,10 +56,7 @@ bool ColorBar::ScrollableView::onProcessMessage(Message* msg)
case JM_DRAW: case JM_DRAW:
{ {
Viewport* viewport = getViewport();
Widget* child = reinterpret_cast<Widget*>(jlist_first_data(viewport->children));
SkinTheme* theme = static_cast<SkinTheme*>(getTheme()); SkinTheme* theme = static_cast<SkinTheme*>(getTheme());
theme->draw_bounds_nw(ji_screen, theme->draw_bounds_nw(ji_screen,
rc->x1, rc->y1, rc->x1, rc->y1,
rc->x2-1, rc->y2-1, rc->x2-1, rc->y2-1,

View File

@ -31,7 +31,6 @@
#include "tools/ink.h" #include "tools/ink.h"
#include "tools/tool.h" #include "tools/tool.h"
#include "ui/base.h" #include "ui/base.h"
#include "ui/list.h"
#include "ui/rect.h" #include "ui/rect.h"
#include "ui/region.h" #include "ui/region.h"
#include "ui/system.h" #include "ui/system.h"

View File

@ -22,7 +22,6 @@
#include "modules/editors.h" #include "modules/editors.h"
#include "skin/skin_theme.h" #include "skin/skin_theme.h"
#include "ui/list.h"
#include "ui/message.h" #include "ui/message.h"
#include "widgets/editor/editor.h" #include "widgets/editor/editor.h"
@ -60,7 +59,7 @@ bool EditorView::onProcessMessage(Message* msg)
case JM_DRAW: case JM_DRAW:
{ {
Widget* viewport = getViewport(); Widget* viewport = getViewport();
Widget* child = reinterpret_cast<Widget*>(jlist_first_data(viewport->children)); Widget* child = UI_FIRST_WIDGET(viewport->getChildren());
JRect pos = jwidget_get_rect(this); JRect pos = jwidget_get_rect(this);
SkinTheme* theme = static_cast<SkinTheme*>(getTheme()); SkinTheme* theme = static_cast<SkinTheme*>(getTheme());
bool selected = false; bool selected = false;

View File

@ -442,13 +442,12 @@ void FileSelector::updateLocation()
{ {
IFileItem* currentFolder = m_fileList->getCurrentFolder(); IFileItem* currentFolder = m_fileList->getCurrentFolder();
IFileItem* fileItem = currentFolder; IFileItem* fileItem = currentFolder;
JList locations = jlist_new(); std::list<IFileItem*> locations;
JLink link;
int selected_index = -1; int selected_index = -1;
int newItem; int newItem;
while (fileItem != NULL) { while (fileItem != NULL) {
jlist_prepend(locations, fileItem); locations.push_front(fileItem);
fileItem = fileItem->getParent(); fileItem = fileItem->getParent();
} }
@ -457,8 +456,9 @@ void FileSelector::updateLocation()
// Add item by item (from root to the specific current folder) // Add item by item (from root to the specific current folder)
int level = 0; int level = 0;
JI_LIST_FOR_EACH(locations, link) { for (std::list<IFileItem*>::iterator it=locations.begin(), end=locations.end();
fileItem = reinterpret_cast<IFileItem*>(link->data); it != end; ++it) {
fileItem = *it;
// Indentation // Indentation
base::string buf; base::string buf;
@ -495,8 +495,6 @@ void FileSelector::updateLocation()
m_location->getEntryWidget()->setText(currentFolder->getDisplayName().c_str()); m_location->getEntryWidget()->setText(currentFolder->getDisplayName().c_str());
m_location->getEntryWidget()->deselectText(); m_location->getEntryWidget()->deselectText();
} }
jlist_free(locations);
} }
void FileSelector::updateNavigationButtons() void FileSelector::updateNavigationButtons()
@ -572,7 +570,7 @@ void FileSelector::onGoBack()
void FileSelector::onGoForward() void FileSelector::onGoForward()
{ {
if (jlist_length(navigation_history) > 1) { if (navigation_history->size() > 1) {
if (navigation_position.isNull()) if (navigation_position.isNull())
navigation_position.setIterator(navigation_history->begin()); navigation_position.setIterator(navigation_history->begin());

View File

@ -373,12 +373,10 @@ void StatusBar::showTool(int msecs, tools::Tool* tool)
std::string text = tool->getText(); std::string text = tool->getText();
// Tool shortcut // Tool shortcut
JAccel accel = get_accel_to_change_tool(tool); Accelerator* accel = get_accel_to_change_tool(tool);
if (accel) { if (accel) {
char buf[512]; // TODO possible buffer overflow
jaccel_to_string(accel, buf);
text += ", Shortcut: "; text += ", Shortcut: ";
text += buf; text += accel->toString();
} }
// Set text // Set text

View File

@ -492,12 +492,10 @@ void ToolBar::openTipWindow(int group_index, Tool* tool)
} }
// Tool shortcut // Tool shortcut
JAccel accel = get_accel_to_change_tool(tool); Accelerator* accel = get_accel_to_change_tool(tool);
if (accel) { if (accel) {
char buf[512]; // TODO possible buffer overflow
jaccel_to_string(accel, buf);
tooltip += "\n\nShortcut: "; tooltip += "\n\nShortcut: ";
tooltip += buf; tooltip += accel->toString();
} }
} }
else if (group_index == ConfigureToolIndex) { else if (group_index == ConfigureToolIndex) {