mirror of
https://github.com/aseprite/aseprite.git
synced 2025-03-03 16:13:43 +00:00
Add "Snap to Grid" indicator when it's enabled (fix #122)
This commit is contained in:
parent
9e5ccbcca9
commit
a7ea0f7ec5
1
TODO.md
1
TODO.md
@ -29,7 +29,6 @@
|
||||
* Fix problem with export sprite sheet when the cel has negative pos
|
||||
* MovingPixelsState: Add undo information in each transformation step.
|
||||
* Add IntEntry class in src/ui/ with spin-buttons.
|
||||
* Add feedback to "Shift+S" shortcut to switch "snap to grid".
|
||||
* Add color swatches bar.
|
||||
* Sort palette entries.
|
||||
* Add "Remap" button to palette editor after a palette entry is modified:
|
||||
|
@ -88,13 +88,10 @@ protected:
|
||||
|
||||
void onExecute(Context* ctx) {
|
||||
DocumentPreferences& docPref = Preferences::instance().document(ctx->activeDocument());
|
||||
docPref.grid.snap(!docPref.grid.snap());
|
||||
bool newValue = !docPref.grid.snap();
|
||||
docPref.grid.snap(newValue);
|
||||
|
||||
char buf[512];
|
||||
sprintf(buf, "Snap to grid: %s",
|
||||
(docPref.grid.snap() ? "On": "Off"));
|
||||
|
||||
StatusBar::instance()->setStatusText(250, buf);
|
||||
StatusBar::instance()->showSnapToGridWarning(newValue);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -19,12 +19,14 @@
|
||||
#include "app/modules/gfx.h"
|
||||
#include "app/modules/gui.h"
|
||||
#include "app/modules/palettes.h"
|
||||
#include "app/pref/preferences.h"
|
||||
#include "app/tools/tool.h"
|
||||
#include "app/ui/button_set.h"
|
||||
#include "app/ui/color_button.h"
|
||||
#include "app/ui/editor/editor.h"
|
||||
#include "app/ui/keyboard_shortcuts.h"
|
||||
#include "app/ui/main_window.h"
|
||||
#include "app/ui/skin/skin_style_property.h"
|
||||
#include "app/ui/skin/skin_theme.h"
|
||||
#include "app/ui/status_bar.h"
|
||||
#include "app/ui/timeline.h"
|
||||
@ -56,7 +58,7 @@ using namespace doc;
|
||||
|
||||
class StatusBar::CustomizedTipWindow : public ui::TipWindow {
|
||||
public:
|
||||
CustomizedTipWindow(const char* text)
|
||||
CustomizedTipWindow(const std::string& text)
|
||||
: ui::TipWindow(text, gfx::Rect())
|
||||
{
|
||||
}
|
||||
@ -81,6 +83,32 @@ private:
|
||||
base::UniquePtr<ui::Timer> m_timer;
|
||||
};
|
||||
|
||||
class StatusBar::SnapToGridWindow : public ui::TipWindow {
|
||||
public:
|
||||
SnapToGridWindow()
|
||||
: ui::TipWindow("", ui::Manager::getDefault()->getBounds())
|
||||
, m_button("Disable Snap to Grid") {
|
||||
makeFloating();
|
||||
setCloseOnKeyDown(false);
|
||||
|
||||
addChild(&m_button);
|
||||
m_button.Click.connect(Bind<void>(&SnapToGridWindow::onDisableSnapToGrid, this));
|
||||
}
|
||||
|
||||
void setDocument(app::Document* doc) {
|
||||
m_doc = doc;
|
||||
}
|
||||
|
||||
private:
|
||||
void onDisableSnapToGrid() {
|
||||
Preferences::instance().document(m_doc).grid.snap(false);
|
||||
closeWindow(nullptr);
|
||||
}
|
||||
|
||||
app::Document* m_doc;
|
||||
ui::Button m_button;
|
||||
};
|
||||
|
||||
static WidgetType statusbar_type()
|
||||
{
|
||||
static WidgetType type = kGenericWidget;
|
||||
@ -134,8 +162,13 @@ StatusBar* StatusBar::m_instance = NULL;
|
||||
|
||||
StatusBar::StatusBar()
|
||||
: Widget(statusbar_type())
|
||||
, m_timeout(0)
|
||||
, m_state(SHOW_TEXT)
|
||||
, m_color(app::Color::fromMask())
|
||||
, m_docControls(new HBox)
|
||||
, m_doc(nullptr)
|
||||
, m_tipwindow(nullptr)
|
||||
, m_snapToGridWindow(nullptr)
|
||||
{
|
||||
m_instance = this;
|
||||
|
||||
@ -146,15 +179,14 @@ StatusBar::StatusBar()
|
||||
|
||||
this->setFocusStop(true);
|
||||
|
||||
m_timeout = 0;
|
||||
m_state = SHOW_TEXT;
|
||||
m_tipwindow = NULL;
|
||||
|
||||
// The extra pixel in left and right borders are necessary so
|
||||
// m_commandsBox and m_movePixelsBox do not overlap the upper-left
|
||||
// and upper-right pixels drawn in onPaint() event (see putpixels)
|
||||
setBorder(gfx::Border(1*guiscale(), 0, 1*guiscale(), 0));
|
||||
|
||||
m_docControls->setVisible(false);
|
||||
addChild(m_docControls);
|
||||
|
||||
// Construct the commands box
|
||||
{
|
||||
Box* box1 = new Box(HORIZONTAL);
|
||||
@ -181,9 +213,7 @@ StatusBar::StatusBar()
|
||||
box1->addChild(box4);
|
||||
box1->addChild(m_slider);
|
||||
|
||||
m_commandsBox = box1;
|
||||
addChild(m_commandsBox);
|
||||
m_commandsBox->setVisible(false);
|
||||
m_docControls->addChild(box1);
|
||||
}
|
||||
|
||||
// Tooltips manager
|
||||
@ -205,7 +235,7 @@ StatusBar::~StatusBar()
|
||||
UIContext::instance()->removeObserver(this);
|
||||
|
||||
delete m_tipwindow; // widget
|
||||
delete m_commandsBox;
|
||||
delete m_snapToGridWindow;
|
||||
}
|
||||
|
||||
void StatusBar::onCurrentToolChange()
|
||||
@ -313,6 +343,38 @@ void StatusBar::showTool(int msecs, tools::Tool* tool)
|
||||
}
|
||||
}
|
||||
|
||||
void StatusBar::showSnapToGridWarning(bool state)
|
||||
{
|
||||
if (state) {
|
||||
ASSERT(m_doc);
|
||||
if (!m_doc)
|
||||
return;
|
||||
|
||||
if (!m_snapToGridWindow) {
|
||||
m_snapToGridWindow = new SnapToGridWindow;
|
||||
}
|
||||
|
||||
if (!m_snapToGridWindow->isVisible()) {
|
||||
m_snapToGridWindow->openWindow();
|
||||
m_snapToGridWindow->remapWindow();
|
||||
|
||||
Rect rc = getBounds();
|
||||
int toolBarWidth = ToolBar::instance()->getPreferredSize().w;
|
||||
|
||||
m_snapToGridWindow->positionWindow(
|
||||
rc.x+rc.w-toolBarWidth-m_snapToGridWindow->getBounds().w,
|
||||
rc.y-m_snapToGridWindow->getBounds().h);
|
||||
}
|
||||
|
||||
m_snapToGridWindow->setDocument(
|
||||
static_cast<app::Document*>(m_doc));
|
||||
}
|
||||
else {
|
||||
if (m_snapToGridWindow)
|
||||
m_snapToGridWindow->closeWindow(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// StatusBar message handler
|
||||
|
||||
@ -324,21 +386,20 @@ void StatusBar::onResize(ResizeEvent& ev)
|
||||
|
||||
Border border = this->border();
|
||||
Rect rc = ev.getBounds();
|
||||
bool frameControls = (rc.w > 300*ui::guiscale());
|
||||
|
||||
if (frameControls) {
|
||||
bool docControls = (rc.w > 300*ui::guiscale());
|
||||
if (docControls) {
|
||||
m_slider->setVisible(rc.w > 400*ui::guiscale());
|
||||
int prefWidth = m_commandsBox->getPreferredSize().w;
|
||||
int prefWidth = m_docControls->getPreferredSize().w;
|
||||
int toolBarWidth = ToolBar::instance()->getPreferredSize().w;
|
||||
|
||||
rc.x += rc.w - prefWidth - border.right() - toolBarWidth;
|
||||
rc.w = prefWidth;
|
||||
|
||||
m_commandsBox->setVisible(m_doc != nullptr);
|
||||
m_commandsBox->setBounds(rc);
|
||||
m_docControls->setVisible(m_doc != nullptr);
|
||||
m_docControls->setBounds(rc);
|
||||
}
|
||||
else
|
||||
m_commandsBox->setVisible(false);
|
||||
m_docControls->setVisible(false);
|
||||
}
|
||||
|
||||
void StatusBar::onPreferredSize(PreferredSizeEvent& ev)
|
||||
@ -463,7 +524,10 @@ void StatusBar::onActiveSiteChange(const doc::Site& site)
|
||||
ASSERT(m_doc == site.document());
|
||||
}
|
||||
|
||||
m_commandsBox->setVisible(true);
|
||||
m_docControls->setVisible(true);
|
||||
showSnapToGridWarning(
|
||||
Preferences::instance().document(
|
||||
static_cast<app::Document*>(m_doc)).grid.snap());
|
||||
|
||||
// Current frame
|
||||
m_currentFrame->setTextf("%d", site.frame()+1);
|
||||
@ -485,8 +549,10 @@ void StatusBar::onActiveSiteChange(const doc::Site& site)
|
||||
}
|
||||
else {
|
||||
ASSERT(m_doc == nullptr);
|
||||
m_commandsBox->setVisible(false);
|
||||
m_docControls->setVisible(false);
|
||||
showSnapToGridWarning(false);
|
||||
}
|
||||
layout();
|
||||
}
|
||||
|
||||
void StatusBar::onRemoveDocument(doc::Document* doc)
|
||||
|
@ -56,6 +56,7 @@ namespace app {
|
||||
void showTip(int msecs, const char *format, ...);
|
||||
void showColor(int msecs, const char* text, const Color& color);
|
||||
void showTool(int msecs, tools::Tool* tool);
|
||||
void showSnapToGridWarning(bool state);
|
||||
|
||||
protected:
|
||||
void onResize(ui::ResizeEvent& ev) override;
|
||||
@ -89,7 +90,7 @@ namespace app {
|
||||
Color m_color;
|
||||
|
||||
// Box of main commands
|
||||
ui::Widget* m_commandsBox;
|
||||
ui::Widget* m_docControls;
|
||||
ui::Label* m_frameLabel;
|
||||
ui::Slider* m_slider; // Opacity slider
|
||||
ui::Entry* m_currentFrame; // Current frame and go to frame entry
|
||||
@ -99,6 +100,10 @@ namespace app {
|
||||
// Tip window
|
||||
class CustomizedTipWindow;
|
||||
CustomizedTipWindow* m_tipwindow;
|
||||
|
||||
// Snap to grid window
|
||||
class SnapToGridWindow;
|
||||
SnapToGridWindow* m_snapToGridWindow;
|
||||
};
|
||||
|
||||
} // namespace app
|
||||
|
@ -548,7 +548,7 @@ void ToolBar::openTipWindow(int group_index, Tool* tool)
|
||||
Rect toolrc = getToolGroupBounds(group_index);
|
||||
Point arrow = tool ? getToolPositionInGroup(group_index, tool): Point(0, 0);
|
||||
|
||||
m_tipWindow = new TipWindow(tooltip.c_str(), gfx::Rect(arrow, toolrc.getSize()));
|
||||
m_tipWindow = new TipWindow(tooltip, gfx::Rect(arrow, toolrc.getSize()));
|
||||
m_tipWindow->setArrowAlign(TOP | RIGHT);
|
||||
m_tipWindow->remapWindow();
|
||||
|
||||
|
@ -98,7 +98,7 @@ void TooltipManager::onTick()
|
||||
if (!m_tipWindow) {
|
||||
gfx::Rect bounds = m_target.widget->getBounds();
|
||||
|
||||
m_tipWindow.reset(new TipWindow(m_target.tipInfo.text.c_str(), bounds));
|
||||
m_tipWindow.reset(new TipWindow(m_target.tipInfo.text, bounds));
|
||||
int x = get_mouse_position().x+12*guiscale();
|
||||
int y = get_mouse_position().y+12*guiscale();
|
||||
|
||||
@ -181,10 +181,11 @@ void TooltipManager::onTick()
|
||||
|
||||
// TipWindow
|
||||
|
||||
TipWindow::TipWindow(const char* text, const gfx::Rect& target)
|
||||
TipWindow::TipWindow(const std::string& text, const gfx::Rect& target)
|
||||
: PopupWindow(text, kCloseOnClickInOtherWindow)
|
||||
, m_arrowAlign(0)
|
||||
, m_target(target)
|
||||
, m_closeOnKeyDown(true)
|
||||
{
|
||||
setTransparent(true);
|
||||
|
||||
@ -206,12 +207,18 @@ void TipWindow::setArrowAlign(int arrowAlign)
|
||||
m_arrowAlign = arrowAlign;
|
||||
}
|
||||
|
||||
void TipWindow::setCloseOnKeyDown(bool state)
|
||||
{
|
||||
m_closeOnKeyDown = state;
|
||||
}
|
||||
|
||||
bool TipWindow::onProcessMessage(Message* msg)
|
||||
{
|
||||
switch (msg->type()) {
|
||||
|
||||
case kKeyDownMessage:
|
||||
if (static_cast<KeyMessage*>(msg)->scancode() < kKeyFirstModifierScancode)
|
||||
if (m_closeOnKeyDown &&
|
||||
static_cast<KeyMessage*>(msg)->scancode() < kKeyFirstModifierScancode)
|
||||
closeWindow(NULL);
|
||||
break;
|
||||
|
||||
|
@ -56,12 +56,14 @@ namespace ui {
|
||||
|
||||
class TipWindow : public PopupWindow {
|
||||
public:
|
||||
TipWindow(const char* text, const gfx::Rect& target);
|
||||
TipWindow(const std::string& text, const gfx::Rect& target);
|
||||
~TipWindow();
|
||||
|
||||
int getArrowAlign() const;
|
||||
void setArrowAlign(int arrowAlign);
|
||||
|
||||
void setCloseOnKeyDown(bool state);
|
||||
|
||||
const gfx::Rect& target() const { return m_target; }
|
||||
|
||||
protected:
|
||||
@ -73,6 +75,7 @@ namespace ui {
|
||||
private:
|
||||
int m_arrowAlign;
|
||||
gfx::Rect m_target;
|
||||
bool m_closeOnKeyDown;
|
||||
};
|
||||
|
||||
} // namespace ui
|
||||
|
Loading…
x
Reference in New Issue
Block a user