mirror of
https://github.com/aseprite/aseprite.git
synced 2025-01-29 21:33:12 +00:00
Update ButtonSet to use theme's styles
This commit is contained in:
parent
40426075f2
commit
3ab993d1d6
@ -1013,5 +1013,31 @@
|
||||
<text color="slider_empty_text" align="center middle" />
|
||||
<text color="slider_empty_text" align="center middle" state="focus" />
|
||||
</style>
|
||||
<style id="buttonset" gap-rows="-3" gap-columns="-1" />
|
||||
<style id="buttonset_item" font="mini">
|
||||
<background-border part="buttonset_item_normal" />
|
||||
<background-border part="buttonset_item_hot" state="selected" />
|
||||
<background-border part="buttonset_item_hot" state="mouse" />
|
||||
<background-border part="buttonset_item_hot_focused" state="selected focus" />
|
||||
<background-border part="buttonset_item_hot_focused" state="mouse focus" />
|
||||
<background-border part="buttonset_item_pushed" state="capture selected" />
|
||||
<background-border part="buttonset_item_pushed" state="mouse capture" />
|
||||
<background-border part="buttonset_item_focused" state="focus" />
|
||||
</style>
|
||||
<style id="buttonset_item_icon" extends="buttonset_item">
|
||||
<icon />
|
||||
<icon state="disabled" color="disabled" />
|
||||
<icon state="capture selected" color="button_selected_text" />
|
||||
</style>
|
||||
<style id="buttonset_item_text" extends="buttonset_item" padding="1">
|
||||
<text color="button_normal_text" y="1" />
|
||||
<text color="button_hot_text" state="selected" y="1" />
|
||||
<text color="button_hot_text" state="mouse" y="1" />
|
||||
<text color="button_selected_text" state="mouse capture" y="1" />
|
||||
<text color="button_selected_text" state="capture selected" y="1" />
|
||||
<text color="background" x="1" y="2" state="disabled" />
|
||||
<newlayer />
|
||||
<text color="disabled" state="disabled" align="top" y="1" />
|
||||
</style>
|
||||
</styles>
|
||||
</theme>
|
||||
|
@ -48,22 +48,15 @@ WidgetType buttonset_item_type()
|
||||
ButtonSet::Item::Item()
|
||||
: Widget(buttonset_item_type())
|
||||
, m_icon(NULL)
|
||||
, m_hotColor(gfx::ColorNone)
|
||||
{
|
||||
setup_mini_font(this);
|
||||
setAlign(CENTER | MIDDLE);
|
||||
setFocusStop(true);
|
||||
}
|
||||
|
||||
void ButtonSet::Item::setHotColor(gfx::Color color)
|
||||
{
|
||||
m_hotColor = color;
|
||||
}
|
||||
|
||||
void ButtonSet::Item::setIcon(const SkinPartPtr& icon, bool mono)
|
||||
void ButtonSet::Item::setIcon(const SkinPartPtr& icon)
|
||||
{
|
||||
m_icon = icon;
|
||||
m_mono = mono;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
@ -74,97 +67,17 @@ ButtonSet* ButtonSet::Item::buttonSet()
|
||||
|
||||
void ButtonSet::Item::onPaint(ui::PaintEvent& ev)
|
||||
{
|
||||
auto theme = SkinTheme::get(this);
|
||||
Graphics* g = ev.graphics();
|
||||
gfx::Rect rc = clientBounds();
|
||||
gfx::Color fg;
|
||||
SkinPartPtr nw;
|
||||
gfx::Rect boxRc, textRc, iconRc;
|
||||
gfx::Size iconSize;
|
||||
if (m_icon)
|
||||
iconSize = m_icon->size();
|
||||
if (style()) {
|
||||
gfx::Rect rc = clientBounds();
|
||||
Grid::Info info = buttonSet()->getChildInfo(this);
|
||||
bool isLastCol = (info.col + info.hspan >= info.grid_cols);
|
||||
bool isLastRow = (info.row + info.vspan >= info.grid_rows);
|
||||
// When gaps are negative we need to compensate client bounds size so the painting is based on a
|
||||
// complete button, and not just the part not overlapped.
|
||||
if (buttonSet()->m_colgap < 0 && !isLastCol) rc.w -= buttonSet()->m_colgap;
|
||||
if (buttonSet()->m_rowgap < 0 && !isLastRow) rc.h -= buttonSet()->m_rowgap;
|
||||
|
||||
getTextIconInfo(
|
||||
&boxRc, &textRc, &iconRc,
|
||||
CENTER | (hasText() ? BOTTOM: MIDDLE),
|
||||
iconSize.w, iconSize.h);
|
||||
|
||||
Grid::Info info = buttonSet()->getChildInfo(this);
|
||||
bool isLastCol = (info.col+info.hspan >= info.grid_cols);
|
||||
bool isLastRow = (info.row+info.vspan >= info.grid_rows);
|
||||
|
||||
if (m_icon || isLastRow) {
|
||||
textRc.y -= 2*guiscale();
|
||||
iconRc.y -= 1*guiscale();
|
||||
if (isLastRow && info.row > 0) iconRc.y -= 2*guiscale();
|
||||
}
|
||||
|
||||
if (!gfx::is_transparent(bgColor()))
|
||||
g->fillRect(bgColor(), g->getClipBounds());
|
||||
|
||||
if (isSelected() || hasMouseOver()) {
|
||||
if (hasCapture()) {
|
||||
nw = theme->parts.buttonsetItemPushed();
|
||||
fg = theme->colors.buttonSelectedText();
|
||||
}
|
||||
else {
|
||||
nw = (hasFocus() ? theme->parts.buttonsetItemHotFocused():
|
||||
theme->parts.buttonsetItemHot());
|
||||
fg = theme->colors.buttonHotText();
|
||||
}
|
||||
}
|
||||
else {
|
||||
nw = (hasFocus() ? theme->parts.buttonsetItemFocused():
|
||||
theme->parts.buttonsetItemNormal());
|
||||
fg = theme->colors.buttonNormalText();
|
||||
}
|
||||
|
||||
if (!isLastCol)
|
||||
rc.w += 1*guiscale();
|
||||
|
||||
if (!isLastRow) {
|
||||
if (nw == theme->parts.buttonsetItemHotFocused())
|
||||
rc.h += 2*guiscale();
|
||||
else
|
||||
rc.h += 3*guiscale();
|
||||
}
|
||||
|
||||
theme->drawRect(g, rc, nw.get(),
|
||||
gfx::is_transparent(m_hotColor));
|
||||
|
||||
if (!gfx::is_transparent(m_hotColor)) {
|
||||
gfx::Rect rc2(rc);
|
||||
gfx::Rect sprite(nw->spriteBounds());
|
||||
gfx::Rect slices(nw->slicesBounds());
|
||||
rc2.shrink(
|
||||
gfx::Border(
|
||||
slices.x-1, // TODO this "-1" is an ugly hack for the pal edit
|
||||
// button, replace all this with styles
|
||||
slices.y-1,
|
||||
sprite.w-slices.w-slices.x-1,
|
||||
sprite.h-slices.h-slices.y));
|
||||
g->fillRect(m_hotColor, rc2);
|
||||
}
|
||||
|
||||
if (m_icon) {
|
||||
os::Surface* bmp = m_icon->bitmap(0);
|
||||
|
||||
if (!isEnabled())
|
||||
g->drawColoredRgbaSurface(bmp, theme->colors.disabled(),
|
||||
iconRc.x, iconRc.y);
|
||||
else if (isSelected() && hasCapture())
|
||||
g->drawColoredRgbaSurface(bmp, theme->colors.buttonSelectedText(),
|
||||
iconRc.x, iconRc.y);
|
||||
else if (m_mono)
|
||||
g->drawColoredRgbaSurface(bmp, theme->colors.buttonNormalText(),
|
||||
iconRc.x, iconRc.y);
|
||||
else
|
||||
g->drawRgbaSurface(bmp, iconRc.x, iconRc.y);
|
||||
}
|
||||
|
||||
if (hasText()) {
|
||||
g->setFont(AddRef(font()));
|
||||
g->drawUIText(text(), fg, gfx::ColorNone, textRc.origin(), 0);
|
||||
theme()->paintWidget(ev.graphics(), this, style(), rc);
|
||||
}
|
||||
}
|
||||
|
||||
@ -195,6 +108,7 @@ bool ButtonSet::Item::onProcessMessage(ui::Message* msg)
|
||||
break;
|
||||
|
||||
case ui::kMouseDownMessage:
|
||||
if (!isEnabled()) return true;
|
||||
// Only for single-item and trigerred on mouse up ButtonSets: We
|
||||
// save the current selected item to restore it just in case the
|
||||
// user leaves the ButtonSet without releasing the mouse button
|
||||
@ -259,38 +173,13 @@ bool ButtonSet::Item::onProcessMessage(ui::Message* msg)
|
||||
|
||||
case ui::kMouseLeaveMessage:
|
||||
case ui::kMouseEnterMessage:
|
||||
if (!isEnabled()) return true;
|
||||
invalidate();
|
||||
break;
|
||||
}
|
||||
return Widget::onProcessMessage(msg);
|
||||
}
|
||||
|
||||
void ButtonSet::Item::onSizeHint(ui::SizeHintEvent& ev)
|
||||
{
|
||||
gfx::Size iconSize;
|
||||
if (m_icon) {
|
||||
iconSize = m_icon->size();
|
||||
iconSize.w = std::max(iconSize.w, 16*guiscale());
|
||||
iconSize.h = std::max(iconSize.h, 16*guiscale());
|
||||
}
|
||||
|
||||
gfx::Rect boxRc;
|
||||
getTextIconInfo(
|
||||
&boxRc, NULL, NULL,
|
||||
CENTER | (hasText() ? BOTTOM: MIDDLE),
|
||||
iconSize.w, iconSize.h);
|
||||
|
||||
gfx::Size sz = boxRc.size();
|
||||
if (hasText())
|
||||
sz += 8*guiscale();
|
||||
|
||||
Grid::Info info = buttonSet()->getChildInfo(this);
|
||||
if (info.row == info.grid_rows-1)
|
||||
sz.h += 3*guiscale();
|
||||
|
||||
ev.setSizeHint(sz);
|
||||
}
|
||||
|
||||
void ButtonSet::Item::onClick()
|
||||
{
|
||||
buttonSet()->onItemChange(this);
|
||||
@ -310,28 +199,66 @@ ButtonSet::ButtonSet(int columns)
|
||||
InitTheme.connect(
|
||||
[this]{
|
||||
noBorderNoChildSpacing();
|
||||
// Set default buttonset style if it wasn't already set.
|
||||
if (style() == SkinTheme::instance()->styles.grid()) {
|
||||
setStyle(SkinTheme::instance()->styles.buttonset());
|
||||
}
|
||||
});
|
||||
initTheme();
|
||||
}
|
||||
|
||||
ButtonSet::Item* ButtonSet::addItem(const std::string& text, int hspan, int vspan)
|
||||
ButtonSet::Item* ButtonSet::addItem(const std::string& text, const char* styleId)
|
||||
{
|
||||
return addItem(text, 1, 1, styleId);
|
||||
}
|
||||
|
||||
ButtonSet::Item* ButtonSet::addItem(const std::string& text, int hspan, int vspan, const char* styleId)
|
||||
{
|
||||
Item* item = new Item();
|
||||
item->setText(text);
|
||||
addItem(item, hspan, vspan);
|
||||
addItem(item, hspan, vspan, styleId);
|
||||
return item;
|
||||
}
|
||||
|
||||
ButtonSet::Item* ButtonSet::addItem(const skin::SkinPartPtr& icon, int hspan, int vspan)
|
||||
ButtonSet::Item* ButtonSet::addItem(const skin::SkinPartPtr& icon, const char* styleId)
|
||||
{
|
||||
return addItem(icon, 1, 1, styleId);
|
||||
}
|
||||
|
||||
ButtonSet::Item* ButtonSet::addItem(const skin::SkinPartPtr& icon, int hspan, int vspan, const char* styleId)
|
||||
{
|
||||
Item* item = new Item();
|
||||
item->setIcon(icon);
|
||||
addItem(item, hspan, vspan);
|
||||
addItem(item, hspan, vspan, styleId);
|
||||
return item;
|
||||
}
|
||||
|
||||
ButtonSet::Item* ButtonSet::addItem(Item* item, int hspan, int vspan)
|
||||
ButtonSet::Item* ButtonSet::addItem(Item* item, const char* styleId)
|
||||
{
|
||||
return addItem(item, 1, 1, styleId);
|
||||
}
|
||||
|
||||
ButtonSet::Item* ButtonSet::addItem(Item* item, int hspan, int vspan, const char* styleId)
|
||||
{
|
||||
item->InitTheme.connect(
|
||||
[item, styleId] {
|
||||
ui::Style* style;
|
||||
if (styleId) {
|
||||
auto theme = SkinTheme::get(item);
|
||||
style = theme->getStyleById(styleId);
|
||||
if (!style)
|
||||
throw base::Exception("Style %s not found", styleId);
|
||||
}
|
||||
else {
|
||||
style = SkinTheme::instance()->styles.buttonsetItemIcon();
|
||||
if (!item->text().empty()) {
|
||||
style = item->icon() ? SkinTheme::instance()->styles.buttonsetItemTextTopIconBottom() :
|
||||
SkinTheme::instance()->styles.buttonsetItemText();
|
||||
}
|
||||
}
|
||||
|
||||
item->setStyle(style);
|
||||
}
|
||||
);
|
||||
addChildInCell(item, hspan, vspan, HORIZONTAL | VERTICAL);
|
||||
return item;
|
||||
}
|
||||
|
@ -23,22 +23,17 @@ namespace app {
|
||||
class Item : public ui::Widget, public ui::Style::Layer::IconSurfaceProvider {
|
||||
public:
|
||||
Item();
|
||||
void setHotColor(gfx::Color color);
|
||||
void setIcon(const skin::SkinPartPtr& icon, bool mono = false);
|
||||
void setMono(const bool mono) { m_mono = mono; }
|
||||
void setIcon(const skin::SkinPartPtr& icon);
|
||||
os::Surface* iconSurface() const override { return m_icon ? m_icon->bitmap(0) : nullptr; }
|
||||
skin::SkinPartPtr icon() const { return m_icon; }
|
||||
ButtonSet* buttonSet();
|
||||
protected:
|
||||
void onPaint(ui::PaintEvent& ev) override;
|
||||
bool onProcessMessage(ui::Message* msg) override;
|
||||
void onSizeHint(ui::SizeHintEvent& ev) override;
|
||||
virtual void onClick();
|
||||
virtual void onRightClick();
|
||||
private:
|
||||
skin::SkinPartPtr m_icon;
|
||||
bool m_mono;
|
||||
gfx::Color m_hotColor;
|
||||
};
|
||||
|
||||
enum class MultiMode {
|
||||
@ -49,9 +44,12 @@ namespace app {
|
||||
|
||||
ButtonSet(int columns);
|
||||
|
||||
Item* addItem(const std::string& text, int hspan = 1, int vspan = 1);
|
||||
Item* addItem(const skin::SkinPartPtr& icon, int hspan = 1, int vspan = 1);
|
||||
Item* addItem(Item* item, int hspan = 1, int vspan = 1);
|
||||
Item* addItem(const std::string& text, const char* styleId);
|
||||
Item* addItem(const std::string& text, int hspan = 1, int vspan = 1, const char* styleId = nullptr);
|
||||
Item* addItem(const skin::SkinPartPtr& icon, const char* styleId);
|
||||
Item* addItem(const skin::SkinPartPtr& icon, int hspan = 1, int vspan = 1, const char* styleId = nullptr);
|
||||
Item* addItem(Item* item, const char* styleId);
|
||||
Item* addItem(Item* item, int hspan = 1, int vspan = 1, const char* styleId = nullptr);
|
||||
Item* getItem(int index);
|
||||
int getItemIndex(const Item* item) const;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user