Improve FilterTargetButtons UI style using a ButtonSet

Related to #786
This commit is contained in:
David Capello 2015-08-28 14:37:00 -03:00
parent db4817e3ef
commit 5c371285ab
6 changed files with 107 additions and 159 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View File

@ -274,13 +274,9 @@
<part id="pal_options" x="168" y="200" w="5" h="5" />
<part id="pal_resize" x="176" y="200" w="5" h="5" />
<part id="target_one" x="144" y="224" w="32" h="16" />
<part id="target_one_selected" x="144" y="240" w="32" h="16" />
<part id="target_frames" x="176" y="224" w="32" h="16" />
<part id="target_frames_selected" x="176" y="240" w="32" h="16" />
<part id="target_layers" x="208" y="224" w="32" h="16" />
<part id="target_layers_selected" x="208" y="240" w="32" h="16" />
<part id="target_frames_layers" x="240" y="224" w="32" h="16" />
<part id="target_frames_layers_selected" x="240" y="240" w="32" h="16" />
<part id="brush_circle" x="144" y="144" w="7" h="8" />
<part id="brush_circle_selected" x="144" y="152" w="7" h="8" />
<part id="brush_square" x="160" y="144" w="7" h="8" />

View File

@ -31,158 +31,104 @@ using namespace filters;
using namespace ui;
FilterTargetButtons::FilterTargetButtons(int imgtype, bool withChannels)
: Box(VERTICAL)
: ButtonSet(4)
, m_target(0)
, m_red(nullptr)
, m_green(nullptr)
, m_blue(nullptr)
, m_alpha(nullptr)
, m_gray(nullptr)
, m_index(nullptr)
, m_cels(nullptr)
{
#define ADD(box, widget, hook) \
if (widget) { \
widget->setBorder(gfx::Border(2 * guiscale())); \
box->addChild(widget); \
widget->Click.connect(Bind<void>(&FilterTargetButtons::hook, this, widget)); \
}
Box* hbox;
CheckBox* r = NULL;
CheckBox* g = NULL;
CheckBox* b = NULL;
CheckBox* k = NULL;
CheckBox* a = NULL;
CheckBox* index = NULL;
Button* images = NULL;
hbox = new Box(HORIZONTAL | HOMOGENEOUS);
this->noBorderNoChildSpacing();
hbox->noBorderNoChildSpacing();
setMultipleSelection(true);
if (withChannels) {
switch (imgtype) {
case IMAGE_RGB:
case IMAGE_INDEXED:
r = check_button_new("R", 2, 0, 0, 0);
g = check_button_new("G", 0, 0, 0, 0);
b = check_button_new("B", 0, 0, 0, 0);
a = check_button_new("A", 0, 2, 0, 0);
r->setId("r");
g->setId("g");
b->setId("b");
a->setId("a");
m_red = addItem("R");
m_green = addItem("G");
m_blue = addItem("B");
m_alpha = addItem("A");
if (imgtype == IMAGE_INDEXED) {
index = check_button_new("Index", 0, 0, 0, 0);
index->setId("i");
m_index = addItem("Index", 4, 1);
}
break;
case IMAGE_GRAYSCALE:
k = check_button_new("K", 2, 0, 0, 0);
a = check_button_new("A", 0, 2, 0, 0);
k->setId("k");
a->setId("a");
m_gray = addItem("K", 2, 1);
m_alpha = addItem("A", 2, 1);
break;
}
}
// Create the button to select "image" target
images = new Button("");
setup_bevels(images,
withChannels ? 0: 2,
withChannels ? 0: 2, 2, 2);
setup_mini_look(images);
images->setIconInterface(
new ButtonIconImpl(getTargetNormalIcon(),
getTargetSelectedIcon(),
SkinPartPtr(nullptr),
CENTER | MIDDLE));
// Make hierarchy
ADD(hbox, r, onChannelChange);
ADD(hbox, g, onChannelChange);
ADD(hbox, b, onChannelChange);
ADD(hbox, k, onChannelChange);
ADD(hbox, a, onChannelChange);
if (withChannels)
addChild(hbox);
else
delete hbox;
ADD(this, index, onChannelChange);
ADD(this, images, onImagesChange);
// Create the button to select which cels will be modified by the
// filter.
m_cels = addItem(getCelsIcon(), 4, 1);
}
void FilterTargetButtons::setTarget(int target)
{
m_target = target;
selectTargetButton("r", TARGET_RED_CHANNEL);
selectTargetButton("g", TARGET_GREEN_CHANNEL);
selectTargetButton("b", TARGET_BLUE_CHANNEL);
selectTargetButton("a", TARGET_ALPHA_CHANNEL);
selectTargetButton("k", TARGET_GRAY_CHANNEL);
selectTargetButton("i", TARGET_INDEX_CHANNEL);
selectTargetButton(m_red, TARGET_RED_CHANNEL);
selectTargetButton(m_green, TARGET_GREEN_CHANNEL);
selectTargetButton(m_blue, TARGET_BLUE_CHANNEL);
selectTargetButton(m_alpha, TARGET_ALPHA_CHANNEL);
selectTargetButton(m_gray, TARGET_GRAY_CHANNEL);
selectTargetButton(m_index, TARGET_INDEX_CHANNEL);
m_cels->setIcon(getCelsIcon());
}
void FilterTargetButtons::selectTargetButton(const char* name, int specificTarget)
void FilterTargetButtons::selectTargetButton(Item* item, Target specificTarget)
{
Widget* wgt = findChild(name);
if (wgt != NULL) {
wgt->setSelected((m_target & specificTarget) == specificTarget);
}
if (item)
item->setSelected((m_target & specificTarget) == specificTarget);
}
void FilterTargetButtons::onChannelChange(ButtonBase* button)
void FilterTargetButtons::onItemChange()
{
int flag = 0;
ButtonSet::onItemChange();
Target flags = 0;
switch (button->getId()[0]) {
case 'r': flag = TARGET_RED_CHANNEL; break;
case 'g': flag = TARGET_GREEN_CHANNEL; break;
case 'b': flag = TARGET_BLUE_CHANNEL; break;
case 'k': flag = TARGET_GRAY_CHANNEL; break;
case 'a': flag = TARGET_ALPHA_CHANNEL; break;
case 'i': flag = TARGET_INDEX_CHANNEL; break;
default:
return;
if (m_red && m_red->isSelected()) flags |= TARGET_RED_CHANNEL;
if (m_green && m_green->isSelected()) flags |= TARGET_GREEN_CHANNEL;
if (m_blue && m_blue->isSelected()) flags |= TARGET_BLUE_CHANNEL;
if (m_gray && m_gray->isSelected()) flags |= TARGET_GRAY_CHANNEL;
if (m_index && m_index->isSelected()) flags |= TARGET_INDEX_CHANNEL;
if (m_alpha && m_alpha->isSelected()) flags |= TARGET_ALPHA_CHANNEL;
if (m_cels->isSelected()) {
m_cels->setSelected(false);
// Rotate cels target
flags |= (m_target & (TARGET_ALL_FRAMES | TARGET_ALL_LAYERS));
if (flags & TARGET_ALL_FRAMES) {
flags &= ~TARGET_ALL_FRAMES;
if (flags & TARGET_ALL_LAYERS)
flags &= ~TARGET_ALL_LAYERS;
else
flags |= TARGET_ALL_LAYERS;
}
else {
flags |= TARGET_ALL_FRAMES;
}
}
if (button->isSelected())
m_target |= flag;
else
m_target &= ~flag;
if (m_target != flags) {
m_target = flags;
m_cels->setIcon(getCelsIcon());
TargetChange();
TargetChange();
}
}
void FilterTargetButtons::onImagesChange(ButtonBase* button)
{
// Rotate target
if (m_target & TARGET_ALL_FRAMES) {
m_target &= ~TARGET_ALL_FRAMES;
if (m_target & TARGET_ALL_LAYERS)
m_target &= ~TARGET_ALL_LAYERS;
else
m_target |= TARGET_ALL_LAYERS;
}
else {
m_target |= TARGET_ALL_FRAMES;
}
button->setIconInterface(
new ButtonIconImpl(getTargetNormalIcon(),
getTargetSelectedIcon(),
SkinPartPtr(nullptr),
CENTER | MIDDLE));
TargetChange();
}
SkinPartPtr FilterTargetButtons::getTargetNormalIcon() const
SkinPartPtr FilterTargetButtons::getCelsIcon() const
{
SkinTheme* theme = SkinTheme::instance();
@ -198,20 +144,4 @@ SkinPartPtr FilterTargetButtons::getTargetNormalIcon() const
}
}
SkinPartPtr FilterTargetButtons::getTargetSelectedIcon() const
{
SkinTheme* theme = SkinTheme::instance();
if (m_target & TARGET_ALL_FRAMES) {
return (m_target & TARGET_ALL_LAYERS) ?
theme->parts.targetFramesLayersSelected():
theme->parts.targetFramesSelected();
}
else {
return (m_target & TARGET_ALL_LAYERS) ?
theme->parts.targetLayersSelected():
theme->parts.targetOneSelected();
}
}
} // namespace app

