Change infinite scroll implementation

Remove necessity of jmouse_x(1) and jmouse_y(1) calls.

- Renamed jmouse_control_infinite_scroll() -> ui::control_infinite_scroll()
- Renamed jmouse_set_position() -> ui::set_mouse_position()
- Added ui::get_delta_outside_box()
This commit is contained in:
David Capello 2014-02-02 18:46:19 -03:00
parent 5eb516f0f5
commit e671508d85
14 changed files with 133 additions and 125 deletions

View File

@ -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();

View File

@ -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<MouseMessage*>(msg)->right()) {
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),
@ -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<MouseMessage*>(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();

View File

@ -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<MouseMessage*>(msg)->position();
EditorStatePtr holdState(m_state);
return m_state->onMouseDown(this, static_cast<MouseMessage*>(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);

View File

@ -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();

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -282,6 +282,7 @@ bool Timeline::onProcessMessage(Message* msg)
m_clk_frame = m_hot_frame;
captureMouse();
m_oldPos = static_cast<MouseMessage*>(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<MouseMessage*>(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();

View File

@ -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

View File

@ -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;

View File

@ -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()

View File

@ -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

View File

@ -97,6 +97,7 @@ bool TextBox::onProcessMessage(Message* msg)
View* view = View::getView(this);
if (view) {
captureMouse();
m_oldPos = static_cast<MouseMessage*>(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<MouseMessage*>(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;
}

View File

@ -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