mirror of
https://github.com/aseprite/aseprite.git
synced 2025-03-17 13:20:45 +00:00
Change zoom scale to avoid similar zoom levels
- Renamed Editor::offset() with padding() - Changed padding size (and added Editor::calcExtraPadding() function) - Added Zoom::linearScale() and Zoom::fromLinearScale()
This commit is contained in:
parent
43a3ee8bce
commit
3103f54131
@ -72,8 +72,8 @@ public:
|
||||
gfx::Point scroll = view->getViewScroll();
|
||||
|
||||
m_oldMousePos = ui::get_mouse_position();
|
||||
m_pos.x = -scroll.x + vp.x + editor->offsetX();
|
||||
m_pos.y = -scroll.y + vp.y + editor->offsetY();
|
||||
m_pos.x = -scroll.x + vp.x + editor->padding().x;
|
||||
m_pos.y = -scroll.y + vp.y + editor->padding().y;
|
||||
|
||||
setFocusStop(true);
|
||||
captureMouse();
|
||||
|
@ -153,8 +153,7 @@ Editor::Editor(Document* document, EditorFlags flags)
|
||||
, m_brushPreview(this)
|
||||
, m_quicktool(NULL)
|
||||
, m_selectionMode(tools::SelectionMode::DEFAULT)
|
||||
, m_offset_x(0)
|
||||
, m_offset_y(0)
|
||||
, m_padding(0, 0)
|
||||
, m_mask_timer(100, this)
|
||||
, m_offset_count(0)
|
||||
, m_customizationDelegate(NULL)
|
||||
@ -346,8 +345,8 @@ void Editor::setDefaultScroll()
|
||||
|
||||
setEditorScroll(
|
||||
gfx::Point(
|
||||
m_offset_x - vp.w/2 + (m_sprite->width()/2),
|
||||
m_offset_y - vp.h/2 + (m_sprite->height()/2)), false);
|
||||
m_padding.x - vp.w/2 + m_zoom.apply(m_sprite->width())/2,
|
||||
m_padding.y - vp.h/2 + m_zoom.apply(m_sprite->height())/2), false);
|
||||
}
|
||||
|
||||
// Sets the scroll position of the editor
|
||||
@ -390,8 +389,8 @@ void Editor::drawOneSpriteUnclippedRect(ui::Graphics* g, const gfx::Rect& sprite
|
||||
gfx::Rect rc = m_sprite->bounds().createIntersection(spriteRectToDraw);
|
||||
rc = m_zoom.apply(rc);
|
||||
|
||||
int dest_x = dx + m_offset_x + rc.x;
|
||||
int dest_y = dy + m_offset_y + rc.y;
|
||||
int dest_x = dx + m_padding.x + rc.x;
|
||||
int dest_y = dy + m_padding.y + rc.y;
|
||||
|
||||
// Clip from graphics/screen
|
||||
const gfx::Rect& clip = g->getClipBounds();
|
||||
@ -536,8 +535,8 @@ void Editor::drawSpriteUnclippedRect(ui::Graphics* g, const gfx::Rect& _rc)
|
||||
|
||||
gfx::Rect client = getClientBounds();
|
||||
gfx::Rect spriteRect(
|
||||
client.x + m_offset_x,
|
||||
client.y + m_offset_y,
|
||||
client.x + m_padding.x,
|
||||
client.y + m_padding.y,
|
||||
m_zoom.apply(m_sprite->width()),
|
||||
m_zoom.apply(m_sprite->height()));
|
||||
gfx::Rect enclosingRect = spriteRect;
|
||||
@ -680,8 +679,8 @@ void Editor::drawMask(Graphics* g)
|
||||
|
||||
ASSERT(m_document->getMaskBoundaries());
|
||||
|
||||
int x = m_offset_x;
|
||||
int y = m_offset_y;
|
||||
int x = m_padding.x;
|
||||
int y = m_padding.y;
|
||||
|
||||
for (const auto& seg : *m_document->getMaskBoundaries()) {
|
||||
CheckedDrawMode checked(g, m_offset_count);
|
||||
@ -954,8 +953,8 @@ gfx::Point Editor::screenToEditor(const gfx::Point& pt)
|
||||
Point scroll = view->getViewScroll();
|
||||
|
||||
return gfx::Point(
|
||||
m_zoom.remove(pt.x - vp.x + scroll.x - m_offset_x),
|
||||
m_zoom.remove(pt.y - vp.y + scroll.y - m_offset_y));
|
||||
m_zoom.remove(pt.x - vp.x + scroll.x - m_padding.x),
|
||||
m_zoom.remove(pt.y - vp.y + scroll.y - m_padding.y));
|
||||
}
|
||||
|
||||
Point Editor::editorToScreen(const gfx::Point& pt)
|
||||
@ -965,8 +964,8 @@ Point Editor::editorToScreen(const gfx::Point& pt)
|
||||
Point scroll = view->getViewScroll();
|
||||
|
||||
return Point(
|
||||
(vp.x - scroll.x + m_offset_x + m_zoom.apply(pt.x)),
|
||||
(vp.y - scroll.y + m_offset_y + m_zoom.apply(pt.y)));
|
||||
(vp.x - scroll.x + m_padding.x + m_zoom.apply(pt.x)),
|
||||
(vp.y - scroll.y + m_padding.y + m_zoom.apply(pt.y)));
|
||||
}
|
||||
|
||||
Rect Editor::screenToEditor(const Rect& rc)
|
||||
@ -1022,8 +1021,8 @@ void Editor::centerInSpritePoint(const gfx::Point& spritePos)
|
||||
Rect vp = view->getViewportBounds();
|
||||
|
||||
gfx::Point scroll(
|
||||
m_offset_x - (vp.w/2) + m_zoom.apply(1)/2 + m_zoom.apply(spritePos.x),
|
||||
m_offset_y - (vp.h/2) + m_zoom.apply(1)/2 + m_zoom.apply(spritePos.y));
|
||||
m_padding.x - (vp.w/2) + m_zoom.apply(1)/2 + m_zoom.apply(spritePos.x),
|
||||
m_padding.y - (vp.h/2) + m_zoom.apply(1)/2 + m_zoom.apply(spritePos.y));
|
||||
|
||||
updateEditor();
|
||||
setEditorScroll(scroll, false);
|
||||
@ -1263,13 +1262,9 @@ void Editor::onPreferredSize(PreferredSizeEvent& ev)
|
||||
gfx::Size sz(0, 0);
|
||||
|
||||
if (m_sprite) {
|
||||
View* view = View::getView(this);
|
||||
Rect vp = view->getViewportBounds();
|
||||
int offset_x = std::max<int>(vp.w/2, vp.w - m_sprite->width()/2);
|
||||
int offset_y = std::max<int>(vp.h/2, vp.h - m_sprite->height()/2);
|
||||
|
||||
sz.w = m_zoom.apply(m_sprite->width()) + offset_x*2;
|
||||
sz.h = m_zoom.apply(m_sprite->height()) + offset_y*2;
|
||||
gfx::Point padding = calcExtraPadding(m_zoom);
|
||||
sz.w = m_zoom.apply(m_sprite->width()) + padding.x*2;
|
||||
sz.h = m_zoom.apply(m_sprite->height()) + padding.y*2;
|
||||
}
|
||||
else {
|
||||
sz.w = 4;
|
||||
@ -1281,13 +1276,7 @@ void Editor::onPreferredSize(PreferredSizeEvent& ev)
|
||||
void Editor::onResize(ui::ResizeEvent& ev)
|
||||
{
|
||||
Widget::onResize(ev);
|
||||
|
||||
View* view = View::getView(this);
|
||||
if (view) {
|
||||
Rect vp = view->getViewportBounds();
|
||||
m_offset_x = std::max<int>(vp.w/2, vp.w - m_sprite->width()/2);
|
||||
m_offset_y = std::max<int>(vp.h/2, vp.h - m_sprite->height()/2);
|
||||
}
|
||||
m_padding = calcExtraPadding(m_zoom);
|
||||
}
|
||||
|
||||
void Editor::onPaint(ui::PaintEvent& ev)
|
||||
@ -1412,13 +1401,20 @@ void Editor::setZoomAndCenterInMouse(Zoom zoom,
|
||||
subpixelPos.x = (0.5 + screenPos.x - screenPos2.x) / m_zoom.scale();
|
||||
subpixelPos.y = (0.5 + screenPos.y - screenPos2.y) / m_zoom.scale();
|
||||
|
||||
if (zoom.scale() > m_zoom.scale()) {
|
||||
double t = 1.0 / zoom.scale();
|
||||
if (subpixelPos.x >= 0.5-t && subpixelPos.x <= 0.5+t) subpixelPos.x = 0.5;
|
||||
if (subpixelPos.y >= 0.5-t && subpixelPos.y <= 0.5+t) subpixelPos.y = 0.5;
|
||||
}
|
||||
|
||||
ASSERT(subpixelPos.x >= -1.0 && subpixelPos.x <= 1.0);
|
||||
ASSERT(subpixelPos.y >= -1.0 && subpixelPos.y <= 1.0);
|
||||
}
|
||||
|
||||
gfx::Point padding = calcExtraPadding(zoom);
|
||||
gfx::Point scrollPos(
|
||||
m_offset_x - (screenPos.x-vp.x) + zoom.apply(spritePos.x+zoom.remove(1)/2) + int(zoom.apply(subpixelPos.x)),
|
||||
m_offset_y - (screenPos.y-vp.y) + zoom.apply(spritePos.y+zoom.remove(1)/2) + int(zoom.apply(subpixelPos.y)));
|
||||
padding.x - (screenPos.x-vp.x) + zoom.apply(spritePos.x+zoom.remove(1)/2) + int(zoom.apply(subpixelPos.x)),
|
||||
padding.y - (screenPos.y-vp.y) + zoom.apply(spritePos.y+zoom.remove(1)/2) + int(zoom.apply(subpixelPos.y)));
|
||||
|
||||
if ((m_zoom != zoom) || (screenPos != view->getViewScroll())) {
|
||||
bool blitValidRegion = (m_zoom == zoom);
|
||||
@ -1574,4 +1570,18 @@ ImageBufferPtr Editor::getRenderImageBuffer()
|
||||
return m_renderBuffer;
|
||||
}
|
||||
|
||||
// static
|
||||
gfx::Point Editor::calcExtraPadding(const Zoom& zoom)
|
||||
{
|
||||
View* view = View::getView(this);
|
||||
if (view) {
|
||||
Rect vp = view->getViewportBounds();
|
||||
return gfx::Point(
|
||||
std::max<int>(vp.w/2, vp.w - zoom.apply(m_sprite->width())),
|
||||
std::max<int>(vp.h/2, vp.h - zoom.apply(m_sprite->height())));
|
||||
}
|
||||
else
|
||||
return gfx::Point(0, 0);
|
||||
}
|
||||
|
||||
} // namespace app
|
||||
|
@ -116,13 +116,9 @@ namespace app {
|
||||
void setFrame(frame_t frame);
|
||||
|
||||
const render::Zoom& zoom() const { return m_zoom; }
|
||||
int offsetX() const { return m_offset_x; }
|
||||
int offsetY() const { return m_offset_y; }
|
||||
const gfx::Point& padding() const { return m_padding; }
|
||||
|
||||
void setZoom(render::Zoom zoom) { m_zoom = zoom; }
|
||||
void setOffsetX(int x) { m_offset_x = x; }
|
||||
void setOffsetY(int y) { m_offset_y = y; }
|
||||
|
||||
void setDefaultScroll();
|
||||
void setEditorScroll(const gfx::Point& scroll, bool blitValidRegion);
|
||||
void setEditorZoom(render::Zoom zoom);
|
||||
@ -238,6 +234,8 @@ namespace app {
|
||||
// routine.
|
||||
void drawOneSpriteUnclippedRect(ui::Graphics* g, const gfx::Rect& rc, int dx, int dy);
|
||||
|
||||
gfx::Point calcExtraPadding(const render::Zoom& zoom);
|
||||
|
||||
// Stack of states. The top element in the stack is the current state (m_state).
|
||||
EditorStatesHistory m_statesHistory;
|
||||
|
||||
@ -264,9 +262,8 @@ namespace app {
|
||||
tools::SelectionMode m_selectionMode;
|
||||
bool m_autoSelectLayer;
|
||||
|
||||
// Offset for the sprite
|
||||
int m_offset_x;
|
||||
int m_offset_y;
|
||||
// Extra space around the sprite.
|
||||
gfx::Point m_padding;
|
||||
|
||||
// Marching ants stuff
|
||||
ui::Timer m_mask_timer;
|
||||
|
@ -14,12 +14,17 @@
|
||||
#include "app/app.h"
|
||||
#include "app/ui/editor/editor.h"
|
||||
#include "app/ui/status_bar.h"
|
||||
#include "gfx/rect.h"
|
||||
#include "doc/sprite.h"
|
||||
#include "gfx/rect.h"
|
||||
#include "she/display.h"
|
||||
#include "ui/manager.h"
|
||||
#include "ui/message.h"
|
||||
#include "ui/system.h"
|
||||
#include "ui/theme.h"
|
||||
#include "ui/view.h"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
namespace app {
|
||||
|
||||
using namespace ui;
|
||||
@ -65,16 +70,17 @@ bool ZoomingState::onMouseUp(Editor* editor, MouseMessage* msg)
|
||||
bool ZoomingState::onMouseMove(Editor* editor, MouseMessage* msg)
|
||||
{
|
||||
gfx::Point pt = (msg->position() - m_startPos);
|
||||
render::Zoom zoom(1, 1);
|
||||
double scale = m_startZoom.scale() + pt.x / 16.0;
|
||||
if (scale < 1.0)
|
||||
scale = 1.0 / -(scale-2.0);
|
||||
zoom = render::Zoom::fromScale(scale);
|
||||
int threshold = 8 * guiscale() * editor->getManager()->getDisplay()->scale();
|
||||
|
||||
editor->setZoomAndCenterInMouse(
|
||||
zoom, m_startPos, Editor::ZoomBehavior::MOUSE);
|
||||
if (m_moved || std::sqrt(pt.x*pt.x + pt.y*pt.y) > threshold) {
|
||||
m_moved = true;
|
||||
|
||||
m_moved = true;
|
||||
int newScale = m_startZoom.linearScale() + pt.x / threshold;
|
||||
render::Zoom newZoom = render::Zoom::fromLinearScale(newScale);
|
||||
|
||||
editor->setZoomAndCenterInMouse(
|
||||
newZoom, m_startPos, Editor::ZoomBehavior::MOUSE);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite Render Library
|
||||
// Copyright (c) 2001-2014 David Capello
|
||||
// Copyright (c) 2001-2015 David Capello
|
||||
//
|
||||
// This file is released under the terms of the MIT license.
|
||||
// Read LICENSE.txt for more information.
|
||||
@ -12,35 +12,86 @@
|
||||
|
||||
namespace render {
|
||||
|
||||
static int scales[][2] = {
|
||||
{ 1, 64 },
|
||||
{ 1, 32 },
|
||||
{ 1, 16 },
|
||||
{ 1, 8 },
|
||||
{ 1, 6 },
|
||||
{ 1, 4 },
|
||||
{ 1, 3 },
|
||||
{ 1, 2 },
|
||||
{ 1, 1 }, // 100%
|
||||
{ 2, 1 },
|
||||
{ 3, 1 },
|
||||
{ 4, 1 },
|
||||
{ 6, 1 },
|
||||
{ 8, 1 },
|
||||
{ 16, 1 },
|
||||
{ 32, 1 },
|
||||
{ 64, 1 },
|
||||
};
|
||||
|
||||
static int scales_size = sizeof(scales) / sizeof(scales[0]);
|
||||
|
||||
void Zoom::in()
|
||||
{
|
||||
if (m_den > 1) {
|
||||
m_den--;
|
||||
}
|
||||
else if (m_num < 64) {
|
||||
m_num++;
|
||||
int i = linearScale();
|
||||
if (i < scales_size-1) {
|
||||
++i;
|
||||
m_num = scales[i][0];
|
||||
m_den = scales[i][1];
|
||||
}
|
||||
}
|
||||
|
||||
void Zoom::out()
|
||||
{
|
||||
if (m_num > 1) {
|
||||
m_num--;
|
||||
int i = linearScale();
|
||||
if (i > 0) {
|
||||
--i;
|
||||
m_num = scales[i][0];
|
||||
m_den = scales[i][1];
|
||||
}
|
||||
else if (m_den < 32) {
|
||||
m_den++;
|
||||
}
|
||||
|
||||
int Zoom::linearScale()
|
||||
{
|
||||
for (int i=0; i<scales_size; ++i) {
|
||||
// Exact match
|
||||
if (scales[i][0] == m_num &&
|
||||
scales[i][1] == m_den) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return findClosestLinearScale(scale());
|
||||
}
|
||||
|
||||
// static
|
||||
Zoom Zoom::fromScale(double scale)
|
||||
{
|
||||
if (scale >= 1.0) {
|
||||
return Zoom(int(scale), 1);
|
||||
}
|
||||
else {
|
||||
return Zoom(1, int(1.0 / scale));
|
||||
return fromLinearScale(findClosestLinearScale(scale));
|
||||
}
|
||||
|
||||
// static
|
||||
Zoom Zoom::fromLinearScale(int i)
|
||||
{
|
||||
i = MID(0, i, scales_size-1);
|
||||
return Zoom(scales[i][0], scales[i][1]);
|
||||
}
|
||||
|
||||
// static
|
||||
int Zoom::findClosestLinearScale(double scale)
|
||||
{
|
||||
for (int i=0; i<scales_size-1; ++i) {
|
||||
double min = double(scales[i ][0]) / double(scales[i ][1]) - 0.5;
|
||||
double max = double(scales[i+1][0]) / double(scales[i+1][1]) - 0.5;
|
||||
if (scale >= min && scale <= max)
|
||||
return i;
|
||||
}
|
||||
if (scale < 1.0)
|
||||
return 0;
|
||||
else
|
||||
return scales_size-1;
|
||||
}
|
||||
|
||||
} // namespace render
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite Render Library
|
||||
// Copyright (c) 2001-2014 David Capello
|
||||
// Copyright (c) 2001-2015 David Capello
|
||||
//
|
||||
// This file is released under the terms of the MIT license.
|
||||
// Read LICENSE.txt for more information.
|
||||
@ -44,6 +44,10 @@ namespace render {
|
||||
void in();
|
||||
void out();
|
||||
|
||||
// Returns an linear zoom scale. This position can be incremented
|
||||
// or decremented to get a new zoom value.
|
||||
int linearScale();
|
||||
|
||||
bool operator==(const Zoom& other) const {
|
||||
return m_num == other.m_num && m_den == other.m_den;
|
||||
}
|
||||
@ -53,8 +57,11 @@ namespace render {
|
||||
}
|
||||
|
||||
static Zoom fromScale(double scale);
|
||||
static Zoom fromLinearScale(int i);
|
||||
|
||||
private:
|
||||
static int findClosestLinearScale(double scale);
|
||||
|
||||
int m_num;
|
||||
int m_den;
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user