mirror of
https://github.com/aseprite/aseprite.git
synced 2025-01-27 06:35:16 +00:00
Improve status bar with icons/automatically generated and re-used parts (fix #752)
This commit is contained in:
parent
af0267de03
commit
87ef48b50b
Binary file not shown.
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
@ -400,6 +400,15 @@
|
||||
<part id="icon_close" x="152" y="256" w="7" h="7" />
|
||||
<part id="icon_search" x="160" y="256" w="8" h="8" />
|
||||
<part id="icon_user_data" x="168" y="256" w="8" h="8" />
|
||||
<part id="icon_pos" x="144" y="264" w="8" h="8" />
|
||||
<part id="icon_size" x="152" y="264" w="8" h="8" />
|
||||
<part id="icon_selsize" x="160" y="264" w="8" h="8" />
|
||||
<part id="icon_frame" x="168" y="264" w="8" h="8" />
|
||||
<part id="icon_clock" x="176" y="264" w="8" h="8" />
|
||||
<part id="icon_start" x="184" y="264" w="8" h="8" />
|
||||
<part id="icon_end" x="192" y="264" w="8" h="8" />
|
||||
<part id="icon_angle" x="200" y="264" w="8" h="8" />
|
||||
<part id="icon_key" x="208" y="264" w="8" h="8" />
|
||||
</parts>
|
||||
|
||||
<stylesheet>
|
||||
|
@ -81,7 +81,7 @@ public:
|
||||
return;
|
||||
|
||||
char buf[1024];
|
||||
sprintf(buf, "Start %3d %3d End %3d %3d",
|
||||
sprintf(buf, ":start: %3d %3d :end: %3d %3d",
|
||||
stroke.firstPoint().x,
|
||||
stroke.firstPoint().y,
|
||||
stroke.lastPoint().x,
|
||||
@ -202,7 +202,7 @@ public:
|
||||
return;
|
||||
|
||||
char buf[1024];
|
||||
sprintf(buf, "Start %3d %3d End %3d %3d (Size %3d %3d) Angle %.1f",
|
||||
sprintf(buf, ":start: %3d %3d :end: %3d %3d :size: %3d %3d :angle: %.1f",
|
||||
stroke[0].x, stroke[0].y,
|
||||
stroke[1].x, stroke[1].y,
|
||||
ABS(stroke[1].x-stroke[0].x)+1,
|
||||
@ -264,7 +264,7 @@ public:
|
||||
return;
|
||||
|
||||
char buf[1024];
|
||||
sprintf(buf, "Start %3d %3d End %3d %3d",
|
||||
sprintf(buf, ":start: %3d %3d :end: %3d %3d",
|
||||
stroke.firstPoint().x,
|
||||
stroke.firstPoint().y,
|
||||
stroke.lastPoint().x,
|
||||
@ -303,7 +303,7 @@ public:
|
||||
return;
|
||||
|
||||
char buf[1024];
|
||||
sprintf(buf, "Pos %3d %3d", stroke[0].x, stroke[0].y);
|
||||
sprintf(buf, ":pos: %3d %3d", stroke[0].x, stroke[0].y);
|
||||
text = buf;
|
||||
}
|
||||
|
||||
@ -358,7 +358,7 @@ public:
|
||||
return;
|
||||
|
||||
char buf[1024];
|
||||
sprintf(buf, "Start %3d %3d End %3d %3d (%3d %3d - %3d %3d)",
|
||||
sprintf(buf, ":start: %3d %3d :end: %3d %3d (%3d %3d - %3d %3d)",
|
||||
stroke[0].x, stroke[0].y,
|
||||
stroke[3].x, stroke[3].y,
|
||||
stroke[1].x, stroke[1].y,
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2001-2015 David Capello
|
||||
// Copyright (C) 2001-2016 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
|
||||
@ -163,7 +163,7 @@ bool MovingCelState::onUpdateStatusBar(Editor* editor)
|
||||
{
|
||||
StatusBar::instance()->setStatusText
|
||||
(0,
|
||||
"Pos %3d %3d Offset %3d %3d",
|
||||
":pos: %3d %3d :offset: %3d %3d",
|
||||
(int)m_cursorStart.x,
|
||||
(int)m_cursorStart.y,
|
||||
(int)m_celOffset.x,
|
||||
|
@ -437,10 +437,10 @@ bool MovingPixelsState::onUpdateStatusBar(Editor* editor)
|
||||
gfx::Size imageSize = m_pixelsMovement->getInitialImageSize();
|
||||
|
||||
StatusBar::instance()->setStatusText
|
||||
(100, "Moving Pixels - Pos %d %d, Size %d %d, Orig: %3d %3d (%.02f%% %.02f%%), Angle %.1f",
|
||||
(100, "Moving Pixels: :pos: %d %d :size: %3d %3d :selsize: %d %d [%.02f%% %.02f%%] :angle: %.1f",
|
||||
transform.bounds().x, transform.bounds().y,
|
||||
transform.bounds().w, transform.bounds().h,
|
||||
imageSize.w, imageSize.h,
|
||||
transform.bounds().w, transform.bounds().h,
|
||||
(double)transform.bounds().w*100.0/imageSize.w,
|
||||
(double)transform.bounds().h*100.0/imageSize.h,
|
||||
180.0 * transform.angle() / PI);
|
||||
|
@ -445,7 +445,7 @@ bool StandbyState::onUpdateStatusBar(Editor* editor)
|
||||
cmd.pickSample(editor->getSite(), spritePos, color);
|
||||
|
||||
char buf[256];
|
||||
sprintf(buf, "- Pos %d %d", spritePos.x, spritePos.y);
|
||||
sprintf(buf, " :pos: %d %d", spritePos.x, spritePos.y);
|
||||
|
||||
StatusBar::instance()->showColor(0, buf, color);
|
||||
}
|
||||
@ -454,13 +454,21 @@ bool StandbyState::onUpdateStatusBar(Editor* editor)
|
||||
(editor->document()->isMaskVisible() ?
|
||||
editor->document()->mask(): NULL);
|
||||
|
||||
StatusBar::instance()->setStatusText(0,
|
||||
"Pos %d %d, Size %d %d, Frame %d [%d msecs]",
|
||||
char buf[1024];
|
||||
sprintf(
|
||||
buf, ":pos: %d %d :%s: %d %d",
|
||||
spritePos.x, spritePos.y,
|
||||
(mask ? "selsize": "size"),
|
||||
(mask ? mask->bounds().w: sprite->width()),
|
||||
(mask ? mask->bounds().h: sprite->height()),
|
||||
editor->frame()+1,
|
||||
sprite->frameDuration(editor->frame()));
|
||||
(mask ? mask->bounds().h: sprite->height()));
|
||||
if (sprite->totalFrames() > 1) {
|
||||
sprintf(
|
||||
buf+strlen(buf), " :frame: %d :clock: %d",
|
||||
editor->frame()+1,
|
||||
sprite->frameDuration(editor->frame()));
|
||||
}
|
||||
|
||||
StatusBar::instance()->setStatusText(0, buf);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -45,9 +45,11 @@
|
||||
#include "ui/ui.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <climits>
|
||||
#include <cstdarg>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <vector>
|
||||
|
||||
namespace app {
|
||||
|
||||
@ -56,6 +58,313 @@ using namespace gfx;
|
||||
using namespace ui;
|
||||
using namespace doc;
|
||||
|
||||
class StatusBar::Indicators : public HBox {
|
||||
|
||||
class Indicator : public Widget {
|
||||
public:
|
||||
enum IndicatorType {
|
||||
kText,
|
||||
kIcon,
|
||||
kColor
|
||||
};
|
||||
Indicator(IndicatorType type) : m_type(type) { }
|
||||
IndicatorType indicatorType() const { return m_type; }
|
||||
private:
|
||||
IndicatorType m_type;
|
||||
};
|
||||
|
||||
class TextIndicator : public Indicator {
|
||||
public:
|
||||
TextIndicator(const char* text) : Indicator(kText) {
|
||||
updateIndicator(text);
|
||||
}
|
||||
|
||||
void updateIndicator(const char* text) {
|
||||
if (this->text() == text)
|
||||
return;
|
||||
|
||||
setText(text);
|
||||
|
||||
if (minSize().w > textSize().w*2)
|
||||
setMinSize(textSize());
|
||||
else
|
||||
setMinSize(minSize().createUnion(textSize()));
|
||||
}
|
||||
|
||||
private:
|
||||
void onPaint(ui::PaintEvent& ev) override {
|
||||
SkinTheme* theme = static_cast<SkinTheme*>(this->theme());
|
||||
gfx::Color textColor = theme->colors.statusBarText();
|
||||
Rect rc = clientBounds();
|
||||
Graphics* g = ev.graphics();
|
||||
|
||||
g->fillRect(bgColor(), rc);
|
||||
if (textLength() > 0) {
|
||||
g->drawString(text(), textColor, ColorNone,
|
||||
Point(rc.x, rc.y + rc.h/2 - font()->height()/2));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class IconIndicator : public Indicator {
|
||||
public:
|
||||
IconIndicator(she::Surface* icon, bool colored)
|
||||
: Indicator(kIcon)
|
||||
, m_icon(nullptr)
|
||||
, m_colored(colored) {
|
||||
updateIndicator(icon, colored);
|
||||
}
|
||||
|
||||
void updateIndicator(she::Surface* icon, bool colored) {
|
||||
if (m_icon == icon && m_colored == colored)
|
||||
return;
|
||||
|
||||
ASSERT(icon);
|
||||
|
||||
m_icon = icon;
|
||||
m_colored = colored;
|
||||
setMinSize(minSize().createUnion(Size(m_icon->width(),
|
||||
m_icon->height())));
|
||||
}
|
||||
|
||||
private:
|
||||
void onPaint(ui::PaintEvent& ev) override {
|
||||
SkinTheme* theme = static_cast<SkinTheme*>(this->theme());
|
||||
gfx::Color textColor = theme->colors.statusBarText();
|
||||
Rect rc = clientBounds();
|
||||
Graphics* g = ev.graphics();
|
||||
|
||||
g->fillRect(bgColor(), rc);
|
||||
if (m_colored)
|
||||
g->drawColoredRgbaSurface(
|
||||
m_icon, textColor,
|
||||
rc.x, rc.y + rc.h/2 - m_icon->height()/2);
|
||||
else
|
||||
g->drawRgbaSurface(
|
||||
m_icon,
|
||||
rc.x, rc.y + rc.h/2 - m_icon->height()/2);
|
||||
}
|
||||
|
||||
she::Surface* m_icon;
|
||||
bool m_colored;
|
||||
};
|
||||
|
||||
class ColorIndicator : public Indicator {
|
||||
public:
|
||||
ColorIndicator(const app::Color& color)
|
||||
: Indicator(kColor)
|
||||
, m_color(Color::fromMask()) {
|
||||
updateIndicator(color, true);
|
||||
}
|
||||
|
||||
void updateIndicator(const app::Color& color, bool first = false) {
|
||||
if (m_color == color && !first)
|
||||
return;
|
||||
|
||||
m_color = color;
|
||||
setMinSize(minSize().createUnion(Size(32*guiscale(), 1)));
|
||||
}
|
||||
|
||||
private:
|
||||
void onPaint(ui::PaintEvent& ev) override {
|
||||
SkinTheme* theme = static_cast<SkinTheme*>(this->theme());
|
||||
Rect rc = clientBounds();
|
||||
Graphics* g = ev.graphics();
|
||||
|
||||
g->fillRect(bgColor(), rc);
|
||||
draw_color_button(
|
||||
g, Rect(rc.x, rc.y, 32*guiscale(), rc.h),
|
||||
m_color,
|
||||
(doc::ColorMode)app_get_current_pixel_format(), false, false);
|
||||
}
|
||||
|
||||
app::Color m_color;
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
Indicators() {
|
||||
}
|
||||
|
||||
void startIndicators() {
|
||||
m_iterator = m_indicators.begin();
|
||||
}
|
||||
|
||||
void endIndicators() {
|
||||
removeAllNextIndicators();
|
||||
layout();
|
||||
}
|
||||
|
||||
void addTextIndicator(const char* text) {
|
||||
// Re-use indicator
|
||||
if (m_iterator != m_indicators.end()) {
|
||||
if ((*m_iterator)->indicatorType() == Indicator::kText) {
|
||||
static_cast<TextIndicator*>(*m_iterator)
|
||||
->updateIndicator(text);
|
||||
++m_iterator;
|
||||
return;
|
||||
}
|
||||
else
|
||||
removeAllNextIndicators();
|
||||
}
|
||||
|
||||
auto indicator = new TextIndicator(text);
|
||||
m_indicators.push_back(indicator);
|
||||
m_iterator = m_indicators.end();
|
||||
addChild(indicator);
|
||||
}
|
||||
|
||||
void addIconIndicator(she::Surface* icon, bool colored) {
|
||||
if (m_iterator != m_indicators.end()) {
|
||||
if ((*m_iterator)->indicatorType() == Indicator::kIcon) {
|
||||
static_cast<IconIndicator*>(*m_iterator)
|
||||
->updateIndicator(icon, colored);
|
||||
++m_iterator;
|
||||
return;
|
||||
}
|
||||
else
|
||||
removeAllNextIndicators();
|
||||
}
|
||||
|
||||
auto indicator = new IconIndicator(icon, colored);
|
||||
m_indicators.push_back(indicator);
|
||||
m_iterator = m_indicators.end();
|
||||
addChild(indicator);
|
||||
}
|
||||
|
||||
void addColorIndicator(const app::Color& color) {
|
||||
if (m_iterator != m_indicators.end()) {
|
||||
if ((*m_iterator)->indicatorType() == Indicator::kColor) {
|
||||
static_cast<ColorIndicator*>(*m_iterator)
|
||||
->updateIndicator(color);
|
||||
++m_iterator;
|
||||
return;
|
||||
}
|
||||
else
|
||||
removeAllNextIndicators();
|
||||
}
|
||||
|
||||
auto indicator = new ColorIndicator(color);
|
||||
m_indicators.push_back(indicator);
|
||||
m_iterator = m_indicators.end();
|
||||
addChild(indicator);
|
||||
}
|
||||
|
||||
private:
|
||||
void removeAllNextIndicators() {
|
||||
auto it = m_iterator;
|
||||
auto end = m_indicators.end();
|
||||
for (; it != end; ++it) {
|
||||
auto indicator = *it;
|
||||
removeChild(indicator);
|
||||
delete indicator;
|
||||
}
|
||||
m_indicators.erase(m_iterator, end);
|
||||
}
|
||||
|
||||
std::vector<Indicator*> m_indicators;
|
||||
std::vector<Indicator*>::iterator m_iterator;
|
||||
};
|
||||
|
||||
class StatusBar::IndicatorsGeneration {
|
||||
public:
|
||||
IndicatorsGeneration(StatusBar::Indicators* indicators)
|
||||
: m_indicators(indicators) {
|
||||
m_indicators->startIndicators();
|
||||
}
|
||||
|
||||
~IndicatorsGeneration() {
|
||||
m_indicators->endIndicators();
|
||||
}
|
||||
|
||||
IndicatorsGeneration& add(const char* text) {
|
||||
auto theme = SkinTheme::instance();
|
||||
|
||||
for (auto i = text; *i; ) {
|
||||
// Icon
|
||||
if (*i == ':' && (i == text || *(i-1) == ' ')) {
|
||||
const char* j = i+1;
|
||||
for (; *j; ++j) {
|
||||
if (*j == ':')
|
||||
break;
|
||||
}
|
||||
|
||||
if (*(j+1) == 0 || *(j+1) == ' ') {
|
||||
if (i != text) {
|
||||
// Here i is ':' and i-1 is a whitespace ' '
|
||||
m_indicators->addTextIndicator(std::string(text, i-1).c_str());
|
||||
}
|
||||
|
||||
auto part = theme->getPartById("icon_" + std::string(i+1, j));
|
||||
if (part)
|
||||
add(part.get(), true);
|
||||
|
||||
text = i = (*(j+1) == ' ' ? j+2: j+1);
|
||||
}
|
||||
}
|
||||
else
|
||||
++i;
|
||||
}
|
||||
|
||||
if (*text != 0)
|
||||
m_indicators->addTextIndicator(text);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
IndicatorsGeneration& add(she::Surface* icon, bool colored) {
|
||||
if (icon)
|
||||
m_indicators->addIconIndicator(icon, colored);
|
||||
return *this;
|
||||
}
|
||||
|
||||
IndicatorsGeneration& add(const skin::SkinPart* part, bool colored) {
|
||||
return add(part->bitmap(0), colored);
|
||||
}
|
||||
|
||||
IndicatorsGeneration& add(const app::Color& color) {
|
||||
auto theme = SkinTheme::instance();
|
||||
|
||||
// Eyedropper icon
|
||||
add(theme->getToolIcon("eyedropper"), false);
|
||||
|
||||
// Color
|
||||
m_indicators->addColorIndicator(color);
|
||||
|
||||
// Color description
|
||||
std::string str = color.toHumanReadableString(
|
||||
app_get_current_pixel_format(),
|
||||
app::Color::LongHumanReadableString);
|
||||
if (color.getAlpha() < 255) {
|
||||
char buf[256];
|
||||
sprintf(buf, " \xCE\xB1%d", color.getAlpha());
|
||||
str += buf;
|
||||
}
|
||||
m_indicators->addTextIndicator(str.c_str());
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
IndicatorsGeneration& add(tools::Tool* tool) {
|
||||
auto theme = SkinTheme::instance();
|
||||
|
||||
// Tool icon + text
|
||||
add(theme->getToolIcon(tool->getId().c_str()), false);
|
||||
m_indicators->addTextIndicator(tool->getText().c_str());
|
||||
|
||||
// Tool shortcut
|
||||
Key* key = KeyboardShortcuts::instance()->tool(tool);
|
||||
if (key && !key->accels().empty()) {
|
||||
add(theme->parts.iconKey()->bitmap(0), true);
|
||||
m_indicators->addTextIndicator(key->accels().front().toString().c_str());
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
StatusBar::Indicators* m_indicators;
|
||||
};
|
||||
|
||||
class StatusBar::CustomizedTipWindow : public ui::TipWindow {
|
||||
public:
|
||||
CustomizedTipWindow(const std::string& text)
|
||||
@ -77,7 +386,14 @@ public:
|
||||
}
|
||||
|
||||
protected:
|
||||
bool onProcessMessage(Message* msg);
|
||||
bool onProcessMessage(Message* msg) override {
|
||||
switch (msg->type()) {
|
||||
case kTimerMessage:
|
||||
closeWindow(NULL);
|
||||
break;
|
||||
}
|
||||
return ui::TipWindow::onProcessMessage(msg);
|
||||
}
|
||||
|
||||
private:
|
||||
base::UniquePtr<ui::Timer> m_timer;
|
||||
@ -112,14 +428,6 @@ private:
|
||||
ui::Button m_button;
|
||||
};
|
||||
|
||||
static WidgetType statusbar_type()
|
||||
{
|
||||
static WidgetType type = kGenericWidget;
|
||||
if (type == kGenericWidget)
|
||||
type = register_widget_type();
|
||||
return type;
|
||||
}
|
||||
|
||||
// This widget is used to show the current frame.
|
||||
class GotoFrameEntry : public Entry {
|
||||
public:
|
||||
@ -164,10 +472,8 @@ public:
|
||||
StatusBar* StatusBar::m_instance = NULL;
|
||||
|
||||
StatusBar::StatusBar()
|
||||
: Widget(statusbar_type())
|
||||
, m_timeout(0)
|
||||
, m_state(SHOW_TEXT)
|
||||
, m_color(app::Color::fromMask())
|
||||
: m_timeout(0)
|
||||
, m_indicators(new Indicators)
|
||||
, m_docControls(new HBox)
|
||||
, m_doc(nullptr)
|
||||
, m_tipwindow(nullptr)
|
||||
@ -180,14 +486,15 @@ StatusBar::StatusBar()
|
||||
SkinTheme* theme = static_cast<SkinTheme*>(this->theme());
|
||||
setBgColor(theme->colors.statusBarFace());
|
||||
|
||||
this->setFocusStop(true);
|
||||
setFocusStop(true);
|
||||
setBorder(gfx::Border(6*guiscale(), 0, 6*guiscale(), 0));
|
||||
|
||||
// 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));
|
||||
setMinSize(Size(0, textHeight()+8*guiscale()));
|
||||
setMaxSize(Size(INT_MAX, textHeight()+8*guiscale()));
|
||||
|
||||
m_indicators->setExpansive(true);
|
||||
m_docControls->setVisible(false);
|
||||
addChild(m_indicators);
|
||||
addChild(m_docControls);
|
||||
|
||||
// Construct the commands box
|
||||
@ -271,12 +578,8 @@ bool StatusBar::setStatusText(int msecs, const char *format, ...)
|
||||
vsprintf(buf, format, ap);
|
||||
va_end(ap);
|
||||
|
||||
IndicatorsGeneration(m_indicators).add(buf);
|
||||
m_timeout = base::current_tick() + msecs;
|
||||
m_state = SHOW_TEXT;
|
||||
|
||||
setText(buf);
|
||||
invalidate();
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
@ -315,39 +618,21 @@ void StatusBar::showTip(int msecs, const char *format, ...)
|
||||
m_tipwindow->startTimer();
|
||||
|
||||
// Set the text in status-bar (with inmediate timeout)
|
||||
IndicatorsGeneration(m_indicators).add(buf);
|
||||
m_timeout = base::current_tick();
|
||||
setText(buf);
|
||||
invalidate();
|
||||
}
|
||||
|
||||
void StatusBar::showColor(int msecs, const char* text, const app::Color& color)
|
||||
{
|
||||
if (setStatusText(msecs, text)) {
|
||||
m_state = SHOW_COLOR;
|
||||
m_color = color;
|
||||
IndicatorsGeneration(m_indicators).add(color);
|
||||
}
|
||||
}
|
||||
|
||||
void StatusBar::showTool(int msecs, tools::Tool* tool)
|
||||
{
|
||||
ASSERT(tool != NULL);
|
||||
|
||||
// Tool name
|
||||
std::string text = tool->getText();
|
||||
|
||||
// Tool shortcut
|
||||
Key* key = KeyboardShortcuts::instance()->tool(tool);
|
||||
if (key && !key->accels().empty()) {
|
||||
text += ", Shortcut: ";
|
||||
text += key->accels().front().toString();
|
||||
}
|
||||
|
||||
// Set text
|
||||
if (setStatusText(msecs, text.c_str())) {
|
||||
// Show tool
|
||||
m_state = SHOW_TOOL;
|
||||
m_tool = tool;
|
||||
}
|
||||
IndicatorsGeneration(m_indicators).add(tool);
|
||||
}
|
||||
|
||||
void StatusBar::showSnapToGridWarning(bool state)
|
||||
@ -387,106 +672,10 @@ void StatusBar::showSnapToGridWarning(bool state)
|
||||
|
||||
void StatusBar::onResize(ResizeEvent& ev)
|
||||
{
|
||||
setBoundsQuietly(ev.bounds());
|
||||
|
||||
Border border = this->border();
|
||||
Rect rc = ev.bounds();
|
||||
bool docControls = (rc.w > 300*ui::guiscale());
|
||||
if (docControls) {
|
||||
int prefWidth = m_docControls->sizeHint().w;
|
||||
int toolBarWidth = ToolBar::instance()->sizeHint().w;
|
||||
m_docControls->setVisible(m_doc && rc.w > 300*ui::guiscale());
|
||||
|
||||
rc.x += rc.w - prefWidth - border.right() - toolBarWidth;
|
||||
rc.w = prefWidth;
|
||||
|
||||
m_docControls->setVisible(m_doc != nullptr);
|
||||
m_docControls->setBounds(rc);
|
||||
}
|
||||
else
|
||||
m_docControls->setVisible(false);
|
||||
}
|
||||
|
||||
void StatusBar::onSizeHint(SizeHintEvent& ev)
|
||||
{
|
||||
int s = 4*guiscale() + textHeight() + 4*guiscale();
|
||||
ev.setSizeHint(Size(s, s));
|
||||
}
|
||||
|
||||
void StatusBar::onPaint(ui::PaintEvent& ev)
|
||||
{
|
||||
SkinTheme* theme = static_cast<SkinTheme*>(this->theme());
|
||||
gfx::Color textColor = theme->colors.statusBarText();
|
||||
Rect rc = clientBounds();
|
||||
Graphics* g = ev.graphics();
|
||||
|
||||
g->fillRect(bgColor(), rc);
|
||||
|
||||
rc.shrink(Border(2, 1, 2, 2)*guiscale());
|
||||
|
||||
int x = rc.x + 4*guiscale();
|
||||
|
||||
// Color
|
||||
if (m_state == SHOW_COLOR) {
|
||||
// Draw eyedropper icon
|
||||
she::Surface* icon = theme->getToolIcon("eyedropper");
|
||||
if (icon) {
|
||||
g->drawRgbaSurface(icon, x, rc.y + rc.h/2 - icon->height()/2);
|
||||
x += icon->width() + 4*guiscale();
|
||||
}
|
||||
|
||||
// Draw color
|
||||
draw_color_button(
|
||||
g, gfx::Rect(x, rc.y, 32*guiscale(), rc.h),
|
||||
m_color,
|
||||
(doc::ColorMode)app_get_current_pixel_format(), false, false);
|
||||
|
||||
x += (32+4)*guiscale();
|
||||
|
||||
// Draw color description
|
||||
std::string str = m_color.toHumanReadableString(
|
||||
app_get_current_pixel_format(),
|
||||
app::Color::LongHumanReadableString);
|
||||
if (m_color.getAlpha() < 255) {
|
||||
char buf[256];
|
||||
sprintf(buf, " \xCE\xB1%d", m_color.getAlpha());
|
||||
str += buf;
|
||||
}
|
||||
|
||||
g->drawString(str, textColor, ColorNone,
|
||||
gfx::Point(x, rc.y + rc.h/2 - font()->height()/2));
|
||||
|
||||
x += font()->textLength(str.c_str()) + 4*guiscale();
|
||||
}
|
||||
|
||||
// Show tool
|
||||
if (m_state == SHOW_TOOL) {
|
||||
// Draw eyedropper icon
|
||||
she::Surface* icon = theme->getToolIcon(m_tool->getId().c_str());
|
||||
if (icon) {
|
||||
g->drawRgbaSurface(icon, x, rc.y + rc.h/2 - icon->height()/2);
|
||||
x += icon->width() + 4*guiscale();
|
||||
}
|
||||
}
|
||||
|
||||
// Status bar text
|
||||
if (textLength() > 0) {
|
||||
g->drawString(text(), textColor, ColorNone,
|
||||
gfx::Point(x, rc.y + rc.h/2 - font()->height()/2));
|
||||
|
||||
x += font()->textLength(text().c_str()) + 4*guiscale();
|
||||
}
|
||||
}
|
||||
|
||||
bool StatusBar::CustomizedTipWindow::onProcessMessage(Message* msg)
|
||||
{
|
||||
switch (msg->type()) {
|
||||
|
||||
case kTimerMessage:
|
||||
closeWindow(NULL);
|
||||
break;
|
||||
}
|
||||
|
||||
return ui::TipWindow::onProcessMessage(msg);
|
||||
HBox::onResize(ev);
|
||||
}
|
||||
|
||||
void StatusBar::onActiveSiteChange(const doc::Site& site)
|
||||
|
@ -17,7 +17,7 @@
|
||||
#include "doc/documents_observer.h"
|
||||
#include "doc/layer_index.h"
|
||||
#include "ui/base.h"
|
||||
#include "ui/widget.h"
|
||||
#include "ui/box.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@ -43,7 +43,7 @@ namespace app {
|
||||
class Tool;
|
||||
}
|
||||
|
||||
class StatusBar : public ui::Widget
|
||||
class StatusBar : public ui::HBox
|
||||
, public doc::ContextObserver
|
||||
, public doc::DocumentsObserver
|
||||
, public doc::DocumentObserver {
|
||||
@ -67,8 +67,6 @@ namespace app {
|
||||
|
||||
protected:
|
||||
void onResize(ui::ResizeEvent& ev) override;
|
||||
void onSizeHint(ui::SizeHintEvent& ev) override;
|
||||
void onPaint(ui::PaintEvent& ev) override;
|
||||
|
||||
// ContextObserver impl
|
||||
void onActiveSiteChange(const doc::Site& site) override;
|
||||
@ -85,16 +83,12 @@ namespace app {
|
||||
void newFrame();
|
||||
void onChangeZoom(const render::Zoom& zoom);
|
||||
|
||||
enum State { SHOW_TEXT, SHOW_COLOR, SHOW_TOOL };
|
||||
|
||||
base::tick_t m_timeout;
|
||||
State m_state;
|
||||
|
||||
// Showing a tool
|
||||
tools::Tool* m_tool;
|
||||
|
||||
// Showing a color
|
||||
Color m_color;
|
||||
// Indicators
|
||||
class Indicators;
|
||||
class IndicatorsGeneration;
|
||||
Indicators* m_indicators;
|
||||
|
||||
// Box of main commands
|
||||
ui::Widget* m_docControls;
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2001-2015 David Capello
|
||||
// Copyright (C) 2001-2016 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
|
||||
@ -2181,7 +2181,7 @@ void Timeline::updateStatusBar(ui::Message* msg)
|
||||
case PART_HEADER_FRAME:
|
||||
if (validFrame(m_hot.frame)) {
|
||||
sb->setStatusText(0,
|
||||
"Frame %d [%d msecs]",
|
||||
":frame: %d :clock: %d",
|
||||
(int)m_hot.frame+1,
|
||||
m_sprite->frameDuration(m_hot.frame));
|
||||
return;
|
||||
|
Loading…
x
Reference in New Issue
Block a user