[aseprite] 19/128: Improve status bar with icons/automatically generated and re-used parts (fix #752)

Tobias Hansen thansen at moszumanska.debian.org
Mon May 9 21:24:18 UTC 2016


This is an automated email from the git hooks/post-receive script.

thansen pushed a commit to branch master
in repository aseprite.

commit 87ef48b50b3daa51efd5c6c79bd7fdc9acd81027
Author: David Capello <davidcapello at gmail.com>
Date:   Tue Apr 19 13:45:23 2016 -0300

    Improve status bar with icons/automatically generated and re-used parts (fix #752)
---
 data/skins/default/sheet.png              | Bin 13776 -> 14090 bytes
 data/skins/default/skin.xml               |   9 +
 src/app/tools/controllers.h               |  10 +-
 src/app/ui/editor/moving_cel_state.cpp    |   4 +-
 src/app/ui/editor/moving_pixels_state.cpp |   4 +-
 src/app/ui/editor/standby_state.cpp       |  20 +-
 src/app/ui/status_bar.cpp                 | 473 +++++++++++++++++++++---------
 src/app/ui/status_bar.h                   |  18 +-
 src/app/ui/timeline.cpp                   |   4 +-
 9 files changed, 371 insertions(+), 171 deletions(-)

diff --git a/data/skins/default/sheet.png b/data/skins/default/sheet.png
index b2628d8..150ff3d 100644
Binary files a/data/skins/default/sheet.png and b/data/skins/default/sheet.png differ
diff --git a/data/skins/default/skin.xml b/data/skins/default/skin.xml
index 617269e..5ab0a88 100644
--- a/data/skins/default/skin.xml
+++ b/data/skins/default/skin.xml
@@ -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>
diff --git a/src/app/tools/controllers.h b/src/app/tools/controllers.h
index 35bab4b..4cbca8a 100644
--- a/src/app/tools/controllers.h
+++ b/src/app/tools/controllers.h
@@ -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,
diff --git a/src/app/ui/editor/moving_cel_state.cpp b/src/app/ui/editor/moving_cel_state.cpp
index 65cbf8e..ffbc33e 100644
--- a/src/app/ui/editor/moving_cel_state.cpp
+++ b/src/app/ui/editor/moving_cel_state.cpp
@@ -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,
diff --git a/src/app/ui/editor/moving_pixels_state.cpp b/src/app/ui/editor/moving_pixels_state.cpp
index 0be8360..c214e96 100644
--- a/src/app/ui/editor/moving_pixels_state.cpp
+++ b/src/app/ui/editor/moving_pixels_state.cpp
@@ -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);
diff --git a/src/app/ui/editor/standby_state.cpp b/src/app/ui/editor/standby_state.cpp
index 1244198..4f4b348 100644
--- a/src/app/ui/editor/standby_state.cpp
+++ b/src/app/ui/editor/standby_state.cpp
@@ -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;
diff --git a/src/app/ui/status_bar.cpp b/src/app/ui/status_bar.cpp
index 62951ee..bf836f6 100644
--- a/src/app/ui/status_bar.cpp
+++ b/src/app/ui/status_bar.cpp
@@ -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;
-
-    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;
-  }
+  m_docControls->setVisible(m_doc && rc.w > 300*ui::guiscale());
 
-  return ui::TipWindow::onProcessMessage(msg);
+  HBox::onResize(ev);
 }
 
 void StatusBar::onActiveSiteChange(const doc::Site& site)
diff --git a/src/app/ui/status_bar.h b/src/app/ui/status_bar.h
index 1a53a31..06a3bdd 100644
--- a/src/app/ui/status_bar.h
+++ b/src/app/ui/status_bar.h
@@ -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;
diff --git a/src/app/ui/timeline.cpp b/src/app/ui/timeline.cpp
index 8b4260f..7908756 100644
--- a/src/app/ui/timeline.cpp
+++ b/src/app/ui/timeline.cpp
@@ -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;

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-games/aseprite.git



More information about the Pkg-games-commits mailing list