Add custom data to Sprite Properties Window (fix #1306)

This commit is contained in:
Gaspar Capello 2020-12-15 14:00:44 -03:00 committed by David Capello
parent 6f9f6006cc
commit 116201d8a1
19 changed files with 115 additions and 17 deletions

View File

@ -177,6 +177,9 @@
<section id="layers"> <section id="layers">
<option id="user_data_visibility" type="bool" default="false" /> <option id="user_data_visibility" type="bool" default="false" />
</section> </section>
<section id="sprite">
<option id="user_data_visibility" type="bool" default="false" />
</section>
<section id="tags"> <section id="tags">
<option id="user_data_visibility" type="bool" default="false" /> <option id="user_data_visibility" type="bool" default="false" />
</section> </section>

View File

@ -1,45 +1,47 @@
<!-- Aseprite --> <!-- Aseprite -->
<!-- Copyright (C) 2018 Igara Studio S.A. --> <!-- Copyright (C) 2018-2020 Igara Studio S.A. -->
<!-- Copyright (C) 2001-2016 David Capello --> <!-- Copyright (C) 2001-2016 David Capello -->
<gui> <gui>
<window id="sprite_properties" text="@.title"> <window id="sprite_properties" text="@.title">
<vbox> <vbox>
<grid columns="2"> <grid id="properties_grid" columns="3">
<label text="@.filename" /> <label text="@.filename" />
<entry text="" id="name" maxsize="256" minwidth="64" readonly="true" cell_align="horizontal" /> <entry text="" id="name" maxsize="256" minwidth="64" readonly="true" cell_align="horizontal" />
<button id="user_data" icon="icon_user_data" maxsize="32" tooltip="@general.user_data" />
<label text="@.type" /> <label text="@.type" />
<label text="" id="type" /> <label text="" id="type" cell_hspan="2" />
<label text="@.size" /> <label text="@.size" />
<label text="" id="size" /> <label text="" id="size" cell_hspan="2" />
<label text="@.frames" /> <label text="@.frames" />
<label text="" id="frames" /> <label text="" id="frames" cell_hspan="2" />
</grid>
<grid columns="2">
<separator text="@.advanced" horizontal="true" cell_hspan="2" /> <separator text="@.advanced" horizontal="true" cell_hspan="2" />
<label text="@.transparent_color" /> <label text="@.transparent_color" />
<hbox> <hbox>
<hbox id="transparent_color_placeholder" /> <hbox id="transparent_color_placeholder" />
</hbox> </hbox>
<label text="@.pixel_ratio" /> <label text="@.pixel_ratio" />
<combobox id="pixel_ratio" cell_align="horizontal"> <combobox id="pixel_ratio" cell_align="horizontal">
<listitem text="@.square_pixels" value="1:1" /> <listitem text="@.square_pixels" value="1:1" />
<listitem text="@.double_wide" value="2:1" /> <listitem text="@.double_wide" value="2:1" />
<listitem text="@.double_high" value="1:2" /> <listitem text="@.double_high" value="1:2" />
</combobox> </combobox>
<label text="@.color_profile" /> <label text="@.color_profile" />
<hbox> <hbox>
<combobox id="color_profile" cell_align="horizontal" expansive="true"></combobox> <combobox id="color_profile" cell_align="horizontal" expansive="true"></combobox>
<hbox homogeneous="true"> <hbox homogeneous="true">
<button id="assign_color_profile" text="@.assign_color_profile">Assign</button> <button id="assign_color_profile" text="@.assign_color_profile">Assign</button>
<button id="convert_color_profile" text="@.convert_color_profile">Convert</button> <button id="convert_color_profile" text="@.convert_color_profile">Convert</button>
</hbox> </hbox>
</hbox> </hbox>
</grid> </grid>
<separator horizontal="true" /> <separator horizontal="true" />
<hbox> <hbox>

View File

@ -12,6 +12,7 @@
#include "app/cmd/assign_color_profile.h" #include "app/cmd/assign_color_profile.h"
#include "app/cmd/convert_color_profile.h" #include "app/cmd/convert_color_profile.h"
#include "app/cmd/set_pixel_ratio.h" #include "app/cmd/set_pixel_ratio.h"
#include "app/cmd/set_user_data.h"
#include "app/color.h" #include "app/color.h"
#include "app/commands/command.h" #include "app/commands/command.h"
#include "app/context_access.h" #include "app/context_access.h"
@ -21,11 +22,13 @@
#include "app/pref/preferences.h" #include "app/pref/preferences.h"
#include "app/tx.h" #include "app/tx.h"
#include "app/ui/color_button.h" #include "app/ui/color_button.h"
#include "app/ui/user_data_view.h"
#include "app/util/pixel_ratio.h" #include "app/util/pixel_ratio.h"
#include "base/mem_utils.h" #include "base/mem_utils.h"
#include "doc/image.h" #include "doc/image.h"
#include "doc/palette.h" #include "doc/palette.h"
#include "doc/sprite.h" #include "doc/sprite.h"
#include "doc/user_data.h"
#include "fmt/format.h" #include "fmt/format.h"
#include "os/color_space.h" #include "os/color_space.h"
#include "os/system.h" #include "os/system.h"
@ -37,6 +40,37 @@ namespace app {
using namespace ui; using namespace ui;
class SpritePropertiesWindow : public app::gen::SpriteProperties {
public:
SpritePropertiesWindow(Sprite* sprite)
: SpriteProperties()
, m_sprite(sprite)
, m_userDataView(new gen::UserData(), &Preferences::instance().sprite.userDataVisibility)
{
userData()->Click.connect([this]{ onToggleUserData(); });
ui::Grid* mainGrid = propertiesGrid();
m_userDataView.configureAndSet(m_sprite->userData(), mainGrid);
remapWindow();
centerWindow();
load_window_pos(this, "SpriteProperties");
manager()->invalidate();
}
const UserData& getUserData() const { return m_userDataView.userData(); }
private:
void onToggleUserData() {
m_userDataView.toggleVisibility();
remapWindow();
manager()->invalidate();
}
Sprite* m_sprite;
UserDataView m_userDataView;
};
class SpritePropertiesCommand : public Command { class SpritePropertiesCommand : public Command {
public: public:
SpritePropertiesCommand(); SpritePropertiesCommand();
@ -67,7 +101,8 @@ void SpritePropertiesCommand::onExecute(Context* context)
os::instance()->listColorSpaces(colorSpaces); os::instance()->listColorSpaces(colorSpaces);
// Load the window widget // Load the window widget
app::gen::SpriteProperties window; SpritePropertiesWindow window(context->activeDocument()->sprite());
int selectedColorProfile = -1; int selectedColorProfile = -1;
auto updateButtons = auto updateButtons =
@ -208,8 +243,11 @@ void SpritePropertiesCommand::onExecute(Context* context)
PixelRatio pixelRatio = PixelRatio pixelRatio =
base::convert_to<PixelRatio>(window.pixelRatio()->getValue()); base::convert_to<PixelRatio>(window.pixelRatio()->getValue());
const UserData newUserData = window.getUserData();
if (index != sprite->transparentColor() || if (index != sprite->transparentColor() ||
pixelRatio != sprite->pixelRatio()) { pixelRatio != sprite->pixelRatio() ||
newUserData != sprite->userData()) {
Tx tx(writer.context(), "Change Sprite Properties"); Tx tx(writer.context(), "Change Sprite Properties");
DocApi api = writer.document()->getApi(tx); DocApi api = writer.document()->getApi(tx);
@ -219,6 +257,9 @@ void SpritePropertiesCommand::onExecute(Context* context)
if (pixelRatio != sprite->pixelRatio()) if (pixelRatio != sprite->pixelRatio())
tx(new cmd::SetPixelRatio(sprite, pixelRatio)); tx(new cmd::SetPixelRatio(sprite, pixelRatio));
if (newUserData != sprite->userData())
tx(new cmd::SetUserData(sprite, newUserData, static_cast<Doc*>(sprite->document())));
tx.commit(); tx.commit();
update_screen_for_document(writer.document()); update_screen_for_document(writer.document());

View File

@ -378,6 +378,10 @@ bool AseFormat::onSave(FileOp* fop)
// Write extra chunks in the first frame // Write extra chunks in the first frame
if (frame == fop->roi().fromFrame()) { if (frame == fop->roi().fromFrame()) {
// Write sprite user data only if needed
if (!sprite->userData().isEmpty())
ase_file_write_user_data_chunk(f, &frame_header, &sprite->userData());
// Write tilesets // Write tilesets
ase_file_write_tileset_chunks(f, fop, &frame_header, ext_files, ase_file_write_tileset_chunks(f, fop, &frame_header, ext_files,
sprite->tilesets()); sprite->tilesets());

View File

@ -560,6 +560,11 @@ TabIcon BrowserView::getTabIcon()
return TabIcon::NONE; return TabIcon::NONE;
} }
gfx::Color BrowserView::getTabColor()
{
return gfx::ColorNone;
}
WorkspaceView* BrowserView::cloneWorkspaceView() WorkspaceView* BrowserView::cloneWorkspaceView()
{ {
return new BrowserView(); return new BrowserView();

View File

@ -25,6 +25,7 @@ namespace app {
// TabView implementation // TabView implementation
std::string getTabText() override; std::string getTabText() override;
TabIcon getTabIcon() override; TabIcon getTabIcon() override;
gfx::Color getTabColor() override;
// WorkspaceView implementation // WorkspaceView implementation
ui::Widget* getContentWidget() override { return this; } ui::Widget* getContentWidget() override { return this; }

View File

@ -378,6 +378,11 @@ TabIcon DataRecoveryView::getTabIcon()
return TabIcon::NONE; return TabIcon::NONE;
} }
gfx::Color DataRecoveryView::getTabColor()
{
return gfx::ColorNone;
}
void DataRecoveryView::onWorkspaceViewSelected() void DataRecoveryView::onWorkspaceViewSelected()
{ {
// Do nothing // Do nothing

View File

@ -37,6 +37,7 @@ namespace app {
// TabView implementation // TabView implementation
std::string getTabText() override; std::string getTabText() override;
TabIcon getTabIcon() override; TabIcon getTabIcon() override;
gfx::Color getTabColor() override;
// WorkspaceView implementation // WorkspaceView implementation
ui::Widget* getContentWidget() override { return this; } ui::Widget* getContentWidget() override { return this; }

View File

@ -113,6 +113,11 @@ TabIcon DevConsoleView::getTabIcon()
return TabIcon::NONE; return TabIcon::NONE;
} }
gfx::Color DevConsoleView::getTabColor()
{
return gfx::ColorNone;
}
WorkspaceView* DevConsoleView::cloneWorkspaceView() WorkspaceView* DevConsoleView::cloneWorkspaceView()
{ {
return new DevConsoleView(); return new DevConsoleView();

View File

@ -32,6 +32,7 @@ namespace app {
// TabView implementation // TabView implementation
std::string getTabText() override; std::string getTabText() override;
TabIcon getTabIcon() override; TabIcon getTabIcon() override;
gfx::Color getTabColor() override;
// WorkspaceView implementation // WorkspaceView implementation
ui::Widget* getContentWidget() override { return this; } ui::Widget* getContentWidget() override { return this; }

View File

@ -38,6 +38,7 @@
#include "app/util/clipboard.h" #include "app/util/clipboard.h"
#include "app/util/range_utils.h" #include "app/util/range_utils.h"
#include "base/fs.h" #include "base/fs.h"
#include "doc/color.h"
#include "doc/layer.h" #include "doc/layer.h"
#include "doc/sprite.h" #include "doc/sprite.h"
#include "fmt/format.h" #include "fmt/format.h"
@ -234,6 +235,12 @@ TabIcon DocView::getTabIcon()
return TabIcon::NONE; return TabIcon::NONE;
} }
gfx::Color DocView::getTabColor()
{
color_t c = m_editor->sprite()->userData().color();
return gfx::rgba(doc::rgba_getr(c), doc::rgba_getg(c), doc::rgba_getb(c), doc::rgba_geta(c));
}
WorkspaceView* DocView::cloneWorkspaceView() WorkspaceView* DocView::cloneWorkspaceView()
{ {
return new DocView(m_document, Normal, m_previewDelegate); return new DocView(m_document, Normal, m_previewDelegate);

View File

@ -58,6 +58,7 @@ namespace app {
// TabView implementation // TabView implementation
std::string getTabText() override; std::string getTabText() override;
TabIcon getTabIcon() override; TabIcon getTabIcon() override;
gfx::Color getTabColor() override;
// WorkspaceView implementation // WorkspaceView implementation
ui::Widget* getContentWidget() override { return this; } ui::Widget* getContentWidget() override { return this; }

View File

@ -111,6 +111,11 @@ TabIcon HomeView::getTabIcon()
return TabIcon::HOME; return TabIcon::HOME;
} }
gfx::Color HomeView::getTabColor()
{
return gfx::ColorNone;
}
bool HomeView::onCloseView(Workspace* workspace, bool quitting) bool HomeView::onCloseView(Workspace* workspace, bool quitting)
{ {
workspace->removeView(this); workspace->removeView(this);

View File

@ -49,6 +49,7 @@ namespace app {
// TabView implementation // TabView implementation
std::string getTabText() override; std::string getTabText() override;
TabIcon getTabIcon() override; TabIcon getTabIcon() override;
gfx::Color getTabColor() override;
// WorkspaceView implementation // WorkspaceView implementation
ui::Widget* getContentWidget() override { return this; } ui::Widget* getContentWidget() override { return this; }

View File

@ -174,6 +174,7 @@ void Tabs::updateTabs()
tab->text = tab->view->getTabText(); tab->text = tab->view->getTabText();
tab->icon = tab->view->getTabIcon(); tab->icon = tab->view->getTabIcon();
tab->color = tab->view->getTabColor();
tab->x = int(x); tab->x = int(x);
tab->width = int(x+tabWidth) - int(x); tab->width = int(x+tabWidth) - int(x);
x += tabWidth; x += tabWidth;
@ -626,6 +627,10 @@ void Tabs::drawTab(Graphics* g, const gfx::Rect& _box,
// Tab with text + clipping the close button // Tab with text + clipping the close button
if (box.w > 8*ui::guiscale()) { if (box.w > 8*ui::guiscale()) {
info.text = &tab->text; info.text = &tab->text;
if (tab->color != gfx::ColorNone) {
g->fillRect(tab->color, gfx::Rect(box.x+dx+2, box.y+dy+3, box.w-dx-2, box.h-3));
g->fillRect(tab->color, gfx::Rect(box.x+dx+3, box.y+dy+2, box.w-dx-3, 1));
}
theme->paintWidgetPart( theme->paintWidgetPart(
g, theme->styles.tabText(), g, theme->styles.tabText(),
gfx::Rect(box.x+dx, box.y+dy, box.w-dx, box.h), gfx::Rect(box.x+dx, box.y+dy, box.w-dx, box.h),
@ -656,6 +661,11 @@ void Tabs::drawTab(Graphics* g, const gfx::Rect& _box,
} }
} }
if (tab->color != gfx::ColorNone) {
g->fillRect(tab->color, gfx::Rect(closeBox.x, closeBox.y+3, closeBox.w-3, closeBox.h-3));
g->fillRect(tab->color, gfx::Rect(closeBox.x, closeBox.y+2, closeBox.w-4, 1));
}
info.styleFlags = 0; info.styleFlags = 0;
if (selected) if (selected)
info.styleFlags |= ui::Style::Layer::kFocus; info.styleFlags |= ui::Style::Layer::kFocus;

View File

@ -41,6 +41,9 @@ namespace app {
// Returns the icon to be shown in the tab // Returns the icon to be shown in the tab
virtual TabIcon getTabIcon() = 0; virtual TabIcon getTabIcon() = 0;
// Returns the tab background color
virtual gfx::Color getTabColor() = 0;
}; };
enum class DropTabResult { enum class DropTabResult {
@ -116,6 +119,7 @@ namespace app {
TabView* view; TabView* view;
std::string text; std::string text;
TabIcon icon; TabIcon icon;
gfx::Color color;
int x, width; int x, width;
int oldX, oldWidth; int oldX, oldWidth;
bool modified; bool modified;
@ -124,6 +128,7 @@ namespace app {
ASSERT(view); ASSERT(view);
text = view->getTabText(); text = view->getTabText();
icon = view->getTabIcon(); icon = view->getTabIcon();
color = view->getTabColor();
x = width = oldX = oldWidth = x = width = oldX = oldWidth =
#if _DEBUG #if _DEBUG

View File

@ -82,7 +82,7 @@ bool AsepriteDecoder::decode()
// Prepare variables for layer chunks // Prepare variables for layer chunks
doc::Layer* last_layer = sprite->root(); doc::Layer* last_layer = sprite->root();
doc::WithUserData* last_object_with_user_data = nullptr; doc::WithUserData* last_object_with_user_data = sprite.get();
doc::Cel* last_cel = nullptr; doc::Cel* last_cel = nullptr;
auto tag_it = sprite->tags().begin(); auto tag_it = sprite->tags().begin();
auto tag_end = sprite->tags().end(); auto tag_end = sprite->tags().end();

View File

@ -66,7 +66,7 @@ void Sprite::SetDefaultRgbMapAlgorithm(const RgbMapAlgorithm mapAlgo)
Sprite::Sprite(const ImageSpec& spec, Sprite::Sprite(const ImageSpec& spec,
int ncolors) int ncolors)
: Object(ObjectType::Sprite) : WithUserData(ObjectType::Sprite)
, m_document(nullptr) , m_document(nullptr)
, m_spec(spec) , m_spec(spec)
, m_pixelRatio(1, 1) , m_pixelRatio(1, 1)

View File

@ -24,6 +24,7 @@
#include "doc/rgbmap_algorithm.h" #include "doc/rgbmap_algorithm.h"
#include "doc/slices.h" #include "doc/slices.h"
#include "doc/tags.h" #include "doc/tags.h"
#include "doc/with_user_data.h"
#include "gfx/rect.h" #include "gfx/rect.h"
#include <memory> #include <memory>
@ -52,7 +53,7 @@ namespace doc {
typedef std::vector<Palette*> PalettesList; typedef std::vector<Palette*> PalettesList;
// The main structure used in the whole program to handle a sprite. // The main structure used in the whole program to handle a sprite.
class Sprite : public Object { class Sprite : public WithUserData {
public: public:
enum class RgbMapFor { enum class RgbMapFor {
OpaqueLayer, OpaqueLayer,