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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -21,8 +21,6 @@
#include <allegro.h>
#include <string.h>
#include "ui/list.h"
#include "app.h"
#include "modules/palettes.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)
{
if (widget->getId() == kThemeCloseButtonId) {
Widget* window = widget->parent;
Widget* window = widget->getParent();
JRect rect = jrect_new(0, 0, 0, 0);
rect->x2 = m_part[PART_WINDOW_CLOSE_BUTTON_NORMAL]->w;
@ -1092,10 +1092,10 @@ void SkinTheme::draw_menuitem(MenuItem* widget, JRect clip)
JRect pos;
/* TODO ASSERT? */
if (!widget->parent->parent)
if (!widget->getParent()->getParent())
return;
bar = (widget->parent->parent->type == JI_MENUBAR);
bar = (widget->getParent()->getParent()->type == JI_MENUBAR);
/* colors */
if (!widget->isEnabled()) {
@ -1178,18 +1178,17 @@ void SkinTheme::draw_menuitem(MenuItem* widget, JRect clip)
(widget->rc->y1+widget->rc->y2)/2+c, COLOR_DISABLED);
}
}
/* draw the keyboard shortcut */
// Draw the keyboard shortcut
else if (widget->getAccel()) {
int old_align = widget->getAlign();
char buf[256];
pos = jwidget_get_rect(widget);
pos->x2 -= widget->child_spacing/4;
jaccel_to_string(widget->getAccel(), buf);
std::string buf = widget->getAccel()->toString();
widget->setAlign(JI_RIGHT | JI_MIDDLE);
draw_textstring(buf, fg, bg, false, widget, pos, 0);
draw_textstring(buf.c_str(), fg, bg, false, widget, pos, 0);
widget->setAlign(old_align);
jrect_free(pos);

View File

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

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

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

View File

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

View File

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

View File

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

View File

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

View File

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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -9,7 +9,6 @@
#include "ui/separator.h"
#include "gfx/size.h"
#include "ui/list.h"
#include "ui/message.h"
#include "ui/preferred_size_event.h"
#include "ui/theme.h"
@ -41,11 +40,9 @@ bool Separator::onProcessMessage(Message* msg)
void Separator::onPreferredSize(PreferredSizeEvent& ev)
{
Size maxSize(0, 0);
JLink link;
JI_LIST_FOR_EACH(this->children, link) {
Widget* child = (Widget*)link->data;
UI_FOREACH_WIDGET(getChildren(), it) {
Widget* child = *it;
Size reqSize = child->getPreferredSize();
maxSize.w = MAX(maxSize.w, reqSize.w);
maxSize.h = MAX(maxSize.h, reqSize.h);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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