1// Aseprite
2// Copyright (C) 2019-2020 Igara Studio S.A.
3// Copyright (C) 2001-2018 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/cmd/set_grid_bounds.h"
14#include "app/commands/command.h"
15#include "app/context.h"
16#include "app/context_access.h"
17#include "app/doc.h"
18#include "app/find_widget.h"
19#include "app/load_widget.h"
20#include "app/modules/editors.h"
21#include "app/pref/preferences.h"
22#include "app/tx.h"
23#include "app/ui/status_bar.h"
24#include "app/ui_context.h"
25#include "doc/document.h"
26#include "doc/mask.h"
27#include "ui/window.h"
28
29#include "grid_settings.xml.h"
30
31#include <algorithm>
32
33namespace app {
34
35using namespace ui;
36using namespace gfx;
37
38class SnapToGridCommand : public Command {
39public:
40 SnapToGridCommand()
41 : Command(CommandId::SnapToGrid(), CmdUIOnlyFlag) {
42 }
43
44protected:
45 bool onChecked(Context* ctx) override {
46 auto& docPref = Preferences::instance().document(ctx->activeDocument());
47 return docPref.grid.snap();
48 }
49
50 void onExecute(Context* ctx) override {
51 auto& docPref = Preferences::instance().document(ctx->activeDocument());
52 bool newValue = !docPref.grid.snap();
53 docPref.grid.snap(newValue);
54
55 StatusBar::instance()->showSnapToGridWarning(newValue);
56 }
57};
58
59class SelectionAsGridCommand : public Command {
60public:
61 SelectionAsGridCommand()
62 : Command(CommandId::SelectionAsGrid(), CmdUIOnlyFlag) {
63 }
64
65protected:
66 bool onEnabled(Context* ctx) override {
67 return ctx->checkFlags(ContextFlags::ActiveDocumentIsWritable |
68 ContextFlags::HasVisibleMask);
69 }
70
71 void onExecute(Context* ctx) override {
72 ContextWriter writer(ctx);
73 Doc* doc = writer.document();
74 const Mask* mask = doc->mask();
75 gfx::Rect newGrid = mask->bounds();
76
77 Tx tx(writer.context(), friendlyName(), ModifyDocument);
78 tx(new cmd::SetGridBounds(writer.sprite(), newGrid));
79 tx.commit();
80
81 auto& docPref = Preferences::instance().document(doc);
82 docPref.grid.bounds(newGrid);
83 if (!docPref.show.grid()) // Make grid visible
84 docPref.show.grid(true);
85 }
86};
87
88class GridSettingsCommand : public Command {
89public:
90 GridSettingsCommand();
91
92protected:
93 bool onEnabled(Context* context) override;
94 void onExecute(Context* context) override;
95};
96
97GridSettingsCommand::GridSettingsCommand()
98 : Command(CommandId::GridSettings(), CmdUIOnlyFlag)
99{
100}
101
102bool GridSettingsCommand::onEnabled(Context* context)
103{
104 return true;
105}
106
107void GridSettingsCommand::onExecute(Context* context)
108{
109 gen::GridSettings window;
110
111 Site site = context->activeSite();
112 Rect bounds = site.gridBounds();
113
114 window.gridX()->setTextf("%d", bounds.x);
115 window.gridY()->setTextf("%d", bounds.y);
116 window.gridW()->setTextf("%d", bounds.w);
117 window.gridH()->setTextf("%d", bounds.h);
118 window.openWindowInForeground();
119
120 if (window.closer() == window.ok()) {
121 bounds.x = window.gridX()->textInt();
122 bounds.y = window.gridY()->textInt();
123 bounds.w = window.gridW()->textInt();
124 bounds.h = window.gridH()->textInt();
125 bounds.w = std::max(bounds.w, 1);
126 bounds.h = std::max(bounds.h, 1);
127
128 ContextWriter writer(context);
129 Tx tx(context, friendlyName(), ModifyDocument);
130 tx(new cmd::SetGridBounds(site.sprite(), bounds));
131 tx.commit();
132
133 auto& docPref = Preferences::instance().document(site.document());
134 if (!docPref.show.grid()) // Make grid visible
135 docPref.show.grid(true);
136 }
137}
138
139Command* CommandFactory::createSnapToGridCommand()
140{
141 return new SnapToGridCommand;
142}
143
144Command* CommandFactory::createGridSettingsCommand()
145{
146 return new GridSettingsCommand;
147}
148
149Command* CommandFactory::createSelectionAsGridCommand()
150{
151 return new SelectionAsGridCommand;
152}
153
154} // namespace app
155