mirror of
https://github.com/aseprite/aseprite.git
synced 2025-01-28 18:32:50 +00:00
Add zoom/scroll buttons in ContextBar (including a new "Fit Screen" command)
This commit is contained in:
parent
ada6c0666c
commit
1c7abd285e
@ -224,6 +224,7 @@
|
|||||||
|
|
||||||
<!-- Scroll to center -->
|
<!-- Scroll to center -->
|
||||||
<key command="ScrollCenter" shortcut="Shift+C" />
|
<key command="ScrollCenter" shortcut="Shift+C" />
|
||||||
|
<key command="FitScreen" shortcut="Ctrl+0" mac="Cmd+0" />
|
||||||
|
|
||||||
<!-- Scroll with arrows -->
|
<!-- Scroll with arrows -->
|
||||||
<key command="Scroll" shortcut="Space+Left">
|
<key command="Scroll" shortcut="Space+Left">
|
||||||
|
@ -193,6 +193,7 @@ add_library(app-lib
|
|||||||
commands/cmd_exit.cpp
|
commands/cmd_exit.cpp
|
||||||
commands/cmd_export_sprite_sheet.cpp
|
commands/cmd_export_sprite_sheet.cpp
|
||||||
commands/cmd_eyedropper.cpp
|
commands/cmd_eyedropper.cpp
|
||||||
|
commands/cmd_fit_screen.cpp
|
||||||
commands/cmd_flatten_layers.cpp
|
commands/cmd_flatten_layers.cpp
|
||||||
commands/cmd_flip.cpp
|
commands/cmd_flip.cpp
|
||||||
commands/cmd_frame_properties.cpp
|
commands/cmd_frame_properties.cpp
|
||||||
|
51
src/app/commands/cmd_fit_screen.cpp
Normal file
51
src/app/commands/cmd_fit_screen.cpp
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
// Aseprite
|
||||||
|
// Copyright (C) 2001-2016 David Capello
|
||||||
|
//
|
||||||
|
// This program is distributed under the terms of
|
||||||
|
// the End-User License Agreement for Aseprite.
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "app/app.h"
|
||||||
|
#include "app/commands/command.h"
|
||||||
|
#include "app/context_access.h"
|
||||||
|
#include "app/modules/editors.h"
|
||||||
|
#include "app/ui/editor/editor.h"
|
||||||
|
|
||||||
|
namespace app {
|
||||||
|
|
||||||
|
class FitScreenCommand : public Command {
|
||||||
|
public:
|
||||||
|
FitScreenCommand();
|
||||||
|
Command* clone() const override { return new FitScreenCommand(*this); }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool onEnabled(Context* context) override;
|
||||||
|
void onExecute(Context* context) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
FitScreenCommand::FitScreenCommand()
|
||||||
|
: Command("FitScreen",
|
||||||
|
"Fit on Screen",
|
||||||
|
CmdUIOnlyFlag)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FitScreenCommand::onEnabled(Context* context)
|
||||||
|
{
|
||||||
|
return (current_editor != nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FitScreenCommand::onExecute(Context* context)
|
||||||
|
{
|
||||||
|
current_editor->setScrollAndZoomToFitScreen();
|
||||||
|
}
|
||||||
|
|
||||||
|
Command* CommandFactory::createFitScreenCommand()
|
||||||
|
{
|
||||||
|
return new FitScreenCommand;
|
||||||
|
}
|
||||||
|
|
||||||
|
} //namespace app
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2001-2015 David Capello
|
// Copyright (C) 2001-2016 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
// the End-User License Agreement for Aseprite.
|
// the End-User License Agreement for Aseprite.
|
||||||
@ -23,7 +23,8 @@ namespace app {
|
|||||||
|
|
||||||
class ZoomCommand : public Command {
|
class ZoomCommand : public Command {
|
||||||
public:
|
public:
|
||||||
enum Action { In, Out, Set };
|
enum class Action { In, Out, Set };
|
||||||
|
enum class Focus { Default, Mouse, Center };
|
||||||
|
|
||||||
ZoomCommand();
|
ZoomCommand();
|
||||||
Command* clone() const override { return new ZoomCommand(*this); }
|
Command* clone() const override { return new ZoomCommand(*this); }
|
||||||
@ -37,29 +38,37 @@ protected:
|
|||||||
private:
|
private:
|
||||||
Action m_action;
|
Action m_action;
|
||||||
render::Zoom m_zoom;
|
render::Zoom m_zoom;
|
||||||
|
Focus m_focus;
|
||||||
};
|
};
|
||||||
|
|
||||||
ZoomCommand::ZoomCommand()
|
ZoomCommand::ZoomCommand()
|
||||||
: Command("Zoom",
|
: Command("Zoom",
|
||||||
"Zoom",
|
"Zoom",
|
||||||
CmdUIOnlyFlag)
|
CmdUIOnlyFlag)
|
||||||
|
, m_action(Action::In)
|
||||||
, m_zoom(1, 1)
|
, m_zoom(1, 1)
|
||||||
|
, m_focus(Focus::Default)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void ZoomCommand::onLoadParams(const Params& params)
|
void ZoomCommand::onLoadParams(const Params& params)
|
||||||
{
|
{
|
||||||
std::string action = params.get("action");
|
std::string action = params.get("action");
|
||||||
if (action == "in") m_action = In;
|
if (action == "in") m_action = Action::In;
|
||||||
else if (action == "out") m_action = Out;
|
else if (action == "out") m_action = Action::Out;
|
||||||
else if (action == "set") m_action = Set;
|
else if (action == "set") m_action = Action::Set;
|
||||||
|
|
||||||
std::string percentage = params.get("percentage");
|
std::string percentage = params.get("percentage");
|
||||||
if (!percentage.empty()) {
|
if (!percentage.empty()) {
|
||||||
m_zoom = render::Zoom::fromScale(
|
m_zoom = render::Zoom::fromScale(
|
||||||
std::strtod(percentage.c_str(), NULL) / 100.0);
|
std::strtod(percentage.c_str(), NULL) / 100.0);
|
||||||
m_action = Set;
|
m_action = Action::Set;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_focus = Focus::Default;
|
||||||
|
std::string focus = params.get("focus");
|
||||||
|
if (focus == "center") m_focus = Focus::Center;
|
||||||
|
else if (focus == "mouse") m_focus = Focus::Mouse;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ZoomCommand::onEnabled(Context* context)
|
bool ZoomCommand::onEnabled(Context* context)
|
||||||
@ -81,23 +90,31 @@ void ZoomCommand::onExecute(Context* context)
|
|||||||
render::Zoom zoom = editor->zoom();
|
render::Zoom zoom = editor->zoom();
|
||||||
|
|
||||||
switch (m_action) {
|
switch (m_action) {
|
||||||
case In:
|
case Action::In:
|
||||||
zoom.in();
|
zoom.in();
|
||||||
break;
|
break;
|
||||||
case Out:
|
case Action::Out:
|
||||||
zoom.out();
|
zoom.out();
|
||||||
break;
|
break;
|
||||||
case Set:
|
case Action::Set:
|
||||||
zoom = m_zoom;
|
zoom = m_zoom;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool center = Preferences::instance().editor.zoomFromCenterWithKeys();
|
Focus focus = m_focus;
|
||||||
|
if (focus == Focus::Default) {
|
||||||
|
if (Preferences::instance().editor.zoomFromCenterWithKeys()) {
|
||||||
|
focus = Focus::Center;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
focus = Focus::Mouse;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
editor->setZoomAndCenterInMouse(
|
editor->setZoomAndCenterInMouse(
|
||||||
zoom, mousePos,
|
zoom, mousePos,
|
||||||
(center ? Editor::ZoomBehavior::CENTER:
|
(focus == Focus::Center ? Editor::ZoomBehavior::CENTER:
|
||||||
Editor::ZoomBehavior::MOUSE));
|
Editor::ZoomBehavior::MOUSE));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string ZoomCommand::onGetFriendlyName() const
|
std::string ZoomCommand::onGetFriendlyName() const
|
||||||
@ -105,13 +122,13 @@ std::string ZoomCommand::onGetFriendlyName() const
|
|||||||
std::string text = "Zoom";
|
std::string text = "Zoom";
|
||||||
|
|
||||||
switch (m_action) {
|
switch (m_action) {
|
||||||
case In:
|
case Action::In:
|
||||||
text += " in";
|
text += " in";
|
||||||
break;
|
break;
|
||||||
case Out:
|
case Action::Out:
|
||||||
text += " out";
|
text += " out";
|
||||||
break;
|
break;
|
||||||
case Set:
|
case Action::Set:
|
||||||
text += " " + base::convert_to<std::string>(int(100.0*m_zoom.scale())) + "%";
|
text += " " + base::convert_to<std::string>(int(100.0*m_zoom.scale())) + "%";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -37,6 +37,7 @@ FOR_EACH_COMMAND(DuplicateView)
|
|||||||
FOR_EACH_COMMAND(Exit)
|
FOR_EACH_COMMAND(Exit)
|
||||||
FOR_EACH_COMMAND(ExportSpriteSheet)
|
FOR_EACH_COMMAND(ExportSpriteSheet)
|
||||||
FOR_EACH_COMMAND(Eyedropper)
|
FOR_EACH_COMMAND(Eyedropper)
|
||||||
|
FOR_EACH_COMMAND(FitScreen)
|
||||||
FOR_EACH_COMMAND(FlattenLayers)
|
FOR_EACH_COMMAND(FlattenLayers)
|
||||||
FOR_EACH_COMMAND(Flip)
|
FOR_EACH_COMMAND(Flip)
|
||||||
FOR_EACH_COMMAND(FrameProperties)
|
FOR_EACH_COMMAND(FrameProperties)
|
||||||
|
@ -72,6 +72,52 @@ using namespace tools;
|
|||||||
|
|
||||||
static bool g_updatingFromCode = false;
|
static bool g_updatingFromCode = false;
|
||||||
|
|
||||||
|
class ContextBar::ZoomButtons : public ButtonSet {
|
||||||
|
public:
|
||||||
|
ZoomButtons()
|
||||||
|
: ButtonSet(3) {
|
||||||
|
addItem("100%");
|
||||||
|
addItem("Center");
|
||||||
|
addItem("Fit Screen");
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void onItemChange(Item* item) override {
|
||||||
|
ButtonSet::onItemChange(item);
|
||||||
|
|
||||||
|
Command* cmd = nullptr;
|
||||||
|
Params params;
|
||||||
|
|
||||||
|
switch (selectedItem()) {
|
||||||
|
|
||||||
|
case 0: {
|
||||||
|
cmd = CommandsModule::instance()->getCommandByName(CommandId::Zoom);
|
||||||
|
params.set("action", "set");
|
||||||
|
params.set("percentage", "100");
|
||||||
|
params.set("focus", "center");
|
||||||
|
UIContext::instance()->executeCommand(cmd, params);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 1: {
|
||||||
|
cmd = CommandsModule::instance()->getCommandByName(CommandId::ScrollCenter);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 2: {
|
||||||
|
cmd = CommandsModule::instance()->getCommandByName(CommandId::FitScreen);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cmd)
|
||||||
|
UIContext::instance()->executeCommand(cmd, params);
|
||||||
|
|
||||||
|
deselectItems();
|
||||||
|
manager()->freeFocus();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class ContextBar::BrushTypeField : public ButtonSet {
|
class ContextBar::BrushTypeField : public ButtonSet {
|
||||||
public:
|
public:
|
||||||
BrushTypeField(ContextBar* owner)
|
BrushTypeField(ContextBar* owner)
|
||||||
@ -1321,6 +1367,8 @@ ContextBar::ContextBar()
|
|||||||
m_selectionOptionsBox->addChild(m_pivot = new PivotField);
|
m_selectionOptionsBox->addChild(m_pivot = new PivotField);
|
||||||
m_selectionOptionsBox->addChild(m_rotAlgo = new RotAlgorithmField());
|
m_selectionOptionsBox->addChild(m_rotAlgo = new RotAlgorithmField());
|
||||||
|
|
||||||
|
addChild(m_zoomButtons = new ZoomButtons);
|
||||||
|
|
||||||
addChild(m_brushType = new BrushTypeField(this));
|
addChild(m_brushType = new BrushTypeField(this));
|
||||||
addChild(m_brushSize = new BrushSizeField());
|
addChild(m_brushSize = new BrushSizeField());
|
||||||
addChild(m_brushAngle = new BrushAngleField(m_brushType));
|
addChild(m_brushAngle = new BrushAngleField(m_brushType));
|
||||||
@ -1581,6 +1629,13 @@ void ContextBar::updateForTool(tools::Tool* tool)
|
|||||||
(activeBrush()->type() == kSquareBrushType ||
|
(activeBrush()->type() == kSquareBrushType ||
|
||||||
activeBrush()->type() == kLineBrushType);
|
activeBrush()->type() == kLineBrushType);
|
||||||
|
|
||||||
|
// True if the current tool is eyedropper.
|
||||||
|
bool needZoomButtons = tool &&
|
||||||
|
(tool->getInk(0)->isZoom() ||
|
||||||
|
tool->getInk(1)->isZoom() ||
|
||||||
|
tool->getInk(0)->isScrollMovement() ||
|
||||||
|
tool->getInk(1)->isScrollMovement());
|
||||||
|
|
||||||
// True if the current tool is eyedropper.
|
// True if the current tool is eyedropper.
|
||||||
bool isEyedropper = tool &&
|
bool isEyedropper = tool &&
|
||||||
(tool->getInk(0)->isEyedropper() ||
|
(tool->getInk(0)->isEyedropper() ||
|
||||||
@ -1620,6 +1675,7 @@ void ContextBar::updateForTool(tools::Tool* tool)
|
|||||||
(isEffect));
|
(isEffect));
|
||||||
|
|
||||||
// Show/Hide fields
|
// Show/Hide fields
|
||||||
|
m_zoomButtons->setVisible(needZoomButtons);
|
||||||
m_brushType->setVisible(supportOpacity && (!isFloodfill || (isFloodfill && hasImageBrush)));
|
m_brushType->setVisible(supportOpacity && (!isFloodfill || (isFloodfill && hasImageBrush)));
|
||||||
m_brushSize->setVisible(supportOpacity && !isFloodfill && !hasImageBrush);
|
m_brushSize->setVisible(supportOpacity && !isFloodfill && !hasImageBrush);
|
||||||
m_brushAngle->setVisible(supportOpacity && !isFloodfill && !hasImageBrush && hasBrushWithAngle);
|
m_brushAngle->setVisible(supportOpacity && !isFloodfill && !hasImageBrush && hasBrushWithAngle);
|
||||||
|
@ -87,6 +87,7 @@ namespace app {
|
|||||||
// ActiveToolObserver impl
|
// ActiveToolObserver impl
|
||||||
void onActiveToolChange(tools::Tool* tool) override;
|
void onActiveToolChange(tools::Tool* tool) override;
|
||||||
|
|
||||||
|
class ZoomButtons;
|
||||||
class BrushTypeField;
|
class BrushTypeField;
|
||||||
class BrushAngleField;
|
class BrushAngleField;
|
||||||
class BrushSizeField;
|
class BrushSizeField;
|
||||||
@ -109,6 +110,7 @@ namespace app {
|
|||||||
class AutoSelectLayerField;
|
class AutoSelectLayerField;
|
||||||
class SymmetryField;
|
class SymmetryField;
|
||||||
|
|
||||||
|
ZoomButtons* m_zoomButtons;
|
||||||
BrushTypeField* m_brushType;
|
BrushTypeField* m_brushType;
|
||||||
BrushAngleField* m_brushAngle;
|
BrushAngleField* m_brushAngle;
|
||||||
BrushSizeField* m_brushSize;
|
BrushSizeField* m_brushSize;
|
||||||
|
@ -387,6 +387,60 @@ void Editor::setDefaultScroll()
|
|||||||
m_padding.y - vp.h/2 + m_zoom.apply(m_sprite->height())/2));
|
m_padding.y - vp.h/2 + m_zoom.apply(m_sprite->height())/2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Editor::setScrollAndZoomToFitScreen()
|
||||||
|
{
|
||||||
|
View* view = View::getView(this);
|
||||||
|
Rect vp = view->viewportBounds();
|
||||||
|
Zoom zoom = m_zoom;
|
||||||
|
|
||||||
|
if (float(vp.w) / float(m_sprite->width()) <
|
||||||
|
float(vp.h) / float(m_sprite->height())) {
|
||||||
|
if (vp.w < zoom.apply(m_sprite->width())) {
|
||||||
|
while (vp.w < zoom.apply(m_sprite->width()))
|
||||||
|
if (!zoom.out())
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (vp.w > zoom.apply(m_sprite->width())) {
|
||||||
|
bool out = true;
|
||||||
|
while (vp.w > zoom.apply(m_sprite->width())) {
|
||||||
|
if (!zoom.in()) {
|
||||||
|
out = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (out)
|
||||||
|
zoom.out();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (vp.h < zoom.apply(m_sprite->height())) {
|
||||||
|
while (vp.h < zoom.apply(m_sprite->height())) {
|
||||||
|
if (!zoom.out())
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (vp.h > zoom.apply(m_sprite->height())) {
|
||||||
|
bool out = true;
|
||||||
|
while (vp.h > zoom.apply(m_sprite->height())) {
|
||||||
|
if (!zoom.in()) {
|
||||||
|
out = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (out)
|
||||||
|
zoom.out();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setZoom(zoom);
|
||||||
|
|
||||||
|
updateEditor();
|
||||||
|
setEditorScroll(
|
||||||
|
gfx::Point(
|
||||||
|
m_padding.x - vp.w/2 + zoom.apply(m_sprite->width())/2,
|
||||||
|
m_padding.y - vp.h/2 + zoom.apply(m_sprite->height())/2));
|
||||||
|
}
|
||||||
|
|
||||||
// Sets the scroll position of the editor
|
// Sets the scroll position of the editor
|
||||||
void Editor::setEditorScroll(const gfx::Point& scroll)
|
void Editor::setEditorScroll(const gfx::Point& scroll)
|
||||||
{
|
{
|
||||||
|
@ -135,6 +135,7 @@ namespace app {
|
|||||||
|
|
||||||
void setZoom(const render::Zoom& zoom);
|
void setZoom(const render::Zoom& zoom);
|
||||||
void setDefaultScroll();
|
void setDefaultScroll();
|
||||||
|
void setScrollAndZoomToFitScreen();
|
||||||
void setEditorScroll(const gfx::Point& scroll);
|
void setEditorScroll(const gfx::Point& scroll);
|
||||||
void setEditorZoom(const render::Zoom& zoom);
|
void setEditorZoom(const render::Zoom& zoom);
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ Zoom::Zoom(int num, int den)
|
|||||||
m_internalScale = scale();
|
m_internalScale = scale();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Zoom::in()
|
bool Zoom::in()
|
||||||
{
|
{
|
||||||
int i = linearScale();
|
int i = linearScale();
|
||||||
if (i < scales_size-1) {
|
if (i < scales_size-1) {
|
||||||
@ -61,10 +61,13 @@ void Zoom::in()
|
|||||||
m_num = scales[i][0];
|
m_num = scales[i][0];
|
||||||
m_den = scales[i][1];
|
m_den = scales[i][1];
|
||||||
m_internalScale = scale();
|
m_internalScale = scale();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Zoom::out()
|
bool Zoom::out()
|
||||||
{
|
{
|
||||||
int i = linearScale();
|
int i = linearScale();
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
@ -72,7 +75,10 @@ void Zoom::out()
|
|||||||
m_num = scales[i][0];
|
m_num = scales[i][0];
|
||||||
m_den = scales[i][1];
|
m_den = scales[i][1];
|
||||||
m_internalScale = scale();
|
m_internalScale = scale();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Zoom::linearScale() const
|
int Zoom::linearScale() const
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite Render Library
|
// Aseprite Render Library
|
||||||
// Copyright (c) 2001-2015 David Capello
|
// Copyright (c) 2001-2016 David Capello
|
||||||
//
|
//
|
||||||
// This file is released under the terms of the MIT license.
|
// This file is released under the terms of the MIT license.
|
||||||
// Read LICENSE.txt for more information.
|
// Read LICENSE.txt for more information.
|
||||||
@ -51,8 +51,8 @@ namespace render {
|
|||||||
remove(r.y+r.h) - remove(r.y));
|
remove(r.y+r.h) - remove(r.y));
|
||||||
}
|
}
|
||||||
|
|
||||||
void in();
|
bool in();
|
||||||
void out();
|
bool out();
|
||||||
|
|
||||||
// Returns an linear zoom scale. This position can be incremented
|
// Returns an linear zoom scale. This position can be incremented
|
||||||
// or decremented to get a new zoom value.
|
// or decremented to get a new zoom value.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user