2015-02-12 23:16:25 +08:00
|
|
|
// Aseprite
|
2017-02-07 04:58:55 +08:00
|
|
|
// Copyright (C) 2001-2017 David Capello
|
2015-02-12 23:16:25 +08:00
|
|
|
//
|
2016-08-27 04:02:58 +08:00
|
|
|
// This program is distributed under the terms of
|
|
|
|
// the End-User License Agreement for Aseprite.
|
2012-04-20 07:33:57 +08:00
|
|
|
|
2013-08-06 08:20:19 +08:00
|
|
|
#ifdef HAVE_CONFIG_H
|
2012-04-20 07:33:57 +08:00
|
|
|
#include "config.h"
|
2013-08-06 08:20:19 +08:00
|
|
|
#endif
|
2012-04-20 07:33:57 +08:00
|
|
|
|
2013-08-06 08:20:19 +08:00
|
|
|
#include "app/ui/button_set.h"
|
2014-09-08 13:27:41 +08:00
|
|
|
|
2013-08-06 08:20:19 +08:00
|
|
|
#include "app/modules/gui.h"
|
2014-09-08 13:27:41 +08:00
|
|
|
#include "app/ui/skin/skin_theme.h"
|
|
|
|
#include "base/bind.h"
|
|
|
|
#include "gfx/color.h"
|
|
|
|
#include "she/surface.h"
|
2012-06-18 09:49:58 +08:00
|
|
|
#include "ui/box.h"
|
|
|
|
#include "ui/button.h"
|
2014-09-08 13:27:41 +08:00
|
|
|
#include "ui/graphics.h"
|
|
|
|
#include "ui/message.h"
|
|
|
|
#include "ui/paint_event.h"
|
2015-12-04 08:50:05 +08:00
|
|
|
#include "ui/size_hint_event.h"
|
2012-06-18 09:49:58 +08:00
|
|
|
#include "ui/system.h"
|
|
|
|
#include "ui/theme.h"
|
|
|
|
#include "ui/widget.h"
|
2013-08-06 08:20:19 +08:00
|
|
|
|
2014-09-08 13:27:41 +08:00
|
|
|
#include <cstdarg>
|
|
|
|
|
2013-08-06 08:20:19 +08:00
|
|
|
namespace app {
|
2012-04-20 07:33:57 +08:00
|
|
|
|
2012-06-18 09:02:54 +08:00
|
|
|
using namespace ui;
|
2014-09-08 13:27:41 +08:00
|
|
|
using namespace app::skin;
|
2012-06-18 09:02:54 +08:00
|
|
|
|
2015-12-17 03:55:49 +08:00
|
|
|
// Last selected item for ButtonSet activated on mouse up when the
|
|
|
|
// mouse capture is get.
|
|
|
|
static int g_itemBeforeCapture = -1;
|
|
|
|
|
2014-09-08 13:27:41 +08:00
|
|
|
WidgetType buttonset_item_type()
|
2012-04-20 07:33:57 +08:00
|
|
|
{
|
2014-09-08 13:27:41 +08:00
|
|
|
static WidgetType type = kGenericWidget;
|
|
|
|
if (type == kGenericWidget)
|
|
|
|
type = register_widget_type();
|
|
|
|
return type;
|
|
|
|
}
|
2012-04-20 07:33:57 +08:00
|
|
|
|
2014-09-08 13:27:41 +08:00
|
|
|
ButtonSet::Item::Item()
|
|
|
|
: Widget(buttonset_item_type())
|
|
|
|
, m_icon(NULL)
|
|
|
|
{
|
2015-05-21 23:28:21 +08:00
|
|
|
setup_mini_font(this);
|
2015-08-12 23:38:07 +08:00
|
|
|
setAlign(CENTER | MIDDLE);
|
|
|
|
setFocusStop(true);
|
2014-09-08 13:27:41 +08:00
|
|
|
}
|
2012-04-20 07:33:57 +08:00
|
|
|
|
2015-12-16 04:12:11 +08:00
|
|
|
void ButtonSet::Item::setIcon(const SkinPartPtr& icon, bool mono)
|
2012-04-20 07:33:57 +08:00
|
|
|
{
|
2014-09-08 13:27:41 +08:00
|
|
|
m_icon = icon;
|
2015-12-16 04:12:11 +08:00
|
|
|
m_mono = mono;
|
2014-09-08 13:27:41 +08:00
|
|
|
invalidate();
|
|
|
|
}
|
2012-04-20 07:33:57 +08:00
|
|
|
|
2014-09-08 13:27:41 +08:00
|
|
|
ButtonSet* ButtonSet::Item::buttonSet()
|
|
|
|
{
|
Refactor several "getNoun()" getters to "noun()"
This is a work-in-progress to create a consistent API and finally
separate the whole Aseprite base/gfx/ui libs into a reusable C++ library.
Classes:
app::IFileItem, app::AppMenuItem, app::skin::SkinPart,
gfx::Rect, gfx::Border, she::FileDialog,
ui::IButtonIcon, ui::Graphics, ui::Overlay, ui::Widget,
ui::ScrollableViewDelegate, and UI events
2015-12-05 01:39:04 +08:00
|
|
|
return static_cast<ButtonSet*>(parent());
|
2014-09-08 13:27:41 +08:00
|
|
|
}
|
2012-04-20 07:33:57 +08:00
|
|
|
|
2014-09-08 13:27:41 +08:00
|
|
|
void ButtonSet::Item::onPaint(ui::PaintEvent& ev)
|
|
|
|
{
|
Refactor several "getNoun()" getters to "noun()"
This is a work-in-progress to create a consistent API and finally
separate the whole Aseprite base/gfx/ui libs into a reusable C++ library.
Classes:
app::IFileItem, app::AppMenuItem, app::skin::SkinPart,
gfx::Rect, gfx::Border, she::FileDialog,
ui::IButtonIcon, ui::Graphics, ui::Overlay, ui::Widget,
ui::ScrollableViewDelegate, and UI events
2015-12-05 01:39:04 +08:00
|
|
|
SkinTheme* theme = static_cast<SkinTheme*>(this->theme());
|
|
|
|
Graphics* g = ev.graphics();
|
|
|
|
gfx::Rect rc = clientBounds();
|
2015-05-21 23:28:21 +08:00
|
|
|
gfx::Color fg, bg;
|
2015-08-05 06:38:52 +08:00
|
|
|
SkinPartPtr nw;
|
2015-08-12 23:38:07 +08:00
|
|
|
gfx::Rect boxRc, textRc, iconRc;
|
|
|
|
gfx::Size iconSize;
|
|
|
|
if (m_icon)
|
Refactor several "getNoun()" getters to "noun()"
This is a work-in-progress to create a consistent API and finally
separate the whole Aseprite base/gfx/ui libs into a reusable C++ library.
Classes:
app::IFileItem, app::AppMenuItem, app::skin::SkinPart,
gfx::Rect, gfx::Border, she::FileDialog,
ui::IButtonIcon, ui::Graphics, ui::Overlay, ui::Widget,
ui::ScrollableViewDelegate, and UI events
2015-12-05 01:39:04 +08:00
|
|
|
iconSize = m_icon->size();
|
2015-08-12 23:38:07 +08:00
|
|
|
|
|
|
|
getTextIconInfo(
|
|
|
|
&boxRc, &textRc, &iconRc,
|
|
|
|
CENTER | (hasText() ? BOTTOM: MIDDLE),
|
|
|
|
iconSize.w, iconSize.h);
|
|
|
|
|
2015-08-29 02:48:19 +08:00
|
|
|
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) {
|
2015-08-29 01:37:00 +08:00
|
|
|
textRc.y -= 1*guiscale();
|
|
|
|
iconRc.y -= 1*guiscale();
|
|
|
|
}
|
2014-09-08 13:27:41 +08:00
|
|
|
|
Refactor several "getNoun()" getters to "noun()"
This is a work-in-progress to create a consistent API and finally
separate the whole Aseprite base/gfx/ui libs into a reusable C++ library.
Classes:
app::IFileItem, app::AppMenuItem, app::skin::SkinPart,
gfx::Rect, gfx::Border, she::FileDialog,
ui::IButtonIcon, ui::Graphics, ui::Overlay, ui::Widget,
ui::ScrollableViewDelegate, and UI events
2015-12-05 01:39:04 +08:00
|
|
|
if (!gfx::is_transparent(bgColor()))
|
|
|
|
g->fillRect(bgColor(), g->getClipBounds());
|
2014-09-08 13:27:41 +08:00
|
|
|
|
|
|
|
if (isSelected() || hasMouseOver()) {
|
2015-04-07 22:29:36 +08:00
|
|
|
if (hasCapture()) {
|
2015-08-05 06:38:52 +08:00
|
|
|
nw = theme->parts.toolbuttonPushed();
|
2015-05-21 23:28:21 +08:00
|
|
|
fg = theme->colors.buttonSelectedText();
|
|
|
|
bg = theme->colors.buttonSelectedFace();
|
2015-04-07 22:29:36 +08:00
|
|
|
}
|
|
|
|
else {
|
2015-08-12 23:38:07 +08:00
|
|
|
nw = (hasFocus() ? theme->parts.toolbuttonHotFocused():
|
|
|
|
theme->parts.toolbuttonHot());
|
2015-05-21 23:28:21 +08:00
|
|
|
fg = theme->colors.buttonHotText();
|
|
|
|
bg = theme->colors.buttonHotFace();
|
2015-04-07 22:29:36 +08:00
|
|
|
}
|
2014-09-08 13:27:41 +08:00
|
|
|
}
|
|
|
|
else {
|
2015-08-12 23:38:07 +08:00
|
|
|
nw = (hasFocus() ? theme->parts.toolbuttonFocused():
|
|
|
|
theme->parts.toolbuttonLast());
|
2015-05-21 23:28:21 +08:00
|
|
|
fg = theme->colors.buttonNormalText();
|
|
|
|
bg = theme->colors.buttonNormalFace();
|
2014-09-08 13:27:41 +08:00
|
|
|
}
|
2012-04-20 07:33:57 +08:00
|
|
|
|
2015-08-29 02:48:19 +08:00
|
|
|
if (!isLastCol)
|
|
|
|
rc.w += 1*guiscale();
|
|
|
|
|
|
|
|
if (!isLastRow) {
|
2015-08-13 01:37:58 +08:00
|
|
|
if (nw == theme->parts.toolbuttonHotFocused())
|
|
|
|
rc.h += 2*guiscale();
|
|
|
|
else
|
|
|
|
rc.h += 3*guiscale();
|
|
|
|
}
|
2012-04-20 07:33:57 +08:00
|
|
|
|
2015-08-05 06:38:52 +08:00
|
|
|
theme->drawRect(g, rc, nw.get(), bg);
|
2012-04-20 07:33:57 +08:00
|
|
|
|
2014-09-08 13:27:41 +08:00
|
|
|
if (m_icon) {
|
2015-12-16 04:12:11 +08:00
|
|
|
she::Surface* bmp = m_icon->bitmap(0);
|
|
|
|
|
2015-04-07 22:29:36 +08:00
|
|
|
if (isSelected() && hasCapture())
|
2015-12-16 04:12:11 +08:00
|
|
|
g->drawColoredRgbaSurface(bmp, theme->colors.buttonSelectedText(),
|
|
|
|
iconRc.x, iconRc.y);
|
|
|
|
else if (m_mono)
|
|
|
|
g->drawColoredRgbaSurface(bmp, theme->colors.buttonNormalText(),
|
2015-08-12 23:38:07 +08:00
|
|
|
iconRc.x, iconRc.y);
|
2015-04-07 22:29:36 +08:00
|
|
|
else
|
2015-12-16 04:12:11 +08:00
|
|
|
g->drawRgbaSurface(bmp, iconRc.x, iconRc.y);
|
2014-09-08 13:27:41 +08:00
|
|
|
}
|
2015-05-21 23:28:21 +08:00
|
|
|
|
2015-08-12 23:38:07 +08:00
|
|
|
if (hasText()) {
|
Refactor several "getNoun()" getters to "noun()"
This is a work-in-progress to create a consistent API and finally
separate the whole Aseprite base/gfx/ui libs into a reusable C++ library.
Classes:
app::IFileItem, app::AppMenuItem, app::skin::SkinPart,
gfx::Rect, gfx::Border, she::FileDialog,
ui::IButtonIcon, ui::Graphics, ui::Overlay, ui::Widget,
ui::ScrollableViewDelegate, and UI events
2015-12-05 01:39:04 +08:00
|
|
|
g->setFont(font());
|
2017-02-07 04:58:55 +08:00
|
|
|
g->drawUIText(text(), fg, gfx::ColorNone, textRc.origin(),
|
|
|
|
false);
|
2015-05-21 23:28:21 +08:00
|
|
|
}
|
2014-09-08 13:27:41 +08:00
|
|
|
}
|
2012-04-20 07:33:57 +08:00
|
|
|
|
2014-09-08 13:27:41 +08:00
|
|
|
bool ButtonSet::Item::onProcessMessage(ui::Message* msg)
|
|
|
|
{
|
|
|
|
switch (msg->type()) {
|
|
|
|
|
2015-08-12 23:38:07 +08:00
|
|
|
case kFocusEnterMessage:
|
|
|
|
case kFocusLeaveMessage:
|
|
|
|
if (isEnabled()) {
|
|
|
|
// TODO theme specific stuff
|
|
|
|
invalidate();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ui::kKeyDownMessage:
|
|
|
|
if (isEnabled() && hasText()) {
|
|
|
|
KeyMessage* keymsg = static_cast<KeyMessage*>(msg);
|
2016-11-25 06:26:21 +08:00
|
|
|
bool mnemonicPressed = (msg->altPressed() &&
|
|
|
|
mnemonicCharPressed(keymsg));
|
2015-08-12 23:38:07 +08:00
|
|
|
|
|
|
|
if (mnemonicPressed ||
|
|
|
|
(hasFocus() && keymsg->scancode() == kKeySpace)) {
|
|
|
|
buttonSet()->setSelectedItem(this);
|
2015-12-16 04:12:11 +08:00
|
|
|
onClick();
|
2015-08-12 23:38:07 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2014-09-08 13:27:41 +08:00
|
|
|
case ui::kMouseDownMessage:
|
2015-12-17 03:55:49 +08:00
|
|
|
// 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
|
|
|
|
// and the mouse capture if offered to other ButtonSet.
|
|
|
|
if (buttonSet()->m_triggerOnMouseUp) {
|
|
|
|
ASSERT(g_itemBeforeCapture < 0);
|
|
|
|
g_itemBeforeCapture = buttonSet()->selectedItem();
|
|
|
|
}
|
|
|
|
|
2014-09-08 13:27:41 +08:00
|
|
|
captureMouse();
|
|
|
|
buttonSet()->setSelectedItem(this);
|
2015-04-07 22:29:36 +08:00
|
|
|
invalidate();
|
|
|
|
|
2015-05-08 06:08:24 +08:00
|
|
|
if (static_cast<MouseMessage*>(msg)->left() &&
|
|
|
|
!buttonSet()->m_triggerOnMouseUp) {
|
2015-12-16 04:12:11 +08:00
|
|
|
onClick();
|
2015-05-08 06:08:24 +08:00
|
|
|
}
|
2014-09-08 13:27:41 +08:00
|
|
|
break;
|
|
|
|
|
|
|
|
case ui::kMouseUpMessage:
|
2015-04-07 13:29:33 +08:00
|
|
|
if (hasCapture()) {
|
2015-12-17 03:55:49 +08:00
|
|
|
if (g_itemBeforeCapture >= 0)
|
|
|
|
g_itemBeforeCapture = -1;
|
|
|
|
|
2014-09-08 13:27:41 +08:00
|
|
|
releaseMouse();
|
2015-04-07 22:29:36 +08:00
|
|
|
invalidate();
|
|
|
|
|
2015-05-08 06:08:24 +08:00
|
|
|
if (static_cast<MouseMessage*>(msg)->left()) {
|
|
|
|
if (buttonSet()->m_triggerOnMouseUp)
|
2015-12-16 04:12:11 +08:00
|
|
|
onClick();
|
2015-05-08 06:08:24 +08:00
|
|
|
}
|
|
|
|
else if (static_cast<MouseMessage*>(msg)->right()) {
|
2015-12-16 04:12:11 +08:00
|
|
|
onRightClick();
|
2015-05-08 06:08:24 +08:00
|
|
|
}
|
2015-04-07 13:29:33 +08:00
|
|
|
}
|
2014-09-08 13:27:41 +08:00
|
|
|
break;
|
|
|
|
|
|
|
|
case ui::kMouseMoveMessage:
|
|
|
|
if (hasCapture()) {
|
2015-12-17 03:55:49 +08:00
|
|
|
if (buttonSet()->m_offerCapture) {
|
|
|
|
if (offerCapture(static_cast<ui::MouseMessage*>(msg), buttonset_item_type())) {
|
|
|
|
// Only for ButtonSets trigerred on mouse up.
|
|
|
|
if (buttonSet()->m_triggerOnMouseUp &&
|
|
|
|
g_itemBeforeCapture >= 0) {
|
|
|
|
// As we never received a kMouseUpMessage (so we never
|
|
|
|
// called onClick()), we have to restore the selected
|
|
|
|
// item at the point when we received the mouse capture.
|
|
|
|
buttonSet()->setSelectedItem(g_itemBeforeCapture);
|
|
|
|
g_itemBeforeCapture = -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2014-09-08 13:27:41 +08:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ui::kMouseLeaveMessage:
|
|
|
|
case ui::kMouseEnterMessage:
|
|
|
|
invalidate();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return Widget::onProcessMessage(msg);
|
|
|
|
}
|
2012-04-20 07:33:57 +08:00
|
|
|
|
2015-12-04 08:50:05 +08:00
|
|
|
void ButtonSet::Item::onSizeHint(ui::SizeHintEvent& ev)
|
2014-09-08 13:27:41 +08:00
|
|
|
{
|
2015-08-12 23:38:07 +08:00
|
|
|
gfx::Size iconSize;
|
2015-05-21 23:28:21 +08:00
|
|
|
if (m_icon) {
|
Refactor several "getNoun()" getters to "noun()"
This is a work-in-progress to create a consistent API and finally
separate the whole Aseprite base/gfx/ui libs into a reusable C++ library.
Classes:
app::IFileItem, app::AppMenuItem, app::skin::SkinPart,
gfx::Rect, gfx::Border, she::FileDialog,
ui::IButtonIcon, ui::Graphics, ui::Overlay, ui::Widget,
ui::ScrollableViewDelegate, and UI events
2015-12-05 01:39:04 +08:00
|
|
|
iconSize = m_icon->size();
|
2015-08-29 02:48:19 +08:00
|
|
|
iconSize.w = MAX(iconSize.w, 16*guiscale());
|
|
|
|
iconSize.h = MAX(iconSize.h, 16*guiscale());
|
2015-05-21 23:28:21 +08:00
|
|
|
}
|
2015-08-12 23:38:07 +08:00
|
|
|
|
|
|
|
gfx::Rect boxRc;
|
|
|
|
getTextIconInfo(
|
|
|
|
&boxRc, NULL, NULL,
|
|
|
|
CENTER | (hasText() ? BOTTOM: MIDDLE),
|
|
|
|
iconSize.w, iconSize.h);
|
|
|
|
|
Refactor several "getNoun()" getters to "noun()"
This is a work-in-progress to create a consistent API and finally
separate the whole Aseprite base/gfx/ui libs into a reusable C++ library.
Classes:
app::IFileItem, app::AppMenuItem, app::skin::SkinPart,
gfx::Rect, gfx::Border, she::FileDialog,
ui::IButtonIcon, ui::Graphics, ui::Overlay, ui::Widget,
ui::ScrollableViewDelegate, and UI events
2015-12-05 01:39:04 +08:00
|
|
|
gfx::Size sz = boxRc.size();
|
2015-08-12 23:38:07 +08:00
|
|
|
if (hasText())
|
|
|
|
sz += 8*guiscale();
|
2012-04-20 07:33:57 +08:00
|
|
|
|
2014-09-08 13:27:41 +08:00
|
|
|
Grid::Info info = buttonSet()->getChildInfo(this);
|
|
|
|
if (info.row == info.grid_rows-1)
|
2015-04-30 04:16:48 +08:00
|
|
|
sz.h += 3*guiscale();
|
2012-04-20 07:33:57 +08:00
|
|
|
|
2015-12-04 08:50:05 +08:00
|
|
|
ev.setSizeHint(sz);
|
2014-09-08 13:27:41 +08:00
|
|
|
}
|
2012-04-20 07:33:57 +08:00
|
|
|
|
2015-12-16 04:12:11 +08:00
|
|
|
void ButtonSet::Item::onClick()
|
|
|
|
{
|
|
|
|
buttonSet()->onItemChange(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ButtonSet::Item::onRightClick()
|
|
|
|
{
|
|
|
|
buttonSet()->onRightClick(this);
|
|
|
|
}
|
|
|
|
|
2014-09-08 13:27:41 +08:00
|
|
|
ButtonSet::ButtonSet(int columns)
|
|
|
|
: Grid(columns, false)
|
|
|
|
, m_offerCapture(true)
|
2015-04-07 13:29:33 +08:00
|
|
|
, m_triggerOnMouseUp(false)
|
2015-08-29 01:37:00 +08:00
|
|
|
, m_multipleSelection(false)
|
2014-09-08 13:27:41 +08:00
|
|
|
{
|
|
|
|
noBorderNoChildSpacing();
|
|
|
|
}
|
2012-04-20 07:33:57 +08:00
|
|
|
|
2015-08-29 01:37:00 +08:00
|
|
|
ButtonSet::Item* ButtonSet::addItem(const std::string& text, int hspan, int vspan)
|
2015-05-21 23:28:21 +08:00
|
|
|
{
|
|
|
|
Item* item = new Item();
|
|
|
|
item->setText(text);
|
|
|
|
addItem(item, hspan, vspan);
|
2015-08-29 01:37:00 +08:00
|
|
|
return item;
|
2015-05-21 23:28:21 +08:00
|
|
|
}
|
|
|
|
|
2015-08-29 01:37:00 +08:00
|
|
|
ButtonSet::Item* ButtonSet::addItem(const skin::SkinPartPtr& icon, int hspan, int vspan)
|
2014-09-08 13:27:41 +08:00
|
|
|
{
|
|
|
|
Item* item = new Item();
|
|
|
|
item->setIcon(icon);
|
2015-04-29 23:32:44 +08:00
|
|
|
addItem(item, hspan, vspan);
|
2015-08-29 01:37:00 +08:00
|
|
|
return item;
|
2015-04-29 23:32:44 +08:00
|
|
|
}
|
|
|
|
|
2015-08-29 01:37:00 +08:00
|
|
|
ButtonSet::Item* ButtonSet::addItem(Item* item, int hspan, int vspan)
|
2015-04-29 23:32:44 +08:00
|
|
|
{
|
2015-08-12 23:38:07 +08:00
|
|
|
addChildInCell(item, hspan, vspan, HORIZONTAL | VERTICAL);
|
2015-08-29 01:37:00 +08:00
|
|
|
return item;
|
2014-09-08 13:27:41 +08:00
|
|
|
}
|
2012-04-20 07:33:57 +08:00
|
|
|
|
2014-09-08 13:27:41 +08:00
|
|
|
ButtonSet::Item* ButtonSet::getItem(int index)
|
|
|
|
{
|
|
|
|
return dynamic_cast<Item*>(at(index));
|
|
|
|
}
|
2012-04-20 07:33:57 +08:00
|
|
|
|
2014-09-08 13:27:41 +08:00
|
|
|
int ButtonSet::selectedItem() const
|
|
|
|
{
|
|
|
|
int index = 0;
|
2015-12-04 06:46:13 +08:00
|
|
|
for (Widget* child : children()) {
|
2014-09-08 13:27:41 +08:00
|
|
|
if (child->isSelected())
|
|
|
|
return index;
|
|
|
|
++index;
|
2012-04-20 07:33:57 +08:00
|
|
|
}
|
2014-09-08 13:27:41 +08:00
|
|
|
return -1;
|
2012-04-20 07:33:57 +08:00
|
|
|
}
|
|
|
|
|
2016-05-02 23:25:51 +08:00
|
|
|
void ButtonSet::setSelectedItem(int index, bool focusItem)
|
2012-04-20 07:33:57 +08:00
|
|
|
{
|
2015-12-04 06:46:13 +08:00
|
|
|
if (index >= 0 && index < (int)children().size())
|
2016-05-02 23:25:51 +08:00
|
|
|
setSelectedItem(static_cast<Item*>(at(index)), focusItem);
|
2012-04-20 07:33:57 +08:00
|
|
|
else
|
2016-05-02 23:25:51 +08:00
|
|
|
setSelectedItem(static_cast<Item*>(nullptr), focusItem);
|
2012-04-20 07:33:57 +08:00
|
|
|
}
|
|
|
|
|
2016-05-02 23:25:51 +08:00
|
|
|
void ButtonSet::setSelectedItem(Item* item, bool focusItem)
|
2012-04-20 07:33:57 +08:00
|
|
|
{
|
2015-08-29 01:37:00 +08:00
|
|
|
if (!m_multipleSelection) {
|
|
|
|
if (item && item->isSelected())
|
|
|
|
return;
|
2012-04-20 07:33:57 +08:00
|
|
|
|
2015-08-29 01:37:00 +08:00
|
|
|
Item* sel = findSelectedItem();
|
|
|
|
if (sel)
|
|
|
|
sel->setSelected(false);
|
|
|
|
}
|
2014-09-08 13:27:41 +08:00
|
|
|
|
2015-08-12 23:38:07 +08:00
|
|
|
if (item) {
|
2015-08-29 01:37:00 +08:00
|
|
|
item->setSelected(!item->isSelected());
|
2016-05-02 23:25:51 +08:00
|
|
|
if (focusItem)
|
|
|
|
item->requestFocus();
|
2015-08-12 23:38:07 +08:00
|
|
|
}
|
2012-04-20 07:33:57 +08:00
|
|
|
}
|
|
|
|
|
2014-05-26 10:57:51 +08:00
|
|
|
void ButtonSet::deselectItems()
|
|
|
|
{
|
|
|
|
Item* sel = findSelectedItem();
|
|
|
|
if (sel)
|
|
|
|
sel->setSelected(false);
|
|
|
|
}
|
|
|
|
|
2014-09-08 13:27:41 +08:00
|
|
|
void ButtonSet::setOfferCapture(bool state)
|
2014-01-26 04:58:29 +08:00
|
|
|
{
|
2014-09-08 13:27:41 +08:00
|
|
|
m_offerCapture = state;
|
2014-01-26 04:58:29 +08:00
|
|
|
}
|
|
|
|
|
2015-04-07 13:29:33 +08:00
|
|
|
void ButtonSet::setTriggerOnMouseUp(bool state)
|
|
|
|
{
|
|
|
|
m_triggerOnMouseUp = state;
|
|
|
|
}
|
|
|
|
|
2015-08-29 01:37:00 +08:00
|
|
|
void ButtonSet::setMultipleSelection(bool state)
|
|
|
|
{
|
|
|
|
m_multipleSelection = state;
|
|
|
|
}
|
|
|
|
|
2015-08-29 02:41:02 +08:00
|
|
|
void ButtonSet::onItemChange(Item* item)
|
2012-04-20 07:33:57 +08:00
|
|
|
{
|
2015-08-29 02:41:02 +08:00
|
|
|
ItemChange(item);
|
2012-04-20 07:33:57 +08:00
|
|
|
}
|
|
|
|
|
2015-05-08 06:08:24 +08:00
|
|
|
void ButtonSet::onRightClick(Item* item)
|
|
|
|
{
|
|
|
|
RightClick(item);
|
|
|
|
}
|
|
|
|
|
2014-09-08 13:27:41 +08:00
|
|
|
ButtonSet::Item* ButtonSet::findSelectedItem() const
|
2012-04-20 07:33:57 +08:00
|
|
|
{
|
2015-12-04 06:46:13 +08:00
|
|
|
for (auto child : children()) {
|
2014-09-08 13:27:41 +08:00
|
|
|
if (child->isSelected())
|
|
|
|
return static_cast<Item*>(child);
|
|
|
|
}
|
2015-12-04 06:46:13 +08:00
|
|
|
return nullptr;
|
2012-04-20 07:33:57 +08:00
|
|
|
}
|
2015-02-12 23:16:25 +08:00
|
|
|
|
2013-08-06 08:20:19 +08:00
|
|
|
} // namespace app
|