Modify Canvas Size to be more "tool like" (easier to change the edges size, C keyboard shortcut)

This commit is contained in:
David Capello 2019-04-22 15:57:45 -03:00
parent af0b700a6d
commit bbba80c809
5 changed files with 103 additions and 47 deletions

View File

@ -62,6 +62,7 @@
<key command="KeyboardShortcuts" shortcut="Ctrl+Alt+Shift+K" mac="Cmd+Alt+Shift+K" />
<!-- Sprite -->
<key command="SpriteProperties" shortcut="Ctrl+P" mac="Cmd+P" />
<key command="CanvasSize" shortcut="C" />
<!-- Layer -->
<key command="LayerProperties" shortcut="Shift+P" />
<key command="LayerVisibility" shortcut="Shift+X" />
@ -502,7 +503,7 @@
<key tool="eyedropper" shortcut="I" />
<key tool="hand" shortcut="H" />
<key tool="move" shortcut="V" />
<key tool="slice" shortcut="C" />
<key tool="slice" shortcut="Ctrl+Alt+C" mac="Cmd+Alt+C" />
<key tool="zoom" shortcut="Z" />
<key tool="paint_bucket" shortcut="G" />

View File

@ -17,9 +17,11 @@
#include "app/tx.h"
#include "app/ui/button_set.h"
#include "app/ui/color_bar.h"
#include "app/ui/doc_view.h"
#include "app/ui/editor/editor.h"
#include "app/ui/editor/select_box_state.h"
#include "app/ui/skin/skin_theme.h"
#include "app/ui_context.h"
#include "base/bind.h"
#include "doc/image.h"
#include "doc/mask.h"
@ -312,7 +314,15 @@ void CanvasSizeCommand::onExecute(Context* context)
std::unique_ptr<CanvasSizeWindow> window(new CanvasSizeWindow());
window->remapWindow();
window->centerWindow();
// Find best position for the window on the editor
if (DocView* docView = static_cast<UIContext*>(context)->activeView()) {
window->positionWindow(
docView->bounds().x2() - window->bounds().w,
docView->bounds().y);
}
else
window->centerWindow();
load_window_pos(window.get(), "CanvasSize");
window->setVisible(true);

View File

