bool onProcessMessage(Message* msg) override { switch (msg->type()) { case kKeyDownMessage: if (hasFocus() && !isReadOnly()) { KeyMessage* keymsg = static_cast<KeyMessage*>(msg); KeyModifiers modifiers = keymsg->keyModifiers(); if (keymsg->scancode() == kKeySpace) modifiers = (KeyModifiers)(modifiers & ~kKeySpaceModifier); m_accel = Accelerator( modifiers, keymsg->scancode(), keymsg->unicodeChar() > 32 ? std::tolower(keymsg->unicodeChar()): 0); // Convert the accelerator to a string, and parse it // again. Just to obtain the exact accelerator we'll read // when we import the gui.xml file or an .aseprite-keys file. m_accel = Accelerator(m_accel.toString()); updateText(); AccelChange(&m_accel); return true; } break; } return Entry::onProcessMessage(msg); }
bool IntEntry::onProcessMessage(Message* msg) { switch (msg->type()) { // Reset value if it's out of bounds when focus is lost case kFocusLeaveMessage: setValue(MID(m_min, getValue(), m_max)); deselectText(); break; case kMouseDownMessage: requestFocus(); captureMouse(); openPopup(); selectAllText(); return true; case kMouseMoveMessage: if (hasCapture()) { MouseMessage* mouseMsg = static_cast<MouseMessage*>(msg); Widget* pick = getManager()->pick(mouseMsg->position()); if (pick == &m_slider) { releaseMouse(); MouseMessage mouseMsg2(kMouseDownMessage, mouseMsg->buttons(), mouseMsg->modifiers(), mouseMsg->position()); m_slider.sendMessage(&mouseMsg2); } } break; case kMouseWheelMessage: if (isEnabled()) { int oldValue = getValue(); int newValue = oldValue + static_cast<MouseMessage*>(msg)->wheelDelta().x - static_cast<MouseMessage*>(msg)->wheelDelta().y; newValue = MID(m_min, newValue, m_max); if (newValue != oldValue) { setValue(newValue); selectAllText(); } return true; } break; case kKeyDownMessage: if (hasFocus() && !isReadOnly()) { KeyMessage* keymsg = static_cast<KeyMessage*>(msg); int chr = keymsg->unicodeChar(); if (chr < '0' || chr > '9') { // By-pass Entry::onProcessMessage() return Widget::onProcessMessage(msg); } } break; } return Entry::onProcessMessage(msg); }
bool IntEntry::onProcessMessage(Message* msg) { switch (msg->type()) { // Reset value if it's out of bounds when focus is lost case kFocusLeaveMessage: setValue(MID(m_min, getValue(), m_max)); deselectText(); break; case kMouseDownMessage: requestFocus(); captureMouse(); openPopup(); selectAllText(); return true; case kMouseMoveMessage: if (hasCapture()) { MouseMessage* mouseMsg = static_cast<MouseMessage*>(msg); Widget* pick = manager()->pick(mouseMsg->position()); if (pick == &m_slider) { releaseMouse(); MouseMessage mouseMsg2(kMouseDownMessage, mouseMsg->pointerType(), mouseMsg->buttons(), mouseMsg->modifiers(), mouseMsg->position()); m_slider.sendMessage(&mouseMsg2); } } break; case kMouseWheelMessage: if (isEnabled()) { int oldValue = getValue(); int newValue = oldValue + static_cast<MouseMessage*>(msg)->wheelDelta().x - static_cast<MouseMessage*>(msg)->wheelDelta().y; newValue = MID(m_min, newValue, m_max); if (newValue != oldValue) { setValue(newValue); selectAllText(); } return true; } break; case kKeyDownMessage: if (hasFocus() && !isReadOnly()) { KeyMessage* keymsg = static_cast<KeyMessage*>(msg); int chr = keymsg->unicodeChar(); if (chr >= 32 && (chr < '0' || chr > '9')) { // "Eat" all keys that aren't number return true; } // Else we use the default Entry processing function which // will process keys like Left/Right arrows, clipboard // handling, etc. } break; } return Entry::onProcessMessage(msg); }
bool Entry::onProcessMessage(Message* msg) { switch (msg->type()) { case kTimerMessage: if (hasFocus() && static_cast<TimerMessage*>(msg)->timer() == &m_timer) { // Blinking caret m_state = m_state ? false: true; invalidate(); } break; case kFocusEnterMessage: m_timer.start(); m_state = true; invalidate(); if (m_lock_selection) { m_lock_selection = false; } else { selectAllText(); m_recent_focused = true; } break; case kFocusLeaveMessage: invalidate(); m_timer.stop(); if (!m_lock_selection) deselectText(); m_recent_focused = false; break; case kKeyDownMessage: if (hasFocus() && !isReadOnly()) { // Command to execute EntryCmd cmd = EntryCmd::NoOp; KeyMessage* keymsg = static_cast<KeyMessage*>(msg); KeyScancode scancode = keymsg->scancode(); switch (scancode) { case kKeyLeft: if (msg->ctrlPressed()) cmd = EntryCmd::BackwardWord; else cmd = EntryCmd::BackwardChar; break; case kKeyRight: if (msg->ctrlPressed()) cmd = EntryCmd::ForwardWord; else cmd = EntryCmd::ForwardChar; break; case kKeyHome: cmd = EntryCmd::BeginningOfLine; break; case kKeyEnd: cmd = EntryCmd::EndOfLine; break; case kKeyDel: if (msg->shiftPressed()) cmd = EntryCmd::Cut; else cmd = EntryCmd::DeleteForward; break; case kKeyInsert: if (msg->shiftPressed()) cmd = EntryCmd::Paste; else if (msg->ctrlPressed()) cmd = EntryCmd::Copy; break; case kKeyBackspace: cmd = EntryCmd::DeleteBackward; break; default: // Map common Windows shortcuts for Cut/Copy/Paste #if defined __APPLE__ if (msg->onlyCmdPressed()) #else if (msg->onlyCtrlPressed()) #endif { switch (scancode) { case kKeyX: cmd = EntryCmd::Cut; break; case kKeyC: cmd = EntryCmd::Copy; break; case kKeyV: cmd = EntryCmd::Paste; break; } } else if (keymsg->unicodeChar() >= 32) { // Ctrl and Alt must be unpressed to insert a character // in the text-field. if ((msg->keyModifiers() & (kKeyCtrlModifier | kKeyAltModifier)) == 0) { cmd = EntryCmd::InsertChar; } } break; } if (cmd == EntryCmd::NoOp) break; executeCmd(cmd, keymsg->unicodeChar(), (msg->shiftPressed()) ? true: false); return true; } break; case kMouseDownMessage: captureMouse(); case kMouseMoveMessage: if (hasCapture()) { gfx::Point mousePos = static_cast<MouseMessage*>(msg)->position(); base::utf8_const_iterator utf8_begin = base::utf8_const_iterator(getText().begin()); base::utf8_const_iterator utf8_end = base::utf8_const_iterator(getText().end()); int textlen = base::utf8_length(getText()); int c, x; bool move = true; bool is_dirty = false; // Backward scroll if (mousePos.x < getBounds().x) { if (m_scroll > 0) { m_caret = --m_scroll; move = false; is_dirty = true; invalidate(); } } // Forward scroll else if (mousePos.x >= getBounds().x2()) { if (m_scroll < textlen - getAvailableTextLength()) { m_scroll++; x = getBounds().x + this->border_width.l; for (c=m_scroll; utf8_begin != utf8_end; ++c) { int ch = (c < textlen ? *(utf8_begin+c) : ' '); x += getFont()->charWidth(ch); if (x > getBounds().x2()-this->border_width.r) { c--; break; } } m_caret = c; move = false; is_dirty = true; invalidate(); } } c = getCaretFromMouse(static_cast<MouseMessage*>(msg)); if (static_cast<MouseMessage*>(msg)->left() || (move && !isPosInSelection(c))) { // Move caret if (move) { if (m_caret != c) { m_caret = c; is_dirty = true; invalidate(); } } // Move selection if (m_recent_focused) { m_recent_focused = false; m_select = m_caret; } else if (msg->type() == kMouseDownMessage) m_select = m_caret; } // Show the caret if (is_dirty) { m_timer.start(); m_state = true; } return true; } break; case kMouseUpMessage: if (hasCapture()) { releaseMouse(); MouseMessage* mouseMsg = static_cast<MouseMessage*>(msg); if (mouseMsg->right()) { // This flag is disabled in kFocusEnterMessage message handler. m_lock_selection = true; showEditPopupMenu(mouseMsg->position()); requestFocus(); } } return true; case kDoubleClickMessage: forwardWord(); m_select = m_caret; backwardWord(); invalidate(); return true; case kMouseEnterMessage: case kMouseLeaveMessage: // TODO theme stuff if (isEnabled()) invalidate(); break; } return Widget::onProcessMessage(msg); }
bool Entry::onProcessMessage(Message* msg) { switch (msg->type()) { case kTimerMessage: if (hasFocus() && static_cast<TimerMessage*>(msg)->timer() == &m_timer) { // Blinking caret m_state = m_state ? false: true; invalidate(); } break; case kFocusEnterMessage: if (shouldStartTimer(true)) m_timer.start(); m_state = true; invalidate(); if (m_lock_selection) { m_lock_selection = false; } else { selectAllText(); m_recent_focused = true; } // Start processing dead keys if (m_translate_dead_keys) os::instance()->setTranslateDeadKeys(true); break; case kFocusLeaveMessage: invalidate(); m_timer.stop(); if (!m_lock_selection) deselectText(); m_recent_focused = false; // Stop processing dead keys if (m_translate_dead_keys) os::instance()->setTranslateDeadKeys(false); break; case kKeyDownMessage: if (hasFocus() && !isReadOnly()) { // Command to execute EntryCmd cmd = EntryCmd::NoOp; KeyMessage* keymsg = static_cast<KeyMessage*>(msg); KeyScancode scancode = keymsg->scancode(); switch (scancode) { case kKeyLeft: if (msg->ctrlPressed() || msg->altPressed()) cmd = EntryCmd::BackwardWord; else if (msg->cmdPressed()) cmd = EntryCmd::BeginningOfLine; else cmd = EntryCmd::BackwardChar; break; case kKeyRight: if (msg->ctrlPressed() || msg->altPressed()) cmd = EntryCmd::ForwardWord; else if (msg->cmdPressed()) cmd = EntryCmd::EndOfLine; else cmd = EntryCmd::ForwardChar; break; case kKeyHome: cmd = EntryCmd::BeginningOfLine; break; case kKeyEnd: cmd = EntryCmd::EndOfLine; break; case kKeyDel: if (msg->shiftPressed()) cmd = EntryCmd::Cut; else if (msg->ctrlPressed()) cmd = EntryCmd::DeleteForwardToEndOfLine; else cmd = EntryCmd::DeleteForward; break; case kKeyInsert: if (msg->shiftPressed()) cmd = EntryCmd::Paste; else if (msg->ctrlPressed()) cmd = EntryCmd::Copy; break; case kKeyBackspace: if (msg->ctrlPressed()) cmd = EntryCmd::DeleteBackwardWord; else cmd = EntryCmd::DeleteBackward; break; default: // Map common macOS/Windows shortcuts for Cut/Copy/Paste/Select all #if defined __APPLE__ if (msg->onlyCmdPressed()) #else if (msg->onlyCtrlPressed()) #endif { switch (scancode) { case kKeyX: cmd = EntryCmd::Cut; break; case kKeyC: cmd = EntryCmd::Copy; break; case kKeyV: cmd = EntryCmd::Paste; break; case kKeyA: cmd = EntryCmd::SelectAll; break; } } break; } if (cmd == EntryCmd::NoOp) { if (keymsg->unicodeChar() >= 32) { executeCmd(EntryCmd::InsertChar, keymsg->unicodeChar(), (msg->shiftPressed()) ? true: false); // Select dead-key if (keymsg->isDeadKey()) { if (lastCaretPos() < m_maxsize) selectText(m_caret-1, m_caret); } return true; } // Consume all key down of modifiers only, e.g. so the user // can press first "Ctrl" key, and then "Ctrl+C" // combination. else if (keymsg->scancode() >= kKeyFirstModifierScancode) { return true; } else { break; // Propagate to manager } } executeCmd(cmd, keymsg->unicodeChar(), (msg->shiftPressed()) ? true: false); return true; } break; case kMouseDownMessage: captureMouse(); case kMouseMoveMessage: if (hasCapture()) { bool is_dirty = false; int c = getCaretFromMouse(static_cast<MouseMessage*>(msg)); if (static_cast<MouseMessage*>(msg)->left() || !isPosInSelection(c)) { // Move caret if (m_caret != c) { setCaretPos(c); is_dirty = true; invalidate(); } // Move selection if (m_recent_focused) { m_recent_focused = false; m_select = m_caret; } else if (msg->type() == kMouseDownMessage) m_select = m_caret; } // Show the caret if (is_dirty) { if (shouldStartTimer(true)) m_timer.start(); m_state = true; } return true; } break; case kMouseUpMessage: if (hasCapture()) { releaseMouse(); MouseMessage* mouseMsg = static_cast<MouseMessage*>(msg); if (mouseMsg->right()) { // This flag is disabled in kFocusEnterMessage message handler. m_lock_selection = true; showEditPopupMenu(mouseMsg->position()); requestFocus(); } } return true; case kDoubleClickMessage: forwardWord(); m_select = m_caret; backwardWord(); invalidate(); return true; case kMouseEnterMessage: case kMouseLeaveMessage: // TODO theme stuff if (isEnabled()) invalidate(); break; } return Widget::onProcessMessage(msg); }
bool ButtonSet::Item::onProcessMessage(ui::Message* msg) { switch (msg->type()) { case kFocusEnterMessage: case kFocusLeaveMessage: if (isEnabled()) { // TODO theme specific stuff invalidate(); } break; case ui::kKeyDownMessage: if (isEnabled() && hasText()) { KeyMessage* keymsg = static_cast<KeyMessage*>(msg); bool mnemonicPressed = (msg->altPressed() && getMnemonicChar() && getMnemonicChar() == tolower(keymsg->unicodeChar())); if (mnemonicPressed || (hasFocus() && keymsg->scancode() == kKeySpace)) { buttonSet()->setSelectedItem(this); buttonSet()->onItemChange(this); } } break; case ui::kMouseDownMessage: captureMouse(); buttonSet()->setSelectedItem(this); invalidate(); if (static_cast<MouseMessage*>(msg)->left() && !buttonSet()->m_triggerOnMouseUp) { buttonSet()->onItemChange(this); } break; case ui::kMouseUpMessage: if (hasCapture()) { releaseMouse(); invalidate(); if (static_cast<MouseMessage*>(msg)->left()) { if (buttonSet()->m_triggerOnMouseUp) buttonSet()->onItemChange(this); } else if (static_cast<MouseMessage*>(msg)->right()) { buttonSet()->onRightClick(this); } } break; case ui::kMouseMoveMessage: if (hasCapture()) { if (buttonSet()->m_offerCapture) offerCapture(static_cast<ui::MouseMessage*>(msg), buttonset_item_type()); } break; case ui::kMouseLeaveMessage: case ui::kMouseEnterMessage: invalidate(); break; } return Widget::onProcessMessage(msg); }
bool FileList::onProcessMessage(Message* msg) { switch (msg->type()) { case kMouseDownMessage: captureMouse(); case kMouseMoveMessage: if (hasCapture()) { MouseMessage* mouseMsg = static_cast<MouseMessage*>(msg); int th = getTextHeight(); int y = getBounds().y; IFileItem* old_selected = m_selected; m_selected = NULL; // rows for (FileItemList::iterator it=m_list.begin(); it!=m_list.end(); ++it) { IFileItem* fi = *it; gfx::Size itemSize = getFileItemSize(fi); if (((mouseMsg->position().y >= y) && (mouseMsg->position().y < y+th+4*jguiscale())) || (it == m_list.begin() && mouseMsg->position().y < y) || (it == m_list.end()-1 && mouseMsg->position().y >= y+th+4*jguiscale())) { m_selected = fi; makeSelectedFileitemVisible(); break; } y += itemSize.h; } if (old_selected != m_selected) { generatePreviewOfSelectedItem(); invalidate(); // Emit "FileSelected" event. onFileSelected(); } } break; case kMouseUpMessage: if (hasCapture()) { releaseMouse(); } break; case kKeyDownMessage: if (hasFocus()) { KeyMessage* keyMsg = static_cast<KeyMessage*>(msg); KeyScancode scancode = keyMsg->scancode(); int unicodeChar = keyMsg->unicodeChar(); int select = getSelectedIndex(); View* view = View::getView(this); int bottom = m_list.size(); switch (scancode) { case kKeyUp: if (select >= 0) select--; else select = 0; break; case kKeyDown: if (select >= 0) select++; else select = 0; break; case kKeyHome: select = 0; break; case kKeyEnd: select = bottom-1; break; case kKeyPageUp: case kKeyPageDown: { int sgn = (scancode == kKeyPageUp) ? -1: 1; gfx::Rect vp = view->getViewportBounds(); if (select < 0) select = 0; select += sgn * vp.h / (getTextHeight()+4*jguiscale()); break; } case kKeyLeft: case kKeyRight: if (select >= 0) { gfx::Rect vp = view->getViewportBounds(); int sgn = (scancode == kKeyLeft) ? -1: 1; gfx::Point scroll = view->getViewScroll(); scroll.x += vp.w/2*sgn; view->setViewScroll(scroll); } break; case kKeyEnter: case kKeyEnterPad: if (m_selected) { if (m_selected->isBrowsable()) { setCurrentFolder(m_selected); return true; } if (m_selected->isFolder()) { // Do nothing (is a folder but not browseable). return true; } else { // Emit "FileAccepted" event. onFileAccepted(); return true; } } else return Widget::onProcessMessage(msg); case kKeyBackspace: goUp(); return true; default: if (unicodeChar == ' ' || (utolower(unicodeChar) >= 'a' && utolower(unicodeChar) <= 'z') || (unicodeChar >= '0' && unicodeChar <= '9')) { if (ui::clock() - m_isearchClock > ISEARCH_KEYPRESS_INTERVAL_MSECS) m_isearch.clear(); m_isearch.push_back(unicodeChar); int i, chrs = m_isearch.size(); FileItemList::iterator link = m_list.begin() + ((select >= 0) ? select: 0); for (i=MAX(select, 0); i<bottom; ++i, ++link) { IFileItem* fi = *link; if (ustrnicmp(fi->getDisplayName().c_str(), m_isearch.c_str(), chrs) == 0) { select = i; break; } } m_isearchClock = ui::clock(); // Go to selectIndex... } else return Widget::onProcessMessage(msg); } if (bottom > 0) selectIndex(MID(0, select, bottom-1)); return true; } break; case kMouseWheelMessage: { View* view = View::getView(this); if (view) { gfx::Point scroll = view->getViewScroll(); scroll += static_cast<MouseMessage*>(msg)->wheelDelta() * 3*(getTextHeight()+4*jguiscale()); view->setViewScroll(scroll); } break; } case kDoubleClickMessage: if (m_selected) { if (m_selected->isBrowsable()) { setCurrentFolder(m_selected); return true; } else { onFileAccepted(); // Emit "FileAccepted" event. return true; } } break; } return Widget::onProcessMessage(msg); }