mirror of
https://github.com/aseprite/aseprite.git
synced 2025-01-27 06:35:16 +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 -->
|
||||
<key command="ScrollCenter" shortcut="Shift+C" />
|
||||
<key command="FitScreen" shortcut="Ctrl+0" mac="Cmd+0" />
|
||||
|
||||
<!-- Scroll with arrows -->
|
||||
<key command="Scroll" shortcut="Space+Left">
|
||||
|
@ -193,6 +193,7 @@ add_library(app-lib
|
||||
commands/cmd_exit.cpp
|
||||
commands/cmd_export_sprite_sheet.cpp
|
||||
commands/cmd_eyedropper.cpp
|
||||
commands/cmd_fit_screen.cpp
|
||||
commands/cmd_flatten_layers.cpp
|
||||
commands/cmd_flip.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
|
||||
// Copyright (C) 2001-2015 David Capello
|
||||
// Copyright (C) 2001-2016 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
// the End-User License Agreement for Aseprite.
|
||||
@ -23,7 +23,8 @@ namespace app {
|
||||
|
||||
class ZoomCommand : public Command {
|
||||
public:
|
||||
enum Action { In, Out, Set };
|
||||
enum class Action { In, Out, Set };
|
||||
enum class Focus { Default, Mouse, Center };
|
||||
|
||||
ZoomCommand();
|
||||
Command* clone() const override { return new ZoomCommand(*this); }
|
||||
@ -37,29 +38,37 @@ protected:
|
||||
private:
|
||||
Action m_action;
|
||||
render::Zoom m_zoom;
|
||||
Focus m_focus;
|
||||
};
|
||||
|
||||
ZoomCommand::ZoomCommand()
|
||||
: Command("Zoom",
|
||||
"Zoom",
|
||||
CmdUIOnlyFlag)
|
||||
, m_action(Action::In)
|
||||
, m_zoom(1, 1)
|
||||
, m_focus(Focus::Default)
|
||||
{
|
||||
}
|
||||
|
||||
void ZoomCommand::onLoadParams(const Params& params)
|
||||
{
|
||||
std::string action = params.get("action");
|
||||
if (action == "in") m_action = In;
|
||||
else if (action == "out") m_action = Out;
|
||||
else if (action == "set") m_action = Set;
|
||||
if (action == "in") m_action = Action::In;
|
||||
else if (action == "out") m_action = Action::Out;
|
||||
else if (action == "set") m_action = Action::Set;
|
||||
|
||||
std::string percentage = params.get("percentage");
|
||||
if (!percentage.empty()) {
|
||||
m_zoom = render::Zoom::fromScale(
|
||||
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)
|
||||
@ -81,23 +90,31 @@ void ZoomCommand::onExecute(Context* context)
|
||||
render::Zoom zoom = editor->zoom();
|
||||
|
||||
switch (m_action) {
|
||||
case In:
|
||||
case Action::In:
|
||||
zoom.in();
|
||||
break;
|
||||
case Out:
|
||||
case Action::Out:
|
||||
zoom.out();
|
||||
break;
|
||||
case Set:
|
||||
case Action::Set:
|
||||
zoom = m_zoom;
|
||||
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(
|
||||
zoom, mousePos,
|
||||
(center ? Editor::ZoomBehavior::CENTER:
|
||||
Editor::ZoomBehavior::MOUSE));
|
||||
(focus == Focus::Center ? Editor::ZoomBehavior::CENTER:
|
||||
Editor::ZoomBehavior::MOUSE));
|
||||
}
|
||||
|
||||
std::string ZoomCommand::onGetFriendlyName() const
|
||||
@ -105,13 +122,13 @@ std::string ZoomCommand::onGetFriendlyName() const
|
||||
std::string text = "Zoom";
|
||||
|
||||
switch (m_action) {
|
||||
case In:
|
||||
case Action::In:
|
||||
text += " in";
|
||||
break;
|
||||
case Out:
|
||||
case Action::Out:
|
||||
text += " out";
|
||||
break;
|
||||
case Set:
|
||||
case Action::Set:
|
||||
text += " " + base::convert_to<std::string>(int(100.0*m_zoom.scale())) + "%";
|
||||
break;
|
||||
}
|
||||
|
@ -37,6 +37,7 @@ FOR_EACH_COMMAND(DuplicateView)
|
||||
FOR_EACH_COMMAND(Exit)
|
||||
FOR_EACH_COMMAND(ExportSpriteSheet)
|
||||
FOR_EACH_COMMAND(Eyedropper)
|
||||
FOR_EACH_COMMAND(FitScreen)
|
||||
FOR_EACH_COMMAND(FlattenLayers)
|
||||
FOR_EACH_COMMAND(Flip)
|
||||
FOR_EACH_COMMAND(FrameProperties)
|
||||
|
@ -72,6 +72,52 @@ using namespace tools;
|
||||
|
||||
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 {
|
||||
public:
|
||||
BrushTypeField(ContextBar* owner)
|
||||
@ -1321,6 +1367,8 @@ ContextBar::ContextBar()
|
||||
m_selectionOptionsBox->addChild(m_pivot = new PivotField);
|
||||
m_selectionOptionsBox->addChild(m_rotAlgo = new RotAlgorithmField());
|
||||
|
||||
addChild(m_zoomButtons = new ZoomButtons);
|
||||
|
||||
addChild(m_brushType = new BrushTypeField(this));
|
||||
addChild(m_brushSize = new BrushSizeField());
|
||||
addChild(m_brushAngle = new BrushAngleField(m_brushType));
|
||||
@ -1581,6 +1629,13 @@ void ContextBar::updateForTool(tools::Tool* tool)
|
||||
(activeBrush()->type() == kSquareBrushType ||
|
||||
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.
|
||||
bool isEyedropper = tool &&
|
||||
(tool->getInk(0)->isEyedropper() ||
|
||||
@ -1620,6 +1675,7 @@ void ContextBar::updateForTool(tools::Tool* tool)
|
||||
(isEffect));
|
||||
|
||||
// Show/Hide fields
|
||||
m_zoomButtons->setVisible(needZoomButtons);
|
||||
m_brushType->setVisible(supportOpacity && (!isFloodfill || (isFloodfill && hasImageBrush)));
|
||||
m_brushSize->setVisible(supportOpacity && !isFloodfill && !hasImageBrush);
|
||||
m_brushAngle->setVisible(supportOpacity && !isFloodfill && !hasImageBrush && hasBrushWithAngle);
|
||||
|
@ -87,6 +87,7 @@ namespace app {
|
||||
// ActiveToolObserver impl
|
||||
void onActiveToolChange(tools::Tool* tool) override;
|
||||
|
||||
class ZoomButtons;
|
||||
class BrushTypeField;
|
||||
class BrushAngleField;
|
||||
class BrushSizeField;
|
||||
@ -109,6 +110,7 @@ namespace app {
|
||||
class AutoSelectLayerField;
|
||||
class SymmetryField;
|
||||
|
||||
ZoomButtons* m_zoomButtons;
|
||||
BrushTypeField* m_brushType;
|
||||
BrushAngleField* m_brushAngle;
|
||||
BrushSizeField* m_brushSize;
|
||||
|
@ -387,6 +387,60 @@ void Editor::setDefaultScroll()
|
||||
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
|
||||
void Editor::setEditorScroll(const gfx::Point& scroll)
|
||||
{
|
||||
|
@ -135,6 +135,7 @@ namespace app {
|
||||
|
||||
void setZoom(const render::Zoom& zoom);
|
||||
void setDefaultScroll();
|
||||
void setScrollAndZoomToFitScreen();
|
||||
void setEditorScroll(const gfx::Point& scroll);
|
||||
void setEditorZoom(const render::Zoom& zoom);
|
||||
|
||||
|
@ -53,7 +53,7 @@ Zoom::Zoom(int num, int den)
|
||||
m_internalScale = scale();
|
||||
}
|
||||
|
||||
void Zoom::in()
|
||||
bool Zoom::in()
|
||||
{
|
||||
int i = linearScale();
|
||||
if (i < scales_size-1) {
|
||||
@ -61,10 +61,13 @@ void Zoom::in()
|
||||
m_num = scales[i][0];
|
||||
m_den = scales[i][1];
|
||||
m_internalScale = scale();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
void Zoom::out()
|
||||
bool Zoom::out()
|
||||
{
|
||||
int i = linearScale();
|
||||
if (i > 0) {
|
||||
@ -72,7 +75,10 @@ void Zoom::out()
|
||||
m_num = scales[i][0];
|
||||
m_den = scales[i][1];
|
||||
m_internalScale = scale();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
int Zoom::linearScale() const
|
||||
|
@ -1,5 +1,5 @@
|
||||
// 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.
|
||||
// Read LICENSE.txt for more information.
|
||||
@ -51,8 +51,8 @@ namespace render {
|
||||
remove(r.y+r.h) - remove(r.y));
|
||||
}
|
||||
|
||||
void in();
|
||||
void out();
|
||||
bool in();
|
||||
bool out();
|
||||
|
||||
// Returns an linear zoom scale. This position can be incremented
|
||||
// or decremented to get a new zoom value.
|
||||
|
Loading…
x
Reference in New Issue
Block a user