aseprite/src/app/ui/tile_button.cpp
David Capello c2e5e69882 Simplify tilesets impl using tile index 0 = an empty tile
In this way we always have an empty tile available in the drawing
process. We've also added the Tileset::firstVisibleIndex field to
change the visible index of the tile 1 so we can offset the visible
number by the user (just as a visual aid / simulate old tilesets with
index=0=non-empty tile).
2020-10-30 16:33:34 -03:00

169 lines
3.7 KiB
C++

// Aseprite
// Copyright (c) 2020 Igara Studio S.A.
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "app/ui/tile_button.h"
#include "app/modules/gfx.h"
#include "app/ui/skin/skin_theme.h"
#include "app/ui/status_bar.h"
#include "app/ui_context.h"
#include "fmt/format.h"
#include "ui/graphics.h"
#include "ui/message.h"
#include "ui/paint_event.h"
#include "ui/size_hint_event.h"
#include "ui/system.h"
namespace app {
using namespace app::skin;
using namespace ui;
static WidgetType tilebutton_type()
{
static WidgetType type = kGenericWidget;
if (type == kGenericWidget)
type = register_widget_type();
return type;
}
TileButton::TileButton()
: ButtonBase("", tilebutton_type(), kButtonWidget, kButtonWidget)
{
setFocusStop(true);
initTheme();
UIContext::instance()->add_observer(this);
}
TileButton::~TileButton()
{
UIContext::instance()->remove_observer(this);
}
doc::tile_t TileButton::getTile() const
{
return m_tile;
}
void TileButton::setTile(doc::tile_t origTile)
{
// Before change (this signal can modify the color)
doc::tile_t tile = origTile;
BeforeChange(tile);
m_tile = tile;
Change(tile);
invalidate();
}
doc::tile_t TileButton::getTileByPosition(const gfx::Point& pos)
{
// Ignore the position
return m_tile;
}
void TileButton::onInitTheme(InitThemeEvent& ev)
{
ButtonBase::onInitTheme(ev);
setStyle(SkinTheme::instance()->styles.colorButton());
}
bool TileButton::onProcessMessage(Message* msg)
{
switch (msg->type()) {
case kMouseEnterMessage:
StatusBar::instance()->showTile(0, "", m_tile);
break;
case kMouseLeaveMessage:
StatusBar::instance()->showDefaultText();
break;
case kMouseMoveMessage:
if (hasCapture()) {
gfx::Point mousePos = static_cast<MouseMessage*>(msg)->position();
Widget* picked = manager()->pick(mousePos);
doc::tile_t tile = m_tile;
if (picked && picked != this) {
// Pick a tile from a ITileSource
if (ITileSource* tileSource = dynamic_cast<ITileSource*>(picked)) {
tile = tileSource->getTileByPosition(mousePos);
}
}
// Did the tile change?
if (tile != m_tile) {
setTile(tile);
}
}
break;
case kSetCursorMessage:
if (hasCapture()) {
ui::set_mouse_cursor(kCustomCursor, SkinTheme::instance()->cursors.eyedropper());
return true;
}
break;
}
return ButtonBase::onProcessMessage(msg);
}
void TileButton::onSizeHint(SizeHintEvent& ev)
{
ButtonBase::onSizeHint(ev);
gfx::Size sz(32*guiscale(),
32*guiscale());
ev.setSizeHint(sz);
}
void TileButton::onPaint(PaintEvent& ev)
{
Graphics* g = ev.graphics();
SkinTheme* theme = static_cast<SkinTheme*>(this->theme());
gfx::Rect rc = clientBounds();
gfx::Color bg = bgColor();
if (gfx::is_transparent(bg))
bg = theme->colors.face();
g->fillRect(bg, rc);
Site site = UIContext::instance()->activeSite();
draw_tile_button(g, rc,
site, m_tile,
hasMouseOver(), false);
// Draw text
if (m_tile != doc::notile) {
int firstVisibleIndex = 1;
if (site.tileset())
firstVisibleIndex = site.tileset()->firstVisibleIndex();
std::string str = fmt::format("{}", doc::tile_geti(m_tile) + firstVisibleIndex - 1);
setTextQuiet(str.c_str());
// TODO calc a proper color for the text
gfx::Color textcolor = gfx::rgba(0, 0, 0);
gfx::Rect textrc;
getTextIconInfo(NULL, &textrc);
g->drawUIText(text(), textcolor, gfx::ColorNone, textrc.origin(), 0);
}
}
void TileButton::onActiveSiteChange(const Site& site)
{
invalidate();
}
} // namespace app