2015-02-12 23:16:25 +08:00
|
|
|
// Aseprite
|
|
|
|
// Copyright (C) 2001-2015 David Capello
|
|
|
|
//
|
|
|
|
// This program is free software; you can redistribute it and/or modify
|
|
|
|
// it under the terms of the GNU General Public License version 2 as
|
|
|
|
// published by the Free Software Foundation.
|
2007-09-19 07:57:02 +08:00
|
|
|
|
2013-08-06 08:20:19 +08:00
|
|
|
#ifdef HAVE_CONFIG_H
|
2007-09-19 07:57:02 +08:00
|
|
|
#include "config.h"
|
2013-08-06 08:20:19 +08:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#include "app/app.h"
|
|
|
|
#include "app/commands/commands.h"
|
|
|
|
#include "app/commands/params.h"
|
|
|
|
#include "app/context_access.h"
|
2015-04-07 13:29:33 +08:00
|
|
|
#include "app/document_access.h"
|
2014-08-25 06:59:12 +08:00
|
|
|
#include "app/document_range.h"
|
2013-08-06 08:20:19 +08:00
|
|
|
#include "app/modules/editors.h"
|
|
|
|
#include "app/modules/gfx.h"
|
|
|
|
#include "app/modules/gui.h"
|
|
|
|
#include "app/modules/palettes.h"
|
2015-07-29 00:05:59 +08:00
|
|
|
#include "app/pref/preferences.h"
|
2013-08-06 08:20:19 +08:00
|
|
|
#include "app/tools/tool.h"
|
2015-04-07 13:29:33 +08:00
|
|
|
#include "app/ui/button_set.h"
|
2013-08-06 08:20:19 +08:00
|
|
|
#include "app/ui/color_button.h"
|
|
|
|
#include "app/ui/editor/editor.h"
|
2014-10-29 22:58:03 +08:00
|
|
|
#include "app/ui/keyboard_shortcuts.h"
|
2014-08-25 06:59:12 +08:00
|
|
|
#include "app/ui/main_window.h"
|
2015-07-29 00:05:59 +08:00
|
|
|
#include "app/ui/skin/skin_style_property.h"
|
2013-08-06 08:20:19 +08:00
|
|
|
#include "app/ui/skin/skin_theme.h"
|
|
|
|
#include "app/ui/status_bar.h"
|
2014-08-25 06:59:12 +08:00
|
|
|
#include "app/ui/timeline.h"
|
2015-04-10 22:21:37 +08:00
|
|
|
#include "app/ui/toolbar.h"
|
2015-08-15 06:46:48 +08:00
|
|
|
#include "app/ui/zoom_entry.h"
|
2013-08-06 08:20:19 +08:00
|
|
|
#include "app/ui_context.h"
|
2014-08-25 06:59:12 +08:00
|
|
|
#include "app/util/range_utils.h"
|
2010-09-27 02:59:32 +08:00
|
|
|
#include "base/bind.h"
|
2015-05-20 03:38:03 +08:00
|
|
|
#include "doc/document_event.h"
|
2014-10-21 09:21:31 +08:00
|
|
|
#include "doc/image.h"
|
|
|
|
#include "doc/layer.h"
|
|
|
|
#include "doc/sprite.h"
|
2015-04-07 13:29:33 +08:00
|
|
|
#include "gfx/size.h"
|
2014-06-23 05:53:14 +08:00
|
|
|
#include "she/font.h"
|
|
|
|
#include "she/surface.h"
|
2013-08-06 08:20:19 +08:00
|
|
|
#include "ui/ui.h"
|
2007-09-19 07:57:02 +08:00
|
|
|
|
2011-03-24 22:50:00 +08:00
|
|
|
#include <algorithm>
|
|
|
|
#include <cstdarg>
|
|
|
|
#include <cstdio>
|
|
|
|
#include <cstring>
|
|
|
|
|
2013-08-06 08:20:19 +08:00
|
|
|
namespace app {
|
|
|
|
|
|
|
|
using namespace app::skin;
|
2010-09-26 03:22:32 +08:00
|
|
|
using namespace gfx;
|
2012-06-18 09:02:54 +08:00
|
|
|
using namespace ui;
|
2014-10-21 09:21:31 +08:00
|
|
|
using namespace doc;
|
2010-09-26 03:22:32 +08:00
|
|
|
|
2013-08-06 08:20:19 +08:00
|
|
|
class StatusBar::CustomizedTipWindow : public ui::TipWindow {
|
2012-06-16 10:37:59 +08:00
|
|
|
public:
|
2015-07-29 00:05:59 +08:00
|
|
|
CustomizedTipWindow(const std::string& text)
|
2015-05-10 00:20:57 +08:00
|
|
|
: ui::TipWindow(text, gfx::Rect())
|
2012-06-16 10:37:59 +08:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void setInterval(int msecs)
|
|
|
|
{
|
|
|
|
if (!m_timer)
|
2012-07-06 12:06:00 +08:00
|
|
|
m_timer.reset(new ui::Timer(msecs, this));
|
2012-06-16 10:37:59 +08:00
|
|
|
else
|
|
|
|
m_timer->setInterval(msecs);
|
|
|
|
}
|
|
|
|
|
|
|
|
void startTimer()
|
|
|
|
{
|
|
|
|
m_timer->start();
|
|
|
|
}
|
|
|
|
|
|
|
|
protected:
|
|
|
|
bool onProcessMessage(Message* msg);
|
|
|
|
|
|
|
|
private:
|
2013-08-06 08:20:19 +08:00
|
|
|
base::UniquePtr<ui::Timer> m_timer;
|
2012-06-16 10:37:59 +08:00
|
|
|
};
|
2007-09-19 07:57:02 +08:00
|
|
|
|
2015-07-29 01:55:40 +08:00
|
|
|
// TODO Use a ui::TipWindow with rounded borders, when we add support
|
|
|
|
// to invalidate transparent windows.
|
|
|
|
class StatusBar::SnapToGridWindow : public ui::PopupWindow {
|
2015-07-29 00:05:59 +08:00
|
|
|
public:
|
|
|
|
SnapToGridWindow()
|
2015-12-06 02:56:32 +08:00
|
|
|
: ui::PopupWindow("", ClickBehavior::DoNothingOnClick)
|
2015-07-29 00:05:59 +08:00
|
|
|
, m_button("Disable Snap to Grid") {
|
2015-07-29 01:55:40 +08:00
|
|
|
setBorder(gfx::Border(2 * guiscale()));
|
|
|
|
setBgColor(gfx::rgba(255, 255, 200));
|
2015-07-29 00:05:59 +08:00
|
|
|
makeFloating();
|
|
|
|
|
|
|
|
addChild(&m_button);
|
2015-12-05 02:17:42 +08:00
|
|
|
m_button.Click.connect(base::Bind<void>(&SnapToGridWindow::onDisableSnapToGrid, this));
|
2015-07-29 00:05:59 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
};
|
|
|
|
|
2013-04-04 09:07:24 +08:00
|
|
|
static WidgetType statusbar_type()
|
- All tools stuff refactored in various files/components.
- Added classes: IToolLoop, Tool, ToolGroup, ToolInk, ToolController, ToolPointShape, ToolIntertwine, ToolBox, etc.
- Added ToolLoopManager.
- Removed old src/modules/tools.cpp.
- Added ISettings and UISettingsImpl, adding the tools settings (onion skinning, grid, tiled mode, etc.).
- Added App::PenSizeBeforeChange, PenSizeAfterChange, CurrentToolChange signals.
- Renamed Context::get_bg/fg_color to getBg/FgColor.
- Refactored Brush class to Pen and added PenType.
- Renamed tiled_t to TiledMode.
- get_config_rect now uses the new Rect class imported from Vaca instead of old jrect.
- Added default_skin.xml to load tool icons.
- Added pen preview in Editor::cursor stuff.
- Added Editor::decorators.
Note: This big patch is from some time ago. I did my best to pre-commit other small changes before this big one.
2010-03-08 03:47:45 +08:00
|
|
|
{
|
2013-04-04 09:07:24 +08:00
|
|
|
static WidgetType type = kGenericWidget;
|
|
|
|
if (type == kGenericWidget)
|
|
|
|
type = register_widget_type();
|
2010-03-29 11:00:25 +08:00
|
|
|
return type;
|
- All tools stuff refactored in various files/components.
- Added classes: IToolLoop, Tool, ToolGroup, ToolInk, ToolController, ToolPointShape, ToolIntertwine, ToolBox, etc.
- Added ToolLoopManager.
- Removed old src/modules/tools.cpp.
- Added ISettings and UISettingsImpl, adding the tools settings (onion skinning, grid, tiled mode, etc.).
- Added App::PenSizeBeforeChange, PenSizeAfterChange, CurrentToolChange signals.
- Renamed Context::get_bg/fg_color to getBg/FgColor.
- Refactored Brush class to Pen and added PenType.
- Renamed tiled_t to TiledMode.
- get_config_rect now uses the new Rect class imported from Vaca instead of old jrect.
- Added default_skin.xml to load tool icons.
- Added pen preview in Editor::cursor stuff.
- Added Editor::decorators.
Note: This big patch is from some time ago. I did my best to pre-commit other small changes before this big one.
2010-03-08 03:47:45 +08:00
|
|
|
}
|
|
|
|
|
2012-01-10 08:18:32 +08:00
|
|
|
// This widget is used to show the current frame.
|
|
|
|
class GotoFrameEntry : public Entry {
|
|
|
|
public:
|
|
|
|
GotoFrameEntry() : Entry(4, "") {
|
|
|
|
}
|
|
|
|
|
2014-08-15 10:07:47 +08:00
|
|
|
bool onProcessMessage(Message* msg) override {
|
2013-07-29 08:17:07 +08:00
|
|
|
switch (msg->type()) {
|
2012-01-10 08:18:32 +08:00
|
|
|
// When the mouse enter in this entry, it got the focus and the
|
|
|
|
// text is automatically selected.
|
2013-04-05 08:53:29 +08:00
|
|
|
case kMouseEnterMessage:
|
2012-01-10 08:18:32 +08:00
|
|
|
requestFocus();
|
|
|
|
selectText(0, -1);
|
|
|
|
break;
|
|
|
|
|
2013-07-29 08:17:07 +08:00
|
|
|
case kKeyDownMessage: {
|
|
|
|
KeyMessage* keymsg = static_cast<KeyMessage*>(msg);
|
|
|
|
KeyScancode scancode = keymsg->scancode();
|
2015-02-12 23:16:25 +08:00
|
|
|
|
2015-05-05 20:47:05 +08:00
|
|
|
if (hasFocus() &&
|
|
|
|
(scancode == kKeyEnter || // TODO customizable keys
|
|
|
|
scancode == kKeyEnterPad)) {
|
2012-01-10 08:18:32 +08:00
|
|
|
Command* cmd = CommandsModule::instance()->getCommandByName(CommandId::GotoFrame);
|
|
|
|
Params params;
|
Refactor several "getNoun()" getters to "noun()"
This is a work-in-progress to create a consistent API and finally
separate the whole Aseprite base/gfx/ui libs into a reusable C++ library.
Classes:
app::IFileItem, app::AppMenuItem, app::skin::SkinPart,
gfx::Rect, gfx::Border, she::FileDialog,
ui::IButtonIcon, ui::Graphics, ui::Overlay, ui::Widget,
ui::ScrollableViewDelegate, and UI events
2015-12-05 01:39:04 +08:00
|
|
|
int frame = textInt();
|
2012-01-10 08:18:32 +08:00
|
|
|
if (frame > 0) {
|
Refactor several "getNoun()" getters to "noun()"
This is a work-in-progress to create a consistent API and finally
separate the whole Aseprite base/gfx/ui libs into a reusable C++ library.
Classes:
app::IFileItem, app::AppMenuItem, app::skin::SkinPart,
gfx::Rect, gfx::Border, she::FileDialog,
ui::IButtonIcon, ui::Graphics, ui::Overlay, ui::Widget,
ui::ScrollableViewDelegate, and UI events
2015-12-05 01:39:04 +08:00
|
|
|
params.set("frame", text().c_str());
|
2015-03-12 02:40:22 +08:00
|
|
|
UIContext::instance()->executeCommand(cmd, params);
|
2012-01-10 08:18:32 +08:00
|
|
|
}
|
|
|
|
// Select the text again
|
|
|
|
selectText(0, -1);
|
|
|
|
return true; // Key used.
|
|
|
|
}
|
|
|
|
break;
|
2013-07-29 08:17:07 +08:00
|
|
|
}
|
2012-01-10 08:18:32 +08:00
|
|
|
}
|
|
|
|
return Entry::onProcessMessage(msg);
|
|
|
|
}
|
|
|
|
|
|
|
|
};
|
|
|
|
|
2012-07-10 00:20:58 +08:00
|
|
|
StatusBar* StatusBar::m_instance = NULL;
|
|
|
|
|
2010-03-29 11:00:25 +08:00
|
|
|
StatusBar::StatusBar()
|
|
|
|
: Widget(statusbar_type())
|
2015-07-29 00:05:59 +08:00
|
|
|
, m_timeout(0)
|
|
|
|
, m_state(SHOW_TEXT)
|
2013-01-07 01:45:43 +08:00
|
|
|
, m_color(app::Color::fromMask())
|
2015-07-29 00:05:59 +08:00
|
|
|
, m_docControls(new HBox)
|
2015-05-20 03:38:03 +08:00
|
|
|
, m_doc(nullptr)
|
2015-07-29 00:05:59 +08:00
|
|
|
, m_tipwindow(nullptr)
|
|
|
|
, m_snapToGridWindow(nullptr)
|
2007-09-19 07:57:02 +08:00
|
|
|
{
|
2012-07-10 00:20:58 +08:00
|
|
|
m_instance = this;
|
|
|
|
|
2013-12-30 08:12:23 +08:00
|
|
|
setDoubleBuffered(true);
|
|
|
|
|
Refactor several "getNoun()" getters to "noun()"
This is a work-in-progress to create a consistent API and finally
separate the whole Aseprite base/gfx/ui libs into a reusable C++ library.
Classes:
app::IFileItem, app::AppMenuItem, app::skin::SkinPart,
gfx::Rect, gfx::Border, she::FileDialog,
ui::IButtonIcon, ui::Graphics, ui::Overlay, ui::Widget,
ui::ScrollableViewDelegate, and UI events
2015-12-05 01:39:04 +08:00
|
|
|
SkinTheme* theme = static_cast<SkinTheme*>(this->theme());
|
2015-07-28 23:25:15 +08:00
|
|
|
setBgColor(theme->colors.statusBarFace());
|
2014-04-14 00:51:28 +08:00
|
|
|
|
2012-04-06 06:00:19 +08:00
|
|
|
this->setFocusStop(true);
|
2007-09-19 07:57:02 +08:00
|
|
|
|
2010-08-12 08:48:12 +08:00
|
|
|
// The extra pixel in left and right borders are necessary so
|
|
|
|
// m_commandsBox and m_movePixelsBox do not overlap the upper-left
|
2013-12-30 08:12:23 +08:00
|
|
|
// and upper-right pixels drawn in onPaint() event (see putpixels)
|
2014-11-26 09:33:45 +08:00
|
|
|
setBorder(gfx::Border(1*guiscale(), 0, 1*guiscale(), 0));
|
2007-09-19 07:57:02 +08:00
|
|
|
|
2015-07-29 00:05:59 +08:00
|
|
|
m_docControls->setVisible(false);
|
|
|
|
addChild(m_docControls);
|
|
|
|
|
2010-08-12 08:48:12 +08:00
|
|
|
// Construct the commands box
|
|
|
|
{
|
2015-06-24 01:00:00 +08:00
|
|
|
Box* box1 = new Box(HORIZONTAL);
|
|
|
|
Box* box4 = new Box(HORIZONTAL);
|
2015-04-07 22:15:28 +08:00
|
|
|
|
|
|
|
m_frameLabel = new Label("Frame:");
|
2012-01-10 08:18:32 +08:00
|
|
|
m_currentFrame = new GotoFrameEntry();
|
|
|
|
m_newFrame = new Button("+");
|
2015-12-05 02:17:42 +08:00
|
|
|
m_newFrame->Click.connect(base::Bind<void>(&StatusBar::newFrame, this));
|
2015-08-15 06:46:48 +08:00
|
|
|
m_zoomEntry = new ZoomEntry;
|
|
|
|
m_zoomEntry->ZoomChange.connect(&StatusBar::onChangeZoom, this);
|
2010-08-12 08:48:12 +08:00
|
|
|
|
2012-01-10 08:18:32 +08:00
|
|
|
setup_mini_look(m_currentFrame);
|
|
|
|
setup_mini_look(m_newFrame);
|
2010-08-12 08:48:12 +08:00
|
|
|
|
2014-11-26 09:33:45 +08:00
|
|
|
box1->setBorder(gfx::Border(2, 1, 2, 2)*guiscale());
|
2010-08-12 08:48:12 +08:00
|
|
|
|
2012-01-10 08:18:32 +08:00
|
|
|
box4->addChild(m_currentFrame);
|
|
|
|
box4->addChild(m_newFrame);
|
|
|
|
|
2015-04-07 22:15:28 +08:00
|
|
|
box1->addChild(m_frameLabel);
|
2012-01-10 08:18:32 +08:00
|
|
|
box1->addChild(box4);
|
2015-08-15 06:46:48 +08:00
|
|
|
box1->addChild(m_zoomEntry);
|
2010-08-12 08:48:12 +08:00
|
|
|
|
2015-07-29 00:05:59 +08:00
|
|
|
m_docControls->addChild(box1);
|
2010-08-12 08:48:12 +08:00
|
|
|
}
|
2010-03-22 08:30:50 +08:00
|
|
|
|
2015-04-07 22:15:45 +08:00
|
|
|
// Tooltips manager
|
|
|
|
TooltipManager* tooltipManager = new TooltipManager();
|
|
|
|
addChild(tooltipManager);
|
2015-06-24 01:00:00 +08:00
|
|
|
tooltipManager->addTooltipFor(m_currentFrame, "Current Frame", BOTTOM);
|
2015-08-15 06:46:48 +08:00
|
|
|
tooltipManager->addTooltipFor(m_zoomEntry, "Zoom Level", BOTTOM);
|
2015-04-07 22:15:45 +08:00
|
|
|
|
2015-05-19 03:53:25 +08:00
|
|
|
Preferences::instance().toolBox.activeTool.AfterChange.connect(
|
2015-12-05 02:17:42 +08:00
|
|
|
base::Bind<void>(&StatusBar::onCurrentToolChange, this));
|
2015-05-19 03:53:25 +08:00
|
|
|
|
2015-05-06 00:24:26 +08:00
|
|
|
UIContext::instance()->addObserver(this);
|
2015-05-20 03:38:03 +08:00
|
|
|
UIContext::instance()->documents().addObserver(this);
|
2010-03-29 11:00:25 +08:00
|
|
|
}
|
2007-09-19 07:57:02 +08:00
|
|
|
|
2010-03-29 11:00:25 +08:00
|
|
|
StatusBar::~StatusBar()
|
|
|
|
{
|
2015-05-20 03:38:03 +08:00
|
|
|
UIContext::instance()->documents().removeObserver(this);
|
2015-05-06 00:24:26 +08:00
|
|
|
UIContext::instance()->removeObserver(this);
|
|
|
|
|
2012-01-06 06:45:03 +08:00
|
|
|
delete m_tipwindow; // widget
|
2015-07-29 00:05:59 +08:00
|
|
|
delete m_snapToGridWindow;
|
2007-09-19 07:57:02 +08:00
|
|
|
}
|
|
|
|
|
2010-03-29 11:00:25 +08:00
|
|
|
void StatusBar::onCurrentToolChange()
|
2007-09-19 07:57:02 +08:00
|
|
|
{
|
2010-07-04 23:03:14 +08:00
|
|
|
if (isVisible()) {
|
2015-05-19 03:53:25 +08:00
|
|
|
tools::Tool* tool = App::instance()->activeTool();
|
|
|
|
if (tool) {
|
|
|
|
showTool(500, tool);
|
|
|
|
setTextf("%s Selected", tool->getText().c_str());
|
2010-04-24 12:55:51 +08:00
|
|
|
}
|
2010-03-29 11:00:25 +08:00
|
|
|
}
|
2007-09-19 07:57:02 +08:00
|
|
|
}
|
|
|
|
|
2010-06-11 10:58:48 +08:00
|
|
|
void StatusBar::clearText()
|
|
|
|
{
|
|
|
|
setStatusText(1, "");
|
|
|
|
}
|
|
|
|
|
2015-08-15 06:46:48 +08:00
|
|
|
void StatusBar::updateFromEditor(Editor* editor)
|
|
|
|
{
|
|
|
|
if (editor)
|
|
|
|
m_zoomEntry->setZoom(editor->zoom());
|
|
|
|
}
|
|
|
|
|
2010-04-24 12:06:30 +08:00
|
|
|
bool StatusBar::setStatusText(int msecs, const char *format, ...)
|
2007-09-19 07:57:02 +08:00
|
|
|
{
|
2014-09-01 01:17:49 +08:00
|
|
|
if ((ui::clock() > m_timeout) || (msecs > 0)) {
|
2012-01-06 06:45:03 +08:00
|
|
|
char buf[256]; // TODO warning buffer overflow
|
2007-09-19 07:57:02 +08:00
|
|
|
va_list ap;
|
|
|
|
|
2008-01-07 23:10:17 +08:00
|
|
|
va_start(ap, format);
|
|
|
|
vsprintf(buf, format, ap);
|
|
|
|
va_end(ap);
|
2007-09-19 07:57:02 +08:00
|
|
|
|
2014-09-01 01:17:49 +08:00
|
|
|
m_timeout = ui::clock() + msecs;
|
2010-04-24 12:06:30 +08:00
|
|
|
m_state = SHOW_TEXT;
|
|
|
|
|
2011-07-27 10:25:02 +08:00
|
|
|
setText(buf);
|
|
|
|
invalidate();
|
2010-04-24 12:06:30 +08:00
|
|
|
|
|
|
|
return true;
|
2007-09-19 07:57:02 +08:00
|
|
|
}
|
2010-04-24 12:06:30 +08:00
|
|
|
else
|
|
|
|
return false;
|
2007-09-19 07:57:02 +08:00
|
|
|
}
|
|
|
|
|
2010-03-29 11:00:25 +08:00
|
|
|
void StatusBar::showTip(int msecs, const char *format, ...)
|
2007-09-19 07:57:02 +08:00
|
|
|
{
|
2012-01-06 06:45:03 +08:00
|
|
|
char buf[256]; // TODO warning buffer overflow
|
2008-03-23 02:43:56 +08:00
|
|
|
va_list ap;
|
|
|
|
int x, y;
|
|
|
|
|
|
|
|
va_start(ap, format);
|
|
|
|
vsprintf(buf, format, ap);
|
|
|
|
va_end(ap);
|
|
|
|
|
2010-03-29 11:00:25 +08:00
|
|
|
if (m_tipwindow == NULL) {
|
2012-06-16 10:37:59 +08:00
|
|
|
m_tipwindow = new CustomizedTipWindow(buf);
|
2008-03-23 02:43:56 +08:00
|
|
|
}
|
|
|
|
else {
|
2010-03-29 11:00:25 +08:00
|
|
|
m_tipwindow->setText(buf);
|
2008-03-23 02:43:56 +08:00
|
|
|
}
|
|
|
|
|
2012-06-16 10:37:59 +08:00
|
|
|
m_tipwindow->setInterval(msecs);
|
|
|
|
|
2010-07-04 23:03:14 +08:00
|
|
|
if (m_tipwindow->isVisible())
|
2010-03-29 11:00:25 +08:00
|
|
|
m_tipwindow->closeWindow(NULL);
|
2008-03-23 02:43:56 +08:00
|
|
|
|
2012-07-09 10:24:42 +08:00
|
|
|
m_tipwindow->openWindow();
|
2013-01-11 23:43:25 +08:00
|
|
|
m_tipwindow->remapWindow();
|
2008-03-23 02:43:56 +08:00
|
|
|
|
Refactor several "getNoun()" getters to "noun()"
This is a work-in-progress to create a consistent API and finally
separate the whole Aseprite base/gfx/ui libs into a reusable C++ library.
Classes:
app::IFileItem, app::AppMenuItem, app::skin::SkinPart,
gfx::Rect, gfx::Border, she::FileDialog,
ui::IButtonIcon, ui::Graphics, ui::Overlay, ui::Widget,
ui::ScrollableViewDelegate, and UI events
2015-12-05 01:39:04 +08:00
|
|
|
x = bounds().x2() - m_tipwindow->bounds().w;
|
|
|
|
y = bounds().y - m_tipwindow->bounds().h;
|
2013-01-11 23:43:25 +08:00
|
|
|
m_tipwindow->positionWindow(x, y);
|
2008-03-23 02:43:56 +08:00
|
|
|
|
2012-06-16 10:37:59 +08:00
|
|
|
m_tipwindow->startTimer();
|
2010-03-31 10:38:52 +08:00
|
|
|
|
|
|
|
// Set the text in status-bar (with inmediate timeout)
|
2014-09-01 01:17:49 +08:00
|
|
|
m_timeout = ui::clock();
|
2011-07-27 10:25:02 +08:00
|
|
|
setText(buf);
|
|
|
|
invalidate();
|
2008-03-23 02:43:56 +08:00
|
|
|
}
|
|
|
|
|
2015-07-03 05:13:47 +08:00
|
|
|
void StatusBar::showColor(int msecs, const char* text, const app::Color& color)
|
2008-03-23 02:43:56 +08:00
|
|
|
{
|
2010-04-24 12:06:30 +08:00
|
|
|
if (setStatusText(msecs, text)) {
|
|
|
|
m_state = SHOW_COLOR;
|
|
|
|
m_color = color;
|
|
|
|
}
|
2008-03-01 03:29:49 +08:00
|
|
|
}
|
|
|
|
|
2011-04-02 21:47:03 +08:00
|
|
|
void StatusBar::showTool(int msecs, tools::Tool* tool)
|
2010-04-24 12:55:51 +08:00
|
|
|
{
|
2010-08-04 10:33:44 +08:00
|
|
|
ASSERT(tool != NULL);
|
2010-04-24 12:55:51 +08:00
|
|
|
|
|
|
|
// Tool name
|
|
|
|
std::string text = tool->getText();
|
|
|
|
|
|
|
|
// Tool shortcut
|
2014-10-29 22:58:03 +08:00
|
|
|
Key* key = KeyboardShortcuts::instance()->tool(tool);
|
|
|
|
if (key && !key->accels().empty()) {
|
2010-04-24 12:55:51 +08:00
|
|
|
text += ", Shortcut: ";
|
2014-10-29 22:58:03 +08:00
|
|
|
text += key->accels().front().toString();
|
2010-04-24 12:55:51 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Set text
|
|
|
|
if (setStatusText(msecs, text.c_str())) {
|
|
|
|
// Show tool
|
|
|
|
m_state = SHOW_TOOL;
|
|
|
|
m_tool = tool;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-07-29 00:05:59 +08:00
|
|
|
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();
|
|
|
|
|
Refactor several "getNoun()" getters to "noun()"
This is a work-in-progress to create a consistent API and finally
separate the whole Aseprite base/gfx/ui libs into a reusable C++ library.
Classes:
app::IFileItem, app::AppMenuItem, app::skin::SkinPart,
gfx::Rect, gfx::Border, she::FileDialog,
ui::IButtonIcon, ui::Graphics, ui::Overlay, ui::Widget,
ui::ScrollableViewDelegate, and UI events
2015-12-05 01:39:04 +08:00
|
|
|
Rect rc = bounds();
|
2015-12-04 08:50:05 +08:00
|
|
|
int toolBarWidth = ToolBar::instance()->sizeHint().w;
|
2015-07-29 00:05:59 +08:00
|
|
|
|
|
|
|
m_snapToGridWindow->positionWindow(
|
Refactor several "getNoun()" getters to "noun()"
This is a work-in-progress to create a consistent API and finally
separate the whole Aseprite base/gfx/ui libs into a reusable C++ library.
Classes:
app::IFileItem, app::AppMenuItem, app::skin::SkinPart,
gfx::Rect, gfx::Border, she::FileDialog,
ui::IButtonIcon, ui::Graphics, ui::Overlay, ui::Widget,
ui::ScrollableViewDelegate, and UI events
2015-12-05 01:39:04 +08:00
|
|
|
rc.x+rc.w-toolBarWidth-m_snapToGridWindow->bounds().w,
|
|
|
|
rc.y-m_snapToGridWindow->bounds().h);
|
2015-07-29 00:05:59 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
m_snapToGridWindow->setDocument(
|
|
|
|
static_cast<app::Document*>(m_doc));
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (m_snapToGridWindow)
|
|
|
|
m_snapToGridWindow->closeWindow(nullptr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-03-29 11:00:25 +08:00
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
// StatusBar message handler
|
2008-05-06 23:22:57 +08:00
|
|
|
|
2013-05-12 04:56:27 +08:00
|
|
|
void StatusBar::onResize(ResizeEvent& ev)
|
|
|
|
{
|
Refactor several "getNoun()" getters to "noun()"
This is a work-in-progress to create a consistent API and finally
separate the whole Aseprite base/gfx/ui libs into a reusable C++ library.
Classes:
app::IFileItem, app::AppMenuItem, app::skin::SkinPart,
gfx::Rect, gfx::Border, she::FileDialog,
ui::IButtonIcon, ui::Graphics, ui::Overlay, ui::Widget,
ui::ScrollableViewDelegate, and UI events
2015-12-05 01:39:04 +08:00
|
|
|
setBoundsQuietly(ev.bounds());
|
2013-05-12 04:56:27 +08:00
|
|
|
|
2015-06-24 06:20:49 +08:00
|
|
|
Border border = this->border();
|
Refactor several "getNoun()" getters to "noun()"
This is a work-in-progress to create a consistent API and finally
separate the whole Aseprite base/gfx/ui libs into a reusable C++ library.
Classes:
app::IFileItem, app::AppMenuItem, app::skin::SkinPart,
gfx::Rect, gfx::Border, she::FileDialog,
ui::IButtonIcon, ui::Graphics, ui::Overlay, ui::Widget,
ui::ScrollableViewDelegate, and UI events
2015-12-05 01:39:04 +08:00
|
|
|
Rect rc = ev.bounds();
|
2015-07-29 00:05:59 +08:00
|
|
|
bool docControls = (rc.w > 300*ui::guiscale());
|
|
|
|
if (docControls) {
|
2015-12-04 08:50:05 +08:00
|
|
|
int prefWidth = m_docControls->sizeHint().w;
|
|
|
|
int toolBarWidth = ToolBar::instance()->sizeHint().w;
|
2015-04-07 21:48:04 +08:00
|
|
|
|
2015-04-10 22:21:37 +08:00
|
|
|
rc.x += rc.w - prefWidth - border.right() - toolBarWidth;
|
|
|
|
rc.w = prefWidth;
|
|
|
|
|
2015-07-29 00:05:59 +08:00
|
|
|
m_docControls->setVisible(m_doc != nullptr);
|
|
|
|
m_docControls->setBounds(rc);
|
2015-04-10 22:21:37 +08:00
|
|
|
}
|
|
|
|
else
|
2015-07-29 00:05:59 +08:00
|
|
|
m_docControls->setVisible(false);
|
2013-05-12 04:56:27 +08:00
|
|
|
}
|
|
|
|
|
2015-12-04 08:50:05 +08:00
|
|
|
void StatusBar::onSizeHint(SizeHintEvent& ev)
|
2012-09-27 05:34:52 +08:00
|
|
|
{
|
Refactor several "getNoun()" getters to "noun()"
This is a work-in-progress to create a consistent API and finally
separate the whole Aseprite base/gfx/ui libs into a reusable C++ library.
Classes:
app::IFileItem, app::AppMenuItem, app::skin::SkinPart,
gfx::Rect, gfx::Border, she::FileDialog,
ui::IButtonIcon, ui::Graphics, ui::Overlay, ui::Widget,
ui::ScrollableViewDelegate, and UI events
2015-12-05 01:39:04 +08:00
|
|
|
int s = 4*guiscale() + textHeight() + 4*guiscale();
|
2015-12-04 08:50:05 +08:00
|
|
|
ev.setSizeHint(Size(s, s));
|
2012-09-27 05:34:52 +08:00
|
|
|
}
|
|
|
|
|
2013-12-30 08:12:23 +08:00
|
|
|
void StatusBar::onPaint(ui::PaintEvent& ev)
|
|
|
|
{
|
Refactor several "getNoun()" getters to "noun()"
This is a work-in-progress to create a consistent API and finally
separate the whole Aseprite base/gfx/ui libs into a reusable C++ library.
Classes:
app::IFileItem, app::AppMenuItem, app::skin::SkinPart,
gfx::Rect, gfx::Border, she::FileDialog,
ui::IButtonIcon, ui::Graphics, ui::Overlay, ui::Widget,
ui::ScrollableViewDelegate, and UI events
2015-12-05 01:39:04 +08:00
|
|
|
SkinTheme* theme = static_cast<SkinTheme*>(this->theme());
|
2015-07-28 23:25:15 +08:00
|
|
|
gfx::Color textColor = theme->colors.statusBarText();
|
Refactor several "getNoun()" getters to "noun()"
This is a work-in-progress to create a consistent API and finally
separate the whole Aseprite base/gfx/ui libs into a reusable C++ library.
Classes:
app::IFileItem, app::AppMenuItem, app::skin::SkinPart,
gfx::Rect, gfx::Border, she::FileDialog,
ui::IButtonIcon, ui::Graphics, ui::Overlay, ui::Widget,
ui::ScrollableViewDelegate, and UI events
2015-12-05 01:39:04 +08:00
|
|
|
Rect rc = clientBounds();
|
|
|
|
Graphics* g = ev.graphics();
|
2013-12-30 08:12:23 +08:00
|
|
|
|
Refactor several "getNoun()" getters to "noun()"
This is a work-in-progress to create a consistent API and finally
separate the whole Aseprite base/gfx/ui libs into a reusable C++ library.
Classes:
app::IFileItem, app::AppMenuItem, app::skin::SkinPart,
gfx::Rect, gfx::Border, she::FileDialog,
ui::IButtonIcon, ui::Graphics, ui::Overlay, ui::Widget,
ui::ScrollableViewDelegate, and UI events
2015-12-05 01:39:04 +08:00
|
|
|
g->fillRect(bgColor(), rc);
|
2013-12-30 08:12:23 +08:00
|
|
|
|
2014-11-26 09:33:45 +08:00
|
|
|
rc.shrink(Border(2, 1, 2, 2)*guiscale());
|
2013-12-30 08:12:23 +08:00
|
|
|
|
2014-11-26 09:33:45 +08:00
|
|
|
int x = rc.x + 4*guiscale();
|
2013-12-30 08:12:23 +08:00
|
|
|
|
|
|
|
// Color
|
|
|
|
if (m_state == SHOW_COLOR) {
|
|
|
|
// Draw eyedropper icon
|
2015-08-05 06:38:52 +08:00
|
|
|
she::Surface* icon = theme->getToolIcon("eyedropper");
|
2013-12-30 08:12:23 +08:00
|
|
|
if (icon) {
|
2014-06-23 05:53:14 +08:00
|
|
|
g->drawRgbaSurface(icon, x, rc.y + rc.h/2 - icon->height()/2);
|
2014-11-26 09:33:45 +08:00
|
|
|
x += icon->width() + 4*guiscale();
|
2013-12-30 08:12:23 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Draw color
|
2014-11-26 09:33:45 +08:00
|
|
|
draw_color_button(g, gfx::Rect(x, rc.y, 32*guiscale(), rc.h),
|
2014-06-02 05:15:11 +08:00
|
|
|
m_color, false, false);
|
2013-12-30 08:12:23 +08:00
|
|
|
|
2014-11-26 09:33:45 +08:00
|
|
|
x += (32+4)*guiscale();
|
2013-12-30 08:12:23 +08:00
|
|
|
|
|
|
|
// Draw color description
|
|
|
|
std::string str = m_color.toHumanReadableString(app_get_current_pixel_format(),
|
|
|
|
app::Color::LongHumanReadableString);
|
2015-07-03 05:13:47 +08:00
|
|
|
if (m_color.getAlpha() < 255) {
|
2014-06-23 05:53:14 +08:00
|
|
|
char buf[256];
|
2015-07-03 05:13:47 +08:00
|
|
|
sprintf(buf, " \xCE\xB1%d", m_color.getAlpha());
|
2013-12-30 08:12:23 +08:00
|
|
|
str += buf;
|
|
|
|
}
|
|
|
|
|
2014-06-27 09:14:39 +08:00
|
|
|
g->drawString(str, textColor, ColorNone,
|
Refactor several "getNoun()" getters to "noun()"
This is a work-in-progress to create a consistent API and finally
separate the whole Aseprite base/gfx/ui libs into a reusable C++ library.
Classes:
app::IFileItem, app::AppMenuItem, app::skin::SkinPart,
gfx::Rect, gfx::Border, she::FileDialog,
ui::IButtonIcon, ui::Graphics, ui::Overlay, ui::Widget,
ui::ScrollableViewDelegate, and UI events
2015-12-05 01:39:04 +08:00
|
|
|
gfx::Point(x, rc.y + rc.h/2 - font()->height()/2));
|
2013-12-30 08:12:23 +08:00
|
|
|
|
Refactor several "getNoun()" getters to "noun()"
This is a work-in-progress to create a consistent API and finally
separate the whole Aseprite base/gfx/ui libs into a reusable C++ library.
Classes:
app::IFileItem, app::AppMenuItem, app::skin::SkinPart,
gfx::Rect, gfx::Border, she::FileDialog,
ui::IButtonIcon, ui::Graphics, ui::Overlay, ui::Widget,
ui::ScrollableViewDelegate, and UI events
2015-12-05 01:39:04 +08:00
|
|
|
x += font()->textLength(str.c_str()) + 4*guiscale();
|
2013-12-30 08:12:23 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Show tool
|
|
|
|
if (m_state == SHOW_TOOL) {
|
|
|
|
// Draw eyedropper icon
|
2015-08-05 06:38:52 +08:00
|
|
|
she::Surface* icon = theme->getToolIcon(m_tool->getId().c_str());
|
2013-12-30 08:12:23 +08:00
|
|
|
if (icon) {
|
2014-06-23 05:53:14 +08:00
|
|
|
g->drawRgbaSurface(icon, x, rc.y + rc.h/2 - icon->height()/2);
|
2014-11-26 09:33:45 +08:00
|
|
|
x += icon->width() + 4*guiscale();
|
2013-12-30 08:12:23 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Status bar text
|
Refactor several "getNoun()" getters to "noun()"
This is a work-in-progress to create a consistent API and finally
separate the whole Aseprite base/gfx/ui libs into a reusable C++ library.
Classes:
app::IFileItem, app::AppMenuItem, app::skin::SkinPart,
gfx::Rect, gfx::Border, she::FileDialog,
ui::IButtonIcon, ui::Graphics, ui::Overlay, ui::Widget,
ui::ScrollableViewDelegate, and UI events
2015-12-05 01:39:04 +08:00
|
|
|
if (textLength() > 0) {
|
|
|
|
g->drawString(text(), textColor, ColorNone,
|
|
|
|
gfx::Point(x, rc.y + rc.h/2 - font()->height()/2));
|
2013-12-30 08:12:23 +08:00
|
|
|
|
Refactor several "getNoun()" getters to "noun()"
This is a work-in-progress to create a consistent API and finally
separate the whole Aseprite base/gfx/ui libs into a reusable C++ library.
Classes:
app::IFileItem, app::AppMenuItem, app::skin::SkinPart,
gfx::Rect, gfx::Border, she::FileDialog,
ui::IButtonIcon, ui::Graphics, ui::Overlay, ui::Widget,
ui::ScrollableViewDelegate, and UI events
2015-12-05 01:39:04 +08:00
|
|
|
x += font()->textLength(text().c_str()) + 4*guiscale();
|
2013-12-30 08:12:23 +08:00
|
|
|
}
|
2015-04-07 12:21:31 +08:00
|
|
|
}
|
2013-12-30 08:12:23 +08:00
|
|
|
|
2012-06-16 10:37:59 +08:00
|
|
|
bool StatusBar::CustomizedTipWindow::onProcessMessage(Message* msg)
|
2008-03-23 02:43:56 +08:00
|
|
|
{
|
2013-07-29 08:17:07 +08:00
|
|
|
switch (msg->type()) {
|
2008-03-23 02:43:56 +08:00
|
|
|
|
2013-04-05 08:53:29 +08:00
|
|
|
case kTimerMessage:
|
2012-06-16 10:37:59 +08:00
|
|
|
closeWindow(NULL);
|
2008-03-23 02:43:56 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2012-06-18 09:02:54 +08:00
|
|
|
return ui::TipWindow::onProcessMessage(msg);
|
2008-03-23 02:43:56 +08:00
|
|
|
}
|
|
|
|
|
2015-05-06 00:24:26 +08:00
|
|
|
void StatusBar::onActiveSiteChange(const doc::Site& site)
|
2007-09-19 07:57:02 +08:00
|
|
|
{
|
2015-05-20 03:38:03 +08:00
|
|
|
if (m_doc && site.document() != m_doc) {
|
|
|
|
m_doc->removeObserver(this);
|
|
|
|
m_doc = nullptr;
|
|
|
|
}
|
|
|
|
|
2015-05-06 00:24:26 +08:00
|
|
|
if (site.document() && site.sprite()) {
|
2015-05-20 03:38:03 +08:00
|
|
|
if (!m_doc) {
|
|
|
|
m_doc = const_cast<doc::Document*>(site.document());
|
|
|
|
m_doc->addObserver(this);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
ASSERT(m_doc == site.document());
|
|
|
|
}
|
|
|
|
|
2015-07-29 00:05:59 +08:00
|
|
|
m_docControls->setVisible(true);
|
|
|
|
showSnapToGridWarning(
|
|
|
|
Preferences::instance().document(
|
|
|
|
static_cast<app::Document*>(m_doc)).grid.snap());
|
2015-05-06 00:24:26 +08:00
|
|
|
|
|
|
|
// Current frame
|
|
|
|
m_currentFrame->setTextf("%d", site.frame()+1);
|
2007-09-19 07:57:02 +08:00
|
|
|
}
|
2015-05-06 00:24:26 +08:00
|
|
|
else {
|
2015-05-20 03:38:03 +08:00
|
|
|
ASSERT(m_doc == nullptr);
|
2015-07-29 00:05:59 +08:00
|
|
|
m_docControls->setVisible(false);
|
|
|
|
showSnapToGridWarning(false);
|
2007-09-19 07:57:02 +08:00
|
|
|
}
|
2015-07-29 00:05:59 +08:00
|
|
|
layout();
|
2007-09-19 07:57:02 +08:00
|
|
|
}
|
2012-01-10 08:18:32 +08:00
|
|
|
|
2015-05-20 03:38:03 +08:00
|
|
|
void StatusBar::onRemoveDocument(doc::Document* doc)
|
|
|
|
{
|
|
|
|
if (m_doc &&
|
|
|
|
m_doc == doc) {
|
|
|
|
m_doc->removeObserver(this);
|
|
|
|
m_doc = nullptr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void StatusBar::onPixelFormatChanged(DocumentEvent& ev)
|
|
|
|
{
|
|
|
|
onActiveSiteChange(UIContext::instance()->activeSite());
|
|
|
|
}
|
|
|
|
|
2012-01-10 08:18:32 +08:00
|
|
|
void StatusBar::newFrame()
|
|
|
|
{
|
|
|
|
Command* cmd = CommandsModule::instance()->getCommandByName(CommandId::NewFrame);
|
|
|
|
UIContext::instance()->executeCommand(cmd);
|
|
|
|
}
|
2013-08-06 08:20:19 +08:00
|
|
|
|
2015-08-15 06:46:48 +08:00
|
|
|
void StatusBar::onChangeZoom(const render::Zoom& zoom)
|
|
|
|
{
|
|
|
|
if (current_editor)
|
|
|
|
current_editor->setEditorZoom(zoom);
|
|
|
|
}
|
|
|
|
|
2013-08-06 08:20:19 +08:00
|
|
|
} // namespace app
|