Convert ui::Message union to a class hierarchy

+ Add ui::KeyScancode enum and ui::KeyModifiers flags.
+ Add ui::MouseButtons enum.
This commit is contained in:
David Capello 2013-07-28 21:17:07 -03:00
parent 6022278260
commit 1614786408
74 changed files with 1293 additions and 1041 deletions

View File

@ -398,8 +398,8 @@ void PaletteEntryEditor::setColor(const app::Color& color)
bool PaletteEntryEditor::onProcessMessage(Message* msg)
{
if (msg->type == kTimerMessage &&
msg->timer.timer == &m_redrawTimer) {
if (msg->type() == kTimerMessage &&
static_cast<TimerMessage*>(msg)->timer() == &m_redrawTimer) {
// Redraw all editors
if (m_redrawAll) {
m_redrawAll = false;

View File

@ -187,10 +187,10 @@ void PreviewCommand::onExecute(Context* context)
if (keypressed()) {
int readkey_value = readkey();
Message* msg = jmessage_new_key_related(kKeyDownMessage, readkey_value);
Message* msg = create_message_from_readkey_value(kKeyDownMessage, readkey_value);
Command* command = NULL;
get_command_from_key_message(msg, &command, NULL);
jmessage_free(msg);
delete msg;
// Change frame
if (command != NULL &&
@ -231,12 +231,12 @@ void PreviewCommand::onExecute(Context* context)
else
break;
}
} while (!jmouse_b(0));
} while (jmouse_b(0) == kButtonNone);
do {
jmouse_poll();
gui_feedback();
} while (jmouse_b(0));
} while (jmouse_b(0) != kButtonNone);
clear_keybuf();
jmouse_set_position(old_mouse_x, old_mouse_y);

View File

@ -98,12 +98,12 @@ ColorCurveEditor::ColorCurveEditor(ColorCurve* curve, int x1, int y1, int x2, in
bool ColorCurveEditor::onProcessMessage(Message* msg)
{
switch (msg->type) {
switch (msg->type()) {
case kKeyDownMessage: {
switch (msg->key.scancode) {
switch (static_cast<KeyMessage*>(msg)->scancode()) {
case KEY_INSERT: {
case kKeyInsert: {
int x = SCR2EDIT_X(jmouse_x(0));
int y = SCR2EDIT_Y(jmouse_y(0));
@ -115,7 +115,7 @@ bool ColorCurveEditor::onProcessMessage(Message* msg)
break;
}
case KEY_DEL: {
case kKeyDel: {
gfx::Point* point = getClosestPoint(SCR2EDIT_X(jmouse_x(0)),
SCR2EDIT_Y(jmouse_y(0)),
NULL, NULL);
@ -191,19 +191,20 @@ bool ColorCurveEditor::onProcessMessage(Message* msg)
case kMouseDownMessage:
// Change scroll
if (msg->any.shifts & KB_SHIFT_FLAG) {
if (msg->shiftPressed()) {
m_status = STATUS_SCROLLING;
jmouse_set_cursor(kScrollCursor);
}
/* scaling */
/* else if (msg->shifts & KB_CTRL_FLAG) { */
/* else if (msg->ctrlPressed()) { */
/* m_status = STATUS_SCALING; */
/* jmouse_set_cursor(kScrollCursor); */
/* } */
// Show manual-entry dialog
else if (msg->mouse.right) {
m_editPoint = getClosestPoint(SCR2EDIT_X(msg->mouse.x),
SCR2EDIT_Y(msg->mouse.y),
else if (static_cast<MouseMessage*>(msg)->right()) {
gfx::Point mousePos = static_cast<MouseMessage*>(msg)->position();
m_editPoint = getClosestPoint(SCR2EDIT_X(mousePos.x),
SCR2EDIT_Y(mousePos.y),
NULL, NULL);
if (m_editPoint) {
invalidate();
@ -220,8 +221,9 @@ bool ColorCurveEditor::onProcessMessage(Message* msg)
}
// Edit node
else {
m_editPoint = getClosestPoint(SCR2EDIT_X(msg->mouse.x),
SCR2EDIT_Y(msg->mouse.y),
gfx::Point mousePos = static_cast<MouseMessage*>(msg)->position();
m_editPoint = getClosestPoint(SCR2EDIT_X(mousePos.x),
SCR2EDIT_Y(mousePos.y),
&m_editX,
&m_editY);
@ -252,8 +254,9 @@ bool ColorCurveEditor::onProcessMessage(Message* msg)
case STATUS_MOVING_POINT:
if (m_editPoint) {
*m_editX = SCR2EDIT_X(msg->mouse.x);
*m_editY = SCR2EDIT_Y(msg->mouse.y);
gfx::Point mousePos = static_cast<MouseMessage*>(msg)->position();
*m_editX = SCR2EDIT_X(mousePos.x);
*m_editY = SCR2EDIT_Y(mousePos.y);
*m_editX = MID(m_x1, *m_editX, m_x2);
*m_editY = MID(m_y1, *m_editY, m_y2);

View File

@ -61,7 +61,7 @@ FilterManagerImpl* FilterPreview::getFilterManager() const
bool FilterPreview::onProcessMessage(Message* msg)
{
switch (msg->type) {
switch (msg->type()) {
case kOpenMessage:
RenderEngine::setPreviewImage(m_filterMgr->getLayer(),

View File

@ -146,18 +146,18 @@ protected:
private:
void setCursor(int x, int y);
void getDrawableLayers(JRect clip, int* first_layer, int* last_layer);
void getDrawableFrames(JRect clip, FrameNumber* first_frame, FrameNumber* last_frame);
void drawHeader(JRect clip);
void drawHeaderFrame(JRect clip, FrameNumber frame);
void drawHeaderPart(JRect clip, int x1, int y1, int x2, int y2,
void getDrawableLayers(const gfx::Rect& clip, int* first_layer, int* last_layer);
void getDrawableFrames(const gfx::Rect& clip, FrameNumber* first_frame, FrameNumber* last_frame);
void drawHeader(const gfx::Rect& clip);
void drawHeaderFrame(const gfx::Rect& clip, FrameNumber frame);
void drawHeaderPart(const gfx::Rect& clip, int x1, int y1, int x2, int y2,
bool is_hot, bool is_clk,
const char* line1, int align1,
const char* line2, int align2);
void drawSeparator(JRect clip);
void drawLayer(JRect clip, int layer_index);
void drawSeparator(const gfx::Rect& clip);
void drawLayer(const gfx::Rect& clip, int layer_index);
void drawLayerPadding();
void drawCel(JRect clip, int layer_index, FrameNumber frame, Cel* cel);
void drawCel(const gfx::Rect& clip, int layer_index, FrameNumber frame, Cel* cel);
bool drawPart(int part, int layer, FrameNumber frame);
void regenerateLayers();
void hotThis(int hot_part, int hot_layer, FrameNumber hotFrame);
@ -270,10 +270,10 @@ AnimationEditor::~AnimationEditor()
bool AnimationEditor::onProcessMessage(Message* msg)
{
switch (msg->type) {
switch (msg->type()) {
case kPaintMessage: {
JRect clip = &msg->draw.rect;
gfx::Rect clip = static_cast<PaintMessage*>(msg)->rect();
int layer, first_layer, last_layer;
FrameNumber frame, first_frame, last_frame;
@ -332,7 +332,7 @@ bool AnimationEditor::onProcessMessage(Message* msg)
break;
case kMouseDownMessage:
if (msg->mouse.middle || m_space_pressed) {
if (static_cast<MouseMessage*>(msg)->middle() || m_space_pressed) {
captureMouse();
m_state = STATE_SCROLLING;
return true;
@ -436,8 +436,9 @@ bool AnimationEditor::onProcessMessage(Message* msg)
int hot_part = A_PART_NOTHING;
int hot_layer = -1;
FrameNumber hot_frame(-1);
int mx = msg->mouse.x - rc->x1;
int my = msg->mouse.y - rc->y1;
gfx::Point mousePos = static_cast<MouseMessage*>(msg)->position();
int mx = mousePos.x - rc->x1;
int my = mousePos.y - rc->y1;
if (hasCapture()) {
if (m_state == STATE_SCROLLING) {
@ -525,6 +526,8 @@ bool AnimationEditor::onProcessMessage(Message* msg)
case kMouseUpMessage:
if (hasCapture()) {
MouseMessage* mouseMsg = static_cast<MouseMessage*>(msg);
releaseMouse();
if (m_state == STATE_SCROLLING) {
@ -544,11 +547,12 @@ bool AnimationEditor::onProcessMessage(Message* msg)
break;
case A_PART_HEADER_FRAME:
// Show the frame pop-up menu.
if (msg->mouse.right) {
if (mouseMsg->right()) {
if (m_clk_frame == m_hot_frame) {
Menu* popup_menu = AppMenus::instance()->getFramePopupMenu();
if (popup_menu != NULL) {
popup_menu->showPopup(msg->mouse.x, msg->mouse.y);
gfx::Point mousePos = mouseMsg->position();
popup_menu->showPopup(mousePos.x, mousePos.y);
destroy_thumbnails();
invalidate();
@ -556,7 +560,7 @@ bool AnimationEditor::onProcessMessage(Message* msg)
}
}
// Show the frame's properties dialog.
else if (msg->mouse.left) {
else if (mouseMsg->left()) {
if (m_clk_frame == m_hot_frame) {
// Execute FrameProperties command for current frame.
Command* command = CommandsModule::instance()
@ -585,11 +589,12 @@ bool AnimationEditor::onProcessMessage(Message* msg)
break;
case A_PART_LAYER:
// Show the layer pop-up menu.
if (msg->mouse.right) {
if (mouseMsg->right()) {
if (m_clk_layer == m_hot_layer) {
Menu* popup_menu = AppMenus::instance()->getLayerPopupMenu();
if (popup_menu != NULL) {
popup_menu->showPopup(msg->mouse.x, msg->mouse.y);
gfx::Point mousePos = mouseMsg->position();
popup_menu->showPopup(mousePos.x, mousePos.y);
destroy_thumbnails();
invalidate();
@ -598,7 +603,7 @@ bool AnimationEditor::onProcessMessage(Message* msg)
}
}
// Move a layer.
else if (msg->mouse.left) {
else if (mouseMsg->left()) {
if (m_hot_layer >= 0 &&
m_hot_layer < (int)m_layers.size() &&
m_hot_layer != m_clk_layer &&
@ -668,11 +673,12 @@ bool AnimationEditor::onProcessMessage(Message* msg)
}
// Show the cel pop-up menu.
if (msg->mouse.right) {
if (mouseMsg->right()) {
Menu* popup_menu = movement ? AppMenus::instance()->getCelMovementPopupMenu():
AppMenus::instance()->getCelPopupMenu();
if (popup_menu != NULL) {
popup_menu->showPopup(msg->mouse.x, msg->mouse.y);
gfx::Point mousePos = mouseMsg->position();
popup_menu->showPopup(mousePos.x, mousePos.y);
destroy_thumbnails();
regenerateLayers();
@ -680,7 +686,7 @@ bool AnimationEditor::onProcessMessage(Message* msg)
}
}
// Move the cel.
else if (msg->mouse.left) {
else if (mouseMsg->left()) {
if (movement) {
{
const ContextReader reader(m_context);
@ -707,7 +713,8 @@ bool AnimationEditor::onProcessMessage(Message* msg)
// Restore the cursor.
m_state = STATE_STANDBY;
setCursor(msg->mouse.x, msg->mouse.y);
setCursor(mouseMsg->position().x,
mouseMsg->position().y);
return true;
}
break;
@ -719,7 +726,7 @@ bool AnimationEditor::onProcessMessage(Message* msg)
// Close animation editor.
if ((command && (strcmp(command->short_name(), CommandId::FilmEditor) == 0)) ||
(msg->key.scancode == KEY_ESC)) {
(static_cast<KeyMessage*>(msg)->scancode() == kKeyEsc)) {
closeWindow();
return true;
}
@ -769,8 +776,8 @@ bool AnimationEditor::onProcessMessage(Message* msg)
}
}
switch (msg->key.scancode) {
case KEY_SPACE:
switch (static_cast<KeyMessage*>(msg)->scancode()) {
case kKeySpace:
m_space_pressed = true;
setCursor(jmouse_x(0), jmouse_y(0));
return true;
@ -780,9 +787,9 @@ bool AnimationEditor::onProcessMessage(Message* msg)
}
case kKeyUpMessage:
switch (msg->key.scancode) {
switch (static_cast<KeyMessage*>(msg)->scancode()) {
case KEY_SPACE:
case kKeySpace:
if (m_space_pressed) {
// We have to clear all the KEY_SPACE in buffer.
clear_keybuf();
@ -800,12 +807,12 @@ bool AnimationEditor::onProcessMessage(Message* msg)
int dx = 0;
int dy = 0;
if ((msg->any.shifts & KB_CTRL_FLAG) == KB_CTRL_FLAG)
if (msg->ctrlPressed())
dx = dz * FRMSIZE;
else
dy = dz * LAYSIZE;
if ((msg->any.shifts & KB_SHIFT_FLAG) == KB_SHIFT_FLAG) {
if (msg->shiftPressed()) {
dx *= 3;
dy *= 3;
}
@ -815,9 +822,11 @@ bool AnimationEditor::onProcessMessage(Message* msg)
break;
}
case kSetCursorMessage:
setCursor(msg->mouse.x, msg->mouse.y);
case kSetCursorMessage: {
gfx::Point mousePos = static_cast<MouseMessage*>(msg)->position();
setCursor(mousePos.x, mousePos.y);
return true;
}
}
@ -932,19 +941,19 @@ void AnimationEditor::setCursor(int x, int y)
}
}
void AnimationEditor::getDrawableLayers(JRect clip, int* first_layer, int* last_layer)
void AnimationEditor::getDrawableLayers(const gfx::Rect& clip, int* first_layer, int* last_layer)
{
*first_layer = 0;
*last_layer = m_layers.size()-1;
}
void AnimationEditor::getDrawableFrames(JRect clip, FrameNumber* first_frame, FrameNumber* last_frame)
void AnimationEditor::getDrawableFrames(const gfx::Rect& clip, FrameNumber* first_frame, FrameNumber* last_frame)
{
*first_frame = FrameNumber(0);
*last_frame = m_sprite->getLastFrame();
}
void AnimationEditor::drawHeader(JRect clip)
void AnimationEditor::drawHeader(const gfx::Rect& clip)
{
// bool is_hot = (m_hot_part == A_PART_HEADER_LAYER);
// bool is_clk = (m_clk_part == A_PART_HEADER_LAYER);
@ -963,7 +972,7 @@ void AnimationEditor::drawHeader(JRect clip)
"Layers", -1);
}
void AnimationEditor::drawHeaderFrame(JRect clip, FrameNumber frame)
void AnimationEditor::drawHeaderFrame(const gfx::Rect& clip, FrameNumber frame)
{
SkinTheme* theme = static_cast<SkinTheme*>(getTheme());
bool is_hot = (m_hot_part == A_PART_HEADER_FRAME &&
@ -1019,7 +1028,7 @@ void AnimationEditor::drawHeaderFrame(JRect clip, FrameNumber frame)
set_clip_rect(ji_screen, cx1, cy1, cx2, cy2);
}
void AnimationEditor::drawHeaderPart(JRect clip, int x1, int y1, int x2, int y2,
void AnimationEditor::drawHeaderPart(const gfx::Rect& clip, int x1, int y1, int x2, int y2,
bool is_hot, bool is_clk,
const char *line1, int align1,
const char *line2, int align2)
@ -1028,8 +1037,7 @@ void AnimationEditor::drawHeaderPart(JRect clip, int x1, int y1, int x2, int y2,
ui::Color fg, face;
int x;
if ((x2 < clip->x1) || (x1 >= clip->x2) ||
(y2 < clip->y1) || (y1 >= clip->y2))
if (!clip.intersects(gfx::Rect(x1, y1, x2-x1, y2-y1)))
return;
fg = theme->getColor(!is_hot && is_clk ? ThemeColor::Background: ThemeColor::Text);
@ -1066,7 +1074,7 @@ void AnimationEditor::drawHeaderPart(JRect clip, int x1, int y1, int x2, int y2,
}
}
void AnimationEditor::drawSeparator(JRect clip)
void AnimationEditor::drawSeparator(const gfx::Rect& clip)
{
SkinTheme* theme = static_cast<SkinTheme*>(getTheme());
bool is_hot = (m_hot_part == A_PART_SEPARATOR);
@ -1077,8 +1085,7 @@ void AnimationEditor::drawSeparator(JRect clip)
x2 = this->rc->x1 + m_separator_x + m_separator_w - 1;
y2 = this->rc->y2 - 1;
if ((x2 < clip->x1) || (x1 >= clip->x2) ||
(y2 < clip->y1) || (y1 >= clip->y2))
if (!clip.intersects(gfx::Rect(x1, y1, x2-x1, y2-y1)))
return;
vline(ji_screen, x1, y1, y2,
@ -1086,7 +1093,7 @@ void AnimationEditor::drawSeparator(JRect clip)
theme->getColor(ThemeColor::Text)));
}
void AnimationEditor::drawLayer(JRect clip, int layer_index)
void AnimationEditor::drawLayer(const gfx::Rect& clip, int layer_index)
{
Layer* layer = m_layers[layer_index];
SkinTheme* theme = static_cast<SkinTheme*>(this->getTheme());
@ -1204,7 +1211,7 @@ void AnimationEditor::drawLayerPadding()
}
}
void AnimationEditor::drawCel(JRect clip, int layer_index, FrameNumber frame, Cel* cel)
void AnimationEditor::drawCel(const gfx::Rect& clip, int layer_index, FrameNumber frame, Cel* cel)
{
SkinTheme* theme = static_cast<SkinTheme*>(this->getTheme());
Layer *layer = m_layers[layer_index];
@ -1306,14 +1313,14 @@ bool AnimationEditor::drawPart(int part, int layer, FrameNumber frame)
// Do nothing.
return true;
case A_PART_SEPARATOR:
drawSeparator(this->rc);
drawSeparator(getBounds());
return true;
case A_PART_HEADER_LAYER:
drawHeader(this->rc);
drawHeader(getBounds());
return true;
case A_PART_HEADER_FRAME:
if (frame >= 0 && frame < m_sprite->getTotalFrames()) {
drawHeaderFrame(this->rc, frame);
drawHeaderFrame(getBounds(), frame);
return true;
}
break;
@ -1321,7 +1328,7 @@ bool AnimationEditor::drawPart(int part, int layer, FrameNumber frame)
case A_PART_LAYER_EYE_ICON:
case A_PART_LAYER_LOCK_ICON:
if (layer >= 0 && layer < (int)m_layers.size()) {
drawLayer(this->rc, layer);
drawLayer(getBounds(), layer);
return true;
}
break;
@ -1330,7 +1337,7 @@ bool AnimationEditor::drawPart(int part, int layer, FrameNumber frame)
frame >= 0 && frame < m_sprite->getTotalFrames()) {
Cel* cel = (m_layers[layer]->isImage() ? static_cast<LayerImage*>(m_layers[layer])->getCel(frame): NULL);
drawCel(this->rc, layer, frame, cel);
drawCel(getBounds(), layer, frame, cel);
return true;
}
break;

View File

@ -649,9 +649,9 @@ void Shortcut::add_shortcut(const char* shortcut_string)
bool Shortcut::is_pressed(Message* msg)
{
if (accel) {
return accel->check(msg->any.shifts,
msg->key.ascii,
msg->key.scancode);
return accel->check(msg->keyModifiers(),
static_cast<KeyMessage*>(msg)->scancode(),
static_cast<KeyMessage*>(msg)->ascii());
}
return false;
}
@ -733,7 +733,7 @@ static Shortcut* get_keyboard_shortcut_for_spriteeditor(const char* action_name)
// Manager event handler.
bool CustomizedGuiManager::onProcessMessage(Message* msg)
{
switch (msg->type) {
switch (msg->type()) {
case kCloseAppMessage:
{

View File

@ -33,10 +33,10 @@ class Params;
namespace ui {
class ButtonBase;
class CheckBox;
class Message;
class RadioButton;
class Widget;
class Window;
union Message;
}
namespace tools { class Tool; }

View File

@ -74,21 +74,21 @@ protected:
}
bool onProcessMessage(Message* msg) OVERRIDE {
switch (msg->type) {
switch (msg->type()) {
case kSetCursorMessage:
jmouse_set_cursor(kArrowCursor);
return true;
case kKeyDownMessage:
if (msg->key.scancode == KEY_ESC) {
if (static_cast<KeyMessage*>(msg)->scancode() == kKeyEsc) {
setSelected(true);
return true;
}
break;
case kKeyUpMessage:
if (msg->key.scancode == KEY_ESC) {
if (static_cast<KeyMessage*>(msg)->scancode() == kKeyEsc) {
if (isSelected()) {
setSelected(false);
closeWindow();

View File

@ -23,6 +23,7 @@ add_library(ui-lib
image_view.cpp
int_entry.cpp
intern.cpp
keys.cpp
label.cpp
link_label.cpp
listbox.cpp

View File

@ -14,50 +14,50 @@
#include <allegro/unicode.h>
#include <ctype.h>
/* #define REPORT_KEYS */
// #define REPORT_KEYS
#define PREPROCESS_KEYS
namespace ui {
void Accelerator::addKey(int shifts, int ascii, int scancode)
void Accelerator::addKey(KeyModifiers modifiers, KeyScancode scancode, int ascii)
{
KeyCombo key;
key.shifts = shifts & (KB_SHIFT_FLAG | KB_CTRL_FLAG | KB_ALT_FLAG);
key.ascii = ascii;
key.modifiers = modifiers;
key.scancode = scancode;
key.ascii = ascii;
m_combos.push_back(key);
}
static void process_one_word(Accelerator* accel, char* word)
{
int shifts = 0;
KeyModifiers modifiers = kKeyNoneModifier;
KeyScancode scancode = kKeyNil;
int ascii = 0;
int scancode = 0;
char* tok;
// Special case: plus sign
if (word[0] == '+' && word[1] == 0) {
accel->addKey(0, '+', 0);
accel->addKey(kKeyNoneModifier, kKeyNil, '+');
return;
}
for (tok=ustrtok(word, "+"); tok;
tok=ustrtok(NULL, "+")) {
// modifiers
// Modifiers
if (ustricmp (tok, "Shift") == 0) {
shifts |= KB_SHIFT_FLAG;
if (ustricmp(tok, "Shift") == 0) {
modifiers = (KeyModifiers)((int)modifiers | (int)kKeyShiftModifier);
}
else if (ustricmp (tok, "Alt") == 0) {
shifts |= KB_ALT_FLAG;
modifiers = (KeyModifiers)((int)modifiers | (int)kKeyAltModifier);
}
else if (ustricmp (tok, "Ctrl") == 0) {
shifts |= KB_CTRL_FLAG;
modifiers = (KeyModifiers)((int)modifiers | (int)kKeyCtrlModifier);
}
// scancode
// Scancode
// word with one character
else if (tok[1] == 0) {
@ -71,23 +71,23 @@ static void process_one_word(Accelerator* accel, char* word)
if (((*tok >= 'a') && (*tok <= 'z')) ||
((*tok >= 'A') && (*tok <= 'Z')))
scancode = KEY_A + tolower(*tok) - 'a';
scancode = (KeyScancode)((int)kKeyA + tolower(*tok) - 'a');
else if ((*tok >= '0') && (*tok <= '9'))
scancode = KEY_0 + *tok - '0';
scancode = (KeyScancode)((int)kKey0 + *tok - '0');
else {
switch (*tok) {
case '~': scancode = KEY_TILDE; break;
case '-': scancode = KEY_MINUS; break;
case '=': scancode = KEY_EQUALS; break;
case '[': scancode = KEY_OPENBRACE; break;
case ']': scancode = KEY_CLOSEBRACE; break;
case ';': scancode = KEY_COLON; break;
case '\'': scancode = KEY_QUOTE; break;
case '\\': scancode = KEY_BACKSLASH; break;
case ',': scancode = KEY_COMMA; break;
case '.': scancode = KEY_STOP; break;
case '/': scancode = KEY_SLASH; break;
case '*': scancode = KEY_ASTERISK; break;
case '~': scancode = kKeyTilde; break;
case '-': scancode = kKeyMinus; break;
case '=': scancode = kKeyEquals; break;
case '[': scancode = kKeyOpenbrace; break;
case ']': scancode = kKeyClosebrace; break;
case ';': scancode = kKeyColon; break;
case '\'': scancode = kKeyQuote; break;
case '\\': scancode = kKeyBackslash; break;
case ',': scancode = kKeyComma; break;
case '.': scancode = kKeyStop; break;
case '/': scancode = kKeySlash; break;
case '*': scancode = kKeyAsterisk; break;
}
}
}
@ -97,79 +97,79 @@ static void process_one_word(Accelerator* accel, char* word)
if ((toupper (*tok) == 'F') && (ustrlen(tok) <= 3)) {
int num = ustrtol(tok+1, NULL, 10);
if ((num >= 1) && (num <= 12))
scancode = KEY_F1 + num - 1;
scancode = (KeyScancode)((int)kKeyF1 + num - 1);
}
else if ((ustricmp(tok, "Escape") == 0) ||
(ustricmp(tok, "Esc") == 0))
scancode = KEY_ESC;
scancode = kKeyEsc;
else if (ustricmp(tok, "Backspace") == 0)
scancode = KEY_BACKSPACE;
scancode = kKeyBackspace;
else if (ustricmp(tok, "Tab") == 0)
scancode = KEY_TAB;
scancode = kKeyTab;
else if (ustricmp(tok, "Enter") == 0)
scancode = KEY_ENTER;
scancode = kKeyEnter;
else if (ustricmp(tok, "Space") == 0)
scancode = KEY_SPACE;
scancode = kKeySpace;
else if ((ustricmp(tok, "Insert") == 0) ||
(ustricmp(tok, "Ins") == 0))
scancode = KEY_INSERT;
scancode = kKeyInsert;
else if ((ustricmp(tok, "Delete") == 0) ||
(ustricmp(tok, "Del") == 0))
scancode = KEY_DEL;
scancode = kKeyDel;
else if (ustricmp(tok, "Home") == 0)
scancode = KEY_HOME;
scancode = kKeyHome;
else if (ustricmp(tok, "End") == 0)
scancode = KEY_END;
scancode = kKeyEnd;
else if ((ustricmp(tok, "Page Up") == 0) ||
(ustricmp(tok, "PgUp") == 0))
scancode = KEY_PGUP;
scancode = kKeyPageUp;
else if ((ustricmp(tok, "Page Down") == 0) ||
(ustricmp(tok, "PgDn") == 0))
scancode = KEY_PGDN;
scancode = kKeyPageDown;
else if (ustricmp(tok, "Left") == 0)
scancode = KEY_LEFT;
scancode = kKeyLeft;
else if (ustricmp(tok, "Right") == 0)
scancode = KEY_RIGHT;
scancode = kKeyRight;
else if (ustricmp(tok, "Up") == 0)
scancode = KEY_UP;
scancode = kKeyUp;
else if (ustricmp(tok, "Down") == 0)
scancode = KEY_DOWN;
scancode = kKeyDown;
else if (ustricmp(tok, "0 Pad") == 0)
scancode = KEY_0_PAD;
scancode = kKey0Pad;
else if (ustricmp(tok, "1 Pad") == 0)
scancode = KEY_1_PAD;
scancode = kKey1Pad;
else if (ustricmp(tok, "2 Pad") == 0)
scancode = KEY_2_PAD;
scancode = kKey2Pad;
else if (ustricmp(tok, "3 Pad") == 0)
scancode = KEY_3_PAD;
scancode = kKey3Pad;
else if (ustricmp(tok, "4 Pad") == 0)
scancode = KEY_4_PAD;
scancode = kKey4Pad;
else if (ustricmp(tok, "5 Pad") == 0)
scancode = KEY_5_PAD;
scancode = kKey5Pad;
else if (ustricmp(tok, "6 Pad") == 0)
scancode = KEY_6_PAD;
scancode = kKey6Pad;
else if (ustricmp(tok, "7 Pad") == 0)
scancode = KEY_7_PAD;
scancode = kKey7Pad;
else if (ustricmp(tok, "8 Pad") == 0)
scancode = KEY_8_PAD;
scancode = kKey8Pad;
else if (ustricmp(tok, "9 Pad") == 0)
scancode = KEY_9_PAD;
scancode = kKey9Pad;
else if (ustricmp(tok, "Slash Pad") == 0)
scancode = KEY_SLASH_PAD;
scancode = kKeySlashPad;
else if (ustricmp(tok, "Asterisk") == 0)
scancode = KEY_ASTERISK;
scancode = kKeyAsterisk;
else if (ustricmp(tok, "Minus Pad") == 0)
scancode = KEY_MINUS_PAD;
scancode = kKeyMinusPad;
else if (ustricmp(tok, "Plus Pad") == 0)
scancode = KEY_PLUS_PAD;
scancode = kKeyPlusPad;
else if (ustricmp(tok, "Del Pad") == 0)
scancode = KEY_DEL_PAD;
scancode = kKeyDelPad;
else if (ustricmp(tok, "Enter Pad") == 0)
scancode = KEY_ENTER_PAD;
scancode = kKeyEnterPad;
}
}
accel->addKey(shifts, ascii, scancode);
accel->addKey(modifiers, scancode, ascii);
}
void Accelerator::addKeysFromString(const char* string)
@ -200,7 +200,7 @@ void Accelerator::addKeysFromString(const char* string)
std::string Accelerator::KeyCombo::toString()
{
/* same order that Allegro scancodes */
// Same order that Allegro scancodes
static const char *table[] = {
NULL,
"A",
@ -311,13 +311,13 @@ std::string Accelerator::KeyCombo::toString()
ustrcpy(buf, "");
// Shifts
if (this->shifts & KB_CTRL_FLAG)
if (this->modifiers & kKeyCtrlModifier)
ustrcat(buf, "Ctrl+");
if (this->shifts & KB_ALT_FLAG)
if (this->modifiers & kKeyAltModifier)
ustrcat(buf, "Alt+");
if (this->shifts & KB_SHIFT_FLAG)
if (this->modifiers & kKeyShiftModifier)
ustrcat(buf, "Shift+");
// Key
@ -337,29 +337,29 @@ std::string Accelerator::toString()
return m_combos.front().toString();
}
bool Accelerator::check(int shifts, int ascii, int scancode)
bool Accelerator::check(KeyModifiers modifiers, KeyScancode scancode, int ascii)
{
#ifdef REPORT_KEYS
char buf[256];
std::string buf2;
#endif
/* preprocess the character to be compared with the accelerator */
// Preprocess the character to be compared with the accelerator
#ifdef PREPROCESS_KEYS
/* directly scancode */
if ((scancode >= KEY_F1 && scancode <= KEY_F12) ||
(scancode == KEY_ESC) ||
(scancode == KEY_BACKSPACE) ||
(scancode == KEY_TAB) ||
(scancode == KEY_ENTER) ||
(scancode == KEY_BACKSLASH) ||
(scancode == KEY_BACKSLASH2) ||
(scancode >= KEY_SPACE && scancode <= KEY_DOWN) ||
(scancode >= KEY_ENTER_PAD && scancode <= KEY_NOCONVERT) ||
(scancode == KEY_KANJI)) {
// Directly scancode
if ((scancode >= kKeyF1 && scancode <= KEY_F12) ||
(scancode == kKeyEsc) ||
(scancode == kKeyBackspace) ||
(scancode == kKeyTab) ||
(scancode == kKeyEnter) ||
(scancode == kKeyBackslash) ||
(scancode == kKeyBackslash2) ||
(scancode >= kKeySpace && scancode <= kKeyDown) ||
(scancode >= kKeyEnterPad && scancode <= kKeyNoconvert) ||
(scancode == kKeyKanji)) {
ascii = 0;
}
/* for Ctrl+number */
// For Ctrl+number
/* scancode ascii
Ctrl+0 27 0
Ctrl+1 28 2
@ -372,33 +372,33 @@ bool Accelerator::check(int shifts, int ascii, int scancode)
Ctrl+8 35 127
Ctrl+9 36 2
*/
else if ((scancode >= KEY_0 && scancode <= KEY_9) &&
else if ((scancode >= kKey0 && scancode <= kKey9) &&
(ascii < 32 || ascii == 127)) {
ascii = '0'+scancode-KEY_0;
scancode = 0;
ascii = '0' + scancode - kKey0;
scancode = kKeyNil;
}
/* for Ctrl+letter */
// For Ctrl+letter
else if (ascii >= 1 && ascii <= 'z'-'a'+1) {
ascii = 'a'+ascii-1;
scancode = 0;
scancode = kKeyNil;
}
/* for any other legal ASCII code */
// For any other legal ASCII code
else if (ascii >= ' ') {
ascii = tolower(ascii);
/* without shift (because characters like '*' can be trigger with
"Shift+8", so we don't want "Shift+*") */
if (!(ascii >= 'a' && ascii <= 'z'))
shifts &= ~KB_SHIFT_FLAG;
modifiers = (KeyModifiers)((int)modifiers & ((int)~kKeyShiftModifier));
scancode = 0;
scancode = kKeyNil;
}
#endif
#ifdef REPORT_KEYS
{
UniquePtr<Accelerator> a2(new Accelerator);
a2->addKey(shifts, ascii, scancode);
a2->addKey(modifiers, scancode, ascii);
buf2 = a2->getString();
}
#endif
@ -411,9 +411,9 @@ bool Accelerator::check(int shifts, int ascii, int scancode)
it->getString().c_str(), buf2.c_str();
#endif
if (((it->scancode && it->scancode == scancode)
|| (it->ascii && it->ascii == ascii))
&& (it->shifts == (shifts & (KB_SHIFT_FLAG | KB_CTRL_FLAG | KB_ALT_FLAG)))) {
if ((it->modifiers == modifiers) &&
((it->scancode != kKeyNil && it->scancode == scancode) ||
(it->ascii && it->ascii == ascii))) {
#ifdef REPORT_KEYS
printf("true\n");
@ -431,18 +431,18 @@ bool Accelerator::check(int shifts, int ascii, int scancode)
bool Accelerator::checkFromAllegroKeyArray()
{
int shifts = 0;
KeyModifiers modifiers = kKeyNoneModifier;
if (key[KEY_LSHIFT]) shifts |= KB_SHIFT_FLAG;
if (key[KEY_RSHIFT]) shifts |= KB_SHIFT_FLAG;
if (key[KEY_LCONTROL]) shifts |= KB_CTRL_FLAG;
if (key[KEY_RCONTROL]) shifts |= KB_CTRL_FLAG;
if (key[KEY_ALT]) shifts |= KB_ALT_FLAG;
if (key[KEY_LSHIFT] ) modifiers = (KeyModifiers)((int)modifiers | (int)kKeyShiftModifier);
if (key[KEY_RSHIFT] ) modifiers = (KeyModifiers)((int)modifiers | (int)kKeyShiftModifier);
if (key[KEY_LCONTROL]) modifiers = (KeyModifiers)((int)modifiers | (int)kKeyCtrlModifier);
if (key[KEY_RCONTROL]) modifiers = (KeyModifiers)((int)modifiers | (int)kKeyCtrlModifier);
if (key[KEY_ALT] ) modifiers = (KeyModifiers)((int)modifiers | (int)kKeyAltModifier);
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)))) {
(it->modifiers == modifiers)) {
return true;
}
}

View File

@ -10,12 +10,14 @@
#include <string>
#include <vector>
#include "ui/keys.h"
namespace ui {
class Accelerator
{
public:
void addKey(int shifts, int ascii, int scancode);
void addKey(KeyModifiers modifiers, KeyScancode scancode, int ascii);
// Adds keys from strings like "<Ctrl+Q> <ESC>"
void addKeysFromString(const char* string);
@ -23,14 +25,15 @@ namespace ui {
bool isEmpty() const { return m_combos.empty(); }
std::string toString();
bool check(int shifts, int ascii, int scancode);
bool check(KeyModifiers modifiers, KeyScancode scancode, int ascii);
bool checkFromAllegroKeyArray();
private:
struct KeyCombo {
int shifts;
KeyModifiers modifiers;
KeyScancode scancode;
int ascii;
int scancode;
std::string toString();
};

View File

@ -78,7 +78,7 @@ void ButtonBase::onClick(Event& ev)
bool ButtonBase::onProcessMessage(Message* msg)
{
switch (msg->type) {
switch (msg->type()) {
case kFocusEnterMessage:
case kFocusLeaveMessage:
@ -95,30 +95,32 @@ bool ButtonBase::onProcessMessage(Message* msg)
}
break;
case kKeyDownMessage:
case kKeyDownMessage: {
KeyMessage* keymsg = static_cast<KeyMessage*>(msg);
KeyScancode scancode = keymsg->scancode();
// If the button is enabled.
if (isEnabled()) {
// For kButtonWidget
if (m_behaviorType == kButtonWidget) {
// Has focus and press enter/space
if (hasFocus()) {
if ((msg->key.scancode == KEY_ENTER) ||
(msg->key.scancode == KEY_ENTER_PAD) ||
(msg->key.scancode == KEY_SPACE)) {
if ((scancode == kKeyEnter) ||
(scancode == kKeyEnterPad) ||
(scancode == kKeySpace)) {
setSelected(true);
return true;
}
}
// Check if the user pressed mnemonic.
if ((msg->any.shifts & KB_ALT_FLAG) &&
(isScancodeMnemonic(msg->key.scancode))) {
if ((msg->altPressed()) && (isScancodeMnemonic(scancode))) {
setSelected(true);
return true;
}
// Magnetic widget catches ENTERs
else if (isFocusMagnet() &&
((msg->key.scancode == KEY_ENTER) ||
(msg->key.scancode == KEY_ENTER_PAD))) {
((scancode == kKeyEnter) ||
(scancode == kKeyEnterPad))) {
getManager()->setFocus(this);
// Dispatch focus movement messages (because the buttons
@ -134,9 +136,9 @@ bool ButtonBase::onProcessMessage(Message* msg)
/* if the widget has the focus and the user press space or
if the user press Alt+the underscored letter of the button */
if ((hasFocus() &&
(msg->key.scancode == KEY_SPACE)) ||
((msg->any.shifts & KB_ALT_FLAG) &&
(isScancodeMnemonic(msg->key.scancode)))) {
(scancode == kKeySpace)) ||
((msg->altPressed()) &&
(isScancodeMnemonic(scancode)))) {
if (m_behaviorType == kCheckWidget) {
// Swap the select status
setSelected(!isSelected());
@ -153,6 +155,7 @@ bool ButtonBase::onProcessMessage(Message* msg)
}
}
break;
}
case kKeyUpMessage:
if (isEnabled()) {

View File

@ -307,7 +307,7 @@ Button* ComboBox::getButtonWidget()
bool ComboBox::onProcessMessage(Message* msg)
{
switch (msg->type) {
switch (msg->type()) {
case kCloseMessage:
closeListBox();
@ -374,21 +374,24 @@ void ComboBox::onPreferredSize(PreferredSizeEvent& ev)
bool ComboBoxEntry::onProcessMessage(Message* msg)
{
switch (msg->type) {
switch (msg->type()) {
case kKeyDownMessage:
if (hasFocus()) {
KeyMessage* keymsg = static_cast<KeyMessage*>(msg);
KeyScancode scancode = keymsg->scancode();
if (!m_comboBox->isEditable()) {
if (msg->key.scancode == KEY_SPACE ||
msg->key.scancode == KEY_ENTER ||
msg->key.scancode == KEY_ENTER_PAD) {
if (scancode == kKeySpace ||
scancode == kKeyEnter ||
scancode == kKeyEnterPad) {
m_comboBox->switchListBox();
return true;
}
}
else {
if (msg->key.scancode == KEY_ENTER ||
msg->key.scancode == KEY_ENTER_PAD) {
if (scancode == kKeyEnter ||
scancode == kKeyEnterPad) {
m_comboBox->switchListBox();
return true;
}
@ -420,23 +423,25 @@ void ComboBoxEntry::onPaint(PaintEvent& ev)
bool ComboBoxListBox::onProcessMessage(Message* msg)
{
switch (msg->type) {
switch (msg->type()) {
case kMouseUpMessage:
{
int index = m_comboBox->getSelectedItemIndex();
if (isValidItem(index))
m_comboBox->onChange();
case kMouseUpMessage: {
int index = m_comboBox->getSelectedItemIndex();
if (isValidItem(index))
m_comboBox->onChange();
m_comboBox->closeListBox();
}
m_comboBox->closeListBox();
return true;
}
case kKeyDownMessage:
if (hasFocus()) {
if (msg->key.scancode == KEY_SPACE ||
msg->key.scancode == KEY_ENTER ||
msg->key.scancode == KEY_ENTER_PAD) {
KeyMessage* keymsg = static_cast<KeyMessage*>(msg);
KeyScancode scancode = keymsg->scancode();
if (scancode == kKeySpace ||
scancode == kKeyEnter ||
scancode == kKeyEnterPad) {
m_comboBox->closeListBox();
return true;
}

View File

@ -172,10 +172,10 @@ void Entry::getEntryThemeInfo(int* scroll, int* caret, int* state,
bool Entry::onProcessMessage(Message* msg)
{
switch (msg->type) {
switch (msg->type()) {
case kTimerMessage:
if (this->hasFocus() && msg->timer.timer == &m_timer) {
if (hasFocus() && static_cast<TimerMessage*>(msg)->timer() == &m_timer) {
// Blinking caret
m_state = m_state ? false: true;
invalidate();
@ -202,21 +202,23 @@ bool Entry::onProcessMessage(Message* msg)
break;
case kKeyDownMessage:
if (this->hasFocus() && !isReadOnly()) {
if (hasFocus() && !isReadOnly()) {
// Command to execute
EntryCmd::Type cmd = EntryCmd::NoOp;
KeyMessage* keymsg = static_cast<KeyMessage*>(msg);
KeyScancode scancode = keymsg->scancode();
switch (msg->key.scancode) {
switch (scancode) {
case KEY_LEFT:
if (msg->any.shifts & KB_CTRL_FLAG)
if (msg->ctrlPressed())
cmd = EntryCmd::BackwardWord;
else
cmd = EntryCmd::BackwardChar;
break;
case KEY_RIGHT:
if (msg->any.shifts & KB_CTRL_FLAG)
if (msg->ctrlPressed())
cmd = EntryCmd::ForwardWord;
else
cmd = EntryCmd::ForwardChar;
@ -231,16 +233,16 @@ bool Entry::onProcessMessage(Message* msg)
break;
case KEY_DEL:
if (msg->any.shifts & KB_SHIFT_FLAG)
if (msg->shiftPressed())
cmd = EntryCmd::Cut;
else
cmd = EntryCmd::DeleteForward;
break;
case KEY_INSERT:
if (msg->any.shifts & KB_SHIFT_FLAG)
if (msg->shiftPressed())
cmd = EntryCmd::Paste;
else if (msg->any.shifts & KB_CTRL_FLAG)
else if (msg->ctrlPressed())
cmd = EntryCmd::Copy;
break;
@ -249,20 +251,20 @@ bool Entry::onProcessMessage(Message* msg)
break;
default:
if (msg->key.ascii >= 32) {
if (keymsg->ascii() >= 32) {
// Ctrl and Alt must be unpressed to insert a character
// in the text-field.
if ((msg->any.shifts & (KB_CTRL_FLAG | KB_ALT_FLAG)) == 0) {
if ((msg->keyModifiers() & (kKeyCtrlModifier | kKeyAltModifier)) == 0) {
cmd = EntryCmd::InsertChar;
}
}
else {
// map common Windows shortcuts for Cut/Copy/Paste
if ((msg->any.shifts & (KB_CTRL_FLAG | KB_SHIFT_FLAG | KB_ALT_FLAG)) == KB_CTRL_FLAG) {
switch (msg->key.scancode) {
case KEY_X: cmd = EntryCmd::Cut; break;
case KEY_C: cmd = EntryCmd::Copy; break;
case KEY_V: cmd = EntryCmd::Paste; break;
// Map common Windows shortcuts for Cut/Copy/Paste
if (msg->onlyCtrlPressed()) {
switch (scancode) {
case kKeyX: cmd = EntryCmd::Cut; break;
case kKeyC: cmd = EntryCmd::Copy; break;
case kKeyV: cmd = EntryCmd::Paste; break;
}
}
}
@ -272,27 +274,26 @@ bool Entry::onProcessMessage(Message* msg)
if (cmd == EntryCmd::NoOp)
break;
executeCmd(cmd,
msg->key.ascii,
(msg->any.shifts & KB_SHIFT_FLAG) ? true: false);
executeCmd(cmd, keymsg->ascii(),
(msg->shiftPressed()) ? true: false);
return true;
}
break;
case kMouseDownMessage:
this->captureMouse();
captureMouse();
case kMouseMoveMessage:
if (this->hasCapture()) {
if (hasCapture()) {
gfx::Point mousePos = static_cast<MouseMessage*>(msg)->position();
const char *text = this->getText();
bool move, is_dirty;
int c, x;
move = true;
is_dirty = false;
bool move = true;
bool is_dirty = false;
/* backward scroll */
if (msg->mouse.x < this->rc->x1) {
// Backward scroll
if (mousePos.x < this->rc->x1) {
if (m_scroll > 0) {
m_caret = --m_scroll;
move = false;
@ -300,8 +301,8 @@ bool Entry::onProcessMessage(Message* msg)
invalidate();
}
}
/* forward scroll */
else if (msg->mouse.x >= this->rc->x2) {
// Forward scroll
else if (mousePos.x >= this->rc->x2) {
if (m_scroll < ustrlen(text)) {
m_scroll++;
x = this->rc->x1 + this->border_width.l;
@ -324,7 +325,7 @@ bool Entry::onProcessMessage(Message* msg)
// Move caret
if (move) {
c = getCaretFromMouse(msg);
c = getCaretFromMouse(static_cast<MouseMessage*>(msg));
if (m_caret != c) {
m_caret = c;
@ -338,7 +339,7 @@ bool Entry::onProcessMessage(Message* msg)
m_recent_focused = false;
m_select = m_caret;
}
else if (msg->type == kMouseDownMessage)
else if (msg->type() == kMouseDownMessage)
m_select = m_caret;
// Show the caret
@ -352,8 +353,8 @@ bool Entry::onProcessMessage(Message* msg)
break;
case kMouseUpMessage:
if (this->hasCapture())
this->releaseMouse();
if (hasCapture())
releaseMouse();
return true;
case kDoubleClickMessage:
@ -366,7 +367,7 @@ bool Entry::onProcessMessage(Message* msg)
case kMouseEnterMessage:
case kMouseLeaveMessage:
/* TODO theme stuff */
if (this->isEnabled())
if (isEnabled())
invalidate();
break;
}
@ -409,11 +410,11 @@ void Entry::onEntryChange()
EntryChange();
}
int Entry::getCaretFromMouse(Message* msg)
int Entry::getCaretFromMouse(MouseMessage* mousemsg)
{
int c, x, w, mx, caret = m_caret;
mx = msg->mouse.x;
mx = mousemsg->position().x;
mx = MID(this->rc->x1+this->border_width.l,
mx,
this->rc->x2-this->border_width.r-1);
@ -440,7 +441,7 @@ int Entry::getCaretFromMouse(Message* msg)
void Entry::executeCmd(EntryCmd::Type cmd, int ascii, bool shift_pressed)
{
std::string text = this->getText();
std::string text = getText();
int c, selbeg, selend;
getEntryThemeInfo(NULL, NULL, NULL, &selbeg, &selend);

View File

@ -14,6 +14,8 @@
namespace ui {
class MouseMessage;
class Entry : public Widget
{
public:
@ -71,7 +73,7 @@ namespace ui {
};
};
int getCaretFromMouse(Message* msg);
int getCaretFromMouse(MouseMessage* mousemsg);
void executeCmd(EntryCmd::Type cmd, int ascii, bool shift_pressed);
void forwardWord();
void backwardWord();

View File

@ -28,6 +28,7 @@
#include "ui/hit_test_event.h"
#include "ui/image_view.h"
#include "ui/init_theme_event.h"
#include "ui/keys.h"
#include "ui/label.h"
#include "ui/layout_io.h"
#include "ui/link_label.h"
@ -39,6 +40,7 @@
#include "ui/message.h"
#include "ui/message_loop.h"
#include "ui/message_type.h"
#include "ui/mouse_buttons.h"
#include "ui/overlay.h"
#include "ui/overlay_manager.h"
#include "ui/paint_event.h"

View File

@ -56,7 +56,7 @@ void IntEntry::setValue(int value)
bool IntEntry::onProcessMessage(Message* msg)
{
switch (msg->type) {
switch (msg->type()) {
// When the mouse enter in this entry, it got the focus and the
// text is automatically selected.

16
src/ui/keys.cpp Normal file
View File

@ -0,0 +1,16 @@
// ASEPRITE gui library
// Copyright (C) 2001-2013 David Capello
//
// This source file is distributed under a BSD-like license, please
// read LICENSE.txt for more information.
#include "config.h"
#include "ui/keys.h"
#include <allegro.h>
int ui::scancode_to_ascii(KeyScancode scancode)
{
return ::scancode_to_ascii(scancode);
}

158
src/ui/keys.h Normal file
View File

@ -0,0 +1,158 @@
// ASEPRITE gui library
// Copyright (C) 2001-2013 David Capello
//
// This source file is distributed under a BSD-like license, please
// read LICENSE.txt for more information.
#ifndef UI_KEYS_H_INCLUDED
#define UI_KEYS_H_INCLUDED
namespace ui {
enum KeyModifiers {
kKeyNoneModifier = 0,
kKeyShiftModifier = 1,
kKeyCtrlModifier = 2,
kKeyAltModifier = 4
};
enum KeyScancode {
kKeyNil = 0,
kKeyA = 1,
kKeyB = 2,
kKeyC = 3,
kKeyD = 4,
kKeyE = 5,
kKeyF = 6,
kKeyG = 7,
kKeyH = 8,
kKeyI = 9,
kKeyJ = 10,
kKeyK = 11,
kKeyL = 12,
kKeyM = 13,
kKeyN = 14,
kKeyO = 15,
kKeyP = 16,
kKeyQ = 17,
kKeyR = 18,
kKeyS = 19,
kKeyT = 20,
kKeyU = 21,
kKeyV = 22,
kKeyW = 23,
kKeyX = 24,
kKeyY = 25,
kKeyZ = 26,
kKey0 = 27,
kKey1 = 28,
kKey2 = 29,
kKey3 = 30,
kKey4 = 31,
kKey5 = 32,
kKey6 = 33,
kKey7 = 34,
kKey8 = 35,
kKey9 = 36,
kKey0Pad = 37,
kKey1Pad = 38,
kKey2Pad = 39,
kKey3Pad = 40,
kKey4Pad = 41,
kKey5Pad = 42,
kKey6Pad = 43,
kKey7Pad = 44,
kKey8Pad = 45,
kKey9Pad = 46,
kKeyF1 = 47,
kKeyF2 = 48,
kKeyF3 = 49,
kKeyF4 = 50,
kKeyF5 = 51,
kKeyF6 = 52,
kKeyF7 = 53,
kKeyF8 = 54,
kKeyF9 = 55,
kKeyF10 = 56,
kKeyF11 = 57,
kKeyF12 = 58,
kKeyEsc = 59,
kKeyTilde = 60,
kKeyMinus = 61,
kKeyEquals = 62,
kKeyBackspace = 63,
kKeyTab = 64,
kKeyOpenbrace = 65,
kKeyClosebrace = 66,
kKeyEnter = 67,
kKeyColon = 68,
kKeyQuote = 69,
kKeyBackslash = 70,
kKeyBackslash2 = 71,
kKeyComma = 72,
kKeyStop = 73,
kKeySlash = 74,
kKeySpace = 75,
kKeyInsert = 76,
kKeyDel = 77,
kKeyHome = 78,
kKeyEnd = 79,
kKeyPageUp = 80,
kKeyPageDown = 81,
kKeyLeft = 82,
kKeyRight = 83,
kKeyUp = 84,
kKeyDown = 85,
kKeySlashPad = 86,
kKeyAsterisk = 87,
kKeyMinusPad = 88,
kKeyPlusPad = 89,
kKeyDelPad = 90,
kKeyEnterPad = 91,
kKeyPrtscr = 92,
kKeyPause = 93,
kKeyAbntC1 = 94,
kKeyYen = 95,
kKeyKana = 96,
kKeyConvert = 97,
kKeyNoconvert = 98,
kKeyAt = 99,
kKeyCircumflex = 100,
kKeyColon2 = 101,
kKeyKanji = 102,
kKeyEqualsPad = 103, // MacOS X
kKeyBackquote = 104, // MacOS X
kKeySemicolon = 105, // MacOS X
kKeyCommand = 106, // MacOS X
kKeyUnknown1 = 107,
kKeyUnknown2 = 108,
kKeyUnknown3 = 109,
kKeyUnknown4 = 110,
kKeyUnknown5 = 111,
kKeyUnknown6 = 112,
kKeyUnknown7 = 113,
kKeyUnknown8 = 114,
kKeyFirstModifierScancode = 115,
kKeyLShift = 115,
kKeyRShift = 116,
kKeyLControl = 117,
kKeyRControl = 118,
kKeyAlt = 119,
kKeyAltGr = 120,
kKeyLWin = 121,
kKeyRWin = 122,
kKeyMenu = 123,
kKeyScrLock = 124,
kKeyNumLock = 125,
kKeyCapsLock = 126,
kKeyScancodes = 127
};
int scancode_to_ascii(KeyScancode scancode);
} // namespace ui
#endif

View File

@ -34,7 +34,7 @@ void LinkLabel::setUrl(const char* url)
bool LinkLabel::onProcessMessage(Message* msg)
{
switch (msg->type) {
switch (msg->type()) {
case kSetCursorMessage:
// TODO theme stuff

View File

@ -123,7 +123,7 @@ void ListBox::centerScroll()
bool ListBox::onProcessMessage(Message* msg)
{
switch (msg->type) {
switch (msg->type()) {
case kOpenMessage:
centerScroll();
@ -134,6 +134,7 @@ bool ListBox::onProcessMessage(Message* msg)
case kMouseMoveMessage:
if (hasCapture()) {
gfx::Point mousePos = static_cast<MouseMessage*>(msg)->position();
int select = getSelectedIndex();
View* view = View::getView(this);
bool pick_item = true;
@ -141,13 +142,13 @@ bool ListBox::onProcessMessage(Message* msg)
if (view) {
gfx::Rect vp = view->getViewportBounds();
if (msg->mouse.y < vp.y) {
int num = MAX(1, (vp.y - msg->mouse.y) / 8);
if (mousePos.y < vp.y) {
int num = MAX(1, (vp.y - mousePos.y) / 8);
selectIndex(select-num);
pick_item = false;
}
else if (msg->mouse.y >= vp.y + vp.h) {
int num = MAX(1, (msg->mouse.y - (vp.y+vp.h-1)) / 8);
else if (mousePos.y >= vp.y + vp.h) {
int num = MAX(1, (mousePos.y - (vp.y+vp.h-1)) / 8);
selectIndex(select+num);
pick_item = false;
}
@ -157,10 +158,10 @@ bool ListBox::onProcessMessage(Message* msg)
Widget* picked;
if (view) {
picked = view->getViewport()->pick(msg->mouse.x, msg->mouse.y);
picked = view->getViewport()->pick(mousePos);
}
else {
picked = this->pick(msg->mouse.x, msg->mouse.y);
picked = pick(mousePos);
}
/* if the picked widget is a child of the list, select it */
@ -193,21 +194,22 @@ bool ListBox::onProcessMessage(Message* msg)
int select = getSelectedIndex();
View* view = View::getView(this);
int bottom = MAX(0, getChildren().size()-1);
KeyMessage* keymsg = static_cast<KeyMessage*>(msg);
switch (msg->key.scancode) {
case KEY_UP:
switch (keymsg->scancode()) {
case kKeyUp:
select--;
break;
case KEY_DOWN:
case kKeyDown:
select++;
break;
case KEY_HOME:
case kKeyHome:
select = 0;
break;
case KEY_END:
case kKeyEnd:
select = bottom;
break;
case KEY_PGUP:
case kKeyPageUp:
if (view) {
gfx::Rect vp = view->getViewportBounds();
select -= vp.h / jwidget_get_text_height(this);
@ -215,7 +217,7 @@ bool ListBox::onProcessMessage(Message* msg)
else
select = 0;
break;
case KEY_PGDN:
case kKeyPageDown:
if (view) {
gfx::Rect vp = view->getViewportBounds();
select += vp.h / jwidget_get_text_height(this);
@ -223,12 +225,12 @@ bool ListBox::onProcessMessage(Message* msg)
else
select = bottom;
break;
case KEY_LEFT:
case KEY_RIGHT:
case kKeyLeft:
case kKeyRight:
if (view) {
gfx::Rect vp = view->getViewportBounds();
gfx::Point scroll = view->getViewScroll();
int sgn = (msg->key.scancode == KEY_LEFT) ? -1: 1;
int sgn = (keymsg->scancode() == kKeyLeft) ? -1: 1;
scroll.x += vp.w/2*sgn;

View File

@ -60,7 +60,7 @@ typedef std::list<Message*> Messages;
typedef std::list<Filter*> Filters;
static int double_click_level;
static int double_click_buttons;
static MouseButtons double_click_buttons;
static int double_click_ticks;
static int want_close_stage; /* variable to handle the external
@ -189,7 +189,6 @@ bool Manager::generateMessages()
{
Widget* widget;
Widget* window;
Message* msg;
int c;
// Poll keyboard
@ -243,7 +242,7 @@ bool Manager::generateMessages()
widget = NULL;
UI_FOREACH_WIDGET(mouse_widgets_list, it) {
widget = (*it)->pick(jmouse_x(0), jmouse_y(0));
widget = (*it)->pick(gfx::Point(jmouse_x(0), jmouse_y(0)));
if (widget)
break;
}
@ -269,19 +268,18 @@ bool Manager::generateMessages()
dst = mouse_widget;
// Send the mouse movement message
msg = newMouseMessage(kMouseMoveMessage, dst);
enqueueMessage(msg);
enqueueMessage(newMouseMessage(kMouseMoveMessage, dst,
currentMouseButtons(0)));
generateSetCursorMessage();
}
}
// Mouse wheel
if (jmouse_z(0) != jmouse_z(1)) {
msg = newMouseMessage(kMouseWheelMessage,
capture_widget ? capture_widget:
mouse_widget);
enqueueMessage(msg);
enqueueMessage(newMouseMessage(kMouseWheelMessage,
capture_widget ? capture_widget:
mouse_widget,
currentMouseButtons(0)));
}
// Mouse clicks
@ -291,23 +289,20 @@ bool Manager::generateMessages()
((jmouse_b(1) & 1) == 0 && (jmouse_b(0) & 1) == 1) ||
((jmouse_b(1) & 2) == 0 && (jmouse_b(0) & 2) == 2) ||
((jmouse_b(1) & 4) == 0 && (jmouse_b(0) & 4) == 4);
msg = newMouseMessage(pressed ? kMouseDownMessage:
kMouseUpMessage,
capture_widget ? capture_widget:
mouse_widget);
MessageType msgType = (pressed ? kMouseDownMessage: kMouseUpMessage);
MouseButtons mouseButtons = currentMouseButtons(pressed ? 0: 1);
//////////////////////////////////////////////////////////////////////
// Double Click
if (msg->type == kMouseDownMessage) {
if (msgType == kMouseDownMessage) {
if (double_click_level != DOUBLE_CLICK_NONE) {
/* time out, back to NONE */
// Time out, back to NONE
if (current_ticks - double_click_ticks > DOUBLE_CLICK_TIMEOUT_MSECS) {
double_click_level = DOUBLE_CLICK_NONE;
}
else if (double_click_buttons == msg->mouse.flags) {
else if (double_click_buttons == mouseButtons) {
if (double_click_level == DOUBLE_CLICK_UP) {
msg->type = kDoubleClickMessage;
msgType = kDoubleClickMessage;
}
else {
double_click_level = DOUBLE_CLICK_NONE;
@ -322,17 +317,17 @@ bool Manager::generateMessages()
// This could be the beginning of the state
if (double_click_level == DOUBLE_CLICK_NONE) {
double_click_level = DOUBLE_CLICK_DOWN;
double_click_buttons = msg->mouse.flags;
double_click_buttons = mouseButtons;
double_click_ticks = current_ticks;
}
}
else if (msg->type == kMouseUpMessage) {
else if (msgType == kMouseUpMessage) {
if (double_click_level != DOUBLE_CLICK_NONE) {
// Time out, back to NONE
if (current_ticks - double_click_ticks > DOUBLE_CLICK_TIMEOUT_MSECS) {
double_click_level = DOUBLE_CLICK_NONE;
}
else if (double_click_buttons == msg->mouse.flags) {
else if (double_click_buttons == mouseButtons) {
if (double_click_level == DOUBLE_CLICK_DOWN) {
double_click_level = DOUBLE_CLICK_UP;
double_click_ticks = current_ticks;
@ -347,8 +342,7 @@ bool Manager::generateMessages()
// Handle Z order: Send the window to top (only when you click in
// a window that aren't the desktop).
if (msg->type == kMouseDownMessage &&
!capture_widget && mouse_widget) {
if (msgType == kMouseDownMessage && !capture_widget && mouse_widget) {
// The clicked window
Window* window = mouse_widget->getRoot();
Manager* win_manager = (window ? window->getManager(): NULL);
@ -385,55 +379,64 @@ bool Manager::generateMessages()
setFocus(mouse_widget);
}
enqueueMessage(msg);
enqueueMessage(newMouseMessage(msgType,
capture_widget ? capture_widget:
mouse_widget,
mouseButtons));
}
// Generate Close message when the user press close button on the system window.
if (want_close_stage == STAGE_WANT_CLOSE) {
want_close_stage = STAGE_NORMAL;
msg = jmessage_new(kCloseAppMessage);
jmessage_broadcast_to_children(msg, this);
Message* msg = new Message(kCloseAppMessage);
msg->broadcastToChildren(this);
enqueueMessage(msg);
}
// Generate kKeyDownMessage messages.
while (keypressed()) {
int readkey_value = readkey();
msg = jmessage_new_key_related(kKeyDownMessage, readkey_value);
int repeat = 0;
c = readkey_value >> 8;
if (c >= 0 && c < KEY_MAX) {
old_readed_key[c] = key[c];
msg->key.repeat = key_repeated[c]++;
repeat = key_repeated[c]++;
}
Message* msg = new KeyMessage(kKeyDownMessage,
static_cast<KeyScancode>((readkey_value >> 8) & 0xff),
(readkey_value & 0xff), repeat);
broadcastKeyMsg(msg);
enqueueMessage(msg);
}
for (c=0; c<KEY_MAX; c++) {
if (old_readed_key[c] != key[c]) {
KeyScancode scancode = static_cast<ui::KeyScancode>(c);
// Generate kKeyUpMessage messages (old key state is activated,
// the new one is deactivated).
if (old_readed_key[c]) {
// Press/release key interface
msg = jmessage_new_key_related(kKeyUpMessage,
(c << 8) | scancode_to_ascii(c));
Message* msg = new KeyMessage(kKeyUpMessage,
scancode,
scancode_to_ascii(scancode), 0);
old_readed_key[c] = key[c];
key_repeated[c] = 0;
broadcastKeyMsg(msg);
enqueueMessage(msg);
}
/* generate kKeyDownMessage messages for modifiers */
else if (c >= KEY_MODIFIERS) {
/* press/release key interface */
msg = jmessage_new_key_related(kKeyDownMessage,
(c << 8) | scancode_to_ascii(c));
// Generate kKeyDownMessage messages for modifiers
else if (c >= kKeyFirstModifierScancode) {
// Press/release key interface
Message* msg = new KeyMessage(kKeyDownMessage,
scancode,
scancode_to_ascii(scancode),
key_repeated[c]++);
old_readed_key[c] = key[c];
msg->key.repeat = key_repeated[c]++;
broadcastKeyMsg(msg);
enqueueMessage(msg);
@ -456,8 +459,8 @@ bool Manager::generateMessages()
void Manager::dispatchMessages()
{
// Add the "Queue Processing" message for the manager.
Message* msg = newMouseMessage(kQueueProcessingMessage, this);
enqueueMessage(msg);
enqueueMessage(newMouseMessage(kQueueProcessingMessage, this,
currentMouseButtons(0)));
pumpQueue();
}
@ -479,7 +482,7 @@ void Manager::enqueueMessage(Message* msg)
ASSERT(msg != NULL);
// Check if this message must be filtered by some widget before
c = msg->type;
c = msg->type();
if (c >= kFirstRegisteredMessage)
c = kFirstRegisteredMessage;
@ -488,16 +491,15 @@ void Manager::enqueueMessage(Message* msg)
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);
if (msg->type() == filter->message)
msg->prependRecipient(filter->widget);
}
}
// There are a destination widget at least?
if (!msg->any.widgets->empty())
if (msg->hasRecipients())
msg_queue.push_back(msg);
else
jmessage_free(msg);
delete msg;
}
Window* Manager::getTopWindow()
@ -541,7 +543,6 @@ void Manager::setFocus(Widget* widget)
&& someParentIsFocusStop(widget)))) {
WidgetsList widget_parents;
Widget* common_parent = NULL;
Message* msg;
if (widget)
widget->getParents(false, widget_parents);
@ -550,7 +551,8 @@ void Manager::setFocus(Widget* widget)
if (focus_widget) {
WidgetsList focus_parents;
focus_widget->getParents(true, focus_parents);
msg = jmessage_new(kFocusLeaveMessage);
Message* msg = new Message(kFocusLeaveMessage);
UI_FOREACH_WIDGET(focus_parents, it) {
if (widget) {
@ -566,7 +568,7 @@ void Manager::setFocus(Widget* widget)
if ((*it)->hasFocus()) {
(*it)->flags &= ~JI_HASFOCUS;
jmessage_add_dest(msg, *it);
msg->addRecipient(*it);
}
}
@ -588,7 +590,7 @@ void Manager::setFocus(Widget* widget)
else
it = widget_parents.begin();
msg = jmessage_new(kFocusEnterMessage);
Message* msg = new Message(kFocusEnterMessage);
for (; it != widget_parents.end(); ++it) {
Widget* w = *it;
@ -596,7 +598,7 @@ void Manager::setFocus(Widget* widget)
if (w->flags & JI_FOCUSSTOP) {
w->flags |= JI_HASFOCUS;
jmessage_add_dest(msg, w);
msg->addRecipient(w);
}
}
@ -610,7 +612,6 @@ void Manager::setMouse(Widget* widget)
if ((mouse_widget != widget) && (!capture_widget)) {
WidgetsList widget_parents;
Widget* common_parent = NULL;
Message* msg;
if (widget)
widget->getParents(false, widget_parents);
@ -619,7 +620,8 @@ void Manager::setMouse(Widget* widget)
if (mouse_widget) {
WidgetsList mouse_parents;
mouse_widget->getParents(true, mouse_parents);
msg = jmessage_new(kMouseLeaveMessage);
Message* msg = new Message(kMouseLeaveMessage);
UI_FOREACH_WIDGET(mouse_parents, it) {
if (widget) {
@ -635,7 +637,7 @@ void Manager::setMouse(Widget* widget)
if ((*it)->hasMouse()) {
(*it)->flags &= ~JI_HASMOUSE;
jmessage_add_dest(msg, *it);
msg->addRecipient(*it);
}
}
@ -657,11 +659,11 @@ void Manager::setMouse(Widget* widget)
else
it = widget_parents.begin();
msg = jmessage_new(kMouseEnterMessage);
Message* msg = new Message(kMouseEnterMessage);
for (; it != widget_parents.end(); ++it) {
(*it)->flags |= JI_HASMOUSE;
jmessage_add_dest(msg, *it);
msg->addRecipient(*it);
}
enqueueMessage(msg);
@ -740,17 +742,18 @@ void Manager::removeMessagesFor(Widget* widget)
{
for (Messages::iterator it=msg_queue.begin(), end=msg_queue.end();
it != end; ++it)
removeWidgetFromDests(widget, *it);
removeWidgetFromRecipients(widget, *it);
}
void Manager::removeMessagesForTimer(Timer* timer)
{
for (Messages::iterator it=msg_queue.begin(); it != msg_queue.end(); ) {
Message* message = *it;
if (!message->any.used &&
message->any.type == kTimerMessage &&
message->timer.timer == timer) {
jmessage_free(message);
Message* msg = *it;
if (!msg->isUsed() &&
msg->type() == kTimerMessage &&
static_cast<TimerMessage*>(msg)->timer() == timer) {
delete msg;
it = msg_queue.erase(it);
}
else
@ -813,8 +816,8 @@ void Manager::_openWindow(Window* window)
insertChild(0, window);
// Broadcast the open message.
Message* msg = jmessage_new(kOpenMessage);
jmessage_add_dest(msg, window);
Message* msg = new Message(kOpenMessage);
msg->addRecipient(window);
enqueueMessage(msg);
// Update the new windows list to show.
@ -862,8 +865,8 @@ void Manager::_closeWindow(Window* window, bool redraw_background)
window->setVisible(false);
// Close message.
msg = jmessage_new(kCloseMessage);
jmessage_add_dest(msg, window);
msg = new Message(kCloseMessage);
msg->addRecipient(window);
enqueueMessage(msg);
// Update manager list stuff.
@ -881,12 +884,13 @@ void Manager::_closeWindow(Window* window, bool redraw_background)
bool Manager::onProcessMessage(Message* msg)
{
switch (msg->type) {
switch (msg->type()) {
case kKeyDownMessage:
case kKeyUpMessage: {
msg->key.propagate_to_children = true;
msg->key.propagate_to_parent = false;
KeyMessage* keymsg = static_cast<KeyMessage*>(msg);
keymsg->setPropagateToChildren(true);
keymsg->setPropagateToParent(false);
// Continue sending the message to the children of all windows
// (until a desktop or foreground window).
@ -904,7 +908,7 @@ bool Manager::onProcessMessage(Message* msg)
}
// Check the focus movement.
if (msg->type == kKeyDownMessage)
if (msg->type() == kKeyDownMessage)
move_focus(this, msg);
return true;
@ -992,23 +996,23 @@ void Manager::pumpQueue()
Message* msg = *it;
// Go to next message
if (msg->any.used) {
if (msg->isUsed()) {
++it;
continue;
}
// This message is in use
msg->any.used = true;
msg->markAsUsed();
Message* first_msg = msg;
// Call Timer::tick() if this is a tick message.
if (msg->type == kTimerMessage) {
if (msg->type() == kTimerMessage) {
ASSERT(msg->timer.timer != NULL);
msg->timer.timer->tick();
static_cast<TimerMessage*>(msg)->timer()->tick();
}
bool done = false;
UI_FOREACH_WIDGET(*msg->any.widgets, it2) {
UI_FOREACH_WIDGET(msg->recipients(), it2) {
Widget* widget = *it2;
if (!widget)
continue;
@ -1048,35 +1052,40 @@ void Manager::pumpQueue()
}
#endif
/* draw message? */
if (msg->type == kPaintMessage) {
/* hidden? */
// We need to configure the clip region for paint messages
// before we call Widget::sendMessage().
if (msg->type() == kPaintMessage) {
if (widget->flags & JI_HIDDEN)
continue;
PaintMessage* paintMsg = static_cast<PaintMessage*>(msg);
jmouse_hide();
acquire_bitmap(ji_screen);
/* set clip */
ASSERT(get_clip_state(ji_screen));
set_clip_rect(ji_screen,
msg->draw.rect.x1, msg->draw.rect.y1,
msg->draw.rect.x2-1, msg->draw.rect.y2-1);
paintMsg->rect().x,
paintMsg->rect().y,
paintMsg->rect().x2()-1,
paintMsg->rect().y2()-1);
#ifdef REPORT_EVENTS
printf(" - clip(%d, %d, %d, %d)\n",
msg->draw.rect.x1, msg->draw.rect.y1,
msg->draw.rect.x2-1, msg->draw.rect.y2-1);
paintMsg->rect().x,
paintMsg->rect().y,
paintMsg->rect().x2()-1,
paintMsg->rect().y2()-1);
fflush(stdout);
#endif
dirty_display_flag = true;
}
/* call message handler */
// Call the message handler
done = widget->sendMessage(msg);
/* restore clip */
if (msg->type == kPaintMessage) {
// Restore clip region for paint messages.
if (msg->type() == kPaintMessage) {
set_clip_rect(ji_screen, 0, 0, JI_SCREEN_W-1, JI_SCREEN_H-1);
release_bitmap(ji_screen);
@ -1091,7 +1100,7 @@ void Manager::pumpQueue()
it = msg_queue.erase(it);
// Destroy the message
jmessage_free(first_msg);
delete first_msg;
}
}
@ -1153,30 +1162,22 @@ void Manager::collectGarbage()
void Manager::generateSetCursorMessage()
{
Widget* dst;
Message* msg;
if (capture_widget)
dst = capture_widget;
else
dst = mouse_widget;
if (dst) {
msg = newMouseMessage(kSetCursorMessage, dst);
enqueueMessage(msg);
}
if (dst)
enqueueMessage(newMouseMessage(kSetCursorMessage, dst,
currentMouseButtons(0)));
else
jmouse_set_cursor(kArrowCursor);
}
// static
void Manager::removeWidgetFromDests(Widget* widget, Message* msg)
void Manager::removeWidgetFromRecipients(Widget* widget, Message* msg)
{
for (WidgetsList::iterator
it = msg->any.widgets->begin(),
end = msg->any.widgets->end(); it != end; ++it) {
if (*it == widget)
*it = NULL;
}
msg->removeRecipient(widget);
}
// static
@ -1209,40 +1210,40 @@ Widget* Manager::findMagneticWidget(Widget* widget)
}
// static
Message* Manager::newMouseMessage(MessageType type, Widget* widget)
Message* Manager::newMouseMessage(MessageType type, Widget* widget,
MouseButtons buttons)
{
Message* msg = jmessage_new(type);
if (!msg)
return NULL;
msg->mouse.x = jmouse_x(0);
msg->mouse.y = jmouse_y(0);
msg->mouse.flags = (type == kMouseUpMessage ? jmouse_b(1):
jmouse_b(0));
msg->mouse.left = ((jmouse_b(0) & 1) != (jmouse_b(1) & 1));
msg->mouse.right = ((jmouse_b(0) & 2) != (jmouse_b(1) & 2));
msg->mouse.middle = ((jmouse_b(0) & 4) != (jmouse_b(1) & 4));
Message* msg =
new MouseMessage(type, buttons,
gfx::Point(jmouse_x(0),
jmouse_y(0)));
if (widget != NULL)
jmessage_add_dest(msg, widget);
msg->addRecipient(widget);
return msg;
}
// static
MouseButtons Manager::currentMouseButtons(int antique)
{
return jmouse_b(antique);
}
// static
void Manager::broadcastKeyMsg(Message* msg)
{
// Send the message to the widget with capture
if (capture_widget) {
jmessage_add_dest(msg, capture_widget);
msg->addRecipient(capture_widget);
}
// Send the msg to the focused widget
else if (focus_widget) {
jmessage_add_dest(msg, focus_widget);
msg->addRecipient(focus_widget);
}
// Finally, send the message to the manager, it'll know what to do
else {
jmessage_add_dest(msg, this);
msg->addRecipient(this);
}
}
@ -1290,32 +1291,32 @@ static bool move_focus(Manager* manager, Message* msg)
list[c++] = it;
}
/* depend of the pressed key */
switch (msg->key.scancode) {
// Depending on the pressed key...
switch (static_cast<KeyMessage*>(msg)->scancode()) {
case KEY_TAB:
/* reverse tab */
if (msg->any.shifts & (KB_SHIFT_FLAG | KB_CTRL_FLAG | KB_ALT_FLAG)) {
case kKeyTab:
// Reverse tab
if ((msg->keyModifiers() & (kKeyShiftModifier | kKeyCtrlModifier | kKeyAltModifier)) != 0) {
focus = list[count-1];
}
/* normal tab */
// Normal tab
else if (count > 1) {
focus = list[1];
}
ret = true;
break;
/* arrow keys */
case KEY_LEFT: if (!cmp) cmp = cmp_left;
case KEY_RIGHT: if (!cmp) cmp = cmp_right;
case KEY_UP: if (!cmp) cmp = cmp_up;
case KEY_DOWN: if (!cmp) cmp = cmp_down;
// Arrow keys
case kKeyLeft: if (!cmp) cmp = cmp_left;
case kKeyRight: if (!cmp) cmp = cmp_right;
case kKeyUp: if (!cmp) cmp = cmp_up;
case kKeyDown: if (!cmp) cmp = cmp_down;
/* more than one widget */
// More than one widget
if (count > 1) {
int i, j, x, y;
/* position where the focus come */
// Position where the focus come
x = ((focus_widget) ? focus_widget->rc->x1+focus_widget->rc->x2:
window->rc->x1+window->rc->x2)
/ 2;
@ -1325,10 +1326,10 @@ static bool move_focus(Manager* manager, Message* msg)
c = focus_widget ? 1: 0;
/* rearrange the list */
// Rearrange the list
for (i=c; i<count-1; i++) {
for (j=i+1; j<count; j++) {
/* sort the list in ascending order */
// Sort the list in ascending order
if ((*cmp) (list[i], x, y) > (*cmp) (list[j], x, y)) {
Widget* tmp = list[i];
list[i] = list[j];
@ -1337,12 +1338,11 @@ static bool move_focus(Manager* manager, Message* msg)
}
}
/* check if the new widget to put the focus is not
in the wrong way */
// Check if the new widget to put the focus is not in the wrong way.
if ((*cmp) (list[c], x, y) < INT_MAX)
focus = list[c];
}
/* if only there are one widget, put the focus in this */
// If only there are one widget, put the focus in this
else
focus = list[0];

View File

@ -9,6 +9,7 @@
#include "base/compiler_specific.h"
#include "ui/message_type.h"
#include "ui/mouse_buttons.h"
#include "ui/widget.h"
namespace she { class Display; }
@ -83,10 +84,13 @@ namespace ui {
private:
void pumpQueue();
void generateSetCursorMessage();
static void removeWidgetFromDests(Widget* widget, Message* msg);
static void removeWidgetFromRecipients(Widget* widget, Message* msg);
static bool someParentIsFocusStop(Widget* widget);
static Widget* findMagneticWidget(Widget* widget);
static Message* newMouseMessage(MessageType type, Widget* destination);
static Message* newMouseMessage(MessageType type, Widget* destination,
MouseButtons mouseButtons);
static MouseButtons currentMouseButtons(int antique);
void broadcastKeyMsg(Message* msg);
static Manager* m_defaultManager;

View File

@ -6,14 +6,12 @@
#include "config.h"
#include <allegro.h>
#include <ctype.h>
#include <stdio.h>
#include "gfx/size.h"
#include "ui/gui.h"
#include "ui/intern.h"
#include <cctype>
static const int kTimeoutToOpenSubmenu = 250;
using namespace gfx;
@ -23,24 +21,43 @@ namespace ui {
//////////////////////////////////////////////////////////////////////
// Internal messages: to move between menus
// Extra fields for the kOpenMenuItemMessage message:
// bool select_first = msg->user.a;
// If this value is true, it means that after opening the menu, we
// have to select the first item (i.e. highlighting it).
RegisterMessage kOpenMenuItemMessage;
// Extra fields for the kCloseMenuItemMessage message:
// bool last_of_close_chain = msg->user.a;
// This fields is used to indicate the end of a sequence of
// kOpenMenuItemMessage and kCloseMenuItemMessage messages. If it is true
// the message is the last one of the chain, which means that no
// more kOpenMenuItemMessage or kCloseMenuItemMessage messages are in the queue.
RegisterMessage kCloseMenuItemMessage;
RegisterMessage kClosePopupMessage;
RegisterMessage kExecuteMenuItemMessage;
class OpenMenuItemMessage : public Message {
public:
OpenMenuItemMessage(bool select_first) :
Message(kOpenMenuItemMessage),
m_select_first(select_first) {
}
// If this value is true, it means that after opening the menu, we
// have to select the first item (i.e. highlighting it).
bool select_first() const { return m_select_first; }
private:
bool m_select_first;
};
class CloseMenuItemMessage : public Message {
public:
CloseMenuItemMessage(bool last_of_close_chain) :
Message(kCloseMenuItemMessage),
m_last_of_close_chain(last_of_close_chain) {
}
// This fields is used to indicate the end of a sequence of
// kOpenMenuItemMessage and kCloseMenuItemMessage messages. If it is true
// the message is the last one of the chain, which means that no
// more kOpenMenuItemMessage or kCloseMenuItemMessage messages are in the queue.
bool last_of_close_chain() const { return m_last_of_close_chain; }
private:
bool m_last_of_close_chain;
};
// Data for the main jmenubar or the first popuped-jmenubox
struct MenuBaseData
{
@ -81,7 +98,7 @@ public:
protected:
bool onProcessMessage(Message* msg) OVERRIDE
{
switch (msg->type) {
switch (msg->type()) {
case kCloseMessage:
// Delete this window automatically
@ -99,7 +116,6 @@ static MenuBaseData* get_base(Widget* widget);
static bool window_msg_proc(Widget* widget, Message* msg);
static MenuItem* check_for_letter(Menu* menu, int ascii);
static MenuItem* check_for_accel(Menu* menu, Message* msg);
static MenuItem* find_nextitem(Menu* menu, MenuItem* menuitem);
static MenuItem* find_previtem(Menu* menu, MenuItem* menuitem);
@ -251,7 +267,7 @@ void Menu::showPopup(int x, int y)
{
do {
jmouse_poll();
} while (jmouse_b(0));
} while (jmouse_b(0) != kButtonNone);
// New window and new menu-box
Window* window = new Window(false, NULL);
@ -348,25 +364,28 @@ bool MenuBox::onProcessMessage(Message* msg)
{
Menu* menu = MenuBox::getMenu();
switch (msg->type) {
switch (msg->type()) {
case kMouseMoveMessage:
/* isn't pressing a button? */
if (!msg->mouse.flags && !get_base(this)->was_clicked)
// Isn't pressing a button?
if (static_cast<MouseMessage*>(msg)->buttons() == kButtonNone &&
!get_base(this)->was_clicked)
break;
// Fall though
// Fall through
case kMouseDownMessage:
if (menu) {
if (get_base(this)->is_processing)
break;
gfx::Point mousePos = static_cast<MouseMessage*>(msg)->position();
// Here we catch the filtered messages (menu-bar or the
// popuped menu-box) to detect if the user press outside of
// the widget
if (msg->type == kMouseDownMessage && m_base != NULL) {
Widget* picked = getManager()->pick(msg->mouse.x, msg->mouse.y);
if (msg->type() == kMouseDownMessage && m_base != NULL) {
Widget* picked = getManager()->pick(mousePos);
// If one of these conditions are accomplished we have to
// close all menus (back to menu-bar or close the popuped
@ -388,7 +407,7 @@ bool MenuBox::onProcessMessage(Message* msg)
}
// Get the widget below the mouse cursor
Widget* picked = menu->pick(msg->mouse.x, msg->mouse.y);
Widget* picked = menu->pick(mousePos);
if (picked) {
if ((picked->type == kMenuItemWidget) &&
!(picked->flags & JI_DISABLED)) {
@ -399,14 +418,14 @@ bool MenuBox::onProcessMessage(Message* msg)
// open the submenu only if the user does click
bool open_submenu =
(this->type == kMenuBarWidget) ||
(msg->type == kMouseDownMessage);
(msg->type() == kMouseDownMessage);
menu->highlightItem(static_cast<MenuItem*>(picked), false, open_submenu, false);
}
// If the user pressed in a highlighted menu-item (maybe
// the user was waiting for the timer to open the
// submenu...)
else if (msg->type == kMouseDownMessage &&
else if (msg->type() == kMouseDownMessage &&
static_cast<MenuItem*>(picked)->hasSubmenu()) {
static_cast<MenuItem*>(picked)->stopTimer();
@ -459,10 +478,10 @@ bool MenuBox::onProcessMessage(Message* msg)
get_base(this)->was_clicked = false;
// Check for ALT+some underlined letter
if (((this->type == kMenuBoxWidget) && (msg->any.shifts == 0 || // Inside menu-boxes we can use letters without Alt modifier pressed
msg->any.shifts == KB_ALT_FLAG)) ||
((this->type == kMenuBarWidget) && (msg->any.shifts == KB_ALT_FLAG))) {
selected = check_for_letter(menu, scancode_to_ascii(msg->key.scancode));
if (((this->type == kMenuBoxWidget) && (msg->keyModifiers() == kKeyNoneModifier || // <-- Inside menu-boxes we can use letters without Alt modifier pressed
msg->keyModifiers() == kKeyAltModifier)) ||
((this->type == kMenuBarWidget) && (msg->keyModifiers() == kKeyAltModifier))) {
selected = check_for_letter(menu, ui::scancode_to_ascii(static_cast<KeyMessage*>(msg)->scancode()));
if (selected) {
menu->highlightItem(selected, true, true, true);
return true;
@ -488,9 +507,9 @@ bool MenuBox::onProcessMessage(Message* msg)
if (!highlight && child_with_submenu_opened)
highlight = child_with_submenu_opened;
switch (msg->key.scancode) {
switch (static_cast<KeyMessage*>(msg)->scancode()) {
case KEY_ESC:
case kKeyEsc:
// In menu-bar
if (this->type == kMenuBarWidget) {
if (highlight) {
@ -513,7 +532,7 @@ bool MenuBox::onProcessMessage(Message* msg)
}
break;
case KEY_UP:
case kKeyUp:
// In menu-bar
if (this->type == kMenuBarWidget) {
if (child_with_submenu_opened)
@ -528,7 +547,7 @@ bool MenuBox::onProcessMessage(Message* msg)
used = true;
break;
case KEY_DOWN:
case kKeyDown:
// In menu-bar
if (this->type == kMenuBarWidget) {
// Select the active menu
@ -543,7 +562,7 @@ bool MenuBox::onProcessMessage(Message* msg)
used = true;
break;
case KEY_LEFT:
case kKeyLeft:
// In menu-bar
if (this->type == kMenuBarWidget) {
// Go to previous
@ -576,7 +595,7 @@ bool MenuBox::onProcessMessage(Message* msg)
used = true;
break;
case KEY_RIGHT:
case kKeyRight:
// In menu-bar
if (this->type == kMenuBarWidget) {
// Go to next
@ -605,8 +624,8 @@ bool MenuBox::onProcessMessage(Message* msg)
used = true;
break;
case KEY_ENTER:
case KEY_ENTER_PAD:
case kKeyEnter:
case kKeyEnterPad:
if (highlight)
menu->highlightItem(highlight, true, true, true);
used = true;
@ -618,7 +637,7 @@ bool MenuBox::onProcessMessage(Message* msg)
return true;
}
// If the user presses the ALT key we close everything.
else if (msg->key.scancode == KEY_ALT) {
else if (static_cast<KeyMessage*>(msg)->scancode() == kKeyAlt) {
cancelMenuLoop();
}
}
@ -626,8 +645,8 @@ bool MenuBox::onProcessMessage(Message* msg)
break;
default:
if (msg->type == kClosePopupMessage) {
this->getManager()->_closeWindow(this->getRoot(), true);
if (msg->type() == kClosePopupMessage) {
getManager()->_closeWindow(getRoot(), true);
}
break;
@ -659,7 +678,7 @@ void MenuBox::onPreferredSize(PreferredSizeEvent& ev)
bool MenuItem::onProcessMessage(Message* msg)
{
switch (msg->type) {
switch (msg->type()) {
case kMouseEnterMessage:
// TODO theme specific!!
@ -682,9 +701,9 @@ bool MenuItem::onProcessMessage(Message* msg)
break;
default:
if (msg->type == kOpenMenuItemMessage) {
if (msg->type() == kOpenMenuItemMessage) {
MenuBaseData* base = get_base(this);
bool select_first = msg->user.a ? true: false;
bool select_first = static_cast<OpenMenuItemMessage*>(msg)->select_first();
ASSERT(base != NULL);
ASSERT(base->is_processing);
@ -770,10 +789,10 @@ bool MenuItem::onProcessMessage(Message* msg)
return true;
}
else if (msg->type == kCloseMenuItemMessage) {
else if (msg->type() == kCloseMenuItemMessage) {
bool last_of_close_chain = static_cast<CloseMenuItemMessage*>(msg)->last_of_close_chain();
MenuBaseData* base = get_base(this);
Window* window;
bool last_of_close_chain = (msg->user.a ? true: false);
ASSERT(base != NULL);
ASSERT(base->is_processing);
@ -811,14 +830,14 @@ bool MenuItem::onProcessMessage(Message* msg)
stopTimer();
return true;
}
else if (msg->type == kExecuteMenuItemMessage) {
else if (msg->type() == kExecuteMenuItemMessage) {
onClick();
return true;
}
break;
case kTimerMessage:
if (msg->timer.timer == m_submenu_timer.get()) {
if (static_cast<TimerMessage*>(msg)->timer() == m_submenu_timer.get()) {
MenuBaseData* base = get_base(this);
ASSERT(hasSubmenu());
@ -1008,9 +1027,8 @@ void MenuItem::openSubmenu(bool select_first)
}
}
msg = jmessage_new(kOpenMenuItemMessage);
msg->user.a = select_first;
jmessage_add_dest(msg, this);
msg = new OpenMenuItemMessage(select_first);
msg->addRecipient(this);
Manager::getDefault()->enqueueMessage(msg);
// Get the 'base'
@ -1054,9 +1072,8 @@ void MenuItem::closeSubmenu(bool last_of_close_chain)
}
// Second: now we can close the 'menuitem'
msg = jmessage_new(kCloseMenuItemMessage);
msg->user.a = last_of_close_chain;
jmessage_add_dest(msg, this);
msg = new CloseMenuItemMessage(last_of_close_chain);
msg->addRecipient(this);
Manager::getDefault()->enqueueMessage(msg);
// If this is the last message of the chain, here we have the
@ -1130,8 +1147,8 @@ void Menu::closeAll()
void MenuBox::closePopup()
{
Message* msg = jmessage_new(kClosePopupMessage);
jmessage_add_dest(msg, this);
Message* msg = new Message(kClosePopupMessage);
msg->addRecipient(this);
Manager::getDefault()->enqueueMessage(msg);
}
@ -1154,8 +1171,8 @@ void MenuBox::cancelMenuLoop()
void MenuItem::executeClick()
{
// Send the message
Message* msg = jmessage_new(kExecuteMenuItemMessage);
jmessage_add_dest(msg, this);
Message* msg = new Message(kExecuteMenuItemMessage);
msg->addRecipient(this);
Manager::getDefault()->enqueueMessage(msg);
}
@ -1174,30 +1191,6 @@ static MenuItem* check_for_letter(Menu* menu, int ascii)
return NULL;
}
static MenuItem* check_for_accel(Menu* menu, Message* msg)
{
UI_FOREACH_WIDGET(menu->getChildren(), it) {
Widget* child = *it;
if (child->type != kMenuItemWidget)
continue;
MenuItem* menuitem = static_cast<MenuItem*>(child);
if (menuitem->getSubmenu()) {
if ((menuitem = check_for_accel(menuitem->getSubmenu(), msg)))
return menuitem;
}
else if (menuitem->getAccel()) {
if ((menuitem->isEnabled()) &&
(menuitem->getAccel()->check(msg->any.shifts,
msg->key.ascii,
msg->key.scancode)))
return menuitem;
}
}
return NULL;
}
// Finds the next item of `menuitem', if `menuitem' is NULL searchs
// from the first item in `menu'
static MenuItem* find_nextitem(Menu* menu, MenuItem* menuitem)

View File

@ -18,126 +18,68 @@
namespace ui {
Message* jmessage_new(MessageType type)
Message::Message(MessageType type)
: m_type(type)
, m_used(false)
, m_modifiers((KeyModifiers)((key[KEY_LSHIFT] || key[KEY_RSHIFT] ? kKeyShiftModifier: 0) |
(key[KEY_LCONTROL] || key[KEY_RCONTROL] ? kKeyCtrlModifier: 0) |
(key[KEY_ALT] ? kKeyAltModifier: 0)))
{
Message* msg = new Message;
memset(msg, 0, sizeof(Message));
msg->type = type;
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) |
(key[KEY_ALT] ? KB_ALT_FLAG: 0);
// printf("type=%02d ", type);
// if (msg->any.shifts & KB_SHIFT_FLAG) printf("KB_SHIFT_FLAG ");
// if (msg->any.shifts & KB_CTRL_FLAG) printf("KB_CTRL_FLAG ");
// if (msg->any.shifts & KB_ALT_FLAG) printf("KB_ALT_FLAG ");
// printf("\n");
// fflush(stdout);
return msg;
}
Message* jmessage_new_key_related(MessageType type, int readkey_value)
Message::~Message()
{
Message* msg = jmessage_new(type);
msg->key.scancode = (readkey_value >> 8) & 0xff;
msg->key.ascii = readkey_value & 0xff;
msg->key.repeat = 0;
msg->key.propagate_to_children = false;
msg->key.propagate_to_parent = true;
#if 0
printf("%s: %i %i [%c]\n", type == kKeyDownMessage ? "kKeyDownMessage":
"kKeyUpMessage",
msg->key.scancode, msg->key.ascii, msg->key.ascii);
fflush(stdout);
#endif
return msg;
}
Message* jmessage_new_copy(const Message* msg)
void Message::addRecipient(Widget* widget)
{
Message* copy;
ASSERT(msg != NULL);
copy = new Message;
if (!copy)
return NULL;
memcpy(copy, msg, sizeof(Message));
copy->any.widgets = new WidgetsList(*msg->any.widgets);
copy->any.used = false;
return copy;
}
Message* jmessage_new_copy_without_dests(const Message* msg)
{
ASSERT(msg != NULL);
Message* copy = new Message;
if (!copy)
return NULL;
memcpy(copy, msg, sizeof(Message));
copy->any.widgets = new WidgetsList;
copy->any.used = false;
return copy;
}
void jmessage_free(Message* msg)
{
ASSERT(msg != NULL);
delete msg->any.widgets;
delete msg;
}
void jmessage_add_dest(Message* msg, Widget* widget)
{
ASSERT(msg != NULL);
ASSERT_VALID_WIDGET(widget);
msg->any.widgets->push_back(widget);
m_recipients.push_back(widget);
}
void jmessage_add_pre_dest(Message* msg, Widget* widget)
void Message::prependRecipient(Widget* widget)
{
ASSERT(msg != NULL);
ASSERT_VALID_WIDGET(widget);
msg->any.widgets->insert(msg->any.widgets->begin(), widget);
m_recipients.insert(m_recipients.begin(), widget);
}
void jmessage_broadcast_to_children(Message* msg, Widget* widget)
void Message::removeRecipient(Widget* widget)
{
ASSERT(msg != NULL);
ASSERT_VALID_WIDGET(widget);
UI_FOREACH_WIDGET(widget->getChildren(), it)
jmessage_broadcast_to_children(msg, *it);
jmessage_add_dest(msg, widget);
}
void jmessage_broadcast_to_parents(Message* msg, Widget* widget)
{
ASSERT(msg != NULL);
ASSERT_VALID_WIDGET(widget);
if (widget && widget->type != kManagerWidget) {
jmessage_add_dest(msg, widget);
jmessage_broadcast_to_parents(msg, widget->getParent());
for (WidgetsList::iterator
it = m_recipients.begin(),
end = m_recipients.end(); it != end; ++it) {
if (*it == widget)
*it = NULL;
}
}
void Message::broadcastToChildren(Widget* widget)
{
ASSERT_VALID_WIDGET(widget);
UI_FOREACH_WIDGET(widget->getChildren(), it)
broadcastToChildren(*it);
addRecipient(widget);
}
KeyMessage::KeyMessage(MessageType type, KeyScancode scancode, int ascii, int repeat)
: Message(type)
, m_scancode(scancode)
, m_ascii(ascii)
, m_repeat(repeat)
, m_propagate_to_children(false)
, m_propagate_to_parent(true)
{
}
KeyMessage* create_message_from_readkey_value(MessageType type, int readkey_value)
{
return new KeyMessage(type,
static_cast<KeyScancode>((readkey_value >> 8) & 0xff),
(readkey_value & 0xff), 0);
}
} // namespace ui

View File

@ -7,8 +7,13 @@
#ifndef UI_MESSAGE_H_INCLUDED
#define UI_MESSAGE_H_INCLUDED
#include "base/compiler_specific.h"
#include "gfx/point.h"
#include "gfx/rect.h"
#include "ui/base.h"
#include "ui/keys.h"
#include "ui/message_type.h"
#include "ui/mouse_buttons.h"
#include "ui/rect.h"
#include "ui/widgets_list.h"
@ -17,78 +22,113 @@ namespace ui {
class Timer;
class Widget;
struct MessageAny
class Message
{
MessageType type; // Type of message
WidgetsList* widgets; // Destination widgets
bool used : 1; // Was used
int shifts; // Key shifts pressed when message was created
public:
typedef WidgetsList::iterator& recipients_iterator;
Message(MessageType type);
virtual ~Message();
MessageType type() const { return m_type; }
const WidgetsList& recipients() const { return m_recipients; }
bool hasRecipients() const { return !m_recipients.empty(); }
bool isUsed() const { return m_used; }
void markAsUsed() { m_used = true; }
KeyModifiers keyModifiers() const { return m_modifiers; }
bool shiftPressed() const { return (m_modifiers & kKeyShiftModifier) == kKeyShiftModifier; }
bool ctrlPressed() const { return (m_modifiers & kKeyCtrlModifier) == kKeyCtrlModifier; }
bool altPressed() const { return (m_modifiers & kKeyAltModifier) == kKeyAltModifier; }
bool onlyShiftPressed() const { return (m_modifiers & kKeyShiftModifier) == kKeyShiftModifier; }
bool onlyCtrlPressed() const { return (m_modifiers & kKeyCtrlModifier) == kKeyCtrlModifier; }
bool onlyAltPressed() const { return (m_modifiers & kKeyAltModifier) == kKeyAltModifier; }
void addRecipient(Widget* widget);
void prependRecipient(Widget* widget);
void removeRecipient(Widget* widget);
void broadcastToChildren(Widget* widget);
private:
MessageType m_type; // Type of message
WidgetsList m_recipients; // List of recipients of the message
bool m_used; // Was used
KeyModifiers m_modifiers; // Key modifiers pressed when message was created
};
struct MessageKey
class KeyMessage : public Message
{
MessageAny any;
unsigned scancode : 8; /* Allegro scancode */
unsigned ascii : 8; /* ASCII code */
unsigned repeat; /* repeat=0 means the first time the key is pressed */
bool propagate_to_children : 1;
bool propagate_to_parent : 1;
public:
KeyMessage(MessageType type, KeyScancode scancode, int ascii, int repeat);
KeyScancode scancode() const { return m_scancode; }
int ascii() const { return m_ascii; }
int repeat() const { return m_repeat; }
bool propagateToChildren() const { return m_propagate_to_children; }
bool propagateToParent() const { return m_propagate_to_parent; }
void setPropagateToChildren(bool flag) { m_propagate_to_children = flag; }
void setPropagateToParent(bool flag) { m_propagate_to_parent = flag; }
private:
KeyScancode m_scancode;
int m_ascii;
int m_repeat; // repeat=0 means the first time the key is pressed
bool m_propagate_to_children : 1;
bool m_propagate_to_parent : 1;
};
struct MessageDraw
// Deprecated
KeyMessage* create_message_from_readkey_value(MessageType type, int readkey_value);
class PaintMessage : public Message
{
MessageAny any;
int count; /* cound=0 if it's last msg of draw-chain */
struct jrect rect; /* area to draw */
public:
PaintMessage(int count, const gfx::Rect& rect)
: Message(kPaintMessage), m_count(count), m_rect(rect) {
}
int count() const { return m_count; }
const gfx::Rect& rect() const { return m_rect; }
private:
int m_count; // Cound=0 if it's last msg of draw-chain
gfx::Rect m_rect; // Area to draw
};
struct MessageMouse
class MouseMessage : public Message
{
MessageAny any;
int x, y; /* mouse position */
unsigned flags : 4; /* all buttons */
bool left : 1; /* left button */
bool right : 1; /* right button */
bool middle : 1; /* middle button */
public:
MouseMessage(MessageType type, MouseButtons buttons, const gfx::Point& pos)
: Message(type), m_buttons(buttons), m_pos(pos) {
}
MouseButtons buttons() const { return m_buttons; }
bool left() const { return (m_buttons & kButtonLeft) == kButtonLeft; }
bool right() const { return (m_buttons & kButtonRight) == kButtonRight; }
bool middle() const { return (m_buttons & kButtonMiddle) == kButtonMiddle; }
const gfx::Point& position() const { return m_pos; }
private:
MouseButtons m_buttons; // Pressed buttons
gfx::Point m_pos; // Mouse position
};
struct MessageTimer
class TimerMessage : public Message
{
MessageAny any;
int count; // Accumulated calls
Timer* timer; // Timer handle
public:
TimerMessage(int count, Timer* timer)
: Message(kTimerMessage), m_count(count), m_timer(timer) {
}
int count() const { return m_count; }
Timer* timer() { return m_timer; }
private:
int m_count; // Accumulated calls
Timer* m_timer; // Timer handle
};
struct MessageUser
{
MessageAny any;
int a, b, c;
void *dp;
};
union Message
{
MessageType type;
MessageAny any;
MessageKey key;
MessageDraw draw;
MessageMouse mouse;
MessageTimer timer;
MessageUser user;
};
Message* jmessage_new(MessageType type);
Message* jmessage_new_key_related(MessageType type, int readkey_value);
Message* jmessage_new_copy(const Message* msg);
Message* jmessage_new_copy_without_dests(const Message* msg);
void jmessage_free(Message* msg);
void jmessage_add_dest(Message* msg, Widget* widget);
void jmessage_add_pre_dest(Message* msg, Widget* widget);
void jmessage_broadcast_to_children(Message* msg, Widget* widget);
void jmessage_broadcast_to_parents(Message* msg, Widget* widget);
} // namespace ui
#endif

21
src/ui/mouse_buttons.h Normal file
View File

@ -0,0 +1,21 @@
// ASEPRITE gui library
// Copyright (C) 2001-2013 David Capello
//
// This source file is distributed under a BSD-like license, please
// read LICENSE.txt for more information.
#ifndef UI_MOUSE_BUTTONS_H_INCLUDED
#define UI_MOUSE_BUTTONS_H_INCLUDED
namespace ui {
enum MouseButtons {
kButtonNone = 0,
kButtonLeft = 1,
kButtonRight = 2,
kButtonMiddle = 4
};
} // namespace ui
#endif

View File

@ -66,7 +66,7 @@ void PopupWindow::makeFixed()
bool PopupWindow::onProcessMessage(Message* msg)
{
switch (msg->type) {
switch (msg->type()) {
case kCloseMessage:
stopFilteringMessages();
@ -79,9 +79,12 @@ bool PopupWindow::onProcessMessage(Message* msg)
case kKeyDownMessage:
if (m_filtering) {
if (msg->key.scancode == KEY_ESC ||
msg->key.scancode == KEY_ENTER ||
msg->key.scancode == KEY_ENTER_PAD) {
KeyMessage* keymsg = static_cast<KeyMessage*>(msg);
KeyScancode scancode = keymsg->scancode();
if (scancode == kKeyEsc ||
scancode == kKeyEnter ||
scancode == kKeyEnterPad) {
closeWindow(NULL);
}
@ -97,7 +100,8 @@ bool PopupWindow::onProcessMessage(Message* msg)
// If the user click outside the window, we have to close the
// tooltip window.
if (m_filtering) {
Widget* picked = this->pick(msg->mouse.x, msg->mouse.y);
gfx::Point mousePos = static_cast<MouseMessage*>(msg)->position();
Widget* picked = pick(mousePos);
if (!picked || picked->getRoot() != this) {
closeWindow(NULL);
}
@ -112,9 +116,11 @@ bool PopupWindow::onProcessMessage(Message* msg)
if (!isMoveable() &&
!m_hotRegion.isEmpty() &&
getManager()->getCapture() == NULL) {
gfx::Point mousePos = static_cast<MouseMessage*>(msg)->position();
// If the mouse is outside the hot-region we have to close the
// window.
if (!m_hotRegion.contains(Point(msg->mouse.x, msg->mouse.y)))
if (!m_hotRegion.contains(mousePos))
closeWindow(NULL);
}
break;

View File

@ -32,12 +32,20 @@ ScrollBar::ScrollBar(int align)
void ScrollBar::setPos(int pos)
{
m_pos = pos;
if (m_pos != pos)
{
m_pos = pos;
invalidate();
}
}
void ScrollBar::setSize(int size)
{
m_size = size;
if (m_size != size)
{
m_size = size;
invalidate();
}
}
void ScrollBar::getScrollBarThemeInfo(int* pos, int* len)
@ -48,12 +56,13 @@ void ScrollBar::getScrollBarThemeInfo(int* pos, int* len)
bool ScrollBar::onProcessMessage(Message* msg)
{
#define MOUSE_IN(x1, y1, x2, y2) \
((msg->mouse.x >= (x1)) && (msg->mouse.x <= (x2)) && \
(msg->mouse.y >= (y1)) && (msg->mouse.y <= (y2)))
((mousePos.x >= (x1)) && (mousePos.x <= (x2)) && \
(mousePos.y >= (y1)) && (mousePos.y <= (y2)))
switch (msg->type) {
switch (msg->type()) {
case kMouseDownMessage: {
gfx::Point mousePos = static_cast<MouseMessage*>(msg)->position();
View* view = static_cast<View*>(getParent());
int x1, y1, x2, y2;
int u1, v1, u2, v2;
@ -64,8 +73,8 @@ bool ScrollBar::onProcessMessage(Message* msg)
m_wherepos = pos;
m_whereclick = getAlign() & JI_HORIZONTAL ?
msg->mouse.x:
msg->mouse.y;
mousePos.x:
mousePos.y;
x1 = this->rc->x1;
y1 = this->rc->y1;
@ -125,6 +134,7 @@ bool ScrollBar::onProcessMessage(Message* msg)
case kMouseMoveMessage:
if (hasCapture()) {
gfx::Point mousePos = static_cast<MouseMessage*>(msg)->position();
View* view = static_cast<View*>(getParent());
int pos, len, bar_size, viewport_size;
int old_pos;
@ -136,14 +146,14 @@ bool ScrollBar::onProcessMessage(Message* msg)
Point scroll = view->getViewScroll();
if (this->getAlign() & JI_HORIZONTAL) {
pos = (m_wherepos + msg->mouse.x - m_whereclick);
pos = (m_wherepos + mousePos.x - m_whereclick);
pos = MID(0, pos, bar_size - len);
scroll.x = (m_size - viewport_size) * pos / (bar_size - len);
view->setViewScroll(scroll);
}
else {
pos = (m_wherepos + msg->mouse.y - m_whereclick);
pos = (m_wherepos + mousePos.y - m_whereclick);
pos = MID(0, pos, bar_size - len);
scroll.y = (m_size - viewport_size) * pos / (bar_size - len);

View File

@ -6,8 +6,6 @@
#include "config.h"
#include <allegro.h>
#include "ui/font.h"
#include "ui/manager.h"
#include "ui/message.h"
@ -18,11 +16,13 @@
#include "ui/theme.h"
#include "ui/widget.h"
#include <cstdio>
namespace ui {
static int slider_press_x;
static int slider_press_value;
static int slider_press_left;
static bool slider_press_left;
Slider::Slider(int min, int max, int value)
: Widget(kSliderWidget)
@ -65,7 +65,7 @@ void Slider::getSliderThemeInfo(int* min, int* max, int* value)
bool Slider::onProcessMessage(Message* msg)
{
switch (msg->type) {
switch (msg->type()) {
case kFocusEnterMessage:
case kFocusLeaveMessage:
@ -80,9 +80,12 @@ bool Slider::onProcessMessage(Message* msg)
setSelected(true);
captureMouse();
slider_press_x = msg->mouse.x;
slider_press_value = m_value;
slider_press_left = msg->mouse.left;
{
gfx::Point mousePos = static_cast<MouseMessage*>(msg)->position();
slider_press_x = mousePos.x;
slider_press_value = m_value;
slider_press_left = static_cast<MouseMessage*>(msg)->left();
}
setupSliderCursor();
@ -92,19 +95,20 @@ bool Slider::onProcessMessage(Message* msg)
if (hasCapture()) {
int value, accuracy, range;
gfx::Rect rc = getChildrenBounds();
gfx::Point mousePos = static_cast<MouseMessage*>(msg)->position();
range = m_max - m_min + 1;
// With left click
if (slider_press_left) {
value = m_min + range * (msg->mouse.x - rc.x) / rc.w;
value = m_min + range * (mousePos.x - rc.x) / rc.w;
}
// With right click
else {
accuracy = MID(1, rc.w / range, rc.w);
value = slider_press_value +
(msg->mouse.x - slider_press_x) / accuracy;
(mousePos.x - slider_press_x) / accuracy;
}
value = MID(m_min, value, m_max);
@ -159,7 +163,7 @@ bool Slider::onProcessMessage(Message* msg)
/* /\* TODO switch slider signal *\/ */
/* } */
/* TODO theme stuff */
// TODO theme stuff
if (isEnabled())
invalidate();
break;
@ -170,19 +174,19 @@ bool Slider::onProcessMessage(Message* msg)
int max = m_max;
int value = m_value;
switch (msg->key.scancode) {
case KEY_LEFT: value = MAX(value-1, min); break;
case KEY_RIGHT: value = MIN(value+1, max); break;
case KEY_PGDN: value = MAX(value-(max-min+1)/4, min); break;
case KEY_PGUP: value = MIN(value+(max-min+1)/4, max); break;
case KEY_HOME: value = min; break;
case KEY_END: value = max; break;
switch (static_cast<KeyMessage*>(msg)->scancode()) {
case kKeyLeft: value = MAX(value-1, min); break;
case kKeyRight: value = MIN(value+1, max); break;
case kKeyPageDown: value = MAX(value-(max-min+1)/4, min); break;
case kKeyPageUp: value = MIN(value+(max-min+1)/4, max); break;
case kKeyHome: value = min; break;
case kKeyEnd: value = max; break;
default:
goto not_used;
}
if (m_value != value) {
this->setValue(value);
setValue(value);
onChange();
}
@ -218,14 +222,14 @@ void Slider::onPreferredSize(PreferredSizeEvent& ev)
int w, h, min_w, max_w;
char buf[256];
usprintf(buf, "%d", m_min);
std::sprintf(buf, "%d", m_min);
min_w = ji_font_text_len(this->getFont(), buf);
usprintf(buf, "%d", m_max);
std::sprintf(buf, "%d", m_max);
max_w = ji_font_text_len(this->getFont(), buf);
w = MAX(min_w, max_w);
h = text_height(this->getFont());
h = jwidget_get_text_height(this);
w += this->border_width.l + this->border_width.r;
h += this->border_width.t + this->border_width.b;

View File

@ -48,13 +48,14 @@ void Splitter::setPosition(double pos)
bool Splitter::onProcessMessage(Message* msg)
{
switch (msg->type) {
switch (msg->type()) {
case kMouseDownMessage:
if (isEnabled()) {
Widget* c1, *c2;
int x1, y1, x2, y2;
int bar, click_bar;
gfx::Point mousePos = static_cast<MouseMessage*>(msg)->position();
bar = click_bar = 0;
@ -78,8 +79,8 @@ bool Splitter::onProcessMessage(Message* msg)
y2 = c2->rc->y1;
}
if ((msg->mouse.x >= x1) && (msg->mouse.x < x2) &&
(msg->mouse.y >= y1) && (msg->mouse.y < y2))
if ((mousePos.x >= x1) && (mousePos.x < x2) &&
(mousePos.y >= y1) && (mousePos.y < y2))
click_bar = bar;
}
}
@ -87,33 +88,36 @@ bool Splitter::onProcessMessage(Message* msg)
if (!click_bar)
break;
this->captureMouse();
/* Continue with motion message... */
captureMouse();
// Continue with motion message...
}
else
break;
case kMouseMoveMessage:
if (this->hasCapture()) {
if (this->getAlign() & JI_HORIZONTAL) {
if (hasCapture()) {
gfx::Point mousePos = static_cast<MouseMessage*>(msg)->position();
if (getAlign() & JI_HORIZONTAL) {
switch (m_type) {
case ByPercentage:
m_pos = 100.0 * (msg->mouse.x-this->rc->x1) / jrect_w(this->rc);
m_pos = 100.0 * (mousePos.x-this->rc->x1) / jrect_w(this->rc);
m_pos = MID(0, m_pos, 100);
break;
case ByPixel:
m_pos = msg->mouse.x-this->rc->x1;
m_pos = mousePos.x-this->rc->x1;
break;
}
}
else {
switch (m_type) {
case ByPercentage:
m_pos = 100.0 * (msg->mouse.y-this->rc->y1) / jrect_h(this->rc);
m_pos = 100.0 * (mousePos.y-this->rc->y1) / jrect_h(this->rc);
m_pos = MID(0, m_pos, 100);
break;
case ByPixel:
m_pos = (msg->mouse.y-this->rc->y1);
m_pos = (mousePos.y-this->rc->y1);
break;
}
}
@ -132,6 +136,7 @@ bool Splitter::onProcessMessage(Message* msg)
case kSetCursorMessage:
if (isEnabled()) {
gfx::Point mousePos = static_cast<MouseMessage*>(msg)->position();
Widget* c1, *c2;
int x1, y1, x2, y2;
bool change_cursor = false;
@ -154,8 +159,8 @@ bool Splitter::onProcessMessage(Message* msg)
y2 = c2->rc->y1;
}
if ((msg->mouse.x >= x1) && (msg->mouse.x < x2) &&
(msg->mouse.y >= y1) && (msg->mouse.y < y2)) {
if ((mousePos.x >= x1) && (mousePos.x < x2) &&
(mousePos.y >= y1) && (mousePos.y < y2)) {
change_cursor = true;
break;
}
@ -163,7 +168,7 @@ bool Splitter::onProcessMessage(Message* msg)
}
if (change_cursor) {
if (this->getAlign() & JI_HORIZONTAL)
if (getAlign() & JI_HORIZONTAL)
jmouse_set_cursor(kSizeLCursor);
else
jmouse_set_cursor(kSizeTCursor);

View File

@ -271,10 +271,14 @@ void jmouse_release()
#endif
}
MouseButtons jmouse_b(int antique)
{
return (MouseButtons)m_b[antique & 1];
}
int jmouse_x(int antique) { return m_x[antique & 1]; }
int jmouse_y(int antique) { return m_y[antique & 1]; }
int jmouse_z(int antique) { return m_z[antique & 1]; }
int jmouse_b(int antique) { return m_b[antique & 1]; }
bool jmouse_control_infinite_scroll(const gfx::Rect& rect)
{

View File

@ -10,6 +10,7 @@
#include "gfx/rect.h"
#include "ui/base.h"
#include "ui/cursor_type.h"
#include "ui/mouse_buttons.h"
struct BITMAP;
@ -57,7 +58,7 @@ namespace ui {
void jmouse_capture();
void jmouse_release();
int jmouse_b(int antique);
MouseButtons jmouse_b(int antique);
int jmouse_x(int antique);
int jmouse_y(int antique);
int jmouse_z(int antique);

View File

@ -31,7 +31,7 @@ TextBox::TextBox(const char* text, int align)
bool TextBox::onProcessMessage(Message* msg)
{
switch (msg->type) {
switch (msg->type()) {
case kKeyDownMessage:
if (hasFocus()) {
@ -41,44 +41,44 @@ bool TextBox::onProcessMessage(Message* msg)
gfx::Point scroll = view->getViewScroll();
int textheight = jwidget_get_text_height(this);
switch (msg->key.scancode) {
switch (static_cast<KeyMessage*>(msg)->scancode()) {
case KEY_LEFT:
case kKeyLeft:
scroll.x -= vp.w/2;
view->setViewScroll(scroll);
break;
case KEY_RIGHT:
case kKeyRight:
scroll.x += vp.w/2;
view->setViewScroll(scroll);
break;
case KEY_UP:
case kKeyUp:
scroll.y -= vp.h/2;
view->setViewScroll(scroll);
break;
case KEY_DOWN:
case kKeyDown:
scroll.y += vp.h/2;
view->setViewScroll(scroll);
break;
case KEY_PGUP:
case kKeyPageUp:
scroll.y -= (vp.h-textheight);
view->setViewScroll(scroll);
break;
case KEY_PGDN:
case kKeyPageDown:
scroll.y += (vp.h-textheight);
view->setViewScroll(scroll);
break;
case KEY_HOME:
case kKeyHome:
scroll.y = 0;
view->setViewScroll(scroll);
break;
case KEY_END:
case kKeyEnd:
scroll.y = jrect_h(this->rc) - vp.h;
view->setViewScroll(scroll);
break;

View File

@ -98,10 +98,8 @@ void Timer::pollTimers()
if (count > 0) {
ASSERT(timer->m_owner != NULL);
Message* msg = jmessage_new(kTimerMessage);
msg->timer.count = count;
msg->timer.timer = timer;
jmessage_add_dest(msg, timer->m_owner);
Message* msg = new TimerMessage(count, timer);
msg->addRecipient(timer->m_owner);
Manager::getDefault()->enqueueMessage(msg);
}
}

View File

@ -48,10 +48,10 @@ void TooltipManager::addTooltipFor(Widget* widget, const char* text, int arrowAl
bool TooltipManager::onProcessMessage(Message* msg)
{
switch (msg->type) {
switch (msg->type()) {
case kMouseEnterMessage: {
UI_FOREACH_WIDGET(*msg->any.widgets, itWidget) {
UI_FOREACH_WIDGET(msg->recipients(), itWidget) {
Tips::iterator it = m_tips.find(*itWidget);
if (it != m_tips.end()) {
m_target.widget = it->first;
@ -200,7 +200,7 @@ void TipWindow::setArrowAlign(int arrowAlign)
bool TipWindow::onProcessMessage(Message* msg)
{
switch (msg->type) {
switch (msg->type()) {
case kCloseMessage:
if (m_filtering) {
@ -217,31 +217,31 @@ bool TipWindow::onProcessMessage(Message* msg)
break;
case kKeyDownMessage:
if (m_filtering && msg->key.scancode < KEY_MODIFIERS)
this->closeWindow(NULL);
if (m_filtering && static_cast<KeyMessage*>(msg)->scancode() < kKeyFirstModifierScancode)
closeWindow(NULL);
break;
case kMouseDownMessage:
/* if the user click outside the window, we have to close the
tooltip window */
// If the user click outside the window, we have to close the
// tooltip window.
if (m_filtering) {
Widget* picked = this->pick(msg->mouse.x, msg->mouse.y);
gfx::Point mousePos = static_cast<MouseMessage*>(msg)->position();
Widget* picked = pick(mousePos);
if (!picked || picked->getRoot() != this) {
this->closeWindow(NULL);
}
}
/* this is used when the user click inside a small text
tooltip */
// This is used when the user click inside a small text tooltip.
if (m_close_on_buttonpressed)
this->closeWindow(NULL);
closeWindow(NULL);
break;
case kMouseMoveMessage:
if (!m_hotRegion.isEmpty() &&
getManager()->getCapture() == NULL) {
// If the mouse is outside the hot-region we have to close the window
if (!m_hotRegion.contains(Point(msg->mouse.x, msg->mouse.y))) {
if (!m_hotRegion.contains(static_cast<MouseMessage*>(msg)->position())) {
closeWindow(NULL);
}
}

View File

@ -225,7 +225,7 @@ View* View::getView(Widget* widget)
bool View::onProcessMessage(Message* msg)
{
switch (msg->type) {
switch (msg->type()) {
case kFocusEnterMessage:
case kFocusLeaveMessage:

View File

@ -409,16 +409,16 @@ Widget* Widget::getPreviousSibling()
return *(++it);
}
Widget* Widget::pick(int x, int y)
Widget* Widget::pick(const gfx::Point& pt)
{
Widget* inside, *picked = NULL;
if (!(this->flags & JI_HIDDEN) && /* is visible */
jrect_point_in(this->rc, x, y)) { /* the point is inside the bounds */
if (!(this->flags & JI_HIDDEN) && // Is visible
jrect_point_in(this->rc, pt.x, pt.y)) { // The point is inside the bounds
picked = this;
UI_FOREACH_WIDGET(m_children, it) {
inside = (*it)->pick(x, y);
inside = (*it)->pick(pt);
if (inside) {
picked = inside;
break;
@ -924,17 +924,11 @@ void Widget::flushRedraw()
Region::const_iterator it = widget->m_updateRegion.begin();
// Draw the widget
for (c=0; c<nrects; c++, ++it) {
const Rect& rc = *it;
int count = nrects-1;
for (c=0; c<nrects; ++c, ++it, --count) {
// Create the draw message
msg = jmessage_new(kPaintMessage);
msg->draw.count = nrects-1 - c;
msg->draw.rect.x1 = rc.x;
msg->draw.rect.y1 = rc.y;
msg->draw.rect.x2 = rc.x2();
msg->draw.rect.y2 = rc.y2();
jmessage_add_dest(msg, widget);
msg = new PaintMessage(count, *it);
msg->addRecipient(widget);
// Enqueue the draw message
getManager()->enqueueMessage(msg);
@ -1152,7 +1146,7 @@ bool Widget::hasMouse()
bool Widget::hasMouseOver()
{
return (this == this->pick(jmouse_x(0), jmouse_y(0)));
return (this == this->pick(gfx::Point(jmouse_x(0), jmouse_y(0))));
}
bool Widget::hasCapture()
@ -1191,7 +1185,7 @@ bool Widget::onProcessMessage(Message* msg)
{
ASSERT(msg != NULL);
switch (msg->type) {
switch (msg->type()) {
case kOpenMessage:
case kCloseMessage:
@ -1208,14 +1202,16 @@ bool Widget::onProcessMessage(Message* msg)
// screen, we already are painting off-screen using ji_screen,
// so we don't need the temporary bitmap.
if (m_doubleBuffered && ji_screen == screen) {
ASSERT(jrect_w(&msg->draw.rect) > 0);
ASSERT(jrect_h(&msg->draw.rect) > 0);
const PaintMessage* ptmsg = static_cast<const PaintMessage*>(msg);
ASSERT(ptmsg->rect().w > 0);
ASSERT(ptmsg->rect().h > 0);
BITMAP* bmp = create_bitmap_ex(bitmap_color_depth(ji_screen),
jrect_w(&msg->draw.rect),
jrect_h(&msg->draw.rect));
ptmsg->rect().w,
ptmsg->rect().h);
Graphics graphics(bmp, rc->x1-msg->draw.rect.x1, rc->y1-msg->draw.rect.y1);
Graphics graphics(bmp, rc->x1 - ptmsg->rect().x, rc->y1 - ptmsg->rect().y);
graphics.setFont(getFont());
PaintEvent ev(this, &graphics);
@ -1223,7 +1219,7 @@ bool Widget::onProcessMessage(Message* msg)
// Blit the temporary bitmap to the real screen
if (ev.isPainted())
blit(bmp, ji_screen, 0, 0, msg->draw.rect.x1, msg->draw.rect.y1, bmp->w, bmp->h);
blit(bmp, ji_screen, 0, 0, ptmsg->rect().x, ptmsg->rect().y, bmp->w, bmp->h);
destroy_bitmap(bmp);
return ev.isPainted();
@ -1241,14 +1237,14 @@ bool Widget::onProcessMessage(Message* msg)
case kKeyDownMessage:
case kKeyUpMessage:
if (msg->key.propagate_to_children) {
if (static_cast<KeyMessage*>(msg)->propagateToChildren()) {
// Broadcast the message to the children.
UI_FOREACH_WIDGET(getChildren(), it)
(*it)->sendMessage(msg);
}
// Propagate the message to the parent.
if (msg->key.propagate_to_parent && getParent() != NULL)
if (static_cast<KeyMessage*>(msg)->propagateToParent() && getParent() != NULL)
return getParent()->sendMessage(msg);
else
break;

View File

@ -10,6 +10,7 @@
#include <string>
#include "gfx/border.h"
#include "gfx/point.h"
#include "gfx/rect.h"
#include "gfx/region.h"
#include "gfx/size.h"
@ -27,11 +28,10 @@ struct BITMAP;
namespace ui {
union Message;
class InitThemeEvent;
class LoadLayoutEvent;
class Manager;
class Message;
class PaintEvent;
class PreferredSizeEvent;
class ResizeEvent;
@ -205,7 +205,7 @@ namespace ui {
Widget* getNextSibling();
Widget* getPreviousSibling();
Widget* pick(int x, int y);
Widget* pick(const gfx::Point& pt);
bool hasChild(Widget* child);
Widget* findChild(const char* id);

View File

@ -28,8 +28,8 @@ enum {
WINDOW_RESIZE_BOTTOM = 16,
};
static JRect click_pos = NULL;
static int press_x, press_y;
static gfx::Point clickedMousePos;
static gfx::Rect* clickedWindowPos = NULL;
static void displace_widgets(Widget* widget, int x, int y);
@ -259,7 +259,7 @@ bool Window::isTopLevel()
bool Window::onProcessMessage(Message* msg)
{
switch (msg->type) {
switch (msg->type()) {
case kOpenMessage:
m_killer = NULL;
@ -273,16 +273,15 @@ bool Window::onProcessMessage(Message* msg)
if (!m_isMoveable)
break;
press_x = msg->mouse.x;
press_y = msg->mouse.y;
m_hitTest = hitTest(gfx::Point(press_x, press_y));
clickedMousePos = static_cast<MouseMessage*>(msg)->position();
m_hitTest = hitTest(clickedMousePos);
if (m_hitTest != HitTestNowhere &&
m_hitTest != HitTestClient) {
if (click_pos == NULL)
click_pos = jrect_new_copy(this->rc);
if (clickedWindowPos == NULL)
clickedWindowPos = new gfx::Rect(getBounds());
else
jrect_copy(click_pos, this->rc);
*clickedWindowPos = getBounds();
captureMouse();
return true;
@ -296,9 +295,9 @@ bool Window::onProcessMessage(Message* msg)
releaseMouse();
jmouse_set_cursor(kArrowCursor);
if (click_pos != NULL) {
jrect_free(click_pos);
click_pos = NULL;
if (clickedWindowPos != NULL) {
delete clickedWindowPos;
clickedWindowPos = NULL;
}
m_hitTest = HitTestNowhere;
@ -312,10 +311,12 @@ bool Window::onProcessMessage(Message* msg)
// Does it have the mouse captured?
if (hasCapture()) {
gfx::Point mousePos = static_cast<MouseMessage*>(msg)->position();
// Reposition/resize
if (m_hitTest == HitTestCaption) {
int x = click_pos->x1 + (msg->mouse.x - press_x);
int y = click_pos->y1 + (msg->mouse.y - press_y);
int x = clickedWindowPos->x + (mousePos.x - clickedMousePos.x);
int y = clickedWindowPos->y + (mousePos.y - clickedMousePos.y);
moveWindow(gfx::Rect(x, y,
jrect_w(this->rc),
jrect_h(this->rc)), true);
@ -323,8 +324,8 @@ bool Window::onProcessMessage(Message* msg)
else {
int x, y, w, h;
w = jrect_w(click_pos);
h = jrect_h(click_pos);
w = clickedWindowPos->w;
h = clickedWindowPos->h;
bool hitLeft = (m_hitTest == HitTestBorderNW ||
m_hitTest == HitTestBorderW ||
@ -340,17 +341,17 @@ bool Window::onProcessMessage(Message* msg)
m_hitTest == HitTestBorderSE);
if (hitLeft) {
w += press_x - msg->mouse.x;
w += clickedMousePos.x - mousePos.x;
}
else if (hitRight) {
w += msg->mouse.x - press_x;
w += mousePos.x - clickedMousePos.x;
}
if (hitTop) {
h += (press_y - msg->mouse.y);
h += (clickedMousePos.y - mousePos.y);
}
else if (hitBottom) {
h += (msg->mouse.y - press_y);
h += (mousePos.y - clickedMousePos.y);
}
limitSize(&w, &h);
@ -358,12 +359,12 @@ bool Window::onProcessMessage(Message* msg)
if ((jrect_w(this->rc) != w) ||
(jrect_h(this->rc) != h)) {
if (hitLeft)
x = click_pos->x1 - (w - jrect_w(click_pos));
x = clickedWindowPos->x - (w - clickedWindowPos->w);
else
x = this->rc->x1;
if (hitTop)
y = click_pos->y1 - (h - jrect_h(click_pos));
y = clickedWindowPos->y - (h - clickedWindowPos->h);
else
y = this->rc->y1;
@ -376,7 +377,8 @@ bool Window::onProcessMessage(Message* msg)
case kSetCursorMessage:
if (m_isMoveable) {
HitTest ht = hitTest(gfx::Point(msg->mouse.x, msg->mouse.y));
gfx::Point mousePos = static_cast<MouseMessage*>(msg)->position();
HitTest ht = hitTest(mousePos);
CursorType cursor = kArrowCursor;
switch (ht) {
@ -532,9 +534,9 @@ void Window::moveWindow(const gfx::Rect& rect, bool use_blit)
// Get the manager's current position
Rect man_pos = manager->getBounds();
/* sent a kWinMoveMessage message to the window */
msg = jmessage_new(kWinMoveMessage);
jmessage_add_dest(msg, this);
// Send a kWinMoveMessage message to the window
msg = new Message(kWinMoveMessage);
msg->addRecipient(this);
manager->enqueueMessage(msg);
// Get the region & the drawable region of the window

View File

@ -52,7 +52,7 @@ ColorBar::ScrollableView::ScrollableView()
bool ColorBar::ScrollableView::onProcessMessage(Message* msg)
{
switch (msg->type) {
switch (msg->type()) {
case kPaintMessage:
{
@ -201,7 +201,8 @@ void ColorBar::onPaletteIndexChange(int index)
app::Color color = app::Color::fromIndex(index);
if (jmouse_b(0) & 2) // TODO create a PaletteChangeEvent and take left/right mouse button from there
// TODO create a PaletteChangeEvent and take left/right mouse button from there
if ((jmouse_b(0) & kButtonRight) == kButtonRight)
setBgColor(color);
else
setFgColor(color);

View File

@ -93,7 +93,7 @@ void ColorButton::setColor(const app::Color& color)
bool ColorButton::onProcessMessage(Message* msg)
{
switch (msg->type) {
switch (msg->type()) {
case kCloseMessage:
if (m_window && m_window->isVisible())
@ -110,7 +110,8 @@ bool ColorButton::onProcessMessage(Message* msg)
case kMouseMoveMessage:
if (hasCapture()) {
Widget* picked = getManager()->pick(msg->mouse.x, msg->mouse.y);
gfx::Point mousePos = static_cast<MouseMessage*>(msg)->position();
Widget* picked = getManager()->pick(mousePos);
app::Color color = m_color;
if (picked && picked != this) {
@ -120,7 +121,7 @@ bool ColorButton::onProcessMessage(Message* msg)
}
// Pick a color from the color-bar
else if (picked->type == palette_view_type()) {
color = ((PaletteView*)picked)->getColorByPosition(msg->mouse.x, msg->mouse.y);
color = ((PaletteView*)picked)->getColorByPosition(mousePos.x, mousePos.y);
}
// Pick a color from a editor
else if (picked->type == editor_type()) {
@ -129,8 +130,8 @@ bool ColorButton::onProcessMessage(Message* msg)
int x, y, imgcolor;
if (sprite) {
x = msg->mouse.x;
y = msg->mouse.y;
x = mousePos.x;
y = mousePos.y;
editor->screenToEditor(x, y, &x, &y);
imgcolor = sprite->getPixel(x, y, editor->getFrame());
color = app::Color::fromImage(sprite->getPixelFormat(), imgcolor);

View File

@ -178,7 +178,7 @@ void DocumentView::onClonedFrom(WorkspaceView* from)
bool DocumentView::onProcessMessage(Message* msg)
{
switch (msg->type) {
switch (msg->type()) {
case kFocusEnterMessage:
m_editor->requestFocus();
break;

View File

@ -32,17 +32,21 @@
using namespace ui;
static tools::ToolLoopManager::Pointer pointer_from_msg(Message* msg)
static tools::ToolLoopManager::Pointer::Button button_from_msg(MouseMessage* msg)
{
tools::ToolLoopManager::Pointer::Button button =
(msg->mouse.right ? tools::ToolLoopManager::Pointer::Right:
(msg->mouse.middle ? tools::ToolLoopManager::Pointer::Middle:
tools::ToolLoopManager::Pointer::Left));
return tools::ToolLoopManager::Pointer(msg->mouse.x, msg->mouse.y, button);
return
(msg->right() ? tools::ToolLoopManager::Pointer::Right:
(msg->middle() ? tools::ToolLoopManager::Pointer::Middle:
tools::ToolLoopManager::Pointer::Left));
}
DrawingState::DrawingState(tools::ToolLoop* toolLoop, Editor* editor, Message* msg)
static tools::ToolLoopManager::Pointer pointer_from_msg(MouseMessage* msg)
{
return
tools::ToolLoopManager::Pointer(msg->position().x, msg->position().y, button_from_msg(msg));
}
DrawingState::DrawingState(tools::ToolLoop* toolLoop, Editor* editor, MouseMessage* msg)
: m_toolLoop(toolLoop)
, m_toolLoopManager(new tools::ToolLoopManager(toolLoop))
{
@ -63,7 +67,7 @@ DrawingState::~DrawingState()
destroyLoop();
}
bool DrawingState::onMouseDown(Editor* editor, Message* msg)
bool DrawingState::onMouseDown(Editor* editor, MouseMessage* msg)
{
// Drawing loop
ASSERT(m_toolLoopManager != NULL);
@ -84,7 +88,7 @@ bool DrawingState::onMouseDown(Editor* editor, Message* msg)
return true;
}
bool DrawingState::onMouseUp(Editor* editor, Message* msg)
bool DrawingState::onMouseUp(Editor* editor, MouseMessage* msg)
{
ASSERT(m_toolLoopManager != NULL);
@ -101,7 +105,7 @@ bool DrawingState::onMouseUp(Editor* editor, Message* msg)
return true;
}
bool DrawingState::onMouseMove(Editor* editor, Message* msg)
bool DrawingState::onMouseMove(Editor* editor, MouseMessage* msg)
{
ASSERT(m_toolLoopManager != NULL);
@ -111,14 +115,16 @@ bool DrawingState::onMouseMove(Editor* editor, Message* msg)
editor->hideDrawingCursor();
// Infinite scroll
editor->controlInfiniteScroll(msg);
gfx::Point mousePos = editor->controlInfiniteScroll(msg);
// Hide the cursor again
editor->hideDrawingCursor();
// notify mouse movement to the tool
ASSERT(m_toolLoopManager != NULL);
m_toolLoopManager->movement(pointer_from_msg(msg));
m_toolLoopManager
->movement(tools::ToolLoopManager::Pointer(mousePos.x, mousePos.y,
button_from_msg(msg)));
// draw the cursor again
editor->showDrawingCursor();
@ -140,16 +146,16 @@ bool DrawingState::onSetCursor(Editor* editor)
return true;
}
bool DrawingState::onKeyDown(Editor* editor, Message* msg)
bool DrawingState::onKeyDown(Editor* editor, KeyMessage* msg)
{
if (editor->processKeysToSetZoom(msg->key.scancode))
if (editor->processKeysToSetZoom(msg))
return true;
// When we are drawing, we "eat" all pressed keys.
return true;
}
bool DrawingState::onKeyUp(Editor* editor, Message* msg)
bool DrawingState::onKeyUp(Editor* editor, KeyMessage* msg)
{
return true;
}

View File

@ -30,14 +30,14 @@ namespace tools {
class DrawingState : public StandbyState
{
public:
DrawingState(tools::ToolLoop* loop, Editor* editor, ui::Message* msg);
DrawingState(tools::ToolLoop* loop, Editor* editor, ui::MouseMessage* msg);
virtual ~DrawingState();
virtual bool onMouseDown(Editor* editor, ui::Message* msg) OVERRIDE;
virtual bool onMouseUp(Editor* editor, ui::Message* msg) OVERRIDE;
virtual bool onMouseMove(Editor* editor, ui::Message* msg) OVERRIDE;
virtual bool onMouseDown(Editor* editor, ui::MouseMessage* msg) OVERRIDE;
virtual bool onMouseUp(Editor* editor, ui::MouseMessage* msg) OVERRIDE;
virtual bool onMouseMove(Editor* editor, ui::MouseMessage* msg) OVERRIDE;
virtual bool onSetCursor(Editor* editor) OVERRIDE;
virtual bool onKeyDown(Editor* editor, ui::Message* msg) OVERRIDE;
virtual bool onKeyUp(Editor* editor, ui::Message* msg) OVERRIDE;
virtual bool onKeyDown(Editor* editor, ui::KeyMessage* msg) OVERRIDE;
virtual bool onKeyUp(Editor* editor, ui::KeyMessage* msg) OVERRIDE;
virtual bool onUpdateStatusBar(Editor* editor) OVERRIDE;
// Drawing state doesn't require the pen-preview because we are

View File

@ -661,17 +661,16 @@ void Editor::flashCurrentLayer()
#endif
}
void Editor::controlInfiniteScroll(Message* msg)
gfx::Point Editor::controlInfiniteScroll(MouseMessage* msg)
{
View* view = View::getView(this);
Rect vp = view->getViewportBounds();
if (jmouse_control_infinite_scroll(vp)) {
int old_x = msg->mouse.x;
int old_y = msg->mouse.y;
msg->mouse.x = jmouse_x(0);
msg->mouse.y = jmouse_y(0);
int old_x = msg->position().x;
int old_y = msg->position().y;
int new_x = jmouse_x(0);
int new_y = jmouse_y(0);
// Smooth scroll movement
if (get_config_bool("Options", "MoveSmooth", TRUE)) {
@ -680,17 +679,22 @@ void Editor::controlInfiniteScroll(Message* msg)
}
// This is better for high resolutions: scroll movement by big steps
else {
jmouse_set_position((old_x != msg->mouse.x) ? (old_x + (vp.x+vp.w/2))/2: msg->mouse.x,
(old_y != msg->mouse.y) ? (old_y + (vp.y+vp.h/2))/2: msg->mouse.y);
jmouse_set_position((old_x != new_x) ? (old_x + (vp.x+vp.w/2))/2: new_x,
(old_y != new_y) ? (old_y + (vp.y+vp.h/2))/2: new_y);
}
msg->mouse.x = jmouse_x(0);
msg->mouse.y = jmouse_y(0);
// Get new positions.
new_x = jmouse_x(0);
new_y = jmouse_y(0);
Point scroll = view->getViewScroll();
setEditorScroll(scroll.x+old_x-msg->mouse.x,
scroll.y+old_y-msg->mouse.y, true);
setEditorScroll(scroll.x+old_x-new_x,
scroll.y+old_y-new_y, true);
return gfx::Point(new_x, new_y);
}
return msg->position();
}
tools::Tool* Editor::getCurrentEditorTool()
@ -860,7 +864,7 @@ void Editor::editor_update_quicktool()
bool Editor::onProcessMessage(Message* msg)
{
switch (msg->type) {
switch (msg->type()) {
case kPaintMessage: {
SkinTheme* theme = static_cast<SkinTheme*>(this->getTheme());
@ -929,7 +933,7 @@ bool Editor::onProcessMessage(Message* msg)
}
case kTimerMessage:
if (msg->timer.timer == &m_mask_timer) {
if (static_cast<TimerMessage*>(msg)->timer() == &m_mask_timer) {
if (isVisible() && m_sprite) {
drawMaskSafe();
@ -957,21 +961,21 @@ bool Editor::onProcessMessage(Message* msg)
case kMouseDownMessage:
if (m_sprite) {
EditorStatePtr holdState(m_state);
return m_state->onMouseDown(this, msg);
return m_state->onMouseDown(this, static_cast<MouseMessage*>(msg));
}
break;
case kMouseMoveMessage:
if (m_sprite) {
EditorStatePtr holdState(m_state);
return m_state->onMouseMove(this, msg);
return m_state->onMouseMove(this, static_cast<MouseMessage*>(msg));
}
break;
case kMouseUpMessage:
if (m_sprite) {
EditorStatePtr holdState(m_state);
if (m_state->onMouseUp(this, msg))
if (m_state->onMouseUp(this, static_cast<MouseMessage*>(msg)))
return true;
}
break;
@ -979,7 +983,7 @@ bool Editor::onProcessMessage(Message* msg)
case kKeyDownMessage:
if (m_sprite) {
EditorStatePtr holdState(m_state);
bool used = m_state->onKeyDown(this, msg);
bool used = m_state->onKeyDown(this, static_cast<KeyMessage*>(msg));
if (hasMouse()) {
editor_update_quicktool();
@ -994,7 +998,7 @@ bool Editor::onProcessMessage(Message* msg)
case kKeyUpMessage:
if (m_sprite) {
EditorStatePtr holdState(m_state);
bool used = m_state->onKeyUp(this, msg);
bool used = m_state->onKeyUp(this, static_cast<KeyMessage*>(msg));
if (hasMouse()) {
editor_update_quicktool();
@ -1015,7 +1019,7 @@ bool Editor::onProcessMessage(Message* msg)
case kMouseWheelMessage:
if (m_sprite && hasMouse()) {
EditorStatePtr holdState(m_state);
if (m_state->onMouseWheel(this, msg))
if (m_state->onMouseWheel(this, static_cast<MouseMessage*>(msg)))
return true;
}
break;

View File

@ -23,7 +23,7 @@
#include "base/compiler_specific.h"
#include "base/signal.h"
#include "document.h"
#include "gfx/rect.h"
#include "gfx/fwd.h"
#include "raster/frame_number.h"
#include "ui/base.h"
#include "ui/timer.h"
@ -130,7 +130,7 @@ public:
void updateStatusBar();
// Control scroll when cursor goes out of the editor.
void controlInfiniteScroll(ui::Message* msg);
gfx::Point controlInfiniteScroll(ui::MouseMessage* msg);
tools::Tool* getCurrentEditorTool();
@ -142,7 +142,7 @@ public:
void setZoomAndCenterInMouse(int zoom, int mouse_x, int mouse_y);
bool processKeysToSetZoom(int scancode);
bool processKeysToSetZoom(ui::KeyMessage* msg);
void pasteImage(const Image* image, int x, int y);

View File

@ -24,7 +24,10 @@
class Editor;
class EditorDecorator;
namespace ui { union Message; }
namespace ui {
class MouseMessage;
class KeyMessage;
}
// Represents one state of the sprite's editor (Editor class). This
// is a base class, a dummy state that ignores all events from the
@ -69,16 +72,16 @@ public:
virtual void onCurrentToolChange(Editor* editor) { }
// Called when the user presses a mouse button over the editor.
virtual bool onMouseDown(Editor* editor, ui::Message* msg) { return false; }
virtual bool onMouseDown(Editor* editor, ui::MouseMessage* msg) { return false; }
// Called when the user releases a mouse button.
virtual bool onMouseUp(Editor* editor, ui::Message* msg) { return false; }
virtual bool onMouseUp(Editor* editor, ui::MouseMessage* msg) { return false; }
// Called when the user moves the mouse over the editor.
virtual bool onMouseMove(Editor* editor, ui::Message* msg) { return false; }
virtual bool onMouseMove(Editor* editor, ui::MouseMessage* msg) { return false; }
// Called when the user moves the mouse wheel over the editor.
virtual bool onMouseWheel(Editor* editor, ui::Message* msg) { return false; }
virtual bool onMouseWheel(Editor* editor, ui::MouseMessage* msg) { return false; }
// Called each time the mouse changes its position so we can set an
// appropiated cursor depending on the new coordinates of the mouse
@ -86,10 +89,10 @@ public:
virtual bool onSetCursor(Editor* editor) { return false; }
// Called when a key is pressed over the current editor.
virtual bool onKeyDown(Editor* editor, ui::Message* msg) { return false; }
virtual bool onKeyDown(Editor* editor, ui::KeyMessage* msg) { return false; }
// Called when a key is released.
virtual bool onKeyUp(Editor* editor, ui::Message* msg) { return false; }
virtual bool onKeyUp(Editor* editor, ui::KeyMessage* msg) { return false; }
// Called when a key is released.
virtual bool onUpdateStatusBar(Editor* editor) { return false; }

View File

@ -46,7 +46,7 @@ EditorView::EditorView(EditorView::Type type)
bool EditorView::onProcessMessage(Message* msg)
{
switch (msg->type) {
switch (msg->type()) {
case kPaintMessage:
{

View File

@ -26,6 +26,7 @@
#include "raster/image.h"
#include "raster/sprite.h"
#include "settings/settings.h"
#include "ui/message.h"
#include "ui/rect.h"
#include "ui/system.h"
#include "ui/view.h"
@ -36,30 +37,24 @@
using namespace ui;
bool Editor::processKeysToSetZoom(int scancode)
bool Editor::processKeysToSetZoom(KeyMessage* msg)
{
if ((m_sprite) &&
(this->hasMouse()) &&
!key[KEY_LSHIFT] &&
!key[KEY_RSHIFT] &&
!key[KEY_LCONTROL] &&
!key[KEY_RCONTROL] &&
!key[KEY_ALT]) {
(hasMouse()) &&
(msg->keyModifiers() == kKeyNoneModifier)) {
View* view = View::getView(this);
gfx::Rect vp = view->getViewportBounds();
int x, y, zoom;
int x = 0;
int y = 0;
int zoom = -1;
x = 0;
y = 0;
zoom = -1;
switch (scancode) { // TODO make these keys configurable
case KEY_1: zoom = 0; break;
case KEY_2: zoom = 1; break;
case KEY_3: zoom = 2; break;
case KEY_4: zoom = 3; break;
case KEY_5: zoom = 4; break;
case KEY_6: zoom = 5; break;
switch (msg->scancode()) { // TODO make these keys configurable
case kKey1: zoom = 0; break;
case kKey2: zoom = 1; break;
case kKey3: zoom = 2; break;
case kKey4: zoom = 3; break;
case kKey5: zoom = 4; break;
case kKey6: zoom = 5; break;
}
// Change zoom

View File

@ -35,7 +35,7 @@
using namespace ui;
MovingCelState::MovingCelState(Editor* editor, Message* msg)
MovingCelState::MovingCelState(Editor* editor, MouseMessage* msg)
: m_canceled(false)
{
Document* document = editor->getDocument();
@ -55,7 +55,7 @@ MovingCelState::MovingCelState(Editor* editor, Message* msg)
m_celNewX = m_celStartX;
m_celNewY = m_celStartY;
editor->screenToEditor(msg->mouse.x, msg->mouse.y, &m_mouseStartX, &m_mouseStartY);
editor->screenToEditor(msg->position().x, msg->position().y, &m_mouseStartX, &m_mouseStartY);
editor->captureMouse();
// Hide the mask (temporarily, until mouse-up event)
@ -70,7 +70,7 @@ MovingCelState::~MovingCelState()
{
}
bool MovingCelState::onMouseUp(Editor* editor, Message* msg)
bool MovingCelState::onMouseUp(Editor* editor, MouseMessage* msg)
{
Document* document = editor->getDocument();
@ -112,10 +112,10 @@ bool MovingCelState::onMouseUp(Editor* editor, Message* msg)
return true;
}
bool MovingCelState::onMouseMove(Editor* editor, Message* msg)
bool MovingCelState::onMouseMove(Editor* editor, MouseMessage* msg)
{
int newMouseX, newMouseY;
editor->screenToEditor(msg->mouse.x, msg->mouse.y, &newMouseX, &newMouseY);
editor->screenToEditor(msg->position().x, msg->position().y, &newMouseX, &newMouseY);
m_celNewX = m_celStartX - m_mouseStartX + newMouseX;
m_celNewY = m_celStartY - m_mouseStartY + newMouseY;

View File

@ -28,11 +28,11 @@ class Editor;
class MovingCelState : public StandbyState
{
public:
MovingCelState(Editor* editor, ui::Message* msg);
MovingCelState(Editor* editor, ui::MouseMessage* msg);
virtual ~MovingCelState();
virtual bool onMouseUp(Editor* editor, ui::Message* msg) OVERRIDE;
virtual bool onMouseMove(Editor* editor, ui::Message* msg) OVERRIDE;
virtual bool onMouseUp(Editor* editor, ui::MouseMessage* msg) OVERRIDE;
virtual bool onMouseMove(Editor* editor, ui::MouseMessage* msg) OVERRIDE;
virtual bool onUpdateStatusBar(Editor* editor) OVERRIDE;
private:

View File

@ -50,7 +50,7 @@
using namespace ui;
MovingPixelsState::MovingPixelsState(Editor* editor, Message* msg, PixelsMovement* pixelsMovement, HandleType handle)
MovingPixelsState::MovingPixelsState(Editor* editor, MouseMessage* msg, PixelsMovement* pixelsMovement, HandleType handle)
: m_currentEditor(editor)
, m_discarded(false)
{
@ -64,7 +64,7 @@ MovingPixelsState::MovingPixelsState(Editor* editor, Message* msg, PixelsMovemen
if (handle != NoHandle) {
int u, v;
editor->screenToEditor(msg->mouse.x, msg->mouse.y, &u, &v);
editor->screenToEditor(msg->position().x, msg->position().y, &u, &v);
m_pixelsMovement->catchImage(u, v, handle);
editor->captureMouse();
@ -149,7 +149,7 @@ void MovingPixelsState::onCurrentToolChange(Editor* editor)
}
}
bool MovingPixelsState::onMouseDown(Editor* editor, Message* msg)
bool MovingPixelsState::onMouseDown(Editor* editor, MouseMessage* msg)
{
ASSERT(m_pixelsMovement != NULL);
@ -167,13 +167,13 @@ bool MovingPixelsState::onMouseDown(Editor* editor, Message* msg)
// Get the handle covered by the mouse.
HandleType handle = transfHandles->getHandleAtPoint(editor,
gfx::Point(msg->mouse.x, msg->mouse.y),
msg->position(),
getTransformation(editor));
if (handle != NoHandle) {
// Re-catch the image
int x, y;
editor->screenToEditor(msg->mouse.x, msg->mouse.y, &x, &y);
editor->screenToEditor(msg->position().x, msg->position().y, &x, &y);
m_pixelsMovement->catchImageAgain(x, y, handle);
editor->captureMouse();
@ -182,8 +182,8 @@ bool MovingPixelsState::onMouseDown(Editor* editor, Message* msg)
}
// Start "moving pixels" loop
if (editor->isInsideSelection() && (msg->mouse.left ||
msg->mouse.right)) {
if (editor->isInsideSelection() && (msg->left() ||
msg->right())) {
// In case that the user is pressing the copy-selection keyboard shortcut.
EditorCustomizationDelegate* customization = editor->getCustomizationDelegate();
if (customization && customization->isCopySelectionKeyPressed()) {
@ -193,7 +193,7 @@ bool MovingPixelsState::onMouseDown(Editor* editor, Message* msg)
// Re-catch the image
int x, y;
editor->screenToEditor(msg->mouse.x, msg->mouse.y, &x, &y);
editor->screenToEditor(msg->position().x, msg->position().y, &x, &y);
m_pixelsMovement->catchImageAgain(x, y, MoveHandle);
editor->captureMouse();
@ -209,7 +209,7 @@ bool MovingPixelsState::onMouseDown(Editor* editor, Message* msg)
return StandbyState::onMouseDown(editor, msg);
}
bool MovingPixelsState::onMouseUp(Editor* editor, Message* msg)
bool MovingPixelsState::onMouseUp(Editor* editor, MouseMessage* msg)
{
ASSERT(m_pixelsMovement != NULL);
@ -223,18 +223,18 @@ bool MovingPixelsState::onMouseUp(Editor* editor, Message* msg)
return true;
}
bool MovingPixelsState::onMouseMove(Editor* editor, Message* msg)
bool MovingPixelsState::onMouseMove(Editor* editor, MouseMessage* msg)
{
ASSERT(m_pixelsMovement != NULL);
// If there is a button pressed
if (m_pixelsMovement->isDragging()) {
// Infinite scroll
editor->controlInfiniteScroll(msg);
gfx::Point mousePos = editor->controlInfiniteScroll(msg);
// Get the position of the mouse in the sprite
int x, y;
editor->screenToEditor(msg->mouse.x, msg->mouse.y, &x, &y);
editor->screenToEditor(mousePos.x, mousePos.y, &x, &y);
// Get the customization for the pixels movement (snap to grid, angle snap, etc.).
PixelsMovement::MoveModifier moveModifier = PixelsMovement::NormalMovement;
@ -267,7 +267,7 @@ bool MovingPixelsState::onMouseMove(Editor* editor, Message* msg)
return StandbyState::onMouseMove(editor, msg);
}
bool MovingPixelsState::onMouseWheel(Editor* editor, Message* msg)
bool MovingPixelsState::onMouseWheel(Editor* editor, MouseMessage* msg)
{
ASSERT(m_pixelsMovement != NULL);
@ -290,17 +290,17 @@ bool MovingPixelsState::onSetCursor(Editor* editor)
return StandbyState::onSetCursor(editor);
}
bool MovingPixelsState::onKeyDown(Editor* editor, Message* msg)
bool MovingPixelsState::onKeyDown(Editor* editor, KeyMessage* msg)
{
ASSERT(m_pixelsMovement != NULL);
if (msg->key.scancode == KEY_ENTER || // TODO make this key customizable
msg->key.scancode == KEY_ENTER_PAD ||
msg->key.scancode == KEY_ESC ) {
if (msg->scancode() == kKeyEnter || // TODO make this key customizable
msg->scancode() == kKeyEnterPad ||
msg->scancode() == kKeyEsc) {
dropPixels(editor);
// The escape key drop pixels and deselect the mask.
if (msg->key.scancode == KEY_ESC) { // TODO make this key customizable
if (msg->scancode() == kKeyEsc) { // TODO make this key customizable
Command* cmd = CommandsModule::instance()->getCommandByName(CommandId::DeselectMask);
UIContext::instance()->executeCommand(cmd);
}
@ -354,7 +354,7 @@ bool MovingPixelsState::onKeyDown(Editor* editor, Message* msg)
return StandbyState::onKeyDown(editor, msg);
}
bool MovingPixelsState::onKeyUp(Editor* editor, Message* msg)
bool MovingPixelsState::onKeyUp(Editor* editor, KeyMessage* msg)
{
ASSERT(m_pixelsMovement != NULL);

View File

@ -32,19 +32,19 @@ class PixelsMovement;
class MovingPixelsState : public StandbyState, StatusBarObserver, ContextObserver
{
public:
MovingPixelsState(Editor* editor, ui::Message* msg, PixelsMovement* pixelsMovement, HandleType handle);
MovingPixelsState(Editor* editor, ui::MouseMessage* msg, PixelsMovement* pixelsMovement, HandleType handle);
virtual ~MovingPixelsState();
// EditorState
virtual BeforeChangeAction onBeforeChangeState(Editor* editor, EditorState* newState) OVERRIDE;
virtual void onCurrentToolChange(Editor* editor) OVERRIDE;
virtual bool onMouseDown(Editor* editor, ui::Message* msg) OVERRIDE;
virtual bool onMouseUp(Editor* editor, ui::Message* msg) OVERRIDE;
virtual bool onMouseMove(Editor* editor, ui::Message* msg) OVERRIDE;
virtual bool onMouseWheel(Editor* editor, ui::Message* msg) OVERRIDE;
virtual bool onMouseDown(Editor* editor, ui::MouseMessage* msg) OVERRIDE;
virtual bool onMouseUp(Editor* editor, ui::MouseMessage* msg) OVERRIDE;
virtual bool onMouseMove(Editor* editor, ui::MouseMessage* msg) OVERRIDE;
virtual bool onMouseWheel(Editor* editor, ui::MouseMessage* msg) OVERRIDE;
virtual bool onSetCursor(Editor* editor) OVERRIDE;
virtual bool onKeyDown(Editor* editor, ui::Message* msg) OVERRIDE;
virtual bool onKeyUp(Editor* editor, ui::Message* msg) OVERRIDE;
virtual bool onKeyDown(Editor* editor, ui::KeyMessage* msg) OVERRIDE;
virtual bool onKeyUp(Editor* editor, ui::KeyMessage* msg) OVERRIDE;
virtual bool onUpdateStatusBar(Editor* editor) OVERRIDE;
// ContextObserver

View File

@ -39,19 +39,19 @@ ScrollingState::~ScrollingState()
{
}
bool ScrollingState::onMouseDown(Editor* editor, Message* msg)
bool ScrollingState::onMouseDown(Editor* editor, MouseMessage* msg)
{
return true;
}
bool ScrollingState::onMouseUp(Editor* editor, Message* msg)
bool ScrollingState::onMouseUp(Editor* editor, MouseMessage* msg)
{
editor->backToPreviousState();
editor->releaseMouse();
return true;
}
bool ScrollingState::onMouseMove(Editor* editor, Message* msg)
bool ScrollingState::onMouseMove(Editor* editor, MouseMessage* msg)
{
View* view = View::getView(editor);
gfx::Rect vp = view->getViewportBounds();
@ -72,7 +72,7 @@ bool ScrollingState::onMouseMove(Editor* editor, Message* msg)
return true;
}
bool ScrollingState::onMouseWheel(Editor* editor, Message* msg)
bool ScrollingState::onMouseWheel(Editor* editor, MouseMessage* msg)
{
return false;
}
@ -84,12 +84,12 @@ bool ScrollingState::onSetCursor(Editor* editor)
return true;
}
bool ScrollingState::onKeyDown(Editor* editor, Message* msg)
bool ScrollingState::onKeyDown(Editor* editor, KeyMessage* msg)
{
return false;
}
bool ScrollingState::onKeyUp(Editor* editor, Message* msg)
bool ScrollingState::onKeyUp(Editor* editor, KeyMessage* msg)
{
return false;
}

View File

@ -28,13 +28,13 @@ public:
ScrollingState();
virtual ~ScrollingState();
virtual bool isTemporalState() const OVERRIDE { return true; }
virtual bool onMouseDown(Editor* editor, ui::Message* msg) OVERRIDE;
virtual bool onMouseUp(Editor* editor, ui::Message* msg) OVERRIDE;
virtual bool onMouseMove(Editor* editor, ui::Message* msg) OVERRIDE;
virtual bool onMouseWheel(Editor* editor, ui::Message* msg) OVERRIDE;
virtual bool onMouseDown(Editor* editor, ui::MouseMessage* msg) OVERRIDE;
virtual bool onMouseUp(Editor* editor, ui::MouseMessage* msg) OVERRIDE;
virtual bool onMouseMove(Editor* editor, ui::MouseMessage* msg) OVERRIDE;
virtual bool onMouseWheel(Editor* editor, ui::MouseMessage* msg) OVERRIDE;
virtual bool onSetCursor(Editor* editor) OVERRIDE;
virtual bool onKeyDown(Editor* editor, ui::Message* msg) OVERRIDE;
virtual bool onKeyUp(Editor* editor, ui::Message* msg) OVERRIDE;
virtual bool onKeyDown(Editor* editor, ui::KeyMessage* msg) OVERRIDE;
virtual bool onKeyUp(Editor* editor, ui::KeyMessage* msg) OVERRIDE;
virtual bool onUpdateStatusBar(Editor* editor) OVERRIDE;
};

View File

@ -68,13 +68,13 @@ void SelectBoxState::onBeforePopState(Editor* editor)
editor->setDecorator(NULL);
}
bool SelectBoxState::onMouseDown(Editor* editor, Message* msg)
bool SelectBoxState::onMouseDown(Editor* editor, MouseMessage* msg)
{
if (msg->mouse.left || msg->mouse.right) {
if (msg->left() || msg->right()) {
m_movingRuler = -1;
for (int i=0; i<(int)m_rulers.size(); ++i) {
if (touchRuler(editor, m_rulers[i], msg->mouse.x, msg->mouse.y)) {
if (touchRuler(editor, m_rulers[i], msg->position().x, msg->position().y)) {
m_movingRuler = i;
break;
}
@ -87,17 +87,17 @@ bool SelectBoxState::onMouseDown(Editor* editor, Message* msg)
return StandbyState::onMouseDown(editor, msg);
}
bool SelectBoxState::onMouseUp(Editor* editor, Message* msg)
bool SelectBoxState::onMouseUp(Editor* editor, MouseMessage* msg)
{
m_movingRuler = -1;
return StandbyState::onMouseUp(editor, msg);
}
bool SelectBoxState::onMouseMove(Editor* editor, Message* msg)
bool SelectBoxState::onMouseMove(Editor* editor, MouseMessage* msg)
{
if (m_movingRuler >= 0) {
int u, v;
editor->screenToEditor(msg->mouse.x, msg->mouse.y, &u, &v);
editor->screenToEditor(msg->position().x, msg->position().y, &u, &v);
switch (m_rulers[m_movingRuler].getOrientation()) {

View File

@ -55,9 +55,9 @@ public:
// EditorState overrides
virtual void onAfterChangeState(Editor* editor) OVERRIDE;
virtual void onBeforePopState(Editor* editor) OVERRIDE;
virtual bool onMouseDown(Editor* editor, ui::Message* msg) OVERRIDE;
virtual bool onMouseUp(Editor* editor, ui::Message* msg) OVERRIDE;
virtual bool onMouseMove(Editor* editor, ui::Message* msg) OVERRIDE;
virtual bool onMouseDown(Editor* editor, ui::MouseMessage* msg) OVERRIDE;
virtual bool onMouseUp(Editor* editor, ui::MouseMessage* msg) OVERRIDE;
virtual bool onMouseMove(Editor* editor, ui::MouseMessage* msg) OVERRIDE;
virtual bool onSetCursor(Editor* editor) OVERRIDE;
// Returns false as it overrides default standby state behavior &

View File

@ -84,11 +84,6 @@ static CursorType rotated_rotate_cursors[] = {
kRotateBRCursor
};
static inline bool has_shifts(Message* msg, int shift)
{
return ((msg->any.shifts & shift) == shift);
}
#pragma warning(disable:4355) // warning C4355: 'this' : used in base member initializer list
StandbyState::StandbyState()
@ -117,14 +112,14 @@ void StandbyState::onCurrentToolChange(Editor* editor)
editor->invalidate();
}
bool StandbyState::checkForScroll(Editor* editor, Message* msg)
bool StandbyState::checkForScroll(Editor* editor, MouseMessage* msg)
{
UIContext* context = UIContext::instance();
tools::Tool* currentTool = editor->getCurrentEditorTool();
tools::Ink* clickedInk = currentTool->getInk(msg->mouse.right ? 1: 0);
tools::Ink* clickedInk = currentTool->getInk(msg->right() ? 1: 0);
// Start scroll loop
if (msg->mouse.middle || clickedInk->isScrollMovement()) { // TODO raw msg->mouse.middle here, this should be customizable
if (msg->middle() || clickedInk->isScrollMovement()) { // TODO msg->middle() should be customizable
editor->setState(EditorStatePtr(new ScrollingState()));
editor->captureMouse();
return true;
@ -133,14 +128,14 @@ bool StandbyState::checkForScroll(Editor* editor, Message* msg)
return false;
}
bool StandbyState::onMouseDown(Editor* editor, Message* msg)
bool StandbyState::onMouseDown(Editor* editor, MouseMessage* msg)
{
if (editor->hasCapture())
return true;
UIContext* context = UIContext::instance();
tools::Tool* current_tool = editor->getCurrentEditorTool();
tools::Ink* clickedInk = current_tool->getInk(msg->mouse.right ? 1: 0);
tools::Ink* clickedInk = current_tool->getInk(msg->right() ? 1: 0);
DocumentLocation location;
editor->getDocumentLocation(&location);
Document* document = location.document();
@ -182,7 +177,7 @@ bool StandbyState::onMouseDown(Editor* editor, Message* msg)
// Get the handle covered by the mouse.
HandleType handle = transfHandles->getHandleAtPoint(editor,
gfx::Point(msg->mouse.x, msg->mouse.y),
msg->position(),
document->getTransformation());
if (handle != NoHandle) {
@ -204,7 +199,7 @@ bool StandbyState::onMouseDown(Editor* editor, Message* msg)
// Move selected pixels
if (editor->isInsideSelection() &&
current_tool->getInk(0)->isSelection() &&
msg->mouse.left) {
msg->left()) {
int x, y, opacity;
Image* image = location.image(&x, &y, &opacity);
if (image) {
@ -225,7 +220,7 @@ bool StandbyState::onMouseDown(Editor* editor, Message* msg)
CommandsModule::instance()->getCommandByName(CommandId::Eyedropper);
Params params;
params.set("target", msg->mouse.right ? "background": "foreground");
params.set("target", msg->right() ? "background": "foreground");
UIContext::instance()->executeCommand(eyedropper_cmd, &params);
return true;
@ -242,47 +237,47 @@ bool StandbyState::onMouseDown(Editor* editor, Message* msg)
return true;
}
bool StandbyState::onMouseUp(Editor* editor, Message* msg)
bool StandbyState::onMouseUp(Editor* editor, MouseMessage* msg)
{
editor->releaseMouse();
return true;
}
bool StandbyState::onMouseMove(Editor* editor, Message* msg)
bool StandbyState::onMouseMove(Editor* editor, MouseMessage* msg)
{
editor->moveDrawingCursor();
editor->updateStatusBar();
return true;
}
bool StandbyState::onMouseWheel(Editor* editor, Message* msg)
bool StandbyState::onMouseWheel(Editor* editor, MouseMessage* msg)
{
int dz = jmouse_z(1) - jmouse_z(0);
WHEEL_ACTION wheelAction = WHEEL_NONE;
bool scrollBigSteps = false;
// Without modifiers
if (!(msg->any.shifts & (KB_SHIFT_FLAG | KB_ALT_FLAG | KB_CTRL_FLAG))) {
if (msg->keyModifiers() == kKeyNoneModifier) {
wheelAction = WHEEL_ZOOM;
}
else {
#if 1 // TODO make it configurable
if (has_shifts(msg, KB_ALT_FLAG)) {
if (has_shifts(msg, KB_SHIFT_FLAG))
if (msg->altPressed()) {
if (msg->shiftPressed())
wheelAction = WHEEL_BG;
else
wheelAction = WHEEL_FG;
}
else if (has_shifts(msg, KB_CTRL_FLAG)) {
else if (msg->ctrlPressed()) {
wheelAction = WHEEL_FRAME;
}
#else
if (has_shifts(msg, KB_CTRL_FLAG))
if (msg->ctrlPressed())
wheelAction = WHEEL_HSCROLL;
else
wheelAction = WHEEL_VSCROLL;
if (has_shifts(msg, KB_SHIFT_FLAG))
if (msg->shiftPressed())
scrollBigSteps = true;
#endif
}
@ -329,9 +324,10 @@ bool StandbyState::onMouseWheel(Editor* editor, Message* msg)
break;
case WHEEL_ZOOM: {
MouseMessage* mouseMsg = static_cast<MouseMessage*>(msg);
int zoom = MID(MIN_ZOOM, editor->getZoom()-dz, MAX_ZOOM);
if (editor->getZoom() != zoom)
editor->setZoomAndCenterInMouse(zoom, msg->mouse.x, msg->mouse.y);
editor->setZoomAndCenterInMouse(zoom, mouseMsg->position().x, mouseMsg->position().y);
break;
}
@ -429,12 +425,12 @@ bool StandbyState::onSetCursor(Editor* editor)
return true;
}
bool StandbyState::onKeyDown(Editor* editor, Message* msg)
bool StandbyState::onKeyDown(Editor* editor, KeyMessage* msg)
{
return editor->processKeysToSetZoom(msg->key.scancode);
return editor->processKeysToSetZoom(msg);
}
bool StandbyState::onKeyUp(Editor* editor, Message* msg)
bool StandbyState::onKeyUp(Editor* editor, KeyMessage* msg)
{
return false;
}
@ -488,7 +484,7 @@ gfx::Transformation StandbyState::getTransformation(Editor* editor)
return editor->getDocument()->getTransformation();
}
void StandbyState::transformSelection(Editor* editor, Message* msg, HandleType handle)
void StandbyState::transformSelection(Editor* editor, MouseMessage* msg, HandleType handle)
{
EditorCustomizationDelegate* customization = editor->getCustomizationDelegate();
Document* document = editor->getDocument();

View File

@ -34,13 +34,13 @@ public:
virtual ~StandbyState();
virtual void onAfterChangeState(Editor* editor) OVERRIDE;
virtual void onCurrentToolChange(Editor* editor) OVERRIDE;
virtual bool onMouseDown(Editor* editor, ui::Message* msg) OVERRIDE;
virtual bool onMouseUp(Editor* editor, ui::Message* msg) OVERRIDE;
virtual bool onMouseMove(Editor* editor, ui::Message* msg) OVERRIDE;
virtual bool onMouseWheel(Editor* editor, ui::Message* msg) OVERRIDE;
virtual bool onMouseDown(Editor* editor, ui::MouseMessage* msg) OVERRIDE;
virtual bool onMouseUp(Editor* editor, ui::MouseMessage* msg) OVERRIDE;
virtual bool onMouseMove(Editor* editor, ui::MouseMessage* msg) OVERRIDE;
virtual bool onMouseWheel(Editor* editor, ui::MouseMessage* msg) OVERRIDE;
virtual bool onSetCursor(Editor* editor) OVERRIDE;
virtual bool onKeyDown(Editor* editor, ui::Message* msg) OVERRIDE;
virtual bool onKeyUp(Editor* editor, ui::Message* msg) OVERRIDE;
virtual bool onKeyDown(Editor* editor, ui::KeyMessage* msg) OVERRIDE;
virtual bool onKeyUp(Editor* editor, ui::KeyMessage* msg) OVERRIDE;
virtual bool onUpdateStatusBar(Editor* editor) OVERRIDE;
// Returns true as the standby state is the only one which shows the
@ -52,7 +52,7 @@ public:
protected:
// Returns true and changes to ScrollingState when "msg" says "the
// user wants to scroll".
bool checkForScroll(Editor* editor, ui::Message* msg);
bool checkForScroll(Editor* editor, ui::MouseMessage* msg);
class Decorator : public EditorDecorator
{
@ -73,7 +73,7 @@ protected:
};
private:
void transformSelection(Editor* editor, ui::Message* msg, HandleType handle);
void transformSelection(Editor* editor, ui::MouseMessage* msg, HandleType handle);
Decorator* m_decorator;
};

View File

@ -312,7 +312,7 @@ private:
};
tools::ToolLoop* create_tool_loop(Editor* editor, Context* context, Message* msg)
tools::ToolLoop* create_tool_loop(Editor* editor, Context* context, MouseMessage* msg)
{
tools::Tool* current_tool = context->getSettings()->getCurrentTool();
if (!current_tool)
@ -360,8 +360,8 @@ tools::ToolLoop* create_tool_loop(Editor* editor, Context* context, Message* msg
context,
current_tool,
editor->getDocument(),
msg->mouse.left ? tools::ToolLoop::Left:
tools::ToolLoop::Right,
msg->mouse.left ? fg: bg,
msg->mouse.left ? bg: fg);
msg->left() ? tools::ToolLoop::Left:
tools::ToolLoop::Right,
msg->left() ? fg: bg,
msg->left() ? bg: fg);
}

View File

@ -19,12 +19,12 @@
#ifndef WIDGETS_EDITOR_TOOL_LOOP_IMPL_H_INCLUDED
#define WIDGETS_EDITOR_TOOL_LOOP_IMPL_H_INCLUDED
namespace ui { union Message; }
namespace ui { class MouseMessage; }
namespace tools { class ToolLoop; }
class Context;
class Editor;
tools::ToolLoop* create_tool_loop(Editor* editor, Context* context, ui::Message* msg);
tools::ToolLoop* create_tool_loop(Editor* editor, Context* context, ui::MouseMessage* msg);
#endif

View File

@ -108,7 +108,7 @@ void FileList::goUp()
bool FileList::onProcessMessage(Message* msg)
{
switch (msg->type) {
switch (msg->type()) {
case kPaintMessage: {
SkinTheme* theme = static_cast<SkinTheme*>(getTheme());
@ -244,6 +244,7 @@ bool FileList::onProcessMessage(Message* msg)
case kMouseMoveMessage:
if (hasCapture()) {
MouseMessage* mouseMsg = static_cast<MouseMessage*>(msg);
int th = jwidget_get_text_height(this);
int y = this->rc->y1;
IFileItem* old_selected = m_selected;
@ -256,9 +257,10 @@ bool FileList::onProcessMessage(Message* msg)
IFileItem* fi = *it;
gfx::Size itemSize = getFileItemSize(fi);
if (((msg->mouse.y >= y) && (msg->mouse.y < y+2+th+2)) ||
(it == m_list.begin() && msg->mouse.y < y) ||
(it == m_list.end()-1 && msg->mouse.y >= y+2+th+2)) {
if (((mouseMsg->position().y >= y) &&
(mouseMsg->position().y < y+2+th+2)) ||
(it == m_list.begin() && mouseMsg->position().y < y) ||
(it == m_list.end()-1 && mouseMsg->position().y >= y+2+th+2)) {
m_selected = fi;
makeSelectedFileitemVisible();
break;
@ -286,49 +288,52 @@ bool FileList::onProcessMessage(Message* msg)
case kKeyDownMessage:
if (hasFocus()) {
KeyMessage* keyMsg = static_cast<KeyMessage*>(msg);
KeyScancode scancode = keyMsg->scancode();
int ascii = keyMsg->ascii();
int select = getSelectedIndex();
View* view = View::getView(this);
int bottom = m_list.size();
switch (msg->key.scancode) {
case KEY_UP:
switch (scancode) {
case kKeyUp:
if (select >= 0)
select--;
else
select = 0;
break;
case KEY_DOWN:
case kKeyDown:
if (select >= 0)
select++;
else
select = 0;
break;
case KEY_HOME:
case kKeyHome:
select = 0;
break;
case KEY_END:
case kKeyEnd:
select = bottom-1;
break;
case KEY_PGUP:
case KEY_PGDN: {
int sgn = (msg->key.scancode == KEY_PGUP) ? -1: 1;
case kKeyPageUp:
case kKeyPageDown: {
int sgn = (scancode == kKeyPageUp) ? -1: 1;
gfx::Rect vp = view->getViewportBounds();
if (select < 0)
select = 0;
select += sgn * vp.h / (2+jwidget_get_text_height(this)+2);
break;
}
case KEY_LEFT:
case KEY_RIGHT:
case kKeyLeft:
case kKeyRight:
if (select >= 0) {
gfx::Rect vp = view->getViewportBounds();
int sgn = (msg->key.scancode == KEY_LEFT) ? -1: 1;
int sgn = (scancode == kKeyLeft) ? -1: 1;
gfx::Point scroll = view->getViewScroll();
scroll.x += vp.w/2*sgn;
view->setViewScroll(scroll);
}
break;
case KEY_ENTER:
case kKeyEnter:
if (m_selected) {
if (m_selected->isBrowsable()) {
setCurrentFolder(m_selected);
@ -346,19 +351,19 @@ bool FileList::onProcessMessage(Message* msg)
}
else
return Widget::onProcessMessage(msg);
case KEY_BACKSPACE:
case kKeyBackspace:
goUp();
return true;
default:
if (msg->key.ascii == ' ' ||
(utolower(msg->key.ascii) >= 'a' &&
utolower(msg->key.ascii) <= 'z') ||
(utolower(msg->key.ascii) >= '0' &&
utolower(msg->key.ascii) <= '9')) {
if (ascii == ' ' ||
(utolower(ascii) >= 'a' &&
utolower(ascii) <= 'z') ||
(utolower(ascii) >= '0' &&
utolower(ascii) <= '9')) {
if (ji_clock - m_isearchClock > ISEARCH_KEYPRESS_INTERVAL_MSECS)
m_isearch.clear();
m_isearch.push_back(msg->key.ascii);
m_isearch.push_back(ascii);
int i, chrs = m_isearch.size();
FileItemList::iterator

View File

@ -112,7 +112,8 @@ public:
protected:
virtual bool onProcessMessage(Message* msg) OVERRIDE {
if (msg->type == kKeyUpMessage && msg->key.ascii >= 32) {
if (msg->type() == kKeyUpMessage &&
static_cast<KeyMessage*>(msg)->ascii() >= 32) {
// Check if all keys are released
for (int c=0; c<KEY_MAX; ++c) {
if (key[c])

View File

@ -169,7 +169,7 @@ void MainWindow::onActiveViewChange()
UIContext::instance()->setActiveView(docView);
}
void MainWindow::clickTab(Tabs* tabs, TabView* tabView, int button)
void MainWindow::clickTab(Tabs* tabs, TabView* tabView, ui::MouseButtons buttons)
{
if (!tabView)
return;
@ -182,14 +182,14 @@ void MainWindow::clickTab(Tabs* tabs, TabView* tabView, int button)
context->updateFlags();
// Right-button: popup-menu
if (button & 2) {
if (buttons & kButtonRight) {
Menu* popup_menu = AppMenus::instance()->getDocumentTabPopupMenu();
if (popup_menu != NULL) {
popup_menu->showPopup(jmouse_x(0), jmouse_y(0));
}
}
// Middle-button: close the sprite
else if (button & 4) {
else if (buttons & kButtonMiddle) {
Command* close_file_cmd =
CommandsModule::instance()->getCommandByName(CommandId::CloseFile);

View File

@ -53,7 +53,7 @@ public:
void setAdvancedMode(bool advanced);
// TabsDelegate implementation.
void clickTab(Tabs* tabs, TabView* tabView, int button);
void clickTab(Tabs* tabs, TabView* tabView, ui::MouseButtons buttons);
void mouseOverTab(Tabs* tabs, TabView* tabView);
protected:

View File

@ -48,7 +48,7 @@ MenuItem2::~MenuItem2()
bool MenuItem2::onProcessMessage(Message* msg)
{
switch (msg->type) {
switch (msg->type()) {
case kOpenMessage: {
UIContext* context = UIContext::instance();
@ -69,7 +69,7 @@ bool MenuItem2::onProcessMessage(Message* msg)
break;
default:
if (msg->type == kOpenMenuItemMessage) {
if (msg->type() == kOpenMenuItemMessage) {
// Update the context flags after opening the menuitem's
// submenu to update the "enabled" flag of each command
// correctly.

View File

@ -94,7 +94,7 @@ protected:
bool onProcessMessage(Message* msg) OVERRIDE
{
switch (msg->type) {
switch (msg->type()) {
case kSetCursorMessage:
jmouse_set_cursor(kArrowCursor);

View File

@ -199,7 +199,7 @@ app::Color PaletteView::getColorByPosition(int target_x, int target_y)
bool PaletteView::onProcessMessage(Message* msg)
{
switch (msg->type) {
switch (msg->type()) {
case kPaintMessage: {
div_t d = div(Palette::MaxColors, m_columns);
@ -266,13 +266,14 @@ bool PaletteView::onProcessMessage(Message* msg)
/* continue... */
case kMouseMoveMessage: {
MouseMessage* mouseMsg = static_cast<MouseMessage*>(msg);
gfx::Rect cpos = getChildrenBounds();
int req_w, req_h;
request_size(&req_w, &req_h);
int mouse_x = MID(cpos.x, msg->mouse.x, cpos.x+req_w-this->border_width.r-1);
int mouse_y = MID(cpos.y, msg->mouse.y, cpos.y+req_h-this->border_width.b-1);
int mouse_x = MID(cpos.x, mouseMsg->position().x, cpos.x+req_w-this->border_width.r-1);
int mouse_y = MID(cpos.y, mouseMsg->position().y, cpos.y+req_h-this->border_width.b-1);
app::Color color = getColorByPosition(mouse_x, mouse_y);
if (color.getType() == app::Color::IndexType) {
@ -281,10 +282,10 @@ bool PaletteView::onProcessMessage(Message* msg)
StatusBar::instance()->showColor(0, "", color, 255);
if (hasCapture() && idx != m_currentEntry) {
if (!(msg->any.shifts & KB_CTRL_FLAG))
if (!msg->ctrlPressed())
clearSelection();
if (msg->any.shifts & KB_SHIFT_FLAG)
if (msg->shiftPressed())
selectRange(m_rangeAnchor, idx);
else
selectColor(idx);

View File

@ -62,7 +62,7 @@ void PopupWindowPin::onPinClick(Event& ev)
bool PopupWindowPin::onProcessMessage(Message* msg)
{
switch (msg->type) {
switch (msg->type()) {
case kOpenMessage:
m_pin.setSelected(false);

View File

@ -105,7 +105,7 @@ public:
}
bool onProcessMessage(Message* msg) OVERRIDE {
switch (msg->type) {
switch (msg->type()) {
// When the mouse enter in this entry, it got the focus and the
// text is automatically selected.
case kMouseEnterMessage:
@ -113,9 +113,12 @@ public:
selectText(0, -1);
break;
case kKeyDownMessage:
if (msg->key.scancode == KEY_ENTER ||
msg->key.scancode == KEY_ENTER_PAD) {
case kKeyDownMessage: {
KeyMessage* keymsg = static_cast<KeyMessage*>(msg);
KeyScancode scancode = keymsg->scancode();
if (scancode == kKeyEnter || // TODO customizable keys
scancode == kKeyEnterPad) {
Command* cmd = CommandsModule::instance()->getCommandByName(CommandId::GotoFrame);
Params params;
int frame = strtol(this->getText(), NULL, 10);
@ -128,6 +131,7 @@ public:
return true; // Key used.
}
break;
}
}
return Entry::onProcessMessage(msg);
}
@ -470,16 +474,16 @@ double Progress::getPos() const
bool StatusBar::onProcessMessage(Message* msg)
{
switch (msg->type) {
switch (msg->type()) {
case kPaintMessage: {
gfx::Rect clip = static_cast<PaintMessage*>(msg)->rect();
SkinTheme* theme = static_cast<SkinTheme*>(this->getTheme());
ui::Color text_color = theme->getColor(ThemeColor::Text);
ui::Color face_color = theme->getColor(ThemeColor::Face);
Rect rc = getBounds();
BITMAP* doublebuffer = create_bitmap(jrect_w(&msg->draw.rect),
jrect_h(&msg->draw.rect));
rc.offset(-msg->draw.rect.x1, -msg->draw.rect.y1);
BITMAP* doublebuffer = create_bitmap(clip.w, clip.h);
rc.offset(-clip.x, -clip.y);
clear_to_color(doublebuffer, to_system(face_color));
@ -632,8 +636,8 @@ bool StatusBar::onProcessMessage(Message* msg)
}
blit(doublebuffer, ji_screen, 0, 0,
msg->draw.rect.x1,
msg->draw.rect.y1,
clip.x,
clip.y,
doublebuffer->w,
doublebuffer->h);
destroy_bitmap(doublebuffer);
@ -671,6 +675,7 @@ bool StatusBar::onProcessMessage(Message* msg)
}
case kMouseMoveMessage: {
MouseMessage* mouseMsg = static_cast<MouseMessage*>(msg);
gfx::Rect rc = getBounds().shrink(gfx::Border(2*jguiscale(), 1*jguiscale(),
2*jguiscale(), 2*jguiscale()));
@ -697,8 +702,7 @@ bool StatusBar::onProcessMessage(Message* msg)
int x2 = rc.x2()-width + (c+1)*width/count;
if (Rect(Point(x1, rc.y),
Point(x2, rc.y2())).contains(Point(msg->mouse.x,
msg->mouse.y))) {
Point(x2, rc.y2())).contains(mouseMsg->position())) {
hot_layer = LayerIndex(c);
break;
}
@ -710,8 +714,7 @@ bool StatusBar::onProcessMessage(Message* msg)
int x2 = rc.x2();
if (Rect(Point(x1, rc.y),
Point(x2, rc.y2())).contains(Point(msg->mouse.x,
msg->mouse.y))) {
Point(x2, rc.y2())).contains(mouseMsg->position())) {
hot_layer = LayerIndex(0);
}
}
@ -805,7 +808,7 @@ void StatusBar::onPreferredSize(PreferredSizeEvent& ev)
bool StatusBar::CustomizedTipWindow::onProcessMessage(Message* msg)
{
switch (msg->type) {
switch (msg->type()) {
case kTimerMessage:
closeWindow(NULL);

View File

@ -209,7 +209,7 @@ void Tabs::selectNextTab()
if (it != currentTabIt) {
selectTabInternal(*it);
if (m_delegate)
m_delegate->clickTab(this, m_selected->view, 1);
m_delegate->clickTab(this, m_selected->view, kButtonLeft);
}
}
}
@ -229,7 +229,7 @@ void Tabs::selectPreviousTab()
if (it != currentTabIt) {
selectTabInternal(*it);
if (m_delegate)
m_delegate->clickTab(this, m_selected->view, 1);
m_delegate->clickTab(this, m_selected->view, kButtonLeft);
}
}
}
@ -244,7 +244,7 @@ TabView* Tabs::getSelectedTab()
bool Tabs::onProcessMessage(Message* msg)
{
switch (msg->type) {
switch (msg->type()) {
case kMouseEnterMessage:
case kMouseMoveMessage:
@ -268,7 +268,7 @@ bool Tabs::onProcessMessage(Message* msg)
if (m_selected && m_delegate)
m_delegate->clickTab(this,
m_selected->view,
msg->mouse.flags);
static_cast<MouseMessage*>(msg)->buttons());
}
return true;
@ -300,7 +300,7 @@ bool Tabs::onProcessMessage(Message* msg)
case ANI_SCROLL: {
ScrollButton* button = dynamic_cast<ScrollButton*>(getManager()->getCapture());
if (button != NULL)
setScrollX(m_scrollX + button->getDirection()*8*msg->timer.count);
setScrollX(m_scrollX + button->getDirection()*8*static_cast<TimerMessage*>(msg)->count());
break;
}
case ANI_SMOOTH_SCROLL: {
@ -680,7 +680,7 @@ void Tabs::stopAni()
bool Tabs::ScrollButton::onProcessMessage(Message* msg)
{
switch (msg->type) {
switch (msg->type()) {
case kMouseDownMessage:
captureMouse();

View File

@ -20,6 +20,7 @@
#define WIDGETS_TABS_H_INCLUDED
#include "base/compiler_specific.h"
#include "ui/mouse_buttons.h"
#include "ui/timer.h"
#include "ui/widget.h"
@ -48,11 +49,8 @@ class TabsDelegate
public:
virtual ~TabsDelegate() { }
// Called when the user presses a mouse button over a tab
// button & 1 => left click
// button & 2 => right click
// button & 4 => middle click
virtual void clickTab(Tabs* tabs, TabView* tabView, int button) = 0;
// Called when the user presses a mouse button over a tab.
virtual void clickTab(Tabs* tabs, TabView* tabView, ui::MouseButtons buttons) = 0;
// Called when the mouse is over a tab (the data can be null if the
// mouse just leave all tabs)

View File

@ -124,11 +124,11 @@ bool ToolBar::isToolVisible(Tool* tool)
bool ToolBar::onProcessMessage(Message* msg)
{
switch (msg->type) {
switch (msg->type()) {
case kPaintMessage: {
BITMAP *doublebuffer = create_bitmap(jrect_w(&msg->draw.rect),
jrect_h(&msg->draw.rect));
const gfx::Rect& drawRect = static_cast<PaintMessage*>(msg)->rect();
BITMAP *doublebuffer = create_bitmap(drawRect.w, drawRect.h);
SkinTheme* theme = static_cast<SkinTheme*>(this->getTheme());
ui::Color normalFace = theme->getColor(ThemeColor::ButtonNormalFace);
ui::Color hotFace = theme->getColor(ThemeColor::ButtonHotFace);
@ -157,7 +157,7 @@ bool ToolBar::onProcessMessage(Message* msg)
}
toolrc = getToolGroupBounds(c);
toolrc.offset(-msg->draw.rect.x1, -msg->draw.rect.y1);
toolrc.offset(-drawRect.x, -drawRect.y);
theme->draw_bounds_nw(doublebuffer, toolrc, nw, face);
// Draw the tool icon
@ -172,7 +172,7 @@ bool ToolBar::onProcessMessage(Message* msg)
// Draw button to show tool configuration
toolrc = getToolGroupBounds(ConfigureToolIndex);
toolrc.offset(-msg->draw.rect.x1, -msg->draw.rect.y1);
toolrc.offset(-drawRect.x, -drawRect.y);
bool isHot = (m_hot_index == ConfigureToolIndex);
theme->draw_bounds_nw(doublebuffer,
toolrc,
@ -190,7 +190,7 @@ bool ToolBar::onProcessMessage(Message* msg)
// Draw button to show/hide mini editor
toolrc = getToolGroupBounds(MiniEditorVisibilityIndex);
toolrc.offset(-msg->draw.rect.x1, -msg->draw.rect.y1);
toolrc.offset(-drawRect.x, -drawRect.y);
isHot = (m_hot_index == MiniEditorVisibilityIndex ||
App::instance()->getMainWindow()->getMiniEditor()->isMiniEditorEnabled());
theme->draw_bounds_nw(doublebuffer,
@ -209,8 +209,8 @@ bool ToolBar::onProcessMessage(Message* msg)
// Blit result to screen
blit(doublebuffer, ji_screen, 0, 0,
msg->draw.rect.x1,
msg->draw.rect.y1,
drawRect.x,
drawRect.y,
doublebuffer->w,
doublebuffer->h);
destroy_bitmap(doublebuffer);
@ -218,6 +218,7 @@ bool ToolBar::onProcessMessage(Message* msg)
}
case kMouseDownMessage: {
MouseMessage* mouseMsg = static_cast<MouseMessage*>(msg);
ToolBox* toolbox = App::instance()->getToolBox();
int groups = toolbox->getGroupsCount();
Rect toolrc;
@ -231,7 +232,8 @@ bool ToolBar::onProcessMessage(Message* msg)
Tool* tool = m_selected_in_group[tool_group];
toolrc = getToolGroupBounds(c);
if (msg->mouse.y >= toolrc.y && msg->mouse.y < toolrc.y+toolrc.h) {
if (mouseMsg->position().y >= toolrc.y &&
mouseMsg->position().y < toolrc.y+toolrc.h) {
UIContext::instance()->getSettings()->setCurrentTool(tool);
invalidate();
@ -240,7 +242,8 @@ bool ToolBar::onProcessMessage(Message* msg)
}
toolrc = getToolGroupBounds(ConfigureToolIndex);
if (msg->mouse.y >= toolrc.y && msg->mouse.y < toolrc.y+toolrc.h) {
if (mouseMsg->position().y >= toolrc.y &&
mouseMsg->position().y < toolrc.y+toolrc.h) {
Command* conf_tools_cmd =
CommandsModule::instance()->getCommandByName(CommandId::ConfigureTools);
@ -248,7 +251,8 @@ bool ToolBar::onProcessMessage(Message* msg)
}
toolrc = getToolGroupBounds(MiniEditorVisibilityIndex);
if (msg->mouse.y >= toolrc.y && msg->mouse.y < toolrc.y+toolrc.h) {
if (mouseMsg->position().y >= toolrc.y &&
mouseMsg->position().y < toolrc.y+toolrc.h) {
// Switch the state of the mini editor
widgets::MiniEditorWindow* miniEditorWindow =
App::instance()->getMainWindow()->getMiniEditor();
@ -259,6 +263,7 @@ bool ToolBar::onProcessMessage(Message* msg)
}
case kMouseMoveMessage: {
MouseMessage* mouseMsg = static_cast<MouseMessage*>(msg);
ToolBox* toolbox = App::instance()->getToolBox();
int groups = toolbox->getGroupsCount();
Tool* new_hot_tool = NULL;
@ -272,7 +277,8 @@ bool ToolBar::onProcessMessage(Message* msg)
Tool* tool = m_selected_in_group[tool_group];
toolrc = getToolGroupBounds(c);
if (msg->mouse.y >= toolrc.y && msg->mouse.y < toolrc.y+toolrc.h) {
if (mouseMsg->position().y >= toolrc.y &&
mouseMsg->position().y < toolrc.y+toolrc.h) {
new_hot_tool = tool;
new_hot_index = c;
@ -283,12 +289,14 @@ bool ToolBar::onProcessMessage(Message* msg)
}
toolrc = getToolGroupBounds(ConfigureToolIndex);
if (msg->mouse.y >= toolrc.y && msg->mouse.y < toolrc.y+toolrc.h) {
if (mouseMsg->position().y >= toolrc.y &&
mouseMsg->position().y < toolrc.y+toolrc.h) {
new_hot_index = ConfigureToolIndex;
}
toolrc = getToolGroupBounds(MiniEditorVisibilityIndex);
if (msg->mouse.y >= toolrc.y && msg->mouse.y < toolrc.y+toolrc.h) {
if (mouseMsg->position().y >= toolrc.y &&
mouseMsg->position().y < toolrc.y+toolrc.h) {
new_hot_index = MiniEditorVisibilityIndex;
}
@ -324,7 +332,7 @@ bool ToolBar::onProcessMessage(Message* msg)
break;
case kTimerMessage:
if (msg->timer.timer == &m_tipTimer) {
if (static_cast<TimerMessage*>(msg)->timer() == &m_tipTimer) {
if (m_tipWindow)
m_tipWindow->openWindow();
@ -604,20 +612,20 @@ void ToolStrip::saveOverlappedArea(const Rect& bounds)
bool ToolStrip::onProcessMessage(Message* msg)
{
switch (msg->type) {
switch (msg->type()) {
case kPaintMessage: {
BITMAP *doublebuffer = create_bitmap(jrect_w(&msg->draw.rect),
jrect_h(&msg->draw.rect));
SkinTheme* theme = static_cast<SkinTheme*>(this->getTheme());
gfx::Rect paintarea = static_cast<PaintMessage*>(msg)->rect();
BITMAP *doublebuffer = create_bitmap(paintarea.w, paintarea.h);
SkinTheme* theme = static_cast<SkinTheme*>(getTheme());
ToolBox* toolbox = App::instance()->getToolBox();
Rect toolrc;
int index = 0;
// Get the chunk of screen where we will draw
blit(m_overlapped, doublebuffer,
this->rc->x1 - msg->draw.rect.x1,
this->rc->y1 - msg->draw.rect.y1, 0, 0,
this->rc->x1 - paintarea.x,
this->rc->y1 - paintarea.y, 0, 0,
doublebuffer->w,
doublebuffer->h);
@ -638,7 +646,7 @@ bool ToolStrip::onProcessMessage(Message* msg)
}
toolrc = getToolBounds(index++);
toolrc.offset(-msg->draw.rect.x1, -msg->draw.rect.y1);
toolrc.offset(-paintarea.x, -paintarea.y);
theme->draw_bounds_nw(doublebuffer, toolrc, nw, face);
// Draw the tool icon
@ -653,8 +661,8 @@ bool ToolStrip::onProcessMessage(Message* msg)
}
blit(doublebuffer, ji_screen, 0, 0,
msg->draw.rect.x1,
msg->draw.rect.y1,
paintarea.x,
paintarea.y,
doublebuffer->w,
doublebuffer->h);
destroy_bitmap(doublebuffer);
@ -662,6 +670,7 @@ bool ToolStrip::onProcessMessage(Message* msg)
}
case kMouseMoveMessage: {
gfx::Point mousePos = static_cast<MouseMessage*>(msg)->position();
ToolBox* toolbox = App::instance()->getToolBox();
Tool* hot_tool = NULL;
Rect toolrc;
@ -671,7 +680,7 @@ bool ToolStrip::onProcessMessage(Message* msg)
Tool* tool = *it;
if (tool->getGroup() == m_group) {
toolrc = getToolBounds(index++);
if (toolrc.contains(Point(msg->mouse.x, msg->mouse.y))) {
if (toolrc.contains(Point(mousePos.x, mousePos.y))) {
hot_tool = tool;
break;
}