@ -1,4 +1,5 @@
// Aseprite
// Copyright (C) 2019 Igara Studio S.A.
// Copyright (C) 2001-2017 David Capello
//
// This program is distributed under the terms of
@ -8,33 +9,34 @@
#define APP_UI_EDITOR_RULER_H_INCLUDED
#pragma once
#include "ui/base.h"
namespace app {
// A ruler inside the editor. It is used by SelectBoxState to show
// rulers that can be dragged by the user.
class Ruler {
public:
enum Orientation { Horizontal, Vertical };
Ruler()
: m_orientation(Horizontal)
: m_align(0)
, m_position(0) {
}
Ruler(Orientation orientation, int position)
: m_orientation(orientation)
Ruler(const int align,
const int position)
: m_align(align)
, m_position(position) {
}
Orientation orientation() const { return m_orientation; }
int align() const { return m_align; }
int position() const { return m_position; }
void setPosition(int position) {
void setPosition(const int position) {
m_position = position;
}
private:
Orientation m_orientation;
int m_align;
int m_position;
};

View File

@ -79,16 +79,16 @@ gfx::Rect SelectBoxState::getBoxBounds() const
void SelectBoxState::setBoxBounds(const gfx::Rect& box)
{
m_rulers[H1] = Ruler(HORIZONTAL | TOP, box.y);
m_rulers[H2] = Ruler(HORIZONTAL | BOTTOM, box.y+box.h);
m_rulers[V1] = Ruler(VERTICAL | LEFT, box.x);
m_rulers[V2] = Ruler(VERTICAL | RIGHT, box.x+box.w);
if (hasFlag(Flags::PaddingRulers)) {
int w = m_rulers[PV].position() - m_rulers[V2].position();
int h = m_rulers[PH].position() - m_rulers[H2].position();
m_rulers[PH] = Ruler(Ruler::Horizontal, m_rulers[H2].position() + h);
m_rulers[PV] = Ruler(Ruler::Vertical, m_rulers[V2].position() + w);
const gfx::Size padding(
m_rulers[PV].position() - m_rulers[V2].position(),
m_rulers[PH].position() - m_rulers[H2].position());
setPaddingBounds(padding);
}
m_rulers[H1] = Ruler(Ruler::Horizontal, box.y);
m_rulers[H2] = Ruler(Ruler::Horizontal, box.y+box.h);
m_rulers[V1] = Ruler(Ruler::Vertical, box.x);
m_rulers[V2] = Ruler(Ruler::Vertical, box.x+box.w);
}
// Get and Set Padding for Import Sprite Sheet box state
@ -107,8 +107,8 @@ gfx::Size SelectBoxState::getPaddingBounds() const
void SelectBoxState::setPaddingBounds(const gfx::Size& padding)
{
ASSERT(hasFlag(Flags::PaddingRulers));
m_rulers[PH] = Ruler(Ruler::Horizontal, m_rulers[H2].position() + padding.h);
m_rulers[PV] = Ruler(Ruler::Vertical, m_rulers[V2].position() + padding.w);
m_rulers[PH] = Ruler(HORIZONTAL | BOTTOM, m_rulers[H2].position() + padding.h);
m_rulers[PV] = Ruler(VERTICAL | RIGHT, m_rulers[V2].position() + padding.w);
}
void SelectBoxState::onEnterState(Editor* editor)
@ -187,11 +187,10 @@ bool SelectBoxState::onMouseMove(Editor* editor, MouseMessage* msg)
for (int i : m_movingRulers) {
Ruler& ruler = m_rulers[i];
const Ruler& start = m_startRulers[i];
int oppositeRuler = i^1;// 0 and 1 are opposites, and 2 and 3
Ruler& oppRuler = m_rulers[oppositeRuler];
Ruler& oppRuler = oppositeRuler(i);
switch (ruler.orientation()) {
case Ruler::Horizontal:
switch (ruler.align() & (HORIZONTAL | VERTICAL)) {
case HORIZONTAL:
if (hasFlag(Flags::PaddingRulers) && (i == H2)) {
int pad = m_rulers[PH].position() - m_rulers[H2].position();
m_rulers[PH].setPosition(start.position() + delta.y + pad);
@ -201,7 +200,7 @@ bool SelectBoxState::onMouseMove(Editor* editor, MouseMessage* msg)
oppRuler.setPosition(editor->sprite()->height()
- start.position() - delta.y);
break;
case Ruler::Vertical:
case VERTICAL:
if (hasFlag(Flags::PaddingRulers) && (i == V2)) {
int pad = m_rulers[PV].position() - m_rulers[V2].position();
m_rulers[PV].setPosition(start.position() + delta.x + pad);
@ -462,7 +461,7 @@ void SelectBoxState::postRenderDecorator(EditorPostRender* render)
render->fillRect(dark, gfx::Rect(rc.x2(), rc.y, vp.x2()-rc.x2(), rc.h));
}
}
// Draw the grid rulers when padding is posible (i.e. Flag::PaddingRulers=true)
if (hasFlag(Flags::PaddingRulers)) {
if (hasFlag(Flags::HGrid) && hasFlag(Flags::VGrid)) {
@ -527,15 +526,15 @@ void SelectBoxState::postRenderDecorator(EditorPostRender* render)
// Draw the rulers enclosing the box
if (hasFlag(Flags::Rulers)) {
for (const Ruler& ruler : m_rulers) {
switch (ruler.orientation()) {
switch (ruler.align() & (HORIZONTAL | VERTICAL)) {
case Ruler::Horizontal: {
case HORIZONTAL: {
const int y = ruler.position()+mainOffset.y;
render->drawLine(rulerColor, vp.x, y, vp.x+vp.w-1, y);
break;
}
case Ruler::Vertical: {
case VERTICAL: {
const int x = ruler.position()+mainOffset.x;
render->drawLine(rulerColor, x, vp.y, x, vp.y+vp.h-1);
break;
@ -560,6 +559,12 @@ void SelectBoxState::updateContextBar()
contextBar->updateForSelectingBox(m_delegate->onGetContextBarHelp());
}
Ruler& SelectBoxState::oppositeRuler(const int rulerIndex)
{
// 0 and 1 are opposites, and 2 and 3
return m_rulers[rulerIndex ^ 1];
}
int SelectBoxState::hitTestRulers(Editor* editor,
const gfx::Point& mousePos,
const bool updateMovingRulers)
@ -568,15 +573,22 @@ int SelectBoxState::hitTestRulers(Editor* editor,
ASSERT(H2 == 1);
ASSERT(V1 == 2);
ASSERT(V2 == 3);
int aligns[] = { TOP, BOTTOM, LEFT, RIGHT, BOTTOM, RIGHT };
int align = 0;
if (updateMovingRulers)
m_movingRulers.clear();
for (int i=0; i<int(m_rulers.size()); ++i) {
if (hitTestRuler(editor, m_rulers[i], mousePos)) {
align |= aligns[i];
const Ruler& ruler = m_rulers[i];
const Ruler& oppRuler = oppositeRuler(i);
if (hitTestRuler(editor, ruler, oppRuler, mousePos)) {
if (!hasFlag(Flags::PaddingRulers) &&
(((ruler.align() & (LEFT | TOP)) && ruler.position() > oppRuler.position()) ||
((ruler.align() & (RIGHT | BOTTOM)) && ruler.position() <= oppRuler.position())))
align |= oppRuler.align();
else
align |= ruler.align();
if (updateMovingRulers)
m_movingRulers.push_back(i);
}
@ -599,25 +611,52 @@ int SelectBoxState::hitTestRulers(Editor* editor,
return align;
}
bool SelectBoxState::hitTestRuler(Editor* editor, const Ruler& ruler,
const gfx::Point& mousePos)
int SelectBoxState::hitTestRuler(Editor* editor,
const Ruler& ruler,
const Ruler& oppRuler,
const gfx::Point& mousePos)
{
gfx::Point pt = editor->mainTilePosition();
pt = editor->editorToScreen(
pt + gfx::Point(ruler.position(), ruler.position()));
switch (ruler.orientation()) {
switch (ruler.align() & (HORIZONTAL | VERTICAL)) {
case Ruler::Horizontal:
return (mousePos.y >= pt.y-2*guiscale() &&
mousePos.y <= pt.y+2*guiscale());
case HORIZONTAL:
if (!hasFlag(Flags::PaddingRulers)) {
if (ruler.position() <= oppRuler.position()) {
if (mousePos.y <= pt.y+2*guiscale())
return ruler.align();
}
else if (ruler.position() > oppRuler.position()) {
if (mousePos.y >= pt.y-2*guiscale())
return ruler.align();
}
}
if (mousePos.y >= pt.y-2*guiscale() &&
mousePos.y <= pt.y+2*guiscale()) {
return ruler.align();
}
break;
case Ruler::Vertical:
return (mousePos.x >= pt.x-2*guiscale() &&
mousePos.x <= pt.x+2*guiscale());
case VERTICAL:
if (!hasFlag(Flags::PaddingRulers)) {
if (ruler.position() <= oppRuler.position()) {
if (mousePos.x <= pt.x+2*guiscale())
return ruler.align();
}
else if (ruler.position() > oppRuler.position()) {
if (mousePos.x >= pt.x-2*guiscale())
return ruler.align();
}
}
if (mousePos.x >= pt.x-2*guiscale() &&
mousePos.x <= pt.x+2*guiscale())
return ruler.align();
break;
}
return false;
return 0;
}
bool SelectBoxState::hasFlag(Flags flag) const
@ -627,7 +666,7 @@ bool SelectBoxState::hasFlag(Flags flag) const
CursorType SelectBoxState::cursorFromAlign(const int align) const
{
switch (align) {
switch (align & (LEFT | TOP | RIGHT | BOTTOM)) {
case LEFT: return kSizeWCursor;
case RIGHT: return kSizeECursor;
case TOP: return kSizeNCursor;

View File

@ -107,16 +107,20 @@ namespace app {
typedef std::vector<Ruler> Rulers;
void updateContextBar();
Ruler& oppositeRuler(const int rulerIndex);
// This returns a ui align value (e.g. LEFT for the ruler)
int hitTestRulers(Editor* editor,
const gfx::Point& mousePos,
const bool updateMovingRulers);
// Returns true if the position screen position (x, y) is touching
// the given ruler.
bool hitTestRuler(Editor* editor, const Ruler& ruler,
const gfx::Point& mousePos);
// Returns 0 if the mouse position on screen (mousePos) is not
// touching any ruler, or in other case returns the alignment of
// the ruler being touch (useful to show a proper mouse cursor).
int hitTestRuler(Editor* editor,
const Ruler& ruler,
const Ruler& oppRuler,
const gfx::Point& mousePos);
ui::CursorType cursorFromAlign(const int align) const;