View File

@ -9,10 +9,10 @@
#define APP_COMMANDS_FILTERS_FILTER_TARGET_BUTTONS_H_INCLUDED
#pragma once
#include "app/ui/button_set.h"
#include "app/ui/skin/skin_part.h"
#include "base/signal.h"
#include "filters/target.h"
#include "ui/box.h"
namespace ui {
class ButtonBase;
@ -21,7 +21,7 @@ namespace ui {
namespace app {
using namespace filters;
class FilterTargetButtons : public ui::Box {
class FilterTargetButtons : public ButtonSet {
public:
// Creates a new button to handle "targets" to apply some filter in
// the a sprite.
@ -33,15 +33,22 @@ namespace app {
Signal0<void> TargetChange;
protected:
void onItemChange() override;
void onChannelChange(ui::ButtonBase* button);
void onImagesChange(ui::ButtonBase* button);
private:
void selectTargetButton(const char* name, Target specificTarget);
skin::SkinPartPtr getTargetNormalIcon() const;
skin::SkinPartPtr getTargetSelectedIcon() const;
void selectTargetButton(Item* item, Target specificTarget);
skin::SkinPartPtr getCelsIcon() const;
Target m_target;
Item* m_red;
Item* m_green;
Item* m_blue;
Item* m_alpha;
Item* m_gray;
Item* m_index;
Item* m_cels;
};
} // namespace app

View File

@ -78,8 +78,10 @@ void ButtonSet::Item::onPaint(ui::PaintEvent& ev)
CENTER | (hasText() ? BOTTOM: MIDDLE),
iconSize.w, iconSize.h);
textRc.y -= 1*guiscale();
iconRc.y -= 1*guiscale();
if (m_icon) {
textRc.y -= 1*guiscale();
iconRc.y -= 1*guiscale();
}
if (!gfx::is_transparent(getBgColor()))
g->fillRect(getBgColor(), g->getClipBounds());
@ -105,8 +107,8 @@ void ButtonSet::Item::onPaint(ui::PaintEvent& ev)
}
Grid::Info info = buttonSet()->getChildInfo(this);
if (info.col < info.grid_cols-1) rc.w += 1*guiscale();
if (info.row < info.grid_rows-1) {
if (info.col+info.hspan < info.grid_cols) rc.w += 1*guiscale();
if (info.row+info.vspan < info.grid_rows) {
if (nw == theme->parts.toolbuttonHotFocused())
rc.h += 2*guiscale();
else
@ -204,8 +206,8 @@ void ButtonSet::Item::onPreferredSize(ui::PreferredSizeEvent& ev)
gfx::Size iconSize;
if (m_icon) {
iconSize = m_icon->getSize();
iconSize.w = MAX(iconSize.w, 16*guiscale());
iconSize.h = MAX(iconSize.h, 16*guiscale());
iconSize.w = MAX(iconSize.w+4*guiscale(), 16*guiscale());
iconSize.h = MAX(iconSize.h+4*guiscale(), 16*guiscale());
}
gfx::Rect boxRc;
@ -229,27 +231,31 @@ ButtonSet::ButtonSet(int columns)
: Grid(columns, false)
, m_offerCapture(true)
, m_triggerOnMouseUp(false)
, m_multipleSelection(false)
{
noBorderNoChildSpacing();
}
void ButtonSet::addItem(const std::string& text, int hspan, int vspan)
ButtonSet::Item* ButtonSet::addItem(const std::string& text, int hspan, int vspan)
{
Item* item = new Item();
item->setText(text);
addItem(item, hspan, vspan);
return item;
}
void ButtonSet::addItem(const skin::SkinPartPtr& icon, int hspan, int vspan)
ButtonSet::Item* ButtonSet::addItem(const skin::SkinPartPtr& icon, int hspan, int vspan)
{
Item* item = new Item();
item->setIcon(icon);
addItem(item, hspan, vspan);
return item;
}
void ButtonSet::addItem(Item* item, int hspan, int vspan)
ButtonSet::Item* ButtonSet::addItem(Item* item, int hspan, int vspan)
{
addChildInCell(item, hspan, vspan, HORIZONTAL | VERTICAL);
return item;
}
ButtonSet::Item* ButtonSet::getItem(int index)
@ -278,15 +284,17 @@ void ButtonSet::setSelectedItem(int index)
void ButtonSet::setSelectedItem(Item* item)
{
if (item && item->isSelected())
return;
if (!m_multipleSelection) {
if (item && item->isSelected())
return;
Item* sel = findSelectedItem();
if (sel)
sel->setSelected(false);
Item* sel = findSelectedItem();
if (sel)
sel->setSelected(false);
}
if (item) {
item->setSelected(true);
item->setSelected(!item->isSelected());
item->requestFocus();
}
}
@ -308,6 +316,11 @@ void ButtonSet::setTriggerOnMouseUp(bool state)
m_triggerOnMouseUp = state;
}
void ButtonSet::setMultipleSelection(bool state)
{
m_multipleSelection = state;
}
void ButtonSet::onItemChange()
{
ItemChange();

View File

@ -35,9 +35,9 @@ namespace app {
ButtonSet(int columns);
void addItem(const std::string& text, int hspan = 1, int vspan = 1);
void addItem(const skin::SkinPartPtr& icon, int hspan = 1, int vspan = 1);
void addItem(Item* item, int hspan = 1, int vspan = 1);
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* getItem(int index);
int selectedItem() const;
@ -47,6 +47,7 @@ namespace app {
void setOfferCapture(bool state);
void setTriggerOnMouseUp(bool state);
void setMultipleSelection(bool state);
Signal0<void> ItemChange;
Signal1<void, Item*> RightClick;
@ -60,6 +61,7 @@ namespace app {
bool m_offerCapture;
bool m_triggerOnMouseUp;
bool m_multipleSelection;
};
} // namespace app