bool Window::onProcessMessage(Message* msg) { switch (msg->type()) { case kOpenMessage: m_killer = NULL; break; case kCloseMessage: saveLayout(); break; case kMouseDownMessage: { if (!m_isMoveable) break; clickedMousePos = static_cast<MouseMessage*>(msg)->position(); m_hitTest = hitTest(clickedMousePos); if (m_hitTest != HitTestNowhere && m_hitTest != HitTestClient) { if (clickedWindowPos == NULL) clickedWindowPos = new gfx::Rect(getBounds()); else *clickedWindowPos = getBounds(); captureMouse(); return true; } else break; } case kMouseUpMessage: if (hasCapture()) { releaseMouse(); jmouse_set_cursor(kArrowCursor); if (clickedWindowPos != NULL) { delete clickedWindowPos; clickedWindowPos = NULL; } m_hitTest = HitTestNowhere; return true; } break; case kMouseMoveMessage: if (!m_isMoveable) break; // Does it have the mouse captured? if (hasCapture()) { gfx::Point mousePos = static_cast<MouseMessage*>(msg)->position(); // Reposition/resize if (m_hitTest == HitTestCaption) { int x = clickedWindowPos->x + (mousePos.x - clickedMousePos.x); int y = clickedWindowPos->y + (mousePos.y - clickedMousePos.y); moveWindow(gfx::Rect(x, y, getBounds().w, getBounds().h), true); } else { int x, y, w, h; w = clickedWindowPos->w; h = clickedWindowPos->h; bool hitLeft = (m_hitTest == HitTestBorderNW || m_hitTest == HitTestBorderW || m_hitTest == HitTestBorderSW); bool hitTop = (m_hitTest == HitTestBorderNW || m_hitTest == HitTestBorderN || m_hitTest == HitTestBorderNE); bool hitRight = (m_hitTest == HitTestBorderNE || m_hitTest == HitTestBorderE || m_hitTest == HitTestBorderSE); bool hitBottom = (m_hitTest == HitTestBorderSW || m_hitTest == HitTestBorderS || m_hitTest == HitTestBorderSE); if (hitLeft) { w += clickedMousePos.x - mousePos.x; } else if (hitRight) { w += mousePos.x - clickedMousePos.x; } if (hitTop) { h += (clickedMousePos.y - mousePos.y); } else if (hitBottom) { h += (mousePos.y - clickedMousePos.y); } limitSize(&w, &h); if ((getBounds().w != w) || (getBounds().h != h)) { if (hitLeft) x = clickedWindowPos->x - (w - clickedWindowPos->w); else x = getBounds().x; if (hitTop) y = clickedWindowPos->y - (h - clickedWindowPos->h); else y = getBounds().y; moveWindow(gfx::Rect(x, y, w, h), false); invalidate(); } } } break; case kSetCursorMessage: if (m_isMoveable) { gfx::Point mousePos = static_cast<MouseMessage*>(msg)->position(); HitTest ht = hitTest(mousePos); CursorType cursor = kArrowCursor; switch (ht) { case HitTestCaption: cursor = kArrowCursor; break; case HitTestBorderNW: cursor = kSizeTLCursor; break; case HitTestBorderW: cursor = kSizeLCursor; break; case HitTestBorderSW: cursor = kSizeBLCursor; break; case HitTestBorderNE: cursor = kSizeTRCursor; break; case HitTestBorderE: cursor = kSizeRCursor; break; case HitTestBorderSE: cursor = kSizeBRCursor; break; case HitTestBorderN: cursor = kSizeTCursor; break; case HitTestBorderS: cursor = kSizeBCursor; break; } jmouse_set_cursor(cursor); return true; } break; } return Widget::onProcessMessage(msg); }
bool TextBox::onProcessMessage(Message* msg) { switch (msg->type()) { case kKeyDownMessage: if (hasFocus()) { View* view = View::getView(this); if (view) { gfx::Rect vp = view->getViewportBounds(); gfx::Point scroll = view->getViewScroll(); int textheight = getTextHeight(); switch (static_cast<KeyMessage*>(msg)->scancode()) { case kKeyLeft: scroll.x -= vp.w/2; view->setViewScroll(scroll); break; case kKeyRight: scroll.x += vp.w/2; view->setViewScroll(scroll); break; case kKeyUp: scroll.y -= vp.h/2; view->setViewScroll(scroll); break; case kKeyDown: scroll.y += vp.h/2; view->setViewScroll(scroll); break; case kKeyPageUp: scroll.y -= (vp.h-textheight); view->setViewScroll(scroll); break; case kKeyPageDown: scroll.y += (vp.h-textheight); view->setViewScroll(scroll); break; case kKeyHome: scroll.y = 0; view->setViewScroll(scroll); break; case kKeyEnd: scroll.y = getBounds().h - vp.h; view->setViewScroll(scroll); break; default: return Widget::onProcessMessage(msg); } } return true; } break; case kMouseDownMessage: { View* view = View::getView(this); if (view) { captureMouse(); m_oldPos = static_cast<MouseMessage*>(msg)->position(); set_mouse_cursor(kScrollCursor); return true; } break; } case kMouseMoveMessage: { View* view = View::getView(this); if (view && hasCapture()) { gfx::Point scroll = view->getViewScroll(); gfx::Point newPos = static_cast<MouseMessage*>(msg)->position(); scroll += m_oldPos - newPos; view->setViewScroll(scroll); m_oldPos = newPos; } break; } case kMouseUpMessage: { View* view = View::getView(this); if (view && hasCapture()) { releaseMouse(); set_mouse_cursor(kArrowCursor); return true; } break; } case kMouseWheelMessage: { View* view = View::getView(this); if (view) { gfx::Point scroll = view->getViewScroll(); scroll += static_cast<MouseMessage*>(msg)->wheelDelta() * getTextHeight()*3; view->setViewScroll(scroll); } break; } } return Widget::onProcessMessage(msg); }
bool TextBox::onProcessMessage(Message* msg) { switch (msg->type) { case JM_DRAW: getTheme()->draw_textbox(this, &msg->draw.rect); return true; case JM_SIGNAL: if (msg->signal.num == JI_SIGNAL_SET_TEXT) { View* view = View::getView(this); if (view) view->updateView(); } break; case JM_KEYPRESSED: if (hasFocus()) { View* view = View::getView(this); if (view) { gfx::Rect vp = view->getViewportBounds(); gfx::Point scroll = view->getViewScroll(); int textheight = jwidget_get_text_height(this); switch (msg->key.scancode) { case KEY_LEFT: scroll.x -= vp.w/2; view->setViewScroll(scroll); break; case KEY_RIGHT: scroll.x += vp.w/2; view->setViewScroll(scroll); break; case KEY_UP: scroll.y -= vp.h/2; view->setViewScroll(scroll); break; case KEY_DOWN: scroll.y += vp.h/2; view->setViewScroll(scroll); break; case KEY_PGUP: scroll.y -= (vp.h-textheight); view->setViewScroll(scroll); break; case KEY_PGDN: scroll.y += (vp.h-textheight); view->setViewScroll(scroll); break; case KEY_HOME: scroll.y = 0; view->setViewScroll(scroll); break; case KEY_END: scroll.y = jrect_h(this->rc) - vp.h; view->setViewScroll(scroll); break; default: return false; } } return true; } break; case JM_BUTTONPRESSED: { View* view = View::getView(this); if (view) { captureMouse(); jmouse_set_cursor(JI_CURSOR_SCROLL); return true; } break; } case JM_MOTION: { View* view = View::getView(this); if (view && hasCapture()) { gfx::Rect vp = view->getViewportBounds(); gfx::Point scroll = view->getViewScroll(); scroll.x += jmouse_x(1) - jmouse_x(0); scroll.y += jmouse_y(1) - jmouse_y(0); view->setViewScroll(scroll); jmouse_control_infinite_scroll(vp); } break; } case JM_BUTTONRELEASED: { View* view = View::getView(this); if (view && hasCapture()) { releaseMouse(); jmouse_set_cursor(JI_CURSOR_NORMAL); return true; } break; } case JM_WHEEL: { View* view = View::getView(this); if (view) { gfx::Point scroll = view->getViewScroll(); scroll.y += (jmouse_z(1) - jmouse_z(0)) * jwidget_get_text_height(this)*3; view->setViewScroll(scroll); } break; } } return Widget::onProcessMessage(msg); }
bool ListBox::onProcessMessage(Message* msg) { switch (msg->type()) { case kOpenMessage: centerScroll(); break; case kMouseDownMessage: captureMouse(); case kMouseMoveMessage: if (hasCapture()) { gfx::Point mousePos = static_cast<MouseMessage*>(msg)->position(); int select = getSelectedIndex(); View* view = View::getView(this); bool pick_item = true; if (view) { gfx::Rect vp = view->getViewportBounds(); if (mousePos.y < vp.y) { int num = MAX(1, (vp.y - mousePos.y) / 8); selectIndex(select-num); pick_item = false; } 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; } } if (pick_item) { Widget* picked; if (view) { picked = view->getViewport()->pick(mousePos); } else { picked = pick(mousePos); } /* if the picked widget is a child of the list, select it */ if (picked && hasChild(picked)) { if (ListItem* pickedItem = dynamic_cast<ListItem*>(picked)) selectChild(pickedItem); } } return true; } break; case kMouseUpMessage: releaseMouse(); break; case kMouseWheelMessage: { View* view = View::getView(this); if (view) { gfx::Point scroll = view->getViewScroll(); scroll += static_cast<MouseMessage*>(msg)->wheelDelta() * getTextHeight()*3; view->setViewScroll(scroll); } break; } case kKeyDownMessage: if (hasFocus() && !getChildren().empty()) { int select = getSelectedIndex(); View* view = View::getView(this); int bottom = MAX(0, getChildren().size()-1); KeyMessage* keymsg = static_cast<KeyMessage*>(msg); switch (keymsg->scancode()) { case kKeyUp: // Select previous element. if (select >= 0) select--; // Or select the bottom of the list if there is no // selected item. else select = bottom; break; case kKeyDown: select++; break; case kKeyHome: select = 0; break; case kKeyEnd: select = bottom; break; case kKeyPageUp: if (view) { gfx::Rect vp = view->getViewportBounds(); select -= vp.h / getTextHeight(); } else select = 0; break; case kKeyPageDown: if (view) { gfx::Rect vp = view->getViewportBounds(); select += vp.h / getTextHeight(); } else select = bottom; break; case kKeyLeft: case kKeyRight: if (view) { gfx::Rect vp = view->getViewportBounds(); gfx::Point scroll = view->getViewScroll(); int sgn = (keymsg->scancode() == kKeyLeft) ? -1: 1; scroll.x += vp.w/2*sgn; view->setViewScroll(scroll); } break; default: return Widget::onProcessMessage(msg); } selectIndex(MID(0, select, bottom)); return true; } break; case kDoubleClickMessage: onDoubleClickItem(); return true; } return Widget::onProcessMessage(msg); }
bool ButtonBase::onProcessMessage(Message* msg) { switch (msg->type()) { case kFocusEnterMessage: case kFocusLeaveMessage: if (isEnabled()) { if (m_behaviorType == kButtonWidget) { // Deselect the widget (maybe the user press the key, but // before release it, changes the focus). if (isSelected()) setSelected(false); } // TODO theme specific stuff invalidate(); } break; case kKeyDownMessage: { KeyMessage* keymsg = static_cast<KeyMessage*>(msg); KeyScancode scancode = keymsg->scancode(); // If the button is enabled. if (isEnabled()) { bool mnemonicPressed = ((msg->altPressed() || msg->cmdPressed()) && isMnemonicPressed(keymsg)); // For kButtonWidget if (m_behaviorType == kButtonWidget) { // Has focus and press enter/space if (hasFocus()) { if ((scancode == kKeyEnter) || (scancode == kKeyEnterPad) || (scancode == kKeySpace)) { setSelected(true); return true; } } // Check if the user pressed mnemonic. if (mnemonicPressed) { setSelected(true); return true; } // Magnetic widget catches ENTERs else if (isFocusMagnet() && ((scancode == kKeyEnter) || (scancode == kKeyEnterPad))) { manager()->setFocus(this); // Dispatch focus movement messages (because the buttons // process them) manager()->dispatchMessages(); setSelected(true); return true; } } // For kCheckWidget or kRadioWidget else { /* 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() && (scancode == kKeySpace)) || mnemonicPressed) { if (m_behaviorType == kCheckWidget) { // Swap the select status setSelected(!isSelected()); invalidate(); } else if (m_behaviorType == kRadioWidget) { if (!isSelected()) { setSelected(true); } } return true; } } } break; } case kKeyUpMessage: if (isEnabled()) { if (m_behaviorType == kButtonWidget) { if (isSelected()) { generateButtonSelectSignal(); return true; } } } break; case kMouseDownMessage: switch (m_behaviorType) { case kButtonWidget: if (isEnabled()) { setSelected(true); m_pressedStatus = isSelected(); captureMouse(); } return true; case kCheckWidget: if (isEnabled()) { setSelected(!isSelected()); m_pressedStatus = isSelected(); captureMouse(); } return true; case kRadioWidget: if (isEnabled()) { if (!isSelected()) { m_handleSelect = false; setSelected(true); m_handleSelect = true; m_pressedStatus = isSelected(); captureMouse(); } } return true; } break; case kMouseUpMessage: if (hasCapture()) { releaseMouse(); if (hasMouseOver()) { switch (m_behaviorType) { case kButtonWidget: generateButtonSelectSignal(); break; case kCheckWidget: { // Fire onClick() event Event ev(this); onClick(ev); invalidate(); } break; case kRadioWidget: { setSelected(false); setSelected(true); // Fire onClick() event Event ev(this); onClick(ev); } break; } } return true; } break; case kMouseMoveMessage: if (isEnabled() && hasCapture()) { bool hasMouse = hasMouseOver(); m_handleSelect = false; // Switch state when the mouse go out if ((hasMouse && isSelected() != m_pressedStatus) || (!hasMouse && isSelected() == m_pressedStatus)) { if (hasMouse) setSelected(m_pressedStatus); else setSelected(!m_pressedStatus); } m_handleSelect = true; } break; case kMouseEnterMessage: case kMouseLeaveMessage: // TODO theme stuff if (isEnabled()) invalidate(); break; } return Widget::onProcessMessage(msg); }
bool ColorButton::onProcessMessage(Message* msg) { switch (msg->type) { case JM_CLOSE: if (m_frame && m_frame->isVisible()) m_frame->closeWindow(NULL); break; case JM_MOUSEENTER: app_get_statusbar()->showColor(0, "", m_color, 255); break; case JM_MOUSELEAVE: app_get_statusbar()->clearText(); break; case JM_SIGNAL: if (msg->signal.num == JI_SIGNAL_BUTTON_SELECT) { // If the popup window was not created or shown yet.. if (m_frame == NULL || !m_frame->isVisible()) { // Open it openSelectorDialog(); } else if (!m_frame->is_moveable()) { // If it is visible, close it closeSelectorDialog(); } return true; } break; case JM_MOTION: if (hasCapture()) { Widget* picked = ji_get_default_manager()->pick(msg->mouse.x, msg->mouse.y); Color color = m_color; if (picked && picked != this) { // Pick a color from another color-button if (ColorButton* pickedColBut = dynamic_cast<ColorButton*>(picked)) { color = pickedColBut->getColor(); } // Pick a color from the color-bar else if (picked->type == palette_view_type()) { color = ((PaletteView*)picked)->getColorByPosition(msg->mouse.x, msg->mouse.y); } // Pick a color from a editor else if (picked->type == editor_type()) { Editor* editor = static_cast<Editor*>(picked); Sprite* sprite = editor->getSprite(); int x, y, imgcolor; if (sprite) { x = msg->mouse.x; y = msg->mouse.y; editor->screenToEditor(x, y, &x, &y); imgcolor = sprite->getPixel(x, y); color = Color::fromImage(sprite->getImgType(), imgcolor); } } } // Did the color change? if (color != m_color) { setColor(color); } } break; case JM_SETCURSOR: if (hasCapture()) { jmouse_set_cursor(JI_CURSOR_EYEDROPPER); return true; } break; } return ButtonBase::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 ColorShades::onProcessMessage(ui::Message* msg) { switch (msg->type()) { case ui::kOpenMessage: if (m_click == DragAndDropEntries) { // TODO This connection should be in the ContextBar m_conn = ColorBar::instance()->ChangeSelection.connect( base::Bind<void>(&ColorShades::onChangeColorBarSelection, this)); } break; case ui::kSetCursorMessage: if (hasCapture()) { ui::set_mouse_cursor(ui::kMoveCursor); return true; } else if (m_click == ClickEntries && m_hotIndex >= 0 && m_hotIndex < int(m_shade.size())) { ui::set_mouse_cursor(ui::kHandCursor); return true; } break; case ui::kMouseEnterMessage: case ui::kMouseLeaveMessage: if (!hasCapture()) m_hotIndex = -1; invalidate(); break; case ui::kMouseDownMessage: if (m_hotIndex >= 0 && m_hotIndex < int(m_shade.size())) { switch (m_click) { case ClickEntries: Click(); m_hotIndex = -1; invalidate(); break; case DragAndDropEntries: m_dragIndex = m_hotIndex; m_dropBefore = false; captureMouse(); break; } } break; case ui::kMouseUpMessage: { if (m_click == ClickWholeShade) { setSelected(true); Click(); closeWindow(); } if (m_dragIndex >= 0) { ASSERT(m_dragIndex < int(m_shade.size())); auto color = m_shade[m_dragIndex]; m_shade.erase(m_shade.begin()+m_dragIndex); if (m_hotIndex >= 0) m_shade.insert(m_shade.begin()+m_hotIndex, color); m_dragIndex = -1; invalidate(); // Relayout the context bar if we have removed an entry. if (m_hotIndex < 0) parent()->parent()->layout(); } if (hasCapture()) releaseMouse(); break; } case ui::kMouseMoveMessage: { ui::MouseMessage* mouseMsg = static_cast<ui::MouseMessage*>(msg); gfx::Point mousePos = mouseMsg->position() - bounds().origin(); gfx::Rect bounds = clientBounds(); int hot = -1; bounds.shrink(3*ui::guiscale()); if (bounds.contains(mousePos)) { int count = size(); hot = (mousePos.x - bounds.x) / (m_boxSize*ui::guiscale()); hot = MID(0, hot, count-1); } if (m_hotIndex != hot) { m_hotIndex = hot; invalidate(); } bool dropBefore = (hot >= 0 && mousePos.x < (bounds.x+m_boxSize*ui::guiscale()*hot)+m_boxSize*ui::guiscale()/2); if (m_dropBefore != dropBefore) { m_dropBefore = dropBefore; invalidate(); } break; } } return Widget::onProcessMessage(msg); }
bool GLUICurveEditor::onMotion( GLUIMouseEvent* mouseEvent ) { if( !mouseEvent->leftDown && !mouseEvent->rightDown ) return true; if( !hasCapture() ) return true; int x = mouseEvent->x; int y = mouseEvent->y; // Check if we're dragging a knot if( trajectory && pointHeldIdx >= 0 && pointHeldIdx < trajectory->getKnotCount() && mouseEvent->leftDown ) { // Compute the new value double newVal = pixelToVal( y ); trajectory->setKnotValue( pointHeldIdx, newVal ); if( canEditPosition ) { // Compute the new position double newPos = pixelToPos( x ); // Make sure new position is legal (> than previous knot, < than next knot, > 0) if( pointHeldIdx > 0 ) { if( newPos <= trajectory->getKnotPosition(pointHeldIdx-1) ) newPos = trajectory->getKnotPosition(pointHeldIdx-1) + 0.00001; } if( pointHeldIdx < trajectory->getKnotCount()-1 ) { if( newPos >= trajectory->getKnotPosition(pointHeldIdx+1) ) newPos = trajectory->getKnotPosition(pointHeldIdx+1) - 0.00001; } trajectory->setKnotPosition( pointHeldIdx, newPos ); } return true; } // No, then we're dragging the background if( mouseEvent->leftDown ) { // Translate view double deltaY = pixelVecToVal(holdPosY - y); minVal += deltaY; maxVal += deltaY; holdPosY = y; if( canMoveHorizontally ) { double deltaX = pixelVecToPos(holdPosX - x); minPos += deltaX; maxPos += deltaX; holdPosX = x; } } if( mouseEvent->rightDown ) { // Scale view double scaleY = (y - holdPosY)/(double)rect.height * 2.0f; if( scaleY >= 0 ) scaleY = 1.0+scaleY; else scaleY = 1.0 / (1.0-scaleY); double midVal = (minVal+maxVal)/2.0; double sizeY = (maxVal-minVal)*scaleY; minVal = midVal - sizeY/2.0; maxVal = midVal + sizeY/2.0; holdPosY = y; if( canScaleHorizontally ) { double scaleX = (holdPosX - x)/(double)rect.width * 2.0f; if( scaleX >= 0 ) scaleX = 1.0+scaleX; else scaleX = 1.0 / (1.0-scaleX); double midPos = (minPos+maxPos)/2.0; double sizeX = (maxPos-minPos)*scaleX; minPos = midPos - sizeX/2.0; maxPos = midPos + sizeX/2.0; holdPosX = x; } } return true; }
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 Slider::onProcessMessage(Message* msg) { switch (msg->type()) { case kFocusEnterMessage: case kFocusLeaveMessage: if (isEnabled()) invalidate(); break; case kMouseDownMessage: if (!isEnabled() || isReadOnly()) return true; setSelected(true); captureMouse(); { 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(); // Fall through case kMouseMoveMessage: 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 * (mousePos.x - rc.x) / rc.w; } // With right click else { accuracy = MID(1, rc.w / range, rc.w); value = slider_press_value + (mousePos.x - slider_press_x) / accuracy; } value = MID(m_min, value, m_max); if (m_value != value) { setValue(value); onChange(); } return true; } break; case kMouseUpMessage: if (hasCapture()) { setSelected(false); releaseMouse(); setupSliderCursor(); onSliderReleased(); } break; case kMouseEnterMessage: case kMouseLeaveMessage: // TODO theme stuff if (isEnabled()) invalidate(); break; case kKeyDownMessage: if (hasFocus() && !isReadOnly()) { int min = m_min; int max = m_max; int value = m_value; 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) { setValue(value); onChange(); } return true; } break; case kMouseWheelMessage: if (isEnabled() && !isReadOnly()) { int value = m_value + static_cast<MouseMessage*>(msg)->wheelDelta().x - static_cast<MouseMessage*>(msg)->wheelDelta().y; value = MID(m_min, value, m_max); if (m_value != value) { this->setValue(value); onChange(); } return true; } break; case kSetCursorMessage: setupSliderCursor(); return true; } not_used:; return Widget::onProcessMessage(msg); }
bool PaletteView::onProcessMessage(Message* msg) { switch (msg->type) { case JM_REQSIZE: request_size(&msg->reqsize.w, &msg->reqsize.h); return true; case JM_DRAW: { div_t d = div(Palette::MaxColors, m_columns); int cols = m_columns; int rows = d.quot + ((d.rem)? 1: 0); int x, y, u, v; int c, color; BITMAP *bmp; Palette* palette = get_current_palette(); int bordercolor = makecol(255, 255, 255); bmp = create_bitmap(jrect_w(this->rc), jrect_h(this->rc)); clear_to_color(bmp, makecol(0 , 0, 0)); y = this->border_width.t; c = 0; for (v=0; v<rows; v++) { x = this->border_width.l; for (u=0; u<cols; u++) { if (c >= palette->size()) break; if (bitmap_color_depth(ji_screen) == 8) color = c; else color = makecol_depth (bitmap_color_depth(ji_screen), _rgba_getr(palette->getEntry(c)), _rgba_getg(palette->getEntry(c)), _rgba_getb(palette->getEntry(c))); rectfill(bmp, x, y, x+m_boxsize-1, y+m_boxsize-1, color); if (m_selectedEntries[c]) { const int max = Palette::MaxColors; bool top = (c >= m_columns && c-m_columns >= 0 ? m_selectedEntries[c-m_columns]: false); bool bottom = (c < max-m_columns && c+m_columns < max ? m_selectedEntries[c+m_columns]: false); bool left = ((c%m_columns)>0 && c-1 >= 0 ? m_selectedEntries[c-1]: false); bool right = ((c%m_columns)<m_columns-1 && c+1 < max ? m_selectedEntries[c+1]: false); if (!top) hline(bmp, x-1, y-1, x+m_boxsize, bordercolor); if (!bottom) hline(bmp, x-1, y+m_boxsize, x+m_boxsize, bordercolor); if (!left) vline(bmp, x-1, y-1, y+m_boxsize, bordercolor); if (!right) vline(bmp, x+m_boxsize, y-1, y+m_boxsize, bordercolor); } x += m_boxsize+this->child_spacing; c++; } y += m_boxsize+this->child_spacing; } blit(bmp, ji_screen, 0, 0, this->rc->x1, this->rc->y1, bmp->w, bmp->h); destroy_bitmap(bmp); return true; } case JM_BUTTONPRESSED: captureMouse(); /* continue... */ case JM_MOTION: { JRect cpos = jwidget_get_child_rect(this); int req_w, req_h; request_size(&req_w, &req_h); int mouse_x = MID(cpos->x1, msg->mouse.x, cpos->x1+req_w-this->border_width.r-1); int mouse_y = MID(cpos->y1, msg->mouse.y, cpos->y1+req_h-this->border_width.b-1); jrect_free(cpos); Color color = getColorByPosition(mouse_x, mouse_y); if (color.getType() == Color::IndexType) { int idx = color.getIndex(); app_get_statusbar()->showColor(0, "", color, 255); if (hasCapture() && idx != m_currentEntry) { if (!(msg->any.shifts & KB_CTRL_FLAG)) clearSelection(); if (msg->any.shifts & KB_SHIFT_FLAG) selectRange(m_rangeAnchor, idx); else selectColor(idx); // Emit signals jwidget_emit_signal(this, SIGNAL_PALETTE_EDITOR_CHANGE); IndexChange(idx); } } if (hasCapture()) return true; break; } case JM_BUTTONRELEASED: releaseMouse(); return true; case JM_WHEEL: { View* view = View::getView(this); if (view) { gfx::Point scroll = view->getViewScroll(); scroll.y += (jmouse_z(1)-jmouse_z(0)) * 3 * m_boxsize; view->setViewScroll(scroll); } break; } case JM_MOUSELEAVE: app_get_statusbar()->clearText(); break; } return Widget::onProcessMessage(msg); }