1 | // Aseprite |
2 | // Copyright (C) 2021 Igara Studio S.A. |
3 | // Copyright (C) 2001-2017 David Capello |
4 | // |
5 | // This program is distributed under the terms of |
6 | // the End-User License Agreement for Aseprite. |
7 | |
8 | #ifdef HAVE_CONFIG_H |
9 | #include "config.h" |
10 | #endif |
11 | |
12 | #include "app/app.h" |
13 | #include "app/commands/command.h" |
14 | #include "app/commands/params.h" |
15 | #include "app/i18n/strings.h" |
16 | #include "app/modules/editors.h" |
17 | #include "app/pref/preferences.h" |
18 | #include "app/ui/editor/editor.h" |
19 | #include "base/convert_to.h" |
20 | #include "fmt/format.h" |
21 | #include "render/zoom.h" |
22 | #include "ui/manager.h" |
23 | #include "ui/system.h" |
24 | |
25 | namespace app { |
26 | |
27 | class ZoomCommand : public Command { |
28 | public: |
29 | enum class Action { In, Out, Set }; |
30 | enum class Focus { Default, Mouse, Center }; |
31 | |
32 | ZoomCommand(); |
33 | |
34 | protected: |
35 | bool onNeedsParams() const override { return true; } |
36 | void onLoadParams(const Params& params) override; |
37 | bool onEnabled(Context* context) override; |
38 | void onExecute(Context* context) override; |
39 | std::string onGetFriendlyName() const override; |
40 | |
41 | private: |
42 | Action m_action; |
43 | render::Zoom m_zoom; |
44 | Focus m_focus; |
45 | }; |
46 | |
47 | ZoomCommand::ZoomCommand() |
48 | : Command(CommandId::Zoom(), CmdUIOnlyFlag) |
49 | , m_action(Action::In) |
50 | , m_zoom(1, 1) |
51 | , m_focus(Focus::Default) |
52 | { |
53 | } |
54 | |
55 | void ZoomCommand::onLoadParams(const Params& params) |
56 | { |
57 | std::string action = params.get("action" ); |
58 | if (action == "in" ) m_action = Action::In; |
59 | else if (action == "out" ) m_action = Action::Out; |
60 | else if (action == "set" ) m_action = Action::Set; |
61 | |
62 | std::string percentage = params.get("percentage" ); |
63 | if (!percentage.empty()) { |
64 | m_zoom = render::Zoom::fromScale( |
65 | std::strtod(percentage.c_str(), NULL) / 100.0); |
66 | m_action = Action::Set; |
67 | } |
68 | |
69 | m_focus = Focus::Default; |
70 | std::string focus = params.get("focus" ); |
71 | if (focus == "center" ) m_focus = Focus::Center; |
72 | else if (focus == "mouse" ) m_focus = Focus::Mouse; |
73 | } |
74 | |
75 | bool ZoomCommand::onEnabled(Context* context) |
76 | { |
77 | return (current_editor != NULL); |
78 | } |
79 | |
80 | void ZoomCommand::onExecute(Context* context) |
81 | { |
82 | // Use the current editor by default. |
83 | Editor* editor = current_editor; |
84 | gfx::Point mousePos = ui::get_mouse_position(); |
85 | |
86 | // Try to use the editor above the mouse. |
87 | ui::Widget* pick = ui::Manager::getDefault()->pickFromScreenPos(mousePos); |
88 | if (pick && pick->type() == Editor::Type()) |
89 | editor = static_cast<Editor*>(pick); |
90 | |
91 | render::Zoom zoom = editor->zoom(); |
92 | |
93 | switch (m_action) { |
94 | case Action::In: |
95 | zoom.in(); |
96 | break; |
97 | case Action::Out: |
98 | zoom.out(); |
99 | break; |
100 | case Action::Set: |
101 | zoom = m_zoom; |
102 | break; |
103 | } |
104 | |
105 | Focus focus = m_focus; |
106 | if (focus == Focus::Default) { |
107 | if (Preferences::instance().editor.zoomFromCenterWithKeys()) { |
108 | focus = Focus::Center; |
109 | } |
110 | else { |
111 | focus = Focus::Mouse; |
112 | } |
113 | } |
114 | |
115 | editor->setZoomAndCenterInMouse( |
116 | zoom, |
117 | editor->display()->nativeWindow()->pointFromScreen(mousePos), |
118 | (focus == Focus::Center ? Editor::ZoomBehavior::CENTER: |
119 | Editor::ZoomBehavior::MOUSE)); |
120 | } |
121 | |
122 | std::string ZoomCommand::onGetFriendlyName() const |
123 | { |
124 | std::string text; |
125 | |
126 | switch (m_action) { |
127 | case Action::In: |
128 | text = Strings::commands_Zoom_In(); |
129 | break; |
130 | case Action::Out: |
131 | text = Strings::commands_Zoom_Out(); |
132 | break; |
133 | case Action::Set: |
134 | text = fmt::format(Strings::commands_Zoom_Set(), |
135 | int(100.0*m_zoom.scale())); |
136 | break; |
137 | } |
138 | |
139 | return text; |
140 | } |
141 | |
142 | Command* CommandFactory::createZoomCommand() |
143 | { |
144 | return new ZoomCommand; |
145 | } |
146 | |
147 | } // namespace app |
148 | |