diff --git a/src/app/commands/cmd_preview.cpp b/src/app/commands/cmd_preview.cpp index fa320c331..22379a32a 100644 --- a/src/app/commands/cmd_preview.cpp +++ b/src/app/commands/cmd_preview.cpp @@ -109,7 +109,7 @@ void PreviewCommand::onExecute(Context* context) int old_mouse_y = jmouse_y(0); jmouse_set_cursor(kNoCursor); - jmouse_set_position(JI_SCREEN_W/2, JI_SCREEN_H/2); + ui::set_mouse_position(gfx::Point(JI_SCREEN_W/2, JI_SCREEN_H/2)); int pos_x = - scroll.x + vp.x + editor->getOffsetX(); int pos_y = - scroll.y + vp.y + editor->getOffsetY(); @@ -131,7 +131,7 @@ void PreviewCommand::onExecute(Context* context) if (jmouse_poll()) { delta_x += (jmouse_x(0) - JI_SCREEN_W/2); delta_y += (jmouse_y(0) - JI_SCREEN_H/2); - jmouse_set_position(JI_SCREEN_W/2, JI_SCREEN_H/2); + ui::set_mouse_position(gfx::Point(JI_SCREEN_W/2, JI_SCREEN_H/2)); jmouse_poll(); redraw = true; @@ -241,7 +241,7 @@ void PreviewCommand::onExecute(Context* context) } while (jmouse_b(0) != kButtonNone); clear_keybuf(); - jmouse_set_position(old_mouse_x, old_mouse_y); + ui::set_mouse_position(gfx::Point(old_mouse_x, old_mouse_y)); jmouse_set_cursor(kArrowCursor); ui::Manager::getDefault()->invalidate(); diff --git a/src/app/commands/filters/color_curve_editor.cpp b/src/app/commands/filters/color_curve_editor.cpp index 18a2026ac..a7a1604b8 100644 --- a/src/app/commands/filters/color_curve_editor.cpp +++ b/src/app/commands/filters/color_curve_editor.cpp @@ -74,7 +74,6 @@ using namespace filters; enum { STATUS_STANDBY, STATUS_MOVING_POINT, - STATUS_SCROLLING, STATUS_SCALING, }; @@ -194,18 +193,8 @@ bool ColorCurveEditor::onProcessMessage(Message* msg) } case kMouseDownMessage: - // Change scroll - if (msg->shiftPressed()) { - m_status = STATUS_SCROLLING; - jmouse_set_cursor(kScrollCursor); - } - /* scaling */ -/* else if (msg->ctrlPressed()) { */ -/* m_status = STATUS_SCALING; */ -/* jmouse_set_cursor(kScrollCursor); */ -/* } */ // Show manual-entry dialog - else if (static_cast(msg)->right()) { + if (static_cast(msg)->right()) { gfx::Point mousePos = static_cast(msg)->position(); m_editPoint = getClosestPoint(SCR2EDIT_X(mousePos.x), SCR2EDIT_Y(mousePos.y), @@ -242,20 +231,6 @@ bool ColorCurveEditor::onProcessMessage(Message* msg) if (hasCapture()) { switch (m_status) { - case STATUS_SCROLLING: { - View* view = View::getView(this); - 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 STATUS_MOVING_POINT: if (m_editPoint) { gfx::Point mousePos = static_cast(msg)->position(); @@ -274,13 +249,6 @@ bool ColorCurveEditor::onProcessMessage(Message* msg) return true; } -#if 0 // TODO - // If the mouse move above a curve_editor, the focus change to - // this widget immediately - else if (!jwidget_has_focus(this)) { - jmanager_set_focus(this); - } -#endif break; case kMouseUpMessage: @@ -289,14 +257,6 @@ bool ColorCurveEditor::onProcessMessage(Message* msg) switch (m_status) { - case STATUS_SCROLLING: - jmouse_set_cursor(kArrowCursor); - break; - -/* case STATUS_SCALING: */ -/* jmouse_set_cursor(kArrowCursor); */ -/* break; */ - case STATUS_MOVING_POINT: jmouse_set_cursor(kArrowCursor); CurveEditorChange(); diff --git a/src/app/ui/editor/editor.cpp b/src/app/ui/editor/editor.cpp index f48b10e87..f5bdefb1c 100644 --- a/src/app/ui/editor/editor.cpp +++ b/src/app/ui/editor/editor.cpp @@ -672,37 +672,30 @@ void Editor::flashCurrentLayer() gfx::Point Editor::controlInfiniteScroll(MouseMessage* msg) { View* view = View::getView(this); - Rect vp = view->getViewportBounds(); + gfx::Rect vp = view->getViewportBounds(); + gfx::Point mousePos = msg->position(); - if (jmouse_control_infinite_scroll(vp)) { - 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)) { - jmouse_set_position(MID(vp.x+1, old_x, vp.x+vp.w-2), - MID(vp.y+1, old_y, vp.y+vp.h-2)); - } - // This is better for high resolutions: scroll movement by big steps - else { - 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); + gfx::Point delta = ui::get_delta_outside_box(vp, mousePos); + if (delta != gfx::Point(0, 0)) { + // Scrolling-by-steps (non-smooth), this is better for high + // resolutions: scroll movement by big steps. + if (!get_config_bool("Options", "MoveSmooth", true)) { + gfx::Point newPos = mousePos; + if (delta.x != 0) newPos.x = (mousePos.x-delta.x+(vp.x+vp.w/2))/2; + if (delta.y != 0) newPos.y = (mousePos.y-delta.y+(vp.y+vp.h/2))/2; + delta = mousePos - newPos; } - // Get new positions. - new_x = jmouse_x(0); - new_y = jmouse_y(0); + mousePos.x -= delta.x; + mousePos.y -= delta.y; + ui::set_mouse_position(mousePos); - Point scroll = view->getViewScroll(); - setEditorScroll(scroll.x+old_x-new_x, - scroll.y+old_y-new_y, true); - - return gfx::Point(new_x, new_y); + gfx::Point scroll = view->getViewScroll(); + scroll += delta; + setEditorScroll(scroll.x, scroll.y, true); } - return msg->position(); + return mousePos; } tools::Tool* Editor::getCurrentEditorTool() @@ -972,6 +965,8 @@ bool Editor::onProcessMessage(Message* msg) case kMouseDownMessage: if (m_sprite) { + m_oldPos = static_cast(msg)->position(); + EditorStatePtr holdState(m_state); return m_state->onMouseDown(this, static_cast(msg)); } @@ -1144,7 +1139,7 @@ void Editor::setZoomAndCenterInMouse(int zoom, int mouse_x, int mouse_y) setEditorScroll(x, y, use_refresh_region); if (centerMouse) - jmouse_set_position(mx, my); + ui::set_mouse_position(gfx::Point(mx, my)); // Notify observers m_observers.notifyScrollChanged(this); diff --git a/src/app/ui/editor/editor.h b/src/app/ui/editor/editor.h index 10aeae188..544c71f67 100644 --- a/src/app/ui/editor/editor.h +++ b/src/app/ui/editor/editor.h @@ -243,6 +243,8 @@ namespace app { // editors.cpp are finally replaced with a fully funtional Workspace // widget. DocumentView* m_docView; + + gfx::Point m_oldPos; }; ui::WidgetType editor_type(); diff --git a/src/app/ui/editor/scrolling_state.cpp b/src/app/ui/editor/scrolling_state.cpp index 06893a805..f33fc6b5e 100644 --- a/src/app/ui/editor/scrolling_state.cpp +++ b/src/app/ui/editor/scrolling_state.cpp @@ -45,6 +45,9 @@ ScrollingState::~ScrollingState() bool ScrollingState::onMouseDown(Editor* editor, MouseMessage* msg) { + m_oldPos = msg->position(); + + editor->captureMouse(); return true; } @@ -58,20 +61,15 @@ bool ScrollingState::onMouseUp(Editor* editor, MouseMessage* msg) bool ScrollingState::onMouseMove(Editor* editor, MouseMessage* msg) { View* view = View::getView(editor); - gfx::Rect vp = view->getViewportBounds(); gfx::Point scroll = view->getViewScroll(); - editor->setEditorScroll(scroll.x+jmouse_x(1)-jmouse_x(0), - scroll.y+jmouse_y(1)-jmouse_y(0), true); + gfx::Point newPos = msg->position(); - jmouse_control_infinite_scroll(vp); + scroll += m_oldPos - newPos; + editor->setEditorScroll(scroll.x, scroll.y, true); - int x, y; - editor->screenToEditor(jmouse_x(0), jmouse_y(0), &x, &y); - StatusBar::instance()->setStatusText - (0, "Pos %3d %3d (Size %3d %3d)", x, y, - editor->getSprite()->getWidth(), - editor->getSprite()->getHeight()); + gfx::Rect vp = view->getViewportBounds(); + m_oldPos = ui::control_infinite_scroll(editor, vp, newPos); return true; } diff --git a/src/app/ui/editor/scrolling_state.h b/src/app/ui/editor/scrolling_state.h index a822d81dc..d141a5ce0 100644 --- a/src/app/ui/editor/scrolling_state.h +++ b/src/app/ui/editor/scrolling_state.h @@ -21,6 +21,7 @@ #include "app/ui/editor/editor_state.h" #include "base/compiler_specific.h" +#include "gfx/point.h" namespace app { @@ -37,6 +38,9 @@ namespace app { virtual bool onKeyDown(Editor* editor, ui::KeyMessage* msg) OVERRIDE; virtual bool onKeyUp(Editor* editor, ui::KeyMessage* msg) OVERRIDE; virtual bool onUpdateStatusBar(Editor* editor) OVERRIDE; + + private: + gfx::Point m_oldPos; }; } // namespace app diff --git a/src/app/ui/editor/standby_state.cpp b/src/app/ui/editor/standby_state.cpp index 73d8c03e1..a21b3e33d 100644 --- a/src/app/ui/editor/standby_state.cpp +++ b/src/app/ui/editor/standby_state.cpp @@ -126,8 +126,10 @@ bool StandbyState::checkForScroll(Editor* editor, MouseMessage* msg) // Start scroll loop if (msg->middle() || clickedInk->isScrollMovement()) { // TODO msg->middle() should be customizable - editor->setState(EditorStatePtr(new ScrollingState())); - editor->captureMouse(); + EditorStatePtr newState(new ScrollingState()); + editor->setState(newState); + + newState->onMouseDown(editor, msg); return true; } else diff --git a/src/app/ui/timeline.cpp b/src/app/ui/timeline.cpp index 3dd003617..f745bc7df 100644 --- a/src/app/ui/timeline.cpp +++ b/src/app/ui/timeline.cpp @@ -282,6 +282,7 @@ bool Timeline::onProcessMessage(Message* msg) m_clk_frame = m_hot_frame; captureMouse(); + m_oldPos = static_cast(msg)->position(); switch (m_hot_part) { case A_PART_SEPARATOR: @@ -410,13 +411,15 @@ bool Timeline::onProcessMessage(Message* msg) if (hasCapture()) { switch (m_state) { - case STATE_SCROLLING: + case STATE_SCROLLING: { + gfx::Point absMousePos = static_cast(msg)->position(); setScroll( - m_scroll_x+jmouse_x(1)-jmouse_x(0), - m_scroll_y+jmouse_y(1)-jmouse_y(0)); + m_scroll_x + m_oldPos.x - absMousePos.x, + m_scroll_y + m_oldPos.y - absMousePos.y); - jmouse_control_infinite_scroll(getBounds()); + m_oldPos = ui::control_infinite_scroll(this, getBounds(), absMousePos); return true; + } case STATE_MOVING_ONIONSKIN_RANGE_LEFT: { ISettings* m_settings = UIContext::instance()->getSettings(); diff --git a/src/app/ui/timeline.h b/src/app/ui/timeline.h index e00f38341..1d20c4d34 100644 --- a/src/app/ui/timeline.h +++ b/src/app/ui/timeline.h @@ -205,6 +205,8 @@ namespace app { FrameNumber m_clk_frame; // Keys bool m_space_pressed; + // Old mouse position (for scrolling). + gfx::Point m_oldPos; }; } // namespace app diff --git a/src/ui/slider.cpp b/src/ui/slider.cpp index 10b16ac88..fa7a9199f 100644 --- a/src/ui/slider.cpp +++ b/src/ui/slider.cpp @@ -121,20 +121,25 @@ bool Slider::onProcessMessage(Message* msg) // For left click if (slider_press_left) { - int x = jmouse_x(0); + int x = mousePos.x; if (x < rc.x-1) x = rc.x-1; else if (x > rc.x2()) x = rc.x2(); - if (x != jmouse_x(0)) - jmouse_set_position(x, jmouse_y(0)); + if (x != mousePos.x) + ui::set_mouse_position(gfx::Point(x, mousePos.y)); } // For right click - else if (jmouse_control_infinite_scroll(getBounds() - getBorder())) { - slider_press_x = jmouse_x(0); - slider_press_value = m_value; + else { + gfx::Point newPoint = + ui::control_infinite_scroll(this, getBounds() - getBorder(), mousePos); + + if (newPoint != mousePos) { + slider_press_x = newPoint.x; + slider_press_value = m_value; + } } return true; diff --git a/src/ui/system.cpp b/src/ui/system.cpp index ec67430b0..364c22639 100644 --- a/src/ui/system.cpp +++ b/src/ui/system.cpp @@ -240,15 +240,23 @@ bool jmouse_poll() return false; } -void jmouse_set_position(int x, int y) +gfx::Point get_mouse_position() +{ + return gfx::Point(jmouse_x(0), jmouse_y(0)); +} + +void set_mouse_position(const gfx::Point& newPos) { moved = true; - m_x[0] = m_x[1] = x; - m_y[0] = m_y[1] = y; + position_mouse( + SCREEN_W * newPos.x / JI_SCREEN_W, + SCREEN_H * newPos.y / JI_SCREEN_H); - position_mouse(SCREEN_W * x / JI_SCREEN_W, - SCREEN_H * y / JI_SCREEN_H); + update_mouse_position(); + + m_x[1] = m_x[0]; + m_y[1] = m_y[0]; } void jmouse_capture() @@ -281,33 +289,54 @@ 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]; } -bool jmouse_control_infinite_scroll(const gfx::Rect& rect) +gfx::Point get_delta_outside_box(const gfx::Rect& rect, const gfx::Point& mousePoint) { - int x, y, u, v; + gfx::Point delta(0, 0); - u = jmouse_x(0); - v = jmouse_y(0); + if (mousePoint.x < rect.x) + delta.x = mousePoint.x - rect.x; + else if (mousePoint.x >= rect.x+rect.w) + delta.x = mousePoint.x - (rect.x+rect.w); - if (u <= rect.x) - x = rect.x+rect.w-2; - else if (u >= rect.x+rect.w-1) - x = rect.x+1; - else - x = u; + if (mousePoint.y < rect.y) + delta.y = mousePoint.y - rect.y; + else if (mousePoint.y > rect.y+rect.h) + delta.y = mousePoint.y - (rect.y+rect.h); - if (v <= rect.y) - y = rect.y+rect.h-2; - else if (v >= rect.y+rect.h-1) - y = rect.y+1; - else - y = v; + return delta; +} - if ((x != u) || (y != v)) { - jmouse_set_position(x, y); - return true; +gfx::Point control_infinite_scroll(Widget* widget, const gfx::Rect& rect, const gfx::Point& mousePoint) +{ + gfx::Point newPoint = mousePoint; + gfx::Point delta = get_delta_outside_box(rect, newPoint); + + if (delta.x < 0) { + newPoint.x = rect.x+rect.w+delta.x; + if (newPoint.x < rect.x) + newPoint.x = rect.x; } - else - return false; + else if (delta.x > 0) { + newPoint.x = rect.x+delta.x; + if (newPoint.x >= rect.x+rect.w) + newPoint.x = rect.x+rect.w-1; + } + + if (delta.y < 0) { + newPoint.y = rect.y+rect.h+delta.y; + if (newPoint.y < rect.y) + newPoint.y = rect.y; + } + else if (delta.y > 0) { + newPoint.y = rect.y+delta.y; + if (newPoint.y >= rect.y+rect.h) + newPoint.y = rect.y+rect.h-1; + } + + if (mousePoint != newPoint) + ui::set_mouse_position(newPoint); + + return newPoint; } static void update_mouse_position() diff --git a/src/ui/system.h b/src/ui/system.h index 32f08b003..d6b4cd7e9 100644 --- a/src/ui/system.h +++ b/src/ui/system.h @@ -7,7 +7,7 @@ #ifndef UI_SYSTEM_H_INCLUDED #define UI_SYSTEM_H_INCLUDED -#include "gfx/rect.h" +#include "gfx/fwd.h" #include "ui/base.h" #include "ui/cursor_type.h" #include "ui/mouse_buttons.h" @@ -21,6 +21,8 @@ namespace she { class Display; } namespace ui { + class Widget; + // Screen related extern struct BITMAP* ji_screen; @@ -53,7 +55,9 @@ namespace ui { bool jmouse_is_shown(); bool jmouse_poll(); - void jmouse_set_position(int x, int y); + + gfx::Point get_mouse_position(); + void set_mouse_position(const gfx::Point& newPos); void jmouse_capture(); void jmouse_release(); @@ -63,7 +67,8 @@ namespace ui { int jmouse_y(int antique); int jmouse_z(int antique); - bool jmouse_control_infinite_scroll(const gfx::Rect& rect); + gfx::Point get_delta_outside_box(const gfx::Rect& rect, const gfx::Point& mousePoint); + gfx::Point control_infinite_scroll(Widget* widget, const gfx::Rect& rect, const gfx::Point& mousePoint); } // namespace ui diff --git a/src/ui/textbox.cpp b/src/ui/textbox.cpp index 11113b6dd..bdaaa8929 100644 --- a/src/ui/textbox.cpp +++ b/src/ui/textbox.cpp @@ -97,6 +97,7 @@ bool TextBox::onProcessMessage(Message* msg) View* view = View::getView(this); if (view) { captureMouse(); + m_oldPos = static_cast(msg)->position(); jmouse_set_cursor(kScrollCursor); return true; } @@ -108,13 +109,12 @@ bool TextBox::onProcessMessage(Message* msg) if (view && hasCapture()) { gfx::Rect vp = view->getViewportBounds(); gfx::Point scroll = view->getViewScroll(); + gfx::Point newPos = static_cast(msg)->position(); - scroll.x += jmouse_x(1) - jmouse_x(0); - scroll.y += jmouse_y(1) - jmouse_y(0); - + scroll += m_oldPos - newPos; view->setViewScroll(scroll); - jmouse_control_infinite_scroll(vp); + m_oldPos = ui::control_infinite_scroll(this, vp, newPos); } break; } diff --git a/src/ui/textbox.h b/src/ui/textbox.h index 2f31c829f..460984c86 100644 --- a/src/ui/textbox.h +++ b/src/ui/textbox.h @@ -22,6 +22,9 @@ namespace ui { void onPaint(PaintEvent& ev) OVERRIDE; void onPreferredSize(PreferredSizeEvent& ev) OVERRIDE; void onSetText() OVERRIDE; + + private: + gfx::Point m_oldPos; }; } // namespace ui