mirror of
https://github.com/aseprite/aseprite.git
synced 2025-03-23 04:20:56 +00:00
New Style class in "ui" layer to paint widgets (only button at this moment)
This new ui::Style should finally replace the old app::skin::SkinStyle class. At this moment both implementations are working to avoid an huge refactor in just one commit. - Added new ui::Style property in ui::Widget. - Removed old code to set the button "bevel" (removed app::setup_bevels() functions). - Removed setup_look() function and Left/RightButtonLooks. - Removed check_button_new() function. - Removed ui::Theme::paintButton/ComboBoxButton() functions.
This commit is contained in:
parent
75020d9405
commit
bb4faca1d1
@ -898,4 +898,91 @@
|
|||||||
|
|
||||||
</stylesheet>
|
</stylesheet>
|
||||||
|
|
||||||
|
<styles>
|
||||||
|
|
||||||
|
<style id="button">
|
||||||
|
<background part="button_normal" />
|
||||||
|
<background part="button_hot" state="mouse" />
|
||||||
|
<background part="button_focused" state="focus" />
|
||||||
|
<background part="button_selected" state="selected" />
|
||||||
|
<text color="button_normal_text" />
|
||||||
|
<text color="button_hot_text" state="mouse" />
|
||||||
|
<text color="button_selected_text" state="selected" />
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style id="mini_button">
|
||||||
|
<background part="toolbutton_last" />
|
||||||
|
<background part="toolbutton_hot" state="mouse" />
|
||||||
|
<background part="toolbutton_hot" state="focus" />
|
||||||
|
<background part="toolbutton_pushed" state="selected" />
|
||||||
|
<text color="button_normal_text" />
|
||||||
|
<text color="button_hot_text" state="mouse" />
|
||||||
|
<text color="button_selected_text" state="selected" />
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style id="combobox_button" extends="mini_button">
|
||||||
|
<icon part="combobox_arrow_down" />
|
||||||
|
<icon part="combobox_arrow_down_selected" state="selected" />
|
||||||
|
<icon part="combobox_arrow_down_disabled" state="disabled" />
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style id="drop_down_button" extends="button">
|
||||||
|
<background part="drop_down_button_left_normal" />
|
||||||
|
<background part="drop_down_button_left_selected" state="selected" />
|
||||||
|
<background part="drop_down_button_left_hot" state="mouse" />
|
||||||
|
<background part="drop_down_button_left_focused" state="focus" />
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style id="drop_down_expand_button" extends="button">
|
||||||
|
<background part="drop_down_button_right_normal" />
|
||||||
|
<background part="drop_down_button_right_selected" state="selected" />
|
||||||
|
<background part="drop_down_button_right_hot" state="mouse" />
|
||||||
|
<background part="drop_down_button_right_focused" state="focus" />
|
||||||
|
<icon part="combobox_arrow_down" />
|
||||||
|
<icon part="combobox_arrow_down_selected" state="selected" />
|
||||||
|
<icon part="combobox_arrow_down_disabled" state="disabled" />
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style id="go_back_button" extends="mini_button">
|
||||||
|
<icon part="combobox_arrow_left" />
|
||||||
|
<icon part="combobox_arrow_left_selected" state="selected" />
|
||||||
|
<icon part="combobox_arrow_left_disabled" state="disabled" />
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style id="go_forward_button" extends="mini_button">
|
||||||
|
<icon part="combobox_arrow_right" />
|
||||||
|
<icon part="combobox_arrow_right_selected" state="selected" />
|
||||||
|
<icon part="combobox_arrow_right_disabled" state="disabled" />
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style id="go_up_button" extends="mini_button">
|
||||||
|
<icon part="combobox_arrow_up" />
|
||||||
|
<icon part="combobox_arrow_up_selected" state="selected" />
|
||||||
|
<icon part="combobox_arrow_up_disabled" state="disabled" />
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style id="new_folder_button" extends="mini_button">
|
||||||
|
<icon part="newfolder" />
|
||||||
|
<icon part="newfolder_selected" state="selected" />
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style id="color_wheel_options" border="1">
|
||||||
|
<background color="editor_face" />
|
||||||
|
<background color="check_hot_face" state="mouse" />
|
||||||
|
<background color="check_hot_face" state="selected" />
|
||||||
|
<icon part="pal_options" />
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style id="recover_sprites_button" extends="button"
|
||||||
|
border="0" padding="8">
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style id="new_frame_button" extends="mini_button">
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style id="color_button" extends="mini_button" border="5">
|
||||||
|
</style>
|
||||||
|
|
||||||
|
</styles>
|
||||||
|
|
||||||
</theme>
|
</theme>
|
||||||
|
@ -1,23 +1,23 @@
|
|||||||
<!-- Aseprite -->
|
<!-- Aseprite -->
|
||||||
<!-- Copyright (C) 2001-2016 by David Capello -->
|
<!-- Copyright (C) 2001-2017 by David Capello -->
|
||||||
<gui>
|
<gui>
|
||||||
<window id="file_selector" text="">
|
<window id="file_selector" text="">
|
||||||
<vbox id="main">
|
<vbox id="main">
|
||||||
<box horizontal="true">
|
<box horizontal="true">
|
||||||
<box horizontal="true" noborders="true">
|
<box horizontal="true" noborders="true">
|
||||||
<button text="" id="go_back_button" bevel="2 0 2 0" tooltip="@file_selector.go_back_button_tooltip" />
|
<button text="" id="go_back_button" style="go_back_button" tooltip="@.go_back_button_tooltip" />
|
||||||
<button text="" id="go_forward_button" bevel="0 2 0 2" tooltip="@file_selector.go_forward_button_tooltip" />
|
<button text="" id="go_forward_button" style="go_forward_button" tooltip="@.go_forward_button_tooltip" />
|
||||||
</box>
|
</box>
|
||||||
<button text="" id="go_up_button" tooltip="@file_selector.go_up_button_tooltip" />
|
<button text="" id="go_up_button" style="go_up_button" tooltip="@.go_up_button_tooltip" />
|
||||||
<button text="" id="new_folder_button" tooltip="@file_selector.new_folder_button_tooltip" />
|
<button text="" id="new_folder_button" style="new_folder_button" tooltip="@.new_folder_button_tooltip" />
|
||||||
<combobox id="location" expansive="true" />
|
<combobox id="location" expansive="true" />
|
||||||
</box>
|
</box>
|
||||||
<vbox id="file_view_placeholder" expansive="true" />
|
<vbox id="file_view_placeholder" expansive="true" />
|
||||||
<grid columns="2">
|
<grid columns="2">
|
||||||
<label text="@file_selector.file_name" />
|
<label text="@.file_name" />
|
||||||
<box id="file_name_placeholder" cell_align="horizontal" />
|
<box id="file_name_placeholder" cell_align="horizontal" />
|
||||||
|
|
||||||
<label text="@file_selector.file_type" />
|
<label text="@.file_type" />
|
||||||
<hbox cell_align="horizontal">
|
<hbox cell_align="horizontal">
|
||||||
<combobox id="file_type" minwidth="70" />
|
<combobox id="file_type" minwidth="70" />
|
||||||
<vbox>
|
<vbox>
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
<!-- Aseprite -->
|
<!-- Aseprite -->
|
||||||
<!-- Copyright (C) 2001-2016 by David Capello -->
|
<!-- Copyright (C) 2001-2017 by David Capello -->
|
||||||
<gui>
|
<gui>
|
||||||
<vbox noborders="true" id="home_view" border="4" childspacing="2" expansive="true">
|
<vbox noborders="true" id="home_view" border="4" childspacing="2" expansive="true">
|
||||||
<hbox noborders="true" id="recover_sprites_placeholder">
|
<hbox noborders="true" id="recover_sprites_placeholder">
|
||||||
<boxfiller />
|
<boxfiller />
|
||||||
<button id="recover_sprites" text="@.recover" border="8" />
|
<button id="recover_sprites" text="@.recover" style="recover_sprites_button" />
|
||||||
<boxfiller />
|
<boxfiller />
|
||||||
</hbox>
|
</hbox>
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2001-2016 David Capello
|
// Copyright (C) 2001-2017 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
// the End-User License Agreement for Aseprite.
|
// the End-User License Agreement for Aseprite.
|
||||||
@ -286,41 +286,16 @@ Widget* setup_mini_font(Widget* widget)
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget* setup_mini_look(Widget* widget)
|
Widget* setup_mini_look(Widget* widget)
|
||||||
{
|
|
||||||
return setup_look(widget, MiniLook);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget* setup_look(Widget* widget, LookType lookType)
|
|
||||||
{
|
{
|
||||||
SkinPropertyPtr skinProp = get_skin_property(widget);
|
SkinPropertyPtr skinProp = get_skin_property(widget);
|
||||||
skinProp->setLook(lookType);
|
skinProp->setLook(MiniLook);
|
||||||
return widget;
|
return widget;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setup_bevels(Widget* widget, int b1, int b2, int b3, int b4)
|
|
||||||
{
|
|
||||||
SkinPropertyPtr skinProp = get_skin_property(widget);
|
|
||||||
skinProp->setUpperLeft(b1);
|
|
||||||
skinProp->setUpperRight(b2);
|
|
||||||
skinProp->setLowerLeft(b3);
|
|
||||||
skinProp->setLowerRight(b4);
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
// Button style (convert radio or check buttons and draw it like
|
// Button style (convert radio or check buttons and draw it like
|
||||||
// normal buttons)
|
// normal buttons)
|
||||||
|
|
||||||
CheckBox* check_button_new(const char *text, int b1, int b2, int b3, int b4)
|
|
||||||
{
|
|
||||||
CheckBox* widget = new CheckBox(text, kButtonWidget);
|
|
||||||
|
|
||||||
widget->setAlign(CENTER | MIDDLE);
|
|
||||||
|
|
||||||
setup_mini_look(widget);
|
|
||||||
setup_bevels(widget, b1, b2, b3, b4);
|
|
||||||
return widget;
|
|
||||||
}
|
|
||||||
|
|
||||||
void defer_invalid_rect(const gfx::Rect& rc)
|
void defer_invalid_rect(const gfx::Rect& rc)
|
||||||
{
|
{
|
||||||
if (!defered_invalid_timer)
|
if (!defered_invalid_timer)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2001-2015 David Capello
|
// Copyright (C) 2001-2017 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
// the End-User License Agreement for Aseprite.
|
// the End-User License Agreement for Aseprite.
|
||||||
@ -41,10 +41,6 @@ namespace app {
|
|||||||
|
|
||||||
ui::Widget* setup_mini_font(ui::Widget* widget);
|
ui::Widget* setup_mini_font(ui::Widget* widget);
|
||||||
ui::Widget* setup_mini_look(ui::Widget* widget);
|
ui::Widget* setup_mini_look(ui::Widget* widget);
|
||||||
ui::Widget* setup_look(ui::Widget* widget, skin::LookType lookType);
|
|
||||||
void setup_bevels(ui::Widget* widget, int b1, int b2, int b3, int b4);
|
|
||||||
|
|
||||||
ui::CheckBox* check_button_new(const char* text, int b1, int b2, int b3, int b4);
|
|
||||||
|
|
||||||
// This function can be used to reinvalidate a specific rectangle if
|
// This function can be used to reinvalidate a specific rectangle if
|
||||||
// we weren't able to validate it on a onPaint() event. E.g. Because
|
// we weren't able to validate it on a onPaint() event. E.g. Because
|
||||||
|
@ -55,6 +55,7 @@ ColorButton::ColorButton(const app::Color& color,
|
|||||||
this->setFocusStop(true);
|
this->setFocusStop(true);
|
||||||
|
|
||||||
setup_mini_font(this);
|
setup_mini_font(this);
|
||||||
|
setStyle(SkinTheme::instance()->newStyles.colorButton());
|
||||||
|
|
||||||
UIContext::instance()->add_observer(this);
|
UIContext::instance()->add_observer(this);
|
||||||
}
|
}
|
||||||
@ -160,12 +161,15 @@ bool ColorButton::onProcessMessage(Message* msg)
|
|||||||
|
|
||||||
void ColorButton::onSizeHint(SizeHintEvent& ev)
|
void ColorButton::onSizeHint(SizeHintEvent& ev)
|
||||||
{
|
{
|
||||||
|
ButtonBase::onSizeHint(ev);
|
||||||
|
|
||||||
gfx::Rect box;
|
gfx::Rect box;
|
||||||
getTextIconInfo(&box);
|
getTextIconInfo(&box);
|
||||||
box.w = 64*guiscale();
|
box.w = 64*guiscale();
|
||||||
|
|
||||||
ev.setSizeHint(box.w + border().width(),
|
gfx::Size sz = ev.sizeHint();
|
||||||
box.h + border().height());
|
sz.w = std::max(sz.w, box.w);
|
||||||
|
ev.setSizeHint(sz);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ColorButton::onPaint(PaintEvent& ev)
|
void ColorButton::onPaint(PaintEvent& ev)
|
||||||
|
@ -53,20 +53,14 @@ ColorWheel::ColorWheel()
|
|||||||
: m_discrete(Preferences::instance().colorBar.discreteWheel())
|
: m_discrete(Preferences::instance().colorBar.discreteWheel())
|
||||||
, m_colorModel((ColorModel)Preferences::instance().colorBar.wheelModel())
|
, m_colorModel((ColorModel)Preferences::instance().colorBar.wheelModel())
|
||||||
, m_harmony((Harmony)Preferences::instance().colorBar.harmony())
|
, m_harmony((Harmony)Preferences::instance().colorBar.harmony())
|
||||||
, m_options("", kButtonWidget, kButtonWidget, kCheckWidget)
|
, m_options("")
|
||||||
, m_harmonyPicked(false)
|
, m_harmonyPicked(false)
|
||||||
{
|
{
|
||||||
SkinTheme* theme = SkinTheme::instance();
|
SkinTheme* theme = SkinTheme::instance();
|
||||||
|
|
||||||
setBorder(gfx::Border(3*ui::guiscale()));
|
setBorder(gfx::Border(3*ui::guiscale()));
|
||||||
|
|
||||||
m_options.Click.connect(base::Bind<void>(&ColorWheel::onOptions, this));
|
m_options.Click.connect(base::Bind<void>(&ColorWheel::onOptions, this));
|
||||||
m_options.setBgColor(theme->colors.editorFace());
|
m_options.setStyle(theme->newStyles.colorWheelOptions());
|
||||||
m_options.setIconInterface(
|
|
||||||
new ButtonIconImpl(theme->parts.palOptions(),
|
|
||||||
theme->parts.palOptions(),
|
|
||||||
theme->parts.palOptions(),
|
|
||||||
CENTER | MIDDLE));
|
|
||||||
|
|
||||||
addChild(&m_options);
|
addChild(&m_options);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2001-2016 David Capello
|
// Copyright (C) 2001-2017 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
// the End-User License Agreement for Aseprite.
|
// the End-User License Agreement for Aseprite.
|
||||||
@ -63,7 +63,7 @@ namespace app {
|
|||||||
bool m_discrete;
|
bool m_discrete;
|
||||||
ColorModel m_colorModel;
|
ColorModel m_colorModel;
|
||||||
Harmony m_harmony;
|
Harmony m_harmony;
|
||||||
ui::ButtonBase m_options;
|
ui::Button m_options;
|
||||||
|
|
||||||
// Internal flag used to know if after pickColor() we selected an
|
// Internal flag used to know if after pickColor() we selected an
|
||||||
// harmony.
|
// harmony.
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2001-2015 David Capello
|
// Copyright (C) 2001-2017 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
// the End-User License Agreement for Aseprite.
|
// the End-User License Agreement for Aseprite.
|
||||||
@ -28,11 +28,10 @@ DropDownButton::DropDownButton(const char* text)
|
|||||||
{
|
{
|
||||||
SkinTheme* theme = SkinTheme::instance();
|
SkinTheme* theme = SkinTheme::instance();
|
||||||
|
|
||||||
setup_look(m_button, LeftButtonLook);
|
m_button->setStyle(theme->newStyles.dropDownButton());
|
||||||
setup_look(m_dropDown, RightButtonLook);
|
m_dropDown->setStyle(theme->newStyles.dropDownExpandButton());
|
||||||
|
|
||||||
m_button->setExpansive(true);
|
m_button->setExpansive(true);
|
||||||
m_button->setAlign(LEFT | MIDDLE);
|
|
||||||
m_button->Click.connect(&DropDownButton::onButtonClick, this);
|
m_button->Click.connect(&DropDownButton::onButtonClick, this);
|
||||||
m_dropDown->Click.connect(&DropDownButton::onDropDownButtonClick, this);
|
m_dropDown->Click.connect(&DropDownButton::onDropDownButtonClick, this);
|
||||||
|
|
||||||
@ -40,12 +39,6 @@ DropDownButton::DropDownButton(const char* text)
|
|||||||
addChild(m_dropDown);
|
addChild(m_dropDown);
|
||||||
|
|
||||||
setChildSpacing(0);
|
setChildSpacing(0);
|
||||||
|
|
||||||
m_dropDown->setIconInterface
|
|
||||||
(new ButtonIconImpl(theme->parts.comboboxArrowDown(),
|
|
||||||
theme->parts.comboboxArrowDownSelected(),
|
|
||||||
theme->parts.comboboxArrowDownDisabled(),
|
|
||||||
CENTER | MIDDLE));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DropDownButton::onButtonClick(Event& ev)
|
void DropDownButton::onButtonClick(Event& ev)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2001-2016 David Capello
|
// Copyright (C) 2001-2017 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
// the End-User License Agreement for Aseprite.
|
// the End-User License Agreement for Aseprite.
|
||||||
@ -313,7 +313,6 @@ FileSelector::FileSelector(FileSelectorType type, FileSelectorDelegate* delegate
|
|||||||
, m_extras(nullptr)
|
, m_extras(nullptr)
|
||||||
, m_navigationLocked(false)
|
, m_navigationLocked(false)
|
||||||
{
|
{
|
||||||
SkinTheme* theme = SkinTheme::instance();
|
|
||||||
bool withResizeOptions = (delegate && delegate->hasResizeCombobox());
|
bool withResizeOptions = (delegate && delegate->hasResizeCombobox());
|
||||||
|
|
||||||
addChild(new ArrowNavigator(this));
|
addChild(new ArrowNavigator(this));
|
||||||
@ -327,32 +326,6 @@ FileSelector::FileSelector(FileSelectorType type, FileSelectorDelegate* delegate
|
|||||||
goUpButton()->setFocusStop(false);
|
goUpButton()->setFocusStop(false);
|
||||||
newFolderButton()->setFocusStop(false);
|
newFolderButton()->setFocusStop(false);
|
||||||
|
|
||||||
goBackButton()->setIconInterface(
|
|
||||||
new ButtonIconImpl(theme->parts.comboboxArrowLeft(),
|
|
||||||
theme->parts.comboboxArrowLeftSelected(),
|
|
||||||
theme->parts.comboboxArrowLeftDisabled(),
|
|
||||||
CENTER | MIDDLE));
|
|
||||||
goForwardButton()->setIconInterface(
|
|
||||||
new ButtonIconImpl(theme->parts.comboboxArrowRight(),
|
|
||||||
theme->parts.comboboxArrowRightSelected(),
|
|
||||||
theme->parts.comboboxArrowRightDisabled(),
|
|
||||||
CENTER | MIDDLE));
|
|
||||||
goUpButton()->setIconInterface(
|
|
||||||
new ButtonIconImpl(theme->parts.comboboxArrowUp(),
|
|
||||||
theme->parts.comboboxArrowUpSelected(),
|
|
||||||
theme->parts.comboboxArrowUpDisabled(),
|
|
||||||
CENTER | MIDDLE));
|
|
||||||
newFolderButton()->setIconInterface(
|
|
||||||
new ButtonIconImpl(theme->parts.newfolder(),
|
|
||||||
theme->parts.newfolderSelected(),
|
|
||||||
theme->parts.newfolder(),
|
|
||||||
CENTER | MIDDLE));
|
|
||||||
|
|
||||||
setup_mini_look(goBackButton());
|
|
||||||
setup_mini_look(goForwardButton());
|
|
||||||
setup_mini_look(goUpButton());
|
|
||||||
setup_mini_look(newFolderButton());
|
|
||||||
|
|
||||||
m_fileList = new FileList();
|
m_fileList = new FileList();
|
||||||
m_fileList->setId("fileview");
|
m_fileList->setId("fileview");
|
||||||
m_fileName->setAssociatedFileList(m_fileList);
|
m_fileName->setAssociatedFileList(m_fileList);
|
||||||
|
@ -50,7 +50,6 @@ public:
|
|||||||
SkinTheme::instance()->parts.windowButtonSelected(),
|
SkinTheme::instance()->parts.windowButtonSelected(),
|
||||||
SkinTheme::instance()->parts.windowCenterIcon())
|
SkinTheme::instance()->parts.windowCenterIcon())
|
||||||
{
|
{
|
||||||
setup_bevels(this, 0, 0, 0, 0);
|
|
||||||
setDecorative(true);
|
setDecorative(true);
|
||||||
setSelected(true);
|
setSelected(true);
|
||||||
}
|
}
|
||||||
@ -97,7 +96,6 @@ public:
|
|||||||
, m_isPlaying(false) {
|
, m_isPlaying(false) {
|
||||||
enableFlags(CTRL_RIGHT_CLICK);
|
enableFlags(CTRL_RIGHT_CLICK);
|
||||||
setupIcons();
|
setupIcons();
|
||||||
setup_bevels(this, 0, 0, 0, 0);
|
|
||||||
setDecorative(true);
|
setDecorative(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2001-2015 David Capello
|
// Copyright (C) 2001-2017 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
// the End-User License Agreement for Aseprite.
|
// the End-User License Agreement for Aseprite.
|
||||||
@ -22,10 +22,6 @@ SkinProperty::SkinProperty()
|
|||||||
{
|
{
|
||||||
m_look = NormalLook;
|
m_look = NormalLook;
|
||||||
m_miniFont = false;
|
m_miniFont = false;
|
||||||
m_upperLeft = 0;
|
|
||||||
m_upperRight = 0;
|
|
||||||
m_lowerLeft = 0;
|
|
||||||
m_lowerRight = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SkinProperty::~SkinProperty()
|
SkinProperty::~SkinProperty()
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2001-2015 David Capello
|
// Copyright (C) 2001-2015, 2017 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
// the End-User License Agreement for Aseprite.
|
// the End-User License Agreement for Aseprite.
|
||||||
@ -22,8 +22,6 @@ namespace app {
|
|||||||
NormalLook,
|
NormalLook,
|
||||||
MiniLook,
|
MiniLook,
|
||||||
WithoutBordersLook,
|
WithoutBordersLook,
|
||||||
LeftButtonLook,
|
|
||||||
RightButtonLook,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Property to show widgets with a special look (e.g.: buttons or sliders with mini-borders)
|
// Property to show widgets with a special look (e.g.: buttons or sliders with mini-borders)
|
||||||
@ -40,23 +38,9 @@ namespace app {
|
|||||||
bool hasMiniFont() const { return m_miniFont; }
|
bool hasMiniFont() const { return m_miniFont; }
|
||||||
void setMiniFont() { m_miniFont = true; }
|
void setMiniFont() { m_miniFont = true; }
|
||||||
|
|
||||||
int getUpperLeft() const { return m_upperLeft; }
|
|
||||||
int getUpperRight() const { return m_upperRight; }
|
|
||||||
int getLowerLeft() const { return m_lowerLeft; }
|
|
||||||
int getLowerRight() const { return m_lowerRight; }
|
|
||||||
|
|
||||||
void setUpperLeft(int value) { m_upperLeft = value; }
|
|
||||||
void setUpperRight(int value) { m_upperRight = value; }
|
|
||||||
void setLowerLeft(int value) { m_lowerLeft = value; }
|
|
||||||
void setLowerRight(int value) { m_lowerRight = value; }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
LookType m_look;
|
LookType m_look;
|
||||||
bool m_miniFont;
|
bool m_miniFont;
|
||||||
int m_upperLeft;
|
|
||||||
int m_upperRight;
|
|
||||||
int m_lowerLeft;
|
|
||||||
int m_lowerRight;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef base::SharedPtr<SkinProperty> SkinPropertyPtr;
|
typedef base::SharedPtr<SkinProperty> SkinPropertyPtr;
|
||||||
|
@ -56,7 +56,6 @@ const char* SkinTheme::kThemeCloseButtonId = "theme_close_button";
|
|||||||
class WindowCloseButton : public Button {
|
class WindowCloseButton : public Button {
|
||||||
public:
|
public:
|
||||||
WindowCloseButton() : Button("") {
|
WindowCloseButton() : Button("") {
|
||||||
setup_bevels(this, 0, 0, 0, 0);
|
|
||||||
setDecorative(true);
|
setDecorative(true);
|
||||||
setId(SkinTheme::kThemeCloseButtonId);
|
setId(SkinTheme::kThemeCloseButtonId);
|
||||||
}
|
}
|
||||||
@ -422,7 +421,7 @@ void SkinTheme::loadXml(const std::string& skinId)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load styles
|
// Load old stylesheet
|
||||||
{
|
{
|
||||||
TiXmlElement* xmlStyle = handle
|
TiXmlElement* xmlStyle = handle
|
||||||
.FirstChild("theme")
|
.FirstChild("theme")
|
||||||
@ -508,6 +507,140 @@ void SkinTheme::loadXml(const std::string& skinId)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Load new styles
|
||||||
|
{
|
||||||
|
TiXmlElement* xmlStyle = handle
|
||||||
|
.FirstChild("theme")
|
||||||
|
.FirstChild("styles")
|
||||||
|
.FirstChild("style").ToElement();
|
||||||
|
while (xmlStyle) {
|
||||||
|
const char* style_id = xmlStyle->Attribute("id");
|
||||||
|
if (!style_id) {
|
||||||
|
throw base::Exception("<style> without 'id' attribute in '%s'\n",
|
||||||
|
xml_filename.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* extends_id = xmlStyle->Attribute("extends");
|
||||||
|
const ui::Style* base = nullptr;
|
||||||
|
if (extends_id)
|
||||||
|
base = m_styles[extends_id];
|
||||||
|
|
||||||
|
ui::Style* style = m_styles[style_id];
|
||||||
|
if (!style) {
|
||||||
|
m_styles[style_id] = style = new ui::Style(base);
|
||||||
|
style->setId(style_id);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
*style = ui::Style(base);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Border
|
||||||
|
{
|
||||||
|
const char* m = xmlStyle->Attribute("border");
|
||||||
|
const char* l = xmlStyle->Attribute("border-left");
|
||||||
|
const char* t = xmlStyle->Attribute("border-top");
|
||||||
|
const char* r = xmlStyle->Attribute("border-right");
|
||||||
|
const char* b = xmlStyle->Attribute("border-bottom");
|
||||||
|
gfx::Border border(-1, -1, -1, -1);
|
||||||
|
if (m || l) border.left(std::strtol(l ? l: m, nullptr, 10));
|
||||||
|
if (m || t) border.top(std::strtol(t ? t: m, nullptr, 10));
|
||||||
|
if (m || r) border.right(std::strtol(r ? r: m, nullptr, 10));
|
||||||
|
if (m || b) border.bottom(std::strtol(b ? b: m, nullptr, 10));
|
||||||
|
style->setBorder(border*guiscale());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Padding
|
||||||
|
{
|
||||||
|
const char* m = xmlStyle->Attribute("padding");
|
||||||
|
const char* l = xmlStyle->Attribute("padding-left");
|
||||||
|
const char* t = xmlStyle->Attribute("padding-top");
|
||||||
|
const char* r = xmlStyle->Attribute("padding-right");
|
||||||
|
const char* b = xmlStyle->Attribute("padding-bottom");
|
||||||
|
gfx::Border padding(-1, -1, -1, -1);
|
||||||
|
if (m || l) padding.left(std::strtol(l ? l: m, nullptr, 10));
|
||||||
|
if (m || t) padding.top(std::strtol(t ? t: m, nullptr, 10));
|
||||||
|
if (m || r) padding.right(std::strtol(r ? r: m, nullptr, 10));
|
||||||
|
if (m || b) padding.bottom(std::strtol(b ? b: m, nullptr, 10));
|
||||||
|
style->setPadding(padding*guiscale());
|
||||||
|
}
|
||||||
|
|
||||||
|
TiXmlElement* xmlLayer = xmlStyle->FirstChildElement();
|
||||||
|
while (xmlLayer) {
|
||||||
|
const std::string layerName = xmlLayer->Value();
|
||||||
|
|
||||||
|
LOG(VERBOSE) << "SKIN: Layer " << layerName
|
||||||
|
<< " for " << style_id << "\n";
|
||||||
|
|
||||||
|
ui::Style::Layer layer;
|
||||||
|
|
||||||
|
// Layer type
|
||||||
|
if (layerName == "background") {
|
||||||
|
layer.setType(ui::Style::Layer::Type::kBackground);
|
||||||
|
}
|
||||||
|
else if (layerName == "border") {
|
||||||
|
layer.setType(ui::Style::Layer::Type::kBorder);
|
||||||
|
}
|
||||||
|
else if (layerName == "icon") {
|
||||||
|
layer.setType(ui::Style::Layer::Type::kIcon);
|
||||||
|
}
|
||||||
|
else if (layerName == "text") {
|
||||||
|
layer.setType(ui::Style::Layer::Type::kText);
|
||||||
|
}
|
||||||
|
else if (layerName == "newlayer") {
|
||||||
|
layer.setType(ui::Style::Layer::Type::kNewLayer);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse state condition
|
||||||
|
const char* stateValue = xmlLayer->Attribute("state");
|
||||||
|
if (stateValue) {
|
||||||
|
std::string state(stateValue);
|
||||||
|
int flags = 0;
|
||||||
|
if (state.find("disabled") != std::string::npos) flags |= ui::Style::Layer::kDisabled;
|
||||||
|
if (state.find("selected") != std::string::npos) flags |= ui::Style::Layer::kSelected;
|
||||||
|
if (state.find("focus") != std::string::npos) flags |= ui::Style::Layer::kFocus;
|
||||||
|
if (state.find("mouse") != std::string::npos) flags |= ui::Style::Layer::kMouse;
|
||||||
|
layer.setFlags(flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Color
|
||||||
|
const char* colorId = xmlLayer->Attribute("color");
|
||||||
|
if (colorId) {
|
||||||
|
layer.setColor(getColorById(colorId));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sprite sheet
|
||||||
|
const char* partId = xmlLayer->Attribute("part");
|
||||||
|
if (partId) {
|
||||||
|
auto it = m_parts_by_id.find(partId);
|
||||||
|
if (it != m_parts_by_id.end()) {
|
||||||
|
SkinPartPtr part = it->second;
|
||||||
|
if (part) {
|
||||||
|
if (layer.type() == ui::Style::Layer::Type::kIcon)
|
||||||
|
layer.setIcon(part->bitmap(0));
|
||||||
|
else {
|
||||||
|
layer.setSpriteSheet(m_sheet);
|
||||||
|
layer.setSpriteBounds(part->spriteBounds());
|
||||||
|
layer.setSlicesBounds(part->slicesBounds());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw base::Exception("Part <%s part='%s' ...> was not found in '%s'\n",
|
||||||
|
layerName.c_str(), partId,
|
||||||
|
xml_filename.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (layer.type() != ui::Style::Layer::Type::kNone)
|
||||||
|
style->addLayer(layer);
|
||||||
|
|
||||||
|
xmlLayer = xmlLayer->NextSiblingElement();
|
||||||
|
}
|
||||||
|
|
||||||
|
xmlStyle = xmlStyle->NextSiblingElement();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ThemeFile<SkinTheme>::updateInternals();
|
ThemeFile<SkinTheme>::updateInternals();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -570,12 +703,7 @@ void SkinTheme::initWidget(Widget* widget)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case kButtonWidget:
|
case kButtonWidget:
|
||||||
BORDER4(
|
widget->setStyle(newStyles.button());
|
||||||
parts.buttonNormal()->bitmapW()->width(),
|
|
||||||
parts.buttonNormal()->bitmapN()->height(),
|
|
||||||
parts.buttonNormal()->bitmapE()->width(),
|
|
||||||
parts.buttonNormal()->bitmapS()->height());
|
|
||||||
widget->setChildSpacing(0);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case kCheckWidget:
|
case kCheckWidget:
|
||||||
@ -616,25 +744,12 @@ void SkinTheme::initWidget(Widget* widget)
|
|||||||
BORDER(1 * scale);
|
BORDER(1 * scale);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case kComboBoxWidget:
|
case kComboBoxWidget: {
|
||||||
{
|
ComboBox* combobox = static_cast<ComboBox*>(widget);
|
||||||
ComboBox* combobox = dynamic_cast<ComboBox*>(widget);
|
|
||||||
ASSERT(combobox != NULL);
|
|
||||||
|
|
||||||
Button* button = combobox->getButtonWidget();
|
Button* button = combobox->getButtonWidget();
|
||||||
|
button->setStyle(newStyles.comboboxButton());
|
||||||
button->setBorder(gfx::Border(0));
|
|
||||||
button->setChildSpacing(0);
|
|
||||||
button->setMinSize(gfx::Size(15 * guiscale(),
|
|
||||||
16 * guiscale()));
|
|
||||||
|
|
||||||
static_cast<ButtonBase*>(button)->setIconInterface
|
|
||||||
(new ButtonIconImpl(parts.comboboxArrowDown(),
|
|
||||||
parts.comboboxArrowDownSelected(),
|
|
||||||
parts.comboboxArrowDownDisabled(),
|
|
||||||
CENTER | MIDDLE));
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case kMenuWidget:
|
case kMenuWidget:
|
||||||
case kMenuBarWidget:
|
case kMenuBarWidget:
|
||||||
@ -800,79 +915,6 @@ void SkinTheme::paintBox(PaintEvent& ev)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkinTheme::paintButton(PaintEvent& ev)
|
|
||||||
{
|
|
||||||
Graphics* g = ev.graphics();
|
|
||||||
ButtonBase* widget = static_cast<ButtonBase*>(ev.getSource());
|
|
||||||
IButtonIcon* iconInterface = widget->iconInterface();
|
|
||||||
gfx::Rect box, text, icon;
|
|
||||||
gfx::Color fg;
|
|
||||||
SkinPartPtr part_nw;
|
|
||||||
|
|
||||||
widget->getTextIconInfo(&box, &text, &icon,
|
|
||||||
iconInterface ? iconInterface->iconAlign(): 0,
|
|
||||||
iconInterface ? iconInterface->size().w: 0,
|
|
||||||
iconInterface ? iconInterface->size().h: 0);
|
|
||||||
|
|
||||||
// Tool buttons are smaller
|
|
||||||
LookType look = NormalLook;
|
|
||||||
SkinPropertyPtr skinPropery = widget->getProperty(SkinProperty::Name);
|
|
||||||
if (skinPropery)
|
|
||||||
look = skinPropery->getLook();
|
|
||||||
|
|
||||||
// Selected
|
|
||||||
if (widget->isSelected()) {
|
|
||||||
fg = colors.buttonSelectedText();
|
|
||||||
part_nw = (look == MiniLook ? parts.toolbuttonNormal():
|
|
||||||
look == LeftButtonLook ? parts.dropDownButtonLeftSelected():
|
|
||||||
look == RightButtonLook ? parts.dropDownButtonRightSelected():
|
|
||||||
parts.buttonSelected());
|
|
||||||
}
|
|
||||||
// With mouse
|
|
||||||
else if (widget->isEnabled() && widget->hasMouseOver()) {
|
|
||||||
fg = colors.buttonHotText();
|
|
||||||
part_nw = (look == MiniLook ? parts.toolbuttonHot():
|
|
||||||
look == LeftButtonLook ? parts.dropDownButtonLeftHot():
|
|
||||||
look == RightButtonLook ? parts.dropDownButtonRightHot():
|
|
||||||
parts.buttonHot());
|
|
||||||
}
|
|
||||||
// Without mouse
|
|
||||||
else {
|
|
||||||
fg = colors.buttonNormalText();
|
|
||||||
|
|
||||||
if (widget->hasFocus())
|
|
||||||
part_nw = (look == MiniLook ? parts.toolbuttonHot():
|
|
||||||
look == LeftButtonLook ? parts.dropDownButtonLeftFocused():
|
|
||||||
look == RightButtonLook ? parts.dropDownButtonRightFocused():
|
|
||||||
parts.buttonFocused());
|
|
||||||
else
|
|
||||||
part_nw = (look == MiniLook ? parts.toolbuttonNormal():
|
|
||||||
look == LeftButtonLook ? parts.dropDownButtonLeftNormal():
|
|
||||||
look == RightButtonLook ? parts.dropDownButtonRightNormal():
|
|
||||||
parts.buttonNormal());
|
|
||||||
}
|
|
||||||
|
|
||||||
// external background
|
|
||||||
g->fillRect(BGCOLOR, g->getClipBounds());
|
|
||||||
|
|
||||||
// draw borders
|
|
||||||
if (part_nw)
|
|
||||||
drawRect(g, widget->clientBounds(), part_nw.get());
|
|
||||||
|
|
||||||
// text
|
|
||||||
drawText(g, NULL, fg, ColorNone, widget,
|
|
||||||
widget->clientChildrenBounds(), get_button_selected_offset());
|
|
||||||
|
|
||||||
// Paint the icon
|
|
||||||
if (iconInterface) {
|
|
||||||
if (widget->isSelected())
|
|
||||||
icon.offset(get_button_selected_offset(),
|
|
||||||
get_button_selected_offset());
|
|
||||||
|
|
||||||
paintIcon(widget, ev.graphics(), iconInterface, icon.x, icon.y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SkinTheme::paintCheckBox(PaintEvent& ev)
|
void SkinTheme::paintCheckBox(PaintEvent& ev)
|
||||||
{
|
{
|
||||||
Graphics* g = ev.graphics();
|
Graphics* g = ev.graphics();
|
||||||
@ -1516,43 +1558,6 @@ void SkinTheme::paintComboBoxEntry(ui::PaintEvent& ev)
|
|||||||
drawEntryText(g, widget);
|
drawEntryText(g, widget);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkinTheme::paintComboBoxButton(PaintEvent& ev)
|
|
||||||
{
|
|
||||||
Button* widget = static_cast<Button*>(ev.getSource());
|
|
||||||
Graphics* g = ev.graphics();
|
|
||||||
IButtonIcon* iconInterface = widget->iconInterface();
|
|
||||||
SkinPartPtr part_nw;
|
|
||||||
|
|
||||||
if (widget->isSelected()) {
|
|
||||||
part_nw = parts.toolbuttonPushed();
|
|
||||||
}
|
|
||||||
// With mouse
|
|
||||||
else if (widget->isEnabled() && widget->hasMouseOver()) {
|
|
||||||
part_nw = parts.toolbuttonHot();
|
|
||||||
}
|
|
||||||
// Without mouse
|
|
||||||
else {
|
|
||||||
part_nw = parts.toolbuttonLast();
|
|
||||||
}
|
|
||||||
|
|
||||||
Rect rc = widget->clientBounds();
|
|
||||||
|
|
||||||
// external background
|
|
||||||
g->fillRect(BGCOLOR, rc);
|
|
||||||
|
|
||||||
// draw borders
|
|
||||||
drawRect(g, rc, part_nw.get());
|
|
||||||
|
|
||||||
// Paint the icon
|
|
||||||
if (iconInterface) {
|
|
||||||
// Icon
|
|
||||||
int x = rc.x + rc.w/2 - iconInterface->size().w/2;
|
|
||||||
int y = rc.y + rc.h/2 - iconInterface->size().h/2;
|
|
||||||
|
|
||||||
paintIcon(widget, ev.graphics(), iconInterface, x, y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SkinTheme::paintTextBox(ui::PaintEvent& ev)
|
void SkinTheme::paintTextBox(ui::PaintEvent& ev)
|
||||||
{
|
{
|
||||||
Graphics* g = ev.graphics();
|
Graphics* g = ev.graphics();
|
||||||
|
@ -59,7 +59,6 @@ namespace app {
|
|||||||
|
|
||||||
void paintDesktop(ui::PaintEvent& ev) override;
|
void paintDesktop(ui::PaintEvent& ev) override;
|
||||||
void paintBox(ui::PaintEvent& ev) override;
|
void paintBox(ui::PaintEvent& ev) override;
|
||||||
void paintButton(ui::PaintEvent& ev) override;
|
|
||||||
void paintCheckBox(ui::PaintEvent& ev) override;
|
void paintCheckBox(ui::PaintEvent& ev) override;
|
||||||
void paintEntry(ui::PaintEvent& ev) override;
|
void paintEntry(ui::PaintEvent& ev) override;
|
||||||
void paintGrid(ui::PaintEvent& ev) override;
|
void paintGrid(ui::PaintEvent& ev) override;
|
||||||
@ -74,7 +73,6 @@ namespace app {
|
|||||||
void paintSeparator(ui::PaintEvent& ev) override;
|
void paintSeparator(ui::PaintEvent& ev) override;
|
||||||
void paintSlider(ui::PaintEvent& ev) override;
|
void paintSlider(ui::PaintEvent& ev) override;
|
||||||
void paintComboBoxEntry(ui::PaintEvent& ev) override;
|
void paintComboBoxEntry(ui::PaintEvent& ev) override;
|
||||||
void paintComboBoxButton(ui::PaintEvent& ev) override;
|
|
||||||
void paintTextBox(ui::PaintEvent& ev) override;
|
void paintTextBox(ui::PaintEvent& ev) override;
|
||||||
void paintView(ui::PaintEvent& ev) override;
|
void paintView(ui::PaintEvent& ev) override;
|
||||||
void paintViewScrollbar(ui::PaintEvent& ev) override;
|
void paintViewScrollbar(ui::PaintEvent& ev) override;
|
||||||
@ -103,6 +101,10 @@ namespace app {
|
|||||||
return m_stylesheet.getStyle(id);
|
return m_stylesheet.getStyle(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ui::Style* getNewStyle(const std::string& id) {
|
||||||
|
return m_styles[id];
|
||||||
|
}
|
||||||
|
|
||||||
SkinPartPtr getPartById(const std::string& id) {
|
SkinPartPtr getPartById(const std::string& id) {
|
||||||
return m_parts_by_id[id];
|
return m_parts_by_id[id];
|
||||||
}
|
}
|
||||||
@ -149,6 +151,7 @@ namespace app {
|
|||||||
std::map<std::string, int> m_dimensions_by_id;
|
std::map<std::string, int> m_dimensions_by_id;
|
||||||
std::vector<ui::Cursor*> m_cursors;
|
std::vector<ui::Cursor*> m_cursors;
|
||||||
StyleSheet m_stylesheet;
|
StyleSheet m_stylesheet;
|
||||||
|
std::map<std::string, ui::Style*> m_styles;
|
||||||
she::Font* m_defaultFont;
|
she::Font* m_defaultFont;
|
||||||
she::Font* m_miniFont;
|
she::Font* m_miniFont;
|
||||||
};
|
};
|
||||||
|
@ -548,11 +548,11 @@ StatusBar::StatusBar()
|
|||||||
m_currentFrame = new GotoFrameEntry();
|
m_currentFrame = new GotoFrameEntry();
|
||||||
m_newFrame = new Button("+");
|
m_newFrame = new Button("+");
|
||||||
m_newFrame->Click.connect(base::Bind<void>(&StatusBar::newFrame, this));
|
m_newFrame->Click.connect(base::Bind<void>(&StatusBar::newFrame, this));
|
||||||
|
m_newFrame->setStyle(theme->newStyles.newFrameButton());
|
||||||
m_zoomEntry = new ZoomEntry;
|
m_zoomEntry = new ZoomEntry;
|
||||||
m_zoomEntry->ZoomChange.connect(&StatusBar::onChangeZoom, this);
|
m_zoomEntry->ZoomChange.connect(&StatusBar::onChangeZoom, this);
|
||||||
|
|
||||||
setup_mini_look(m_currentFrame);
|
setup_mini_look(m_currentFrame);
|
||||||
setup_mini_look(m_newFrame);
|
|
||||||
|
|
||||||
box1->setBorder(gfx::Border(2, 1, 2, 2)*guiscale());
|
box1->setBorder(gfx::Border(2, 1, 2, 2)*guiscale());
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2001-2016 David Capello
|
// Copyright (C) 2001-2017 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
// the End-User License Agreement for Aseprite.
|
// the End-User License Agreement for Aseprite.
|
||||||
@ -174,30 +174,10 @@ Widget* WidgetLoader::convertXmlElementToWidget(const TiXmlElement* elem, Widget
|
|||||||
bool top = bool_attr_is_true(elem, "top");
|
bool top = bool_attr_is_true(elem, "top");
|
||||||
bool bottom = bool_attr_is_true(elem, "bottom");
|
bool bottom = bool_attr_is_true(elem, "bottom");
|
||||||
bool closewindow = bool_attr_is_true(elem, "closewindow");
|
bool closewindow = bool_attr_is_true(elem, "closewindow");
|
||||||
const char *_bevel = elem->Attribute("bevel");
|
|
||||||
|
|
||||||
widget->setAlign((left ? LEFT: (right ? RIGHT: CENTER)) |
|
widget->setAlign((left ? LEFT: (right ? RIGHT: CENTER)) |
|
||||||
(top ? TOP: (bottom ? BOTTOM: MIDDLE)));
|
(top ? TOP: (bottom ? BOTTOM: MIDDLE)));
|
||||||
|
|
||||||
if (_bevel != NULL) {
|
|
||||||
char* bevel = base_strdup(_bevel);
|
|
||||||
int c, b[4];
|
|
||||||
char *tok;
|
|
||||||
|
|
||||||
for (c=0; c<4; ++c)
|
|
||||||
b[c] = 0;
|
|
||||||
|
|
||||||
for (tok=strtok(bevel, " "), c=0;
|
|
||||||
tok;
|
|
||||||
tok=strtok(NULL, " "), ++c) {
|
|
||||||
if (c < 4)
|
|
||||||
b[c] = strtol(tok, NULL, 10);
|
|
||||||
}
|
|
||||||
base_free(bevel);
|
|
||||||
|
|
||||||
setup_bevels(widget, b[0], b[1], b[2], b[3]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (closewindow) {
|
if (closewindow) {
|
||||||
static_cast<Button*>(widget)
|
static_cast<Button*>(widget)
|
||||||
->Click.connect(base::Bind<void>(&Widget::closeWindow, widget));
|
->Click.connect(base::Bind<void>(&Widget::closeWindow, widget));
|
||||||
@ -594,12 +574,20 @@ void WidgetLoader::fillWidgetWithXmlElementAttributes(const TiXmlElement* elem,
|
|||||||
|
|
||||||
if (styleid) {
|
if (styleid) {
|
||||||
SkinTheme* theme = static_cast<SkinTheme*>(root->theme());
|
SkinTheme* theme = static_cast<SkinTheme*>(root->theme());
|
||||||
|
|
||||||
|
// New styles
|
||||||
|
ui::Style* style = theme->getNewStyle(styleid);
|
||||||
|
if (style)
|
||||||
|
widget->setStyle(style);
|
||||||
|
else {
|
||||||
skin::Style* style = theme->getStyle(styleid);
|
skin::Style* style = theme->getStyle(styleid);
|
||||||
ASSERT(style);
|
if (style) {
|
||||||
SkinStylePropertyPtr prop(new SkinStyleProperty(style));
|
SkinStylePropertyPtr prop(new SkinStyleProperty(style));
|
||||||
widget->setProperty(prop);
|
widget->setProperty(prop);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void WidgetLoader::fillWidgetWithXmlElementAttributesWithChildren(const TiXmlElement* elem, ui::Widget* root, ui::Widget* widget)
|
void WidgetLoader::fillWidgetWithXmlElementAttributesWithChildren(const TiXmlElement* elem, ui::Widget* root, ui::Widget* widget)
|
||||||
{
|
{
|
||||||
|
@ -18,6 +18,7 @@ void gen_theme_class(TiXmlDocument* doc, const std::string& inputFn)
|
|||||||
std::vector<std::string> colors;
|
std::vector<std::string> colors;
|
||||||
std::vector<std::string> parts;
|
std::vector<std::string> parts;
|
||||||
std::vector<std::string> styles;
|
std::vector<std::string> styles;
|
||||||
|
std::vector<std::string> newStyles;
|
||||||
|
|
||||||
TiXmlHandle handle(doc);
|
TiXmlHandle handle(doc);
|
||||||
TiXmlElement* elem = handle
|
TiXmlElement* elem = handle
|
||||||
@ -62,6 +63,16 @@ void gen_theme_class(TiXmlDocument* doc, const std::string& inputFn)
|
|||||||
elem = elem->NextSiblingElement();
|
elem = elem->NextSiblingElement();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
elem = handle
|
||||||
|
.FirstChild("theme")
|
||||||
|
.FirstChild("styles")
|
||||||
|
.FirstChild("style").ToElement();
|
||||||
|
while (elem) {
|
||||||
|
const char* id = elem->Attribute("id");
|
||||||
|
newStyles.push_back(id);
|
||||||
|
elem = elem->NextSiblingElement();
|
||||||
|
}
|
||||||
|
|
||||||
std::cout
|
std::cout
|
||||||
<< "// Don't modify, generated file from " << inputFn << "\n"
|
<< "// Don't modify, generated file from " << inputFn << "\n"
|
||||||
<< "\n"
|
<< "\n"
|
||||||
@ -158,12 +169,34 @@ void gen_theme_class(TiXmlDocument* doc, const std::string& inputFn)
|
|||||||
std::cout
|
std::cout
|
||||||
<< " };\n";
|
<< " };\n";
|
||||||
|
|
||||||
|
// New styles sub class
|
||||||
|
std::cout
|
||||||
|
<< "\n"
|
||||||
|
<< " class NewStyles {\n"
|
||||||
|
<< " template<typename> friend class ThemeFile;\n"
|
||||||
|
<< " public:\n";
|
||||||
|
for (auto style : newStyles) {
|
||||||
|
std::string id = convert_xmlid_to_cppid(style, false);
|
||||||
|
std::cout
|
||||||
|
<< " ui::Style* " << id << "() const { return m_" << id << "; }\n";
|
||||||
|
}
|
||||||
|
std::cout
|
||||||
|
<< " private:\n";
|
||||||
|
for (auto style : newStyles) {
|
||||||
|
std::string id = convert_xmlid_to_cppid(style, false);
|
||||||
|
std::cout
|
||||||
|
<< " ui::Style* m_" << id << ";\n";
|
||||||
|
}
|
||||||
|
std::cout
|
||||||
|
<< " };\n";
|
||||||
|
|
||||||
std::cout
|
std::cout
|
||||||
<< "\n"
|
<< "\n"
|
||||||
<< " Dimensions dimensions;\n"
|
<< " Dimensions dimensions;\n"
|
||||||
<< " Colors colors;\n"
|
<< " Colors colors;\n"
|
||||||
<< " Parts parts;\n"
|
<< " Parts parts;\n"
|
||||||
<< " Styles styles;\n"
|
<< " Styles styles;\n"
|
||||||
|
<< " NewStyles newStyles;\n"
|
||||||
<< "\n"
|
<< "\n"
|
||||||
<< " protected:\n"
|
<< " protected:\n"
|
||||||
<< " void updateInternals() {\n";
|
<< " void updateInternals() {\n";
|
||||||
@ -187,6 +220,11 @@ void gen_theme_class(TiXmlDocument* doc, const std::string& inputFn)
|
|||||||
std::cout << " byId(styles.m_" << id
|
std::cout << " byId(styles.m_" << id
|
||||||
<< ", \"" << style << "\");\n";
|
<< ", \"" << style << "\");\n";
|
||||||
}
|
}
|
||||||
|
for (auto newStyle : newStyles) {
|
||||||
|
std::string id = convert_xmlid_to_cppid(newStyle, false);
|
||||||
|
std::cout << " byId(newStyles.m_" << id
|
||||||
|
<< ", \"" << newStyle << "\");\n";
|
||||||
|
}
|
||||||
std::cout
|
std::cout
|
||||||
<< " }\n"
|
<< " }\n"
|
||||||
<< "\n"
|
<< "\n"
|
||||||
@ -202,6 +240,9 @@ void gen_theme_class(TiXmlDocument* doc, const std::string& inputFn)
|
|||||||
<< " }\n"
|
<< " }\n"
|
||||||
<< " void byId(skin::Style*& style, const std::string& id) {\n"
|
<< " void byId(skin::Style*& style, const std::string& id) {\n"
|
||||||
<< " style = static_cast<T*>(this)->getStyle(id);\n"
|
<< " style = static_cast<T*>(this)->getStyle(id);\n"
|
||||||
|
<< " }\n"
|
||||||
|
<< " void byId(ui::Style*& style, const std::string& id) {\n"
|
||||||
|
<< " style = static_cast<T*>(this)->getNewStyle(id);\n"
|
||||||
<< " }\n";
|
<< " }\n";
|
||||||
|
|
||||||
std::cout
|
std::cout
|
||||||
|
@ -45,6 +45,7 @@ add_library(ui-lib
|
|||||||
size_hint_event.cpp
|
size_hint_event.cpp
|
||||||
slider.cpp
|
slider.cpp
|
||||||
splitter.cpp
|
splitter.cpp
|
||||||
|
style.cpp
|
||||||
system.cpp
|
system.cpp
|
||||||
textbox.cpp
|
textbox.cpp
|
||||||
theme.cpp
|
theme.cpp
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite UI Library
|
// Aseprite UI Library
|
||||||
// Copyright (C) 2001-2016 David Capello
|
// Copyright (C) 2001-2017 David Capello
|
||||||
//
|
//
|
||||||
// This file is released under the terms of the MIT license.
|
// This file is released under the terms of the MIT license.
|
||||||
// Read LICENSE.txt for more information.
|
// Read LICENSE.txt for more information.
|
||||||
@ -272,6 +272,13 @@ bool ButtonBase::onProcessMessage(Message* msg)
|
|||||||
|
|
||||||
void ButtonBase::onSizeHint(SizeHintEvent& ev)
|
void ButtonBase::onSizeHint(SizeHintEvent& ev)
|
||||||
{
|
{
|
||||||
|
// If there is a style specified in this widget, use the new generic
|
||||||
|
// widget to calculate the size hint.
|
||||||
|
if (style()) {
|
||||||
|
Widget::onSizeHint(ev);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
gfx::Rect box;
|
gfx::Rect box;
|
||||||
gfx::Size iconSize = (m_iconInterface ? m_iconInterface->size(): gfx::Size(0, 0));
|
gfx::Size iconSize = (m_iconInterface ? m_iconInterface->size(): gfx::Size(0, 0));
|
||||||
getTextIconInfo(&box, NULL, NULL,
|
getTextIconInfo(&box, NULL, NULL,
|
||||||
@ -285,8 +292,13 @@ void ButtonBase::onSizeHint(SizeHintEvent& ev)
|
|||||||
|
|
||||||
void ButtonBase::onPaint(PaintEvent& ev)
|
void ButtonBase::onPaint(PaintEvent& ev)
|
||||||
{
|
{
|
||||||
|
// If there is a style specified in this widget, use the new generic
|
||||||
|
// widget painting code.
|
||||||
|
if (style())
|
||||||
|
return Widget::onPaint(ev);
|
||||||
|
|
||||||
switch (m_drawType) {
|
switch (m_drawType) {
|
||||||
case kButtonWidget: theme()->paintButton(ev); break;
|
case kButtonWidget: ASSERT(false); break;
|
||||||
case kCheckWidget: theme()->paintCheckBox(ev); break;
|
case kCheckWidget: theme()->paintCheckBox(ev); break;
|
||||||
case kRadioWidget: theme()->paintRadioButton(ev); break;
|
case kRadioWidget: theme()->paintRadioButton(ev); break;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite UI Library
|
// Aseprite UI Library
|
||||||
// Copyright (C) 2001-2016 David Capello
|
// Copyright (C) 2001-2017 David Capello
|
||||||
//
|
//
|
||||||
// This file is released under the terms of the MIT license.
|
// This file is released under the terms of the MIT license.
|
||||||
// Read LICENSE.txt for more information.
|
// Read LICENSE.txt for more information.
|
||||||
@ -21,10 +21,6 @@ public:
|
|||||||
ComboBoxButton() : Button("") {
|
ComboBoxButton() : Button("") {
|
||||||
setFocusStop(false);
|
setFocusStop(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void onPaint(PaintEvent& ev) override {
|
|
||||||
theme()->paintComboBoxButton(ev);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class ComboBoxEntry : public Entry {
|
class ComboBoxEntry : public Entry {
|
||||||
|
51
src/ui/style.cpp
Normal file
51
src/ui/style.cpp
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
// Aseprite UI Library
|
||||||
|
// Copyright (C) 2017 David Capello
|
||||||
|
//
|
||||||
|
// This file is released under the terms of the MIT license.
|
||||||
|
// Read LICENSE.txt for more information.
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "ui/style.h"
|
||||||
|
|
||||||
|
namespace ui {
|
||||||
|
|
||||||
|
Style::Style(const Style* base)
|
||||||
|
: m_insertionPoint(0)
|
||||||
|
, m_border(base ? base->border(): gfx::Border(-1, -1, -1, -1))
|
||||||
|
, m_padding(base ? base->padding(): gfx::Border(-1, -1, -1, -1))
|
||||||
|
{
|
||||||
|
if (base)
|
||||||
|
m_layers = base->layers();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Style::addLayer(const Layer& layer)
|
||||||
|
{
|
||||||
|
int i, j = int(m_layers.size());
|
||||||
|
|
||||||
|
for (i=m_insertionPoint; i<int(m_layers.size()); ++i) {
|
||||||
|
if (layer.type() == m_layers[i].type()) {
|
||||||
|
for (j=i+1; j<int(m_layers.size()); ++j) {
|
||||||
|
if (layer.type() != m_layers[j].type())
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i < int(m_layers.size())) {
|
||||||
|
if (layer.type() == Style::Layer::Type::kNewLayer)
|
||||||
|
m_insertionPoint = i+1;
|
||||||
|
else
|
||||||
|
m_layers.insert(m_layers.begin()+j, layer);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
m_layers.push_back(layer);
|
||||||
|
if (layer.type() == Style::Layer::Type::kNewLayer)
|
||||||
|
m_insertionPoint = int(m_layers.size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ui
|
105
src/ui/style.h
Normal file
105
src/ui/style.h
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
// Aseprite UI Library
|
||||||
|
// Copyright (C) 2017 David Capello
|
||||||
|
//
|
||||||
|
// This file is released under the terms of the MIT license.
|
||||||
|
// Read LICENSE.txt for more information.
|
||||||
|
|
||||||
|
#ifndef UI_STYLE_H_INCLUDED
|
||||||
|
#define UI_STYLE_H_INCLUDED
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "gfx/border.h"
|
||||||
|
#include "gfx/color.h"
|
||||||
|
#include "gfx/rect.h"
|
||||||
|
#include "gfx/size.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace she {
|
||||||
|
class Surface;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace ui {
|
||||||
|
|
||||||
|
class Style {
|
||||||
|
public:
|
||||||
|
class Layer {
|
||||||
|
public:
|
||||||
|
enum class Type {
|
||||||
|
kNone,
|
||||||
|
kBackground,
|
||||||
|
kBorder,
|
||||||
|
kIcon,
|
||||||
|
kText,
|
||||||
|
kNewLayer,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Flags (in which state the widget must be to show this layer)
|
||||||
|
enum {
|
||||||
|
kMouse = 1,
|
||||||
|
kFocus = 2,
|
||||||
|
kSelected = 4,
|
||||||
|
kDisabled = 8,
|
||||||
|
};
|
||||||
|
|
||||||
|
Layer()
|
||||||
|
: m_type(Type::kNone)
|
||||||
|
, m_flags(0)
|
||||||
|
, m_color(gfx::ColorNone)
|
||||||
|
, m_icon(nullptr)
|
||||||
|
, m_spriteSheet(nullptr) {
|
||||||
|
}
|
||||||
|
|
||||||
|
Type type() const { return m_type; }
|
||||||
|
int flags() const { return m_flags; }
|
||||||
|
|
||||||
|
gfx::Color color() const { return m_color; }
|
||||||
|
she::Surface* icon() const { return m_icon; }
|
||||||
|
she::Surface* spriteSheet() const { return m_spriteSheet; }
|
||||||
|
const gfx::Rect& spriteBounds() const { return m_spriteBounds; }
|
||||||
|
const gfx::Rect& slicesBounds() const { return m_slicesBounds; }
|
||||||
|
|
||||||
|
void setType(const Type type) { m_type = type; }
|
||||||
|
void setFlags(const int flags) { m_flags = flags; }
|
||||||
|
void setColor(gfx::Color color) { m_color = color; }
|
||||||
|
void setIcon(she::Surface* icon) { m_icon = icon; }
|
||||||
|
void setSpriteSheet(she::Surface* spriteSheet) { m_spriteSheet = spriteSheet; }
|
||||||
|
void setSpriteBounds(const gfx::Rect& bounds) { m_spriteBounds = bounds; }
|
||||||
|
void setSlicesBounds(const gfx::Rect& bounds) { m_slicesBounds = bounds; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
Type m_type;
|
||||||
|
int m_flags;
|
||||||
|
gfx::Color m_color;
|
||||||
|
she::Surface* m_icon;
|
||||||
|
she::Surface* m_spriteSheet;
|
||||||
|
gfx::Rect m_spriteBounds;
|
||||||
|
gfx::Rect m_slicesBounds;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::vector<Layer> Layers;
|
||||||
|
|
||||||
|
Style(const Style* base);
|
||||||
|
|
||||||
|
const std::string& id() const { return m_id; }
|
||||||
|
const gfx::Border& border() const { return m_border; }
|
||||||
|
const gfx::Border& padding() const { return m_padding; }
|
||||||
|
const Layers& layers() const { return m_layers; }
|
||||||
|
|
||||||
|
void setId(const std::string& id) { m_id = id; }
|
||||||
|
void setBorder(const gfx::Border& value) { m_border = value; }
|
||||||
|
void setPadding(const gfx::Border& value) { m_padding = value; }
|
||||||
|
void addLayer(const Layer& layer);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string m_id; // Just for debugging purposes
|
||||||
|
Layers m_layers;
|
||||||
|
int m_insertionPoint;
|
||||||
|
gfx::Border m_border;
|
||||||
|
gfx::Border m_padding;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ui
|
||||||
|
|
||||||
|
#endif
|
226
src/ui/theme.cpp
226
src/ui/theme.cpp
@ -8,6 +8,8 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "ui/theme.h"
|
||||||
|
|
||||||
#include "gfx/point.h"
|
#include "gfx/point.h"
|
||||||
#include "gfx/size.h"
|
#include "gfx/size.h"
|
||||||
#include "she/font.h"
|
#include "she/font.h"
|
||||||
@ -15,11 +17,14 @@
|
|||||||
#include "she/system.h"
|
#include "she/system.h"
|
||||||
#include "ui/intern.h"
|
#include "ui/intern.h"
|
||||||
#include "ui/manager.h"
|
#include "ui/manager.h"
|
||||||
|
#include "ui/paint_event.h"
|
||||||
|
#include "ui/size_hint_event.h"
|
||||||
|
#include "ui/style.h"
|
||||||
#include "ui/system.h"
|
#include "ui/system.h"
|
||||||
#include "ui/theme.h"
|
|
||||||
#include "ui/view.h"
|
#include "ui/view.h"
|
||||||
#include "ui/widget.h"
|
#include "ui/widget.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
namespace ui {
|
namespace ui {
|
||||||
@ -55,6 +60,225 @@ void Theme::regenerate()
|
|||||||
set_mouse_cursor(type);
|
set_mouse_cursor(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Theme::paintWidget(PaintEvent& ev)
|
||||||
|
{
|
||||||
|
Widget* widget = static_cast<Widget*>(ev.getSource());
|
||||||
|
const Style* style = widget->style();
|
||||||
|
if (!style) {
|
||||||
|
// Without a ui::Style we don't know how to draw the widget
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Graphics* g = ev.graphics();
|
||||||
|
gfx::Rect rc = widget->clientBounds();
|
||||||
|
int flags =
|
||||||
|
(widget->isEnabled() ? 0: Style::Layer::kDisabled) |
|
||||||
|
(widget->isSelected() ? Style::Layer::kSelected: 0) |
|
||||||
|
(widget->hasMouse() ? Style::Layer::kMouse: 0) |
|
||||||
|
(widget->hasFocus() ? Style::Layer::kFocus: 0);
|
||||||
|
|
||||||
|
// External background
|
||||||
|
g->fillRect(widget->bgColor(), rc);
|
||||||
|
|
||||||
|
const Style::Layer* bestLayer = nullptr;
|
||||||
|
|
||||||
|
for (const auto& layer : style->layers()) {
|
||||||
|
if (bestLayer &&
|
||||||
|
bestLayer->type() != layer.type()) {
|
||||||
|
paintLayer(g, widget, *bestLayer, rc);
|
||||||
|
bestLayer = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((!layer.flags()
|
||||||
|
|| (layer.flags() & flags) == layer.flags())
|
||||||
|
&& (!bestLayer
|
||||||
|
|| (bestLayer && compareLayerFlags(bestLayer->flags(), layer.flags()) <= 0))) {
|
||||||
|
bestLayer = &layer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bestLayer)
|
||||||
|
paintLayer(g, widget, *bestLayer, rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Theme::paintLayer(Graphics* g, Widget* widget,
|
||||||
|
const Style::Layer& layer,
|
||||||
|
gfx::Rect& rc)
|
||||||
|
{
|
||||||
|
switch (layer.type()) {
|
||||||
|
|
||||||
|
case Style::Layer::Type::kBackground:
|
||||||
|
if (layer.color() != gfx::ColorNone) {
|
||||||
|
g->fillRect(layer.color(), rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (layer.spriteSheet() &&
|
||||||
|
!layer.spriteBounds().isEmpty() &&
|
||||||
|
!layer.slicesBounds().isEmpty()) {
|
||||||
|
Theme::drawSlices(g, layer.spriteSheet(), rc,
|
||||||
|
layer.spriteBounds(),
|
||||||
|
layer.slicesBounds(), true);
|
||||||
|
|
||||||
|
rc.x += layer.slicesBounds().x;
|
||||||
|
rc.y += layer.slicesBounds().y;
|
||||||
|
rc.w -= layer.spriteBounds().w - layer.slicesBounds().w;
|
||||||
|
rc.h -= layer.spriteBounds().h - layer.slicesBounds().h;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Style::Layer::Type::kBorder:
|
||||||
|
if (layer.color() != gfx::ColorNone) {
|
||||||
|
g->drawRect(layer.color(), rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (layer.spriteSheet() &&
|
||||||
|
!layer.spriteBounds().isEmpty() &&
|
||||||
|
!layer.slicesBounds().isEmpty()) {
|
||||||
|
Theme::drawSlices(g, layer.spriteSheet(), rc,
|
||||||
|
layer.spriteBounds(),
|
||||||
|
layer.slicesBounds(), false);
|
||||||
|
|
||||||
|
rc.x += layer.slicesBounds().x;
|
||||||
|
rc.y += layer.slicesBounds().y;
|
||||||
|
rc.w -= layer.spriteBounds().w - layer.slicesBounds().w;
|
||||||
|
rc.h -= layer.spriteBounds().h - layer.slicesBounds().h;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Style::Layer::Type::kText:
|
||||||
|
if (layer.color() != gfx::ColorNone) {
|
||||||
|
gfx::Size textSize = g->measureUIText(widget->text());
|
||||||
|
g->drawUIText(widget->text(),
|
||||||
|
layer.color(),
|
||||||
|
gfx::ColorNone,
|
||||||
|
gfx::Point(rc.x+rc.w/2-textSize.w/2,
|
||||||
|
rc.y+rc.h/2-textSize.h/2), true);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Style::Layer::Type::kIcon: {
|
||||||
|
she::Surface* icon = layer.icon();
|
||||||
|
if (icon) {
|
||||||
|
if (layer.color() != gfx::ColorNone) {
|
||||||
|
g->drawColoredRgbaSurface(icon,
|
||||||
|
layer.color(),
|
||||||
|
rc.x+rc.w/2-icon->width()/2,
|
||||||
|
rc.y+rc.h/2-icon->height()/2);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
g->drawRgbaSurface(icon,
|
||||||
|
rc.x+rc.w/2-icon->width()/2,
|
||||||
|
rc.y+rc.h/2-icon->height()/2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Theme::calcSizeHint(SizeHintEvent& ev)
|
||||||
|
{
|
||||||
|
Widget* widget = static_cast<Widget*>(ev.getSource());
|
||||||
|
const Style* style = widget->style();
|
||||||
|
if (!style)
|
||||||
|
return;
|
||||||
|
|
||||||
|
gfx::Border hintBorder(0, 0, 0, 0);
|
||||||
|
gfx::Border hintPadding(0, 0, 0, 0);
|
||||||
|
gfx::Size hintText(0, 0);
|
||||||
|
gfx::Size hintIcon(0, 0);
|
||||||
|
|
||||||
|
int flags =
|
||||||
|
(widget->isEnabled() ? 0: Style::Layer::kDisabled) |
|
||||||
|
(widget->isSelected() ? Style::Layer::kSelected: 0) |
|
||||||
|
(widget->hasMouse() ? Style::Layer::kMouse: 0) |
|
||||||
|
(widget->hasFocus() ? Style::Layer::kFocus: 0);
|
||||||
|
|
||||||
|
const Style::Layer* bestLayer = nullptr;
|
||||||
|
|
||||||
|
for (const auto& layer : style->layers()) {
|
||||||
|
if (bestLayer &&
|
||||||
|
bestLayer->type() != layer.type()) {
|
||||||
|
measureLayer(widget, *bestLayer,
|
||||||
|
hintBorder, hintText, hintIcon);
|
||||||
|
bestLayer = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((!layer.flags()
|
||||||
|
|| (layer.flags() & flags) == layer.flags())
|
||||||
|
&& (!bestLayer
|
||||||
|
|| (bestLayer && compareLayerFlags(bestLayer->flags(), layer.flags()) < 0))) {
|
||||||
|
bestLayer = &layer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bestLayer)
|
||||||
|
measureLayer(widget, *bestLayer,
|
||||||
|
hintBorder, hintText, hintIcon);
|
||||||
|
|
||||||
|
if (style->border().left() >= 0) hintBorder.left(style->border().left());
|
||||||
|
if (style->border().top() >= 0) hintBorder.top(style->border().top());
|
||||||
|
if (style->border().right() >= 0) hintBorder.right(style->border().right());
|
||||||
|
if (style->border().bottom() >= 0) hintBorder.bottom(style->border().bottom());
|
||||||
|
|
||||||
|
if (style->padding().left() >= 0) hintPadding.left(style->padding().left());
|
||||||
|
if (style->padding().top() >= 0) hintPadding.top(style->padding().top());
|
||||||
|
if (style->padding().right() >= 0) hintPadding.right(style->padding().right());
|
||||||
|
if (style->padding().bottom() >= 0) hintPadding.bottom(style->padding().bottom());
|
||||||
|
|
||||||
|
gfx::Size sz(hintBorder.width() + hintPadding.width() + hintIcon.w + hintText.w,
|
||||||
|
hintBorder.height() + hintPadding.height() + std::max(hintIcon.h, hintText.h));
|
||||||
|
ev.setSizeHint(sz);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Theme::measureLayer(Widget* widget,
|
||||||
|
const Style::Layer& layer,
|
||||||
|
gfx::Border& hintBorder,
|
||||||
|
gfx::Size& hintText,
|
||||||
|
gfx::Size& hintIcon)
|
||||||
|
{
|
||||||
|
switch (layer.type()) {
|
||||||
|
|
||||||
|
case Style::Layer::Type::kBackground:
|
||||||
|
case Style::Layer::Type::kBorder:
|
||||||
|
if (layer.spriteSheet() &&
|
||||||
|
!layer.spriteBounds().isEmpty() &&
|
||||||
|
!layer.slicesBounds().isEmpty()) {
|
||||||
|
hintBorder.left(std::max(hintBorder.left(), layer.slicesBounds().x));
|
||||||
|
hintBorder.top(std::max(hintBorder.top(), layer.slicesBounds().y));
|
||||||
|
hintBorder.right(std::max(hintBorder.right(), layer.spriteBounds().w - layer.slicesBounds().x2()));
|
||||||
|
hintBorder.bottom(std::max(hintBorder.bottom(), layer.spriteBounds().h - layer.slicesBounds().y2()));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Style::Layer::Type::kText:
|
||||||
|
if (layer.color() != gfx::ColorNone) {
|
||||||
|
gfx::Size textSize(Graphics::measureUITextLength(widget->text(),
|
||||||
|
widget->font()),
|
||||||
|
widget->font()->height());
|
||||||
|
hintText.w = std::max(hintText.w, textSize.w);
|
||||||
|
hintText.h = std::max(hintText.h, textSize.h);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Style::Layer::Type::kIcon: {
|
||||||
|
she::Surface* icon = layer.icon();
|
||||||
|
if (icon) {
|
||||||
|
hintIcon.w = std::max(hintIcon.w, icon->width());
|
||||||
|
hintIcon.h = std::max(hintIcon.h, icon->height());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int Theme::compareLayerFlags(int a, int b)
|
||||||
|
{
|
||||||
|
return a - b;
|
||||||
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void set_theme(Theme* theme)
|
void set_theme(Theme* theme)
|
||||||
|
@ -8,10 +8,13 @@
|
|||||||
#define UI_THEME_H_INCLUDED
|
#define UI_THEME_H_INCLUDED
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "gfx/border.h"
|
||||||
#include "gfx/color.h"
|
#include "gfx/color.h"
|
||||||
|
#include "gfx/rect.h"
|
||||||
#include "gfx/size.h"
|
#include "gfx/size.h"
|
||||||
#include "ui/base.h"
|
#include "ui/base.h"
|
||||||
#include "ui/cursor_type.h"
|
#include "ui/cursor_type.h"
|
||||||
|
#include "ui/style.h"
|
||||||
|
|
||||||
namespace gfx {
|
namespace gfx {
|
||||||
class Region;
|
class Region;
|
||||||
@ -27,6 +30,7 @@ namespace ui {
|
|||||||
class Cursor;
|
class Cursor;
|
||||||
class Graphics;
|
class Graphics;
|
||||||
class PaintEvent;
|
class PaintEvent;
|
||||||
|
class SizeHintEvent;
|
||||||
class Widget;
|
class Widget;
|
||||||
|
|
||||||
class Theme {
|
class Theme {
|
||||||
@ -51,7 +55,6 @@ namespace ui {
|
|||||||
|
|
||||||
virtual void paintDesktop(PaintEvent& ev) = 0;
|
virtual void paintDesktop(PaintEvent& ev) = 0;
|
||||||
virtual void paintBox(PaintEvent& ev) = 0;
|
virtual void paintBox(PaintEvent& ev) = 0;
|
||||||
virtual void paintButton(PaintEvent& ev) = 0;
|
|
||||||
virtual void paintCheckBox(PaintEvent& ev) = 0;
|
virtual void paintCheckBox(PaintEvent& ev) = 0;
|
||||||
virtual void paintEntry(PaintEvent& ev) = 0;
|
virtual void paintEntry(PaintEvent& ev) = 0;
|
||||||
virtual void paintGrid(PaintEvent& ev) = 0;
|
virtual void paintGrid(PaintEvent& ev) = 0;
|
||||||
@ -66,7 +69,6 @@ namespace ui {
|
|||||||
virtual void paintSeparator(PaintEvent& ev) = 0;
|
virtual void paintSeparator(PaintEvent& ev) = 0;
|
||||||
virtual void paintSlider(PaintEvent& ev) = 0;
|
virtual void paintSlider(PaintEvent& ev) = 0;
|
||||||
virtual void paintComboBoxEntry(PaintEvent& ev) = 0;
|
virtual void paintComboBoxEntry(PaintEvent& ev) = 0;
|
||||||
virtual void paintComboBoxButton(PaintEvent& ev) = 0;
|
|
||||||
virtual void paintTextBox(PaintEvent& ev) = 0;
|
virtual void paintTextBox(PaintEvent& ev) = 0;
|
||||||
virtual void paintView(PaintEvent& ev) = 0;
|
virtual void paintView(PaintEvent& ev) = 0;
|
||||||
virtual void paintViewScrollbar(PaintEvent& ev) = 0;
|
virtual void paintViewScrollbar(PaintEvent& ev) = 0;
|
||||||
@ -75,6 +77,10 @@ namespace ui {
|
|||||||
virtual void paintPopupWindow(PaintEvent& ev) = 0;
|
virtual void paintPopupWindow(PaintEvent& ev) = 0;
|
||||||
virtual void paintTooltip(PaintEvent& ev) = 0;
|
virtual void paintTooltip(PaintEvent& ev) = 0;
|
||||||
|
|
||||||
|
// Default implementation to draw widgets with new ui::Styles
|
||||||
|
virtual void paintWidget(PaintEvent& ev);
|
||||||
|
virtual void calcSizeHint(SizeHintEvent& ev);
|
||||||
|
|
||||||
static void drawSlices(Graphics* g,
|
static void drawSlices(Graphics* g,
|
||||||
she::Surface* sheet,
|
she::Surface* sheet,
|
||||||
const gfx::Rect& rc,
|
const gfx::Rect& rc,
|
||||||
@ -89,6 +95,16 @@ namespace ui {
|
|||||||
virtual void onRegenerate() = 0;
|
virtual void onRegenerate() = 0;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void paintLayer(Graphics* g, Widget* widget,
|
||||||
|
const Style::Layer& layer,
|
||||||
|
gfx::Rect& rc);
|
||||||
|
void measureLayer(Widget* widget,
|
||||||
|
const Style::Layer& layer,
|
||||||
|
gfx::Border& hintBorder,
|
||||||
|
gfx::Size& hintText,
|
||||||
|
gfx::Size& hintIcon);
|
||||||
|
int compareLayerFlags(int a, int b);
|
||||||
|
|
||||||
int m_guiscale;
|
int m_guiscale;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite UI Library
|
// Aseprite UI Library
|
||||||
// Copyright (C) 2001-2016 David Capello
|
// Copyright (C) 2001-2017 David Capello
|
||||||
//
|
//
|
||||||
// This file is released under the terms of the MIT license.
|
// This file is released under the terms of the MIT license.
|
||||||
// Read LICENSE.txt for more information.
|
// Read LICENSE.txt for more information.
|
||||||
@ -54,6 +54,7 @@
|
|||||||
#include "ui/size_hint_event.h"
|
#include "ui/size_hint_event.h"
|
||||||
#include "ui/slider.h"
|
#include "ui/slider.h"
|
||||||
#include "ui/splitter.h"
|
#include "ui/splitter.h"
|
||||||
|
#include "ui/style.h"
|
||||||
#include "ui/system.h"
|
#include "ui/system.h"
|
||||||
#include "ui/textbox.h"
|
#include "ui/textbox.h"
|
||||||
#include "ui/theme.h"
|
#include "ui/theme.h"
|
||||||
|
@ -64,6 +64,7 @@ Widget::Widget(WidgetType type)
|
|||||||
: m_type(type)
|
: m_type(type)
|
||||||
, m_flags(0)
|
, m_flags(0)
|
||||||
, m_theme(get_theme())
|
, m_theme(get_theme())
|
||||||
|
, m_style(nullptr)
|
||||||
, m_font(nullptr)
|
, m_font(nullptr)
|
||||||
, m_bgColor(gfx::ColorNone)
|
, m_bgColor(gfx::ColorNone)
|
||||||
, m_bounds(0, 0, 0, 0)
|
, m_bounds(0, 0, 0, 0)
|
||||||
@ -182,6 +183,11 @@ void Widget::setTheme(Theme* theme)
|
|||||||
m_font = nullptr;
|
m_font = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Widget::setStyle(Style* style)
|
||||||
|
{
|
||||||
|
m_style = style;
|
||||||
|
}
|
||||||
|
|
||||||
// ===============================================================
|
// ===============================================================
|
||||||
// COMMON PROPERTIES
|
// COMMON PROPERTIES
|
||||||
// ===============================================================
|
// ===============================================================
|
||||||
@ -1397,8 +1403,13 @@ void Widget::onInvalidateRegion(const Region& region)
|
|||||||
|
|
||||||
void Widget::onSizeHint(SizeHintEvent& ev)
|
void Widget::onSizeHint(SizeHintEvent& ev)
|
||||||
{
|
{
|
||||||
|
if (m_style) {
|
||||||
|
m_theme->calcSizeHint(ev);
|
||||||
|
}
|
||||||
|
else {
|
||||||
ev.setSizeHint(m_minSize);
|
ev.setSizeHint(m_minSize);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Widget::onLoadLayout(LoadLayoutEvent& ev)
|
void Widget::onLoadLayout(LoadLayoutEvent& ev)
|
||||||
{
|
{
|
||||||
@ -1422,7 +1433,8 @@ void Widget::onResize(ResizeEvent& ev)
|
|||||||
|
|
||||||
void Widget::onPaint(PaintEvent& ev)
|
void Widget::onPaint(PaintEvent& ev)
|
||||||
{
|
{
|
||||||
// Do nothing
|
if (m_style)
|
||||||
|
m_theme->paintWidget(ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::onBroadcastMouseMessage(WidgetsList& targets)
|
void Widget::onBroadcastMouseMessage(WidgetsList& targets)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite UI Library
|
// Aseprite UI Library
|
||||||
// Copyright (C) 2001-2016 David Capello
|
// Copyright (C) 2001-2017 David Capello
|
||||||
//
|
//
|
||||||
// This file is released under the terms of the MIT license.
|
// This file is released under the terms of the MIT license.
|
||||||
// Read LICENSE.txt for more information.
|
// Read LICENSE.txt for more information.
|
||||||
@ -40,6 +40,7 @@ namespace ui {
|
|||||||
class ResizeEvent;
|
class ResizeEvent;
|
||||||
class SaveLayoutEvent;
|
class SaveLayoutEvent;
|
||||||
class SizeHintEvent;
|
class SizeHintEvent;
|
||||||
|
class Style;
|
||||||
class Theme;
|
class Theme;
|
||||||
class Window;
|
class Window;
|
||||||
|
|
||||||
@ -151,7 +152,9 @@ namespace ui {
|
|||||||
void setBgColor(gfx::Color color);
|
void setBgColor(gfx::Color color);
|
||||||
|
|
||||||
Theme* theme() const { return m_theme; }
|
Theme* theme() const { return m_theme; }
|
||||||
|
Style* style() const { return m_style; }
|
||||||
void setTheme(Theme* theme);
|
void setTheme(Theme* theme);
|
||||||
|
void setStyle(Style* style);
|
||||||
void initTheme();
|
void initTheme();
|
||||||
|
|
||||||
// ===============================================================
|
// ===============================================================
|
||||||
@ -387,6 +390,7 @@ namespace ui {
|
|||||||
std::string m_id; // Widget's id
|
std::string m_id; // Widget's id
|
||||||
int m_flags; // Special boolean properties (see flags in ui/base.h)
|
int m_flags; // Special boolean properties (see flags in ui/base.h)
|
||||||
Theme* m_theme; // Widget's theme
|
Theme* m_theme; // Widget's theme
|
||||||
|
Style* m_style;
|
||||||
std::string m_text; // Widget text
|
std::string m_text; // Widget text
|
||||||
mutable she::Font* m_font; // Cached font returned by the theme
|
mutable she::Font* m_font; // Cached font returned by the theme
|
||||||
gfx::Color m_bgColor; // Background color
|
gfx::Color m_bgColor; // Background color
|
||||||
|
Loading…
x
Reference in New Issue
Block a user