Add "Snap to Grid" indicator when it's enabled (fix #122)

This commit is contained in:
David Capello 2015-07-28 13:05:59 -03:00
parent 9e5ccbcca9
commit a7ea0f7ec5
7 changed files with 108 additions and 31 deletions

View File

@ -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:

View File

@ -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);
}
};

View File

@ -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)

View File

@ -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

View File

@ -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();

View File

@ -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;

View File

@ -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