clang-format all files

This commit is contained in:
David Capello 2024-12-16 14:52:19 -03:00
parent 35c7f5bc4e
commit 09538f9a1a
1538 changed files with 57316 additions and 63036 deletions

View File

@ -692,11 +692,11 @@
<item command="NewFile" text="@.file_new" group="file_new" />
<item command="OpenFile" text="@.file_open" group="file_open" />
<menu text="@.file_open_recent" group="file_recent">
<item command="ReopenClosedFile" text="@.file_reopen_closed" group="file_recent_reopen" />
<item command="ReopenClosedFile" text="@.file_reopen_closed" group="file_recent_reopen" />
<separator id="recent_files_placeholder" group="file_recent_list" />
<separator />
<item command="ClearRecentFiles" text="@.file_clear_recent_files" group="file_recent_clear" />
</menu>
<item command="ClearRecentFiles" text="@.file_clear_recent_files" group="file_recent_clear" />
</menu>
<separator />
<item command="SaveFile" text="@.file_save" />
<item command="SaveFileAs" text="@.file_save_as" group="file_save" />

View File

@ -8,14 +8,14 @@
<label text="Animated sprite editor &amp;&amp; pixel art tool" />
<hbox homogeneous="true">
<hbox>
<vbox expansive="true">
<vbox expansive="true">
<separator text="Developer Team" horizontal="true" />
<link text="David Capello" url="https://twitter.com/davidcapello" />
<link text="Gaspar Capello" url="https://twitter.com/Gasparoken" />
<link text="Martín Capello" url="https://twitter.com/martincapell0" />
<vbox minheight="8" />
</vbox>
<separator vertical="true" />
<vbox minheight="8" />
</vbox>
<separator vertical="true" />
</hbox>
<vbox>
<separator text="Credits" horizontal="true" cell_hspan="2" />

View File

@ -10,7 +10,7 @@
<link id="new_file" text="@.new_file" style="workspace_link" />
<link id="open_file" text="@.open_file" style="workspace_link" />
<link id="recover_sprites" text="@.recover_files" style="workspace_link"
tooltip="@.recover_files_tooltip" />
tooltip="@.recover_files_tooltip" />
</vbox>
<boxfiller />
<vbox border="4">

View File

@ -12,8 +12,8 @@
<check text="@general.dont_show" id="dont_show" tooltip="@general.dont_show_tooltip" />
<boxfiller />
<hbox homogeneous="true">
<button text="@general.ok" closewindow="true" id="ok" magnet="true" minwidth="60" />
<button text="@general.cancel" closewindow="true" />
<button text="@general.ok" closewindow="true" id="ok" magnet="true" minwidth="60" />
<button text="@general.cancel" closewindow="true" />
</hbox>
</hbox>
</grid>

View File

@ -40,7 +40,7 @@
<listbox id="actions" />
</view>
<vbox id="wheel_section" expansive="true">
<hbox>
<hbox>
<buttonset columns="2" id="wheel_behavior">
<item text="@.default_wheel_behavior" />
<item text="@.custom_wheel_behavior" />

View File

@ -30,7 +30,7 @@
<panel id="panel" expansive="true">
<!-- General -->
<!-- General -->
<vbox id="section_general">
<separator text="@.section_general" horizontal="true" />
<grid columns="3">
@ -62,7 +62,7 @@
<listitem text="300%" value="3" />
<listitem text="400%" value="4" />
</combobox>
<boxfiller />
<boxfiller />
<label text="@.language" />
<combobox id="language" />
@ -72,11 +72,11 @@
text="@.gpu_acceleration"
tooltip="@.gpu_acceleration_tooltip" />
<check id="show_menu_bar"
text="@.show_menu_bar" />
text="@.show_menu_bar" />
<check id="show_aseprite_file_dialog"
text="@.show_aseprite_file_dialog" />
<check id="show_home"
text="@.show_home" />
text="@.show_home" />
<check id="expand_menubar_on_mouseover"
text="@.expand_menu_bar_items_on_mouseover"
tooltip="@.expand_menu_bar_items_on_mouseover_tooltip" />
@ -283,27 +283,27 @@
<check text="@.modifiers_disable_handles" id="modifiers_disable_handles" tooltip="@.modifiers_disable_handles_tooltip" />
<check text="@.move_on_add_mode" id="move_on_add_mode" tooltip="@.move_on_add_mode_tooltip" />
<check text="@.select_tile_with_double_click" id="select_tile_with_double_click"
pref="selection.doubleclick_select_tile" />
pref="selection.doubleclick_select_tile" />
<check text="@.snap_to_grid_selection"
pref="selection.snap_to_grid"/>
<check text="@.force_rotsprite" id="force_rotsprite"
pref="selection.force_rotsprite"/>
pref="selection.force_rotsprite"/>
<check text="@.multicel_when_layers_or_frames" id="multicel_when_layers_or_frames"
tooltip="@.multicel_when_layers_or_frames_tooltip"
pref="selection.multicel_when_layers_or_frames"/>
tooltip="@.multicel_when_layers_or_frames_tooltip"
pref="selection.multicel_when_layers_or_frames"/>
</vbox>
<!-- Timeline -->
<vbox id="section_timeline">
<separator text="@.section_timeline" horizontal="true" />
<check text="@.autotimeline" id="autotimeline" tooltip="@.autotimeline_tooltip"
pref="general.autoshow_timeline" />
pref="general.autoshow_timeline" />
<check text="@.rewind_on_stop" id="rewind_on_stop" tooltip="@.rewind_on_stop_tooltip"
pref="general.rewind_on_stop" />
<hbox>
<label text="@.default_first_frame" />
<expr id="first_frame" />
</hbox>
pref="general.rewind_on_stop" />
<hbox>
<label text="@.default_first_frame" />
<expr id="first_frame" />
</hbox>
<separator text="@.timeline_selection" horizontal="true" />
<check id="keep_selection"
text="@.keep_timeline_selection"
@ -328,7 +328,7 @@
<boxfiller />
<button id="reset_timeline_sel" text="@general.reset" minwidth="60" />
</hbox>
</vbox>
</vbox>
<!-- Cursors -->
<vbox id="section_cursors">
@ -349,11 +349,11 @@
<grid columns="2">
<label text="@.crosshair_type" />
<combobox id="painting_cursor_type">
<listitem text="@.simple_crosshair" value="0" />
<listitem text="@.crosshair_on_sprite" value="1" />
<listitem text="@.simple_crosshair" value="0" />
<listitem text="@.crosshair_on_sprite" value="1" />
</combobox>
<label text="@.brush_preview" />
<label text="@.brush_preview" />
<combobox id="brush_preview">
<listitem text="@.brush_preview_none" value="0" />
<listitem text="@.brush_preview_edges" value="1" />
@ -362,18 +362,18 @@
<listitem text="@.brush_preview_fullnedges" value="4" />
</combobox>
<label text="@.cursor_color_type" />
<combobox id="cursor_color_type">
<listitem text="@.cursor_neg_bw" value="0" />
<listitem text="@.cursor_specific_color" value="1" />
</combobox>
<label text="@.cursor_color_type" />
<combobox id="cursor_color_type">
<listitem text="@.cursor_neg_bw" value="0" />
<listitem text="@.cursor_specific_color" value="1" />
</combobox>
<boxfiller />
<colorpicker id="cursor_color" rgba="true" />
<boxfiller />
<colorpicker id="cursor_color" rgba="true" />
<check text="@.snap_cursor_to_grid"
pref="cursor.snap_to_grid" cell_hspan="2" />
</grid>
</grid>
</vbox>
<!-- Background -->
@ -383,74 +383,74 @@
<separator text="@.bg_checkered" horizontal="true" />
<grid columns="2">
<label text="@.bg_size" />
<hbox>
<hbox>
<combobox id="checkered_bg_size" />
<expr id="checkered_bg_custom_w" />
<expr id="checkered_bg_custom_h" />
<check text="@.bg_apply_zoom" id="checkered_bg_zoom" />
</hbox>
</hbox>
<label text="@.bg_colors" />
<hbox>
<hbox>
<colorpicker id="checkered_bg_color1" rgba="true" />
<colorpicker id="checkered_bg_color2" rgba="true" />
</hbox>
</hbox>
</grid>
<hbox>
<hbox expansive="true" />
<hbox>
<hbox expansive="true" />
<button id="reset_bg" text="@general.reset" minwidth="60" />
</hbox>
</hbox>
</vbox>
<!-- Grid -->
<vbox id="section_grid">
<combobox id="grid_scope" />
<hbox>
<hbox>
<check id="grid_visible" text="@.grid_visible" />
<separator horizontal="true" expansive="true" />
</hbox>
</hbox>
<grid columns="5">
<label text="@.grid_x" />
<expr id="grid_x" text="" />
<label text="@.grid_y" />
<expr id="grid_y" text="" />
<hbox />
<grid columns="5">
<label text="@.grid_x" />
<expr id="grid_x" text="" />
<label text="@.grid_y" />
<expr id="grid_y" text="" />
<hbox />
<label text="@.grid_width" />
<expr id="grid_w" text="" />
<label text="@.grid_height" />
<expr id="grid_h" text="" />
<hbox />
<label text="@.grid_width" />
<expr id="grid_w" text="" />
<label text="@.grid_height" />
<expr id="grid_h" text="" />
<hbox />
<label text="@.grid_color" />
<colorpicker id="grid_color" rgba="true" cell_hspan="3" />
<hbox />
<hbox />
<label text="@.grid_opacity" />
<label text="@.grid_opacity" />
<slider id="grid_opacity" cell_hspan="3" min="1" max="255" width="128" />
<check id="grid_auto_opacity" text="@.grid_auto" />
</grid>
</grid>
<hbox>
<hbox>
<check id="pixel_grid_visible" text="@.grid_pixel_grid_visible" />
<separator horizontal="true" expansive="true" />
</hbox>
</hbox>
<grid columns="3">
<label text="@.grid_color" />
<colorpicker id="pixel_grid_color" rgba="true" />
<hbox />
<hbox />
<label text="@.grid_opacity" />
<label text="@.grid_opacity" />
<slider id="pixel_grid_opacity" min="1" max="255" width="128" />
<check id="pixel_grid_auto_opacity" text="@.grid_auto" />
</grid>
<hbox>
<hbox expansive="true" />
<hbox>
<hbox expansive="true" />
<button id="reset_grid" text="@general.reset" minwidth="60" />
</hbox>
</hbox>
</vbox>
<!-- Guides -->
@ -517,7 +517,7 @@
pref="color_bar.show_invalid_fg_bg_color_alert" />
<check id="run_script_alert" text="@.run_script_alert"
pref="scripts.show_run_script_alert" />
<grid columns="4">
<grid columns="4">
<label text="@.image_format_alerts" />
<check id="css_options_alert" text="!css" pref="css.show_alert" />
<check id="gif_options_alert" text="!gif" pref="gif.show_alert" />
@ -528,10 +528,10 @@
<check id="webp_options_alert" text="!webp" pref="webp.show_alert" />
</grid>
<separator horizontal="true" />
<hbox>
<hbox expansive="true" />
<hbox>
<hbox expansive="true" />
<button id="reset_alerts" text="@.reset_alerts" />
</hbox>
</hbox>
</vbox>
<!-- Theme -->
@ -539,12 +539,12 @@
<separator text="@.available_themes" horizontal="true" />
<view expansive="true" maxsize="true">
<listbox id="theme_list" />
</view>
</view>
<hbox>
<button id="select_theme" text="@.select_theme" minwidth="60" />
<button id="select_theme" text="@.select_theme" minwidth="60" />
<link text="@.download_themes" url="https://www.aseprite.org/themes/" />
<boxfiller />
<button id="open_theme_folder" text="@.open_theme_folder" minwidth="100" />
<boxfiller />
<button id="open_theme_folder" text="@.open_theme_folder" minwidth="100" />
</hbox>
</vbox>
@ -552,13 +552,13 @@
<vbox id="section_extensions">
<view expansive="true" maxsize="true">
<listbox id="extensions_list" />
</view>
</view>
<hbox>
<button id="add_extension" text="@.add_extension" minwidth="60" />
<boxfiller />
<button id="disable_extension" text="@.disable_extension" minwidth="60" />
<button id="uninstall_extension" text="@.uninstall_extension" minwidth="60" />
<button id="open_extension_folder" text="@.open_extension_folder" minwidth="60" />
<button id="add_extension" text="@.add_extension" minwidth="60" />
<boxfiller />
<button id="disable_extension" text="@.disable_extension" minwidth="60" />
<button id="uninstall_extension" text="@.uninstall_extension" minwidth="60" />
<button id="open_extension_folder" text="@.open_extension_folder" minwidth="60" />
</hbox>
</vbox>
@ -622,10 +622,10 @@
<check id="installed_reset" text="@.reset_installed" />
<check id="recent_reset" text="@.reset_recents" />
<check id="perfile_reset" text="@.reset_perfile" tooltip="@.reset_perfile_tooltip" />
<hbox>
<hbox expansive="true" />
<hbox>
<hbox expansive="true" />
<button id="reset_selected_button" text="@.reset" minwidth="60" />
</hbox>
</hbox>
</vbox>
</panel>
</hbox>

View File

@ -10,16 +10,16 @@
</grid>
<hbox>
<vbox>
<hbox>
<buttonset id="outline_type" columns="2">
<hbox>
<buttonset id="outline_type" columns="2">
<item icon="outline_circle" tooltip="@.circle" tooltip_dir="right" />
<item icon="outline_square" tooltip="@.square" tooltip_dir="left" />
<item icon="outline_horizontal" tooltip="@.horizontal" tooltip_dir="right" />
<item icon="outline_vertical" tooltip="@.vertical" tooltip_dir="left" />
</buttonset>
</hbox>
<hbox>
<buttonset id="outline_matrix" columns="3">
</buttonset>
</hbox>
<hbox>
<buttonset id="outline_matrix" columns="3">
<item icon="outline_empty_pixel" style="outline_cell" />
<item icon="outline_empty_pixel" style="outline_cell" />
<item icon="outline_empty_pixel" style="outline_cell" />
@ -29,14 +29,14 @@
<item icon="outline_empty_pixel" style="outline_cell" />
<item icon="outline_empty_pixel" style="outline_cell" />
<item icon="outline_empty_pixel" style="outline_cell" />
</buttonset>
</hbox>
</buttonset>
</hbox>
</vbox>
<vbox>
<buttonset id="place" columns="1">
<item text="@.outside" />
<item text="@.inside" />
</buttonset>
<buttonset id="place" columns="1">
<item text="@.outside" />
<item text="@.inside" />
</buttonset>
</vbox>
</hbox>
</vbox>

View File

@ -28,9 +28,9 @@
</box>
<box vertical="true" homogeneous="true" expansive="true">
<expr expansive="true" text="100" suffix="%" id="width_perc" magnet="true" tooltip="@.width_perc_tooltip"
decimals="4" />
decimals="4" />
<expr expansive="true" text="100" suffix="%" id="height_perc" tooltip="@.height_perc_tooltip"
decimals="4" />
decimals="4" />
</box>
<box horizontal="true" width="64" />
</box>

View File

@ -6,30 +6,30 @@
<vbox>
<separator cell_hspan="2" text="@.position" left="true" horizontal="true" />
<hbox>
<buttonset columns="2" id="position">
<item text="@.left" />
<item text="@.right" />
<item text="@.bottom" hspan="2" />
</buttonset>
<buttonset columns="2" id="position">
<item text="@.left" />
<item text="@.right" />
<item text="@.bottom" hspan="2" />
</buttonset>
</hbox>
</vbox>
<vbox>
<separator text="@.frame_header" left="true" horizontal="true" />
<hbox>
<label text="@.first_frame" />
<expr id="first_frame" />
<label text="@.first_frame" />
<expr id="first_frame" />
</hbox>
<hbox>
<check id="thumb_enabled" text="@.thumbnails" horizontal="true" />
<separator id="thumb_h_separator" horizontal="true" expansive="true" />
<check id="thumb_enabled" text="@.thumbnails" horizontal="true" />
<separator id="thumb_h_separator" horizontal="true" expansive="true" />
</hbox>
<grid columns="2" id="thumb_box">
<label text="@.thumbnail_size" />
<slider min="1" max="10" id="zoom" cell_align="horizontal" width="128" />
<label text="@.thumbnail_size" />
<slider min="1" max="10" id="zoom" cell_align="horizontal" width="128" />
<check id="thumb_overlay_enabled" text="@.overlay_size"/>
<slider min="2" max="10" id="thumb_overlay_size" cell_align="horizontal" width="128" />
<check id="thumb_overlay_enabled" text="@.overlay_size"/>
<slider min="2" max="10" id="thumb_overlay_size" cell_align="horizontal" width="128" />
</grid>
</vbox>
</hbox>

2
laf

@ -1 +1 @@
Subproject commit 226a22bee53e888aff8d5df524edc31c19d9c29e
Subproject commit 20d13cf0c762189650c7860bd3302a0a66cfa346

View File

@ -5,7 +5,7 @@
// the End-User License Agreement for Aseprite.
#ifdef HAVE_CONFIG_H
#include "config.h"
#include "config.h"
#endif
#include "app/active_site_handler.h"
@ -29,7 +29,7 @@ void ActiveSiteHandler::addDoc(Doc* doc)
{
Data data;
data.layer = doc::NullId;
if (doc->sprite()) { // The sprite can be nullptr in some tests
if (doc->sprite()) { // The sprite can be nullptr in some tests
if (doc::Layer* layer = doc->sprite()->root()->firstLayer())
data.layer = layer->id();
}
@ -74,7 +74,7 @@ void ActiveSiteHandler::getActiveSiteForDoc(Doc* doc, Site* site)
void ActiveSiteHandler::setActiveLayerInDoc(Doc* doc, doc::Layer* layer)
{
Data& data = getData(doc);
data.layer = (layer ? layer->id(): 0);
data.layer = (layer ? layer->id() : 0);
}
void ActiveSiteHandler::setActiveFrameInDoc(Doc* doc, doc::frame_t frame)
@ -133,9 +133,8 @@ void ActiveSiteHandler::onAddFrame(DocEvent& ev)
void ActiveSiteHandler::onBeforeRemoveLayer(DocEvent& ev)
{
Data& data = getData(ev.document());
doc::Layer* selectedLayer = (data.layer != doc::NullId ?
doc::get<doc::Layer>(data.layer):
nullptr);
doc::Layer* selectedLayer = (data.layer != doc::NullId ? doc::get<doc::Layer>(data.layer) :
nullptr);
if (!selectedLayer)
return;
@ -143,11 +142,9 @@ void ActiveSiteHandler::onBeforeRemoveLayer(DocEvent& ev)
data.range.eraseAndAdjust(ev.layer());
// Select other layer as active
doc::Layer* layerToSelect =
view::candidate_if_layer_is_deleted(selectedLayer, ev.layer());
doc::Layer* layerToSelect = view::candidate_if_layer_is_deleted(selectedLayer, ev.layer());
if (selectedLayer != layerToSelect) {
data.layer = (layerToSelect ? layerToSelect->id():
doc::NullId);
data.layer = (layerToSelect ? layerToSelect->id() : doc::NullId);
}
}

View File

@ -17,53 +17,53 @@
#include <map>
namespace doc {
class Layer;
class Layer;
}
namespace app {
class Doc;
class Site;
class Doc;
class Site;
// Pseudo-DocViews to handle active layer/frame in a non-UI context
// per Doc.
//
// TODO we could move code to handle active frame/layer from
// Timeline to this class.
class ActiveSiteHandler : public DocObserver {
public:
ActiveSiteHandler();
virtual ~ActiveSiteHandler();
// Pseudo-DocViews to handle active layer/frame in a non-UI context
// per Doc.
//
// TODO we could move code to handle active frame/layer from
// Timeline to this class.
class ActiveSiteHandler : public DocObserver {
public:
ActiveSiteHandler();
virtual ~ActiveSiteHandler();
void addDoc(Doc* doc);
void removeDoc(Doc* doc);
void getActiveSiteForDoc(Doc* doc, Site* site);
void setActiveLayerInDoc(Doc* doc, doc::Layer* layer);
void setActiveFrameInDoc(Doc* doc, doc::frame_t frame);
void setRangeInDoc(Doc* doc, const DocRange& range);
void setSelectedColorsInDoc(Doc* doc, const doc::PalettePicks& picks);
void setSelectedTilesInDoc(Doc* doc, const doc::PalettePicks& picks);
void addDoc(Doc* doc);
void removeDoc(Doc* doc);
void getActiveSiteForDoc(Doc* doc, Site* site);
void setActiveLayerInDoc(Doc* doc, doc::Layer* layer);
void setActiveFrameInDoc(Doc* doc, doc::frame_t frame);
void setRangeInDoc(Doc* doc, const DocRange& range);
void setSelectedColorsInDoc(Doc* doc, const doc::PalettePicks& picks);
void setSelectedTilesInDoc(Doc* doc, const doc::PalettePicks& picks);
private:
// DocObserver impl
void onAddLayer(DocEvent& ev) override;
void onAddFrame(DocEvent& ev) override;
void onBeforeRemoveLayer(DocEvent& ev) override;
void onRemoveFrame(DocEvent& ev) override;
private:
// DocObserver impl
void onAddLayer(DocEvent& ev) override;
void onAddFrame(DocEvent& ev) override;
void onBeforeRemoveLayer(DocEvent& ev) override;
void onRemoveFrame(DocEvent& ev) override;
// Active data for a document
struct Data {
doc::ObjectId layer;
doc::frame_t frame;
DocRange range;
doc::PalettePicks selectedColors;
doc::PalettePicks selectedTiles;
};
Data& getData(Doc* doc);
std::map<Doc*, Data> m_data;
// Active data for a document
struct Data {
doc::ObjectId layer;
doc::frame_t frame;
DocRange range;
doc::PalettePicks selectedColors;
doc::PalettePicks selectedTiles;
};
Data& getData(Doc* doc);
std::map<Doc*, Data> m_data;
};
} // namespace app
#endif

View File

@ -6,7 +6,7 @@
// the End-User License Agreement for Aseprite.
#ifdef HAVE_CONFIG_H
#include "config.h"
#include "config.h"
#endif
#include "app/app.h"
@ -109,13 +109,10 @@ namespace {
class ConsoleEngineDelegate : public script::EngineDelegate {
public:
ConsoleEngineDelegate(Console& console) : m_console(console) { }
void onConsoleError(const char* text) override {
onConsolePrint(text);
}
void onConsolePrint(const char* text) override {
m_console.printf("%s\n", text);
}
ConsoleEngineDelegate(Console& console) : m_console(console) {}
void onConsoleError(const char* text) override { onConsolePrint(text); }
void onConsolePrint(const char* text) override { m_console.printf("%s\n", text); }
private:
Console& m_console;
};
@ -149,8 +146,7 @@ public:
std::unique_ptr<app::crash::DataRecovery> m_recovery;
#endif
Modules(const bool createLogInDesktop,
Preferences& pref)
Modules(const bool createLogInDesktop, Preferences& pref)
: m_loggerModule(createLogInDesktop)
, m_strings(pref, m_extensions)
, m_activeToolManager(&m_toolbox)
@ -161,14 +157,15 @@ public:
{
}
~Modules() {
~Modules()
{
#ifdef ENABLE_DATA_RECOVERY
ASSERT(m_recovery == nullptr ||
ui::get_app_state() == ui::AppState::kClosingWithException);
ASSERT(m_recovery == nullptr || ui::get_app_state() == ui::AppState::kClosingWithException);
#endif
}
app::crash::DataRecovery* recovery() {
app::crash::DataRecovery* recovery()
{
#ifdef ENABLE_DATA_RECOVERY
return m_recovery.get();
#else
@ -176,36 +173,39 @@ public:
#endif
}
void createDataRecovery(Context* ctx) {
void createDataRecovery(Context* ctx)
{
#ifdef ENABLE_DATA_RECOVERY
#ifdef ENABLE_TRIAL_MODE
DRM_INVALID{
#ifdef ENABLE_TRIAL_MODE
DRM_INVALID
{
return;
}
#endif
#endif
m_recovery = std::make_unique<app::crash::DataRecovery>(ctx);
m_recovery->SessionsListIsReady.connect(
[] {
ui::assert_ui_thread();
auto app = App::instance();
if (app && app->mainWindow()) {
// Notify that the list of sessions is ready.
app->mainWindow()->dataRecoverySessionsAreReady();
}
});
m_recovery->SessionsListIsReady.connect([] {
ui::assert_ui_thread();
auto app = App::instance();
if (app && app->mainWindow()) {
// Notify that the list of sessions is ready.
app->mainWindow()->dataRecoverySessionsAreReady();
}
});
#endif
}
void searchDataRecoverySessions() {
void searchDataRecoverySessions()
{
#ifdef ENABLE_DATA_RECOVERY
#ifdef ENABLE_TRIAL_MODE
DRM_INVALID{
#ifdef ENABLE_TRIAL_MODE
DRM_INVALID
{
return;
}
#endif
#endif
ASSERT(m_recovery);
if (m_recovery)
@ -213,19 +213,20 @@ public:
#endif
}
void deleteDataRecovery() {
void deleteDataRecovery()
{
#ifdef ENABLE_DATA_RECOVERY
#ifdef ENABLE_TRIAL_MODE
DRM_INVALID{
#ifdef ENABLE_TRIAL_MODE
DRM_INVALID
{
return;
}
#endif
#endif
m_recovery.reset();
#endif
}
};
App* App::m_instance = nullptr;
@ -258,9 +259,8 @@ int App::initialize(const AppOptions& options)
// True if we should show a warning when running the main Aseprite
// executable (no test/benchmark) without args and the GUI is not
// available.
m_showCliOnlyWarning =
(startGui && base::utf8_icmp(base::get_file_title(options.exeName()),
get_app_name()) == 0);
m_showCliOnlyWarning = (startGui && base::utf8_icmp(base::get_file_title(options.exeName()),
get_app_name()) == 0);
#endif
// Notify the scripting engine that we're going to enter to GUI
@ -281,8 +281,7 @@ int App::initialize(const AppOptions& options)
#if LAF_WINDOWS
if (options.disableWintab() ||
!pref.experimental.loadWintabDriver() ||
if (options.disableWintab() || !pref.experimental.loadWintabDriver() ||
pref.tablet.api() == "pointer") {
tabletOptions.api = os::TabletAPI::WindowsPointerInput;
}
@ -307,20 +306,15 @@ int App::initialize(const AppOptions& options)
system->setTabletOptions(tabletOptions);
system->setAppName(get_app_name());
system->setAppMode(m_isGui ? os::AppMode::GUI:
os::AppMode::CLI);
system->setAppMode(m_isGui ? os::AppMode::GUI : os::AppMode::CLI);
if (m_isGui)
m_uiSystem.reset(new ui::UISystem);
bool createLogInDesktop = false;
switch (options.verboseLevel()) {
case AppOptions::kNoVerbose:
base::set_log_level(ERROR);
break;
case AppOptions::kVerbose:
base::set_log_level(INFO);
break;
case AppOptions::kNoVerbose: base::set_log_level(ERROR); break;
case AppOptions::kVerbose: base::set_log_level(INFO); break;
case AppOptions::kHighlyVerbose:
base::set_log_level(VERBOSE);
createLogInDesktop = true;
@ -341,7 +335,7 @@ int App::initialize(const AppOptions& options)
// Load modules
m_modules = std::make_unique<Modules>(createLogInDesktop, pref);
m_legacy = std::make_unique<LegacyModules>(isGui() ? REQUIRE_INTERFACE: 0);
m_legacy = std::make_unique<LegacyModules>(isGui() ? REQUIRE_INTERFACE : 0);
m_appMenus = std::make_unique<AppMenus>(recentFiles());
m_brushes = std::make_unique<AppBrushes>();
@ -434,47 +428,48 @@ int App::initialize(const AppOptions& options)
namespace {
struct CloseMainWindow {
std::unique_ptr<MainWindow>& m_win;
CloseMainWindow(std::unique_ptr<MainWindow>& win) : m_win(win) { }
~CloseMainWindow() { m_win.reset(nullptr); }
};
struct CloseMainWindow {
std::unique_ptr<MainWindow>& m_win;
CloseMainWindow(std::unique_ptr<MainWindow>& win) : m_win(win) {}
~CloseMainWindow() { m_win.reset(nullptr); }
};
// Deletes all docs.
struct DeleteAllDocs {
Context* m_ctx;
DeleteAllDocs(Context* ctx) : m_ctx(ctx) { }
~DeleteAllDocs() {
std::vector<Doc*> docs;
// Deletes all docs.
struct DeleteAllDocs {
Context* m_ctx;
DeleteAllDocs(Context* ctx) : m_ctx(ctx) {}
~DeleteAllDocs()
{
std::vector<Doc*> docs;
// Add all documents that were closed in the past, these docs
// are not part of any context and they are just temporarily in
// memory just in case the user wants to recover them.
for (Doc* doc : static_cast<UIContext*>(m_ctx)->getAndRemoveAllClosedDocs())
docs.push_back(doc);
// Add all documents that were closed in the past, these docs
// are not part of any context and they are just temporarily in
// memory just in case the user wants to recover them.
for (Doc* doc : static_cast<UIContext*>(m_ctx)->getAndRemoveAllClosedDocs())
docs.push_back(doc);
// Add documents that are currently opened/in tabs/in the
// context.
for (Doc* doc : m_ctx->documents())
docs.push_back(doc);
// Add documents that are currently opened/in tabs/in the
// context.
for (Doc* doc : m_ctx->documents())
docs.push_back(doc);
for (Doc* doc : docs) {
// First we close the document. In this way we receive recent
// notifications related to the document as a app::Doc. If
// we delete the document directly, we destroy the app::Doc
// too early, and then doc::~Document() call
// DocsObserver::onRemoveDocument(). In this way, observers
// could think that they have a fully created app::Doc when
// in reality it's a doc::Document (in the middle of a
// destruction process).
//
// TODO: This problem is because we're extending doc::Document,
// in the future, we should remove app::Doc.
doc->close();
delete doc;
}
for (Doc* doc : docs) {
// First we close the document. In this way we receive recent
// notifications related to the document as a app::Doc. If
// we delete the document directly, we destroy the app::Doc
// too early, and then doc::~Document() call
// DocsObserver::onRemoveDocument(). In this way, observers
// could think that they have a fully created app::Doc when
// in reality it's a doc::Document (in the middle of a
// destruction process).
//
// TODO: This problem is because we're extending doc::Document,
// in the future, we should remove app::Doc.
doc->close();
delete doc;
}
};
}
};
} // anonymous namespace
@ -488,9 +483,8 @@ void App::run()
auto manager = ui::Manager::getDefault();
#if LAF_WINDOWS
// How to interpret one finger on Windows tablets.
manager->display()->nativeWindow()
->setInterpretOneFingerGestureAsMouseMovement(
preferences().experimental.oneFingerAsMouseMovement());
manager->display()->nativeWindow()->setInterpretOneFingerGestureAsMouseMovement(
preferences().experimental.oneFingerAsMouseMovement());
#if ENABLE_WEBP
// In Windows we use a custom webp decoder for drag & drop operations.
os::set_decode_webp(util::decode_webp);
@ -507,8 +501,7 @@ void App::run()
ResourceFinder rf;
rf.includeDataDir(fmt::format("icons/ase{0}.png", size).c_str());
if (rf.findFirst()) {
os::SurfaceRef surf = os::System::instance()
->loadRgbaSurface(rf.filename().c_str());
os::SurfaceRef surf = os::System::instance()->loadRgbaSurface(rf.filename().c_str());
if (surf) {
surf->setImmutable();
icons.push_back(surf);
@ -549,8 +542,7 @@ void App::run()
#ifdef ENABLE_UPDATER
// Launch the thread to check for updates.
app::CheckUpdateThreadLauncher checkUpdate(
m_mainWindow->getCheckUpdateDelegate());
app::CheckUpdateThreadLauncher checkUpdate(m_mainWindow->getCheckUpdateDelegate());
checkUpdate.launch();
#endif
@ -586,7 +578,7 @@ void App::run()
Shell shell;
shell.run(*m_engine);
}
#endif // ENABLE_SCRIPTING
#endif // ENABLE_SCRIPTING
// ----------------------------------------------------------------------
@ -698,10 +690,8 @@ bool App::isPortable()
{
static std::optional<bool> is_portable;
if (!is_portable) {
is_portable =
base::is_file(base::join_path(
base::get_file_path(base::get_app_path()),
"aseprite.ini"));
is_portable = base::is_file(
base::join_path(base::get_file_path(base::get_app_path()), "aseprite.ini"));
}
return *is_portable;
}
@ -896,14 +886,20 @@ int app_get_color_to_clear_layer(Layer* layer)
}
#ifdef ENABLE_DRM
void app_configure_drm() {
void app_configure_drm()
{
ResourceFinder userDirRf, dataDirRf;
userDirRf.includeUserDir("");
dataDirRf.includeDataDir("");
std::map<std::string, std::string> config = {
{"data", dataDirRf.getFirstOrCreateDefault()}
{ "data", dataDirRf.getFirstOrCreateDefault() }
};
DRM_CONFIGURE(get_app_url(), get_app_name(), get_app_version(), userDirRf.getFirstOrCreateDefault(), updater::getUserAgent(), config);
DRM_CONFIGURE(get_app_url(),
get_app_name(),
get_app_version(),
userDirRf.getFirstOrCreateDefault(),
updater::getUserAgent(),
config);
}
#endif

View File

@ -19,150 +19,151 @@
#include <vector>
namespace doc {
class Layer;
class Layer;
}
namespace ui {
class UISystem;
class UISystem;
}
namespace app {
#ifdef ENABLE_SCRIPTING
namespace script {
class Engine;
}
namespace script {
class Engine;
}
#endif
class AppMenus;
class AppMod;
class AppOptions;
class BackupIndicator;
class Context;
class ContextBar;
class Doc;
class Extensions;
class INotificationDelegate;
class InputChain;
class LegacyModules;
class LoggerModule;
class MainWindow;
class Preferences;
class RecentFiles;
class Timeline;
class Workspace;
class AppMenus;
class AppMod;
class AppOptions;
class BackupIndicator;
class Context;
class ContextBar;
class Doc;
class Extensions;
class INotificationDelegate;
class InputChain;
class LegacyModules;
class LoggerModule;
class MainWindow;
class Preferences;
class RecentFiles;
class Timeline;
class Workspace;
namespace crash {
class DataRecovery;
namespace crash {
class DataRecovery;
}
namespace tools {
class ActiveToolManager;
class Tool;
class ToolBox;
} // namespace tools
using namespace doc;
class App {
public:
App(AppMod* mod = nullptr);
~App();
static App* instance() { return m_instance; }
Context* context();
// Returns true if Aseprite is running with GUI available.
bool isGui() const { return m_isGui; }
// Returns true if the application is running in portable mode.
bool isPortable();
// Runs the Aseprite application. In GUI mode it's the top-level
// window, in console/scripting it just runs the specified
// scripts.
int initialize(const AppOptions& options);
void run();
void close();
AppMod* mod() const { return m_mod; }
tools::ToolBox* toolBox() const;
tools::Tool* activeTool() const;
tools::ActiveToolManager* activeToolManager() const;
RecentFiles* recentFiles() const;
MainWindow* mainWindow() const { return m_mainWindow.get(); }
Workspace* workspace() const;
ContextBar* contextBar() const;
Timeline* timeline() const;
Preferences& preferences() const;
Extensions& extensions() const;
crash::DataRecovery* dataRecovery() const;
AppBrushes& brushes()
{
ASSERT(m_brushes.get());
return *m_brushes;
}
namespace tools {
class ActiveToolManager;
class Tool;
class ToolBox;
}
void showNotification(INotificationDelegate* del);
void showBackupNotification(bool state);
void updateDisplayTitleBar();
using namespace doc;
class App {
public:
App(AppMod* mod = nullptr);
~App();
static App* instance() { return m_instance; }
Context* context();
// Returns true if Aseprite is running with GUI available.
bool isGui() const { return m_isGui; }
// Returns true if the application is running in portable mode.
bool isPortable();
// Runs the Aseprite application. In GUI mode it's the top-level
// window, in console/scripting it just runs the specified
// scripts.
int initialize(const AppOptions& options);
void run();
void close();
AppMod* mod() const { return m_mod; }
tools::ToolBox* toolBox() const;
tools::Tool* activeTool() const;
tools::ActiveToolManager* activeToolManager() const;
RecentFiles* recentFiles() const;
MainWindow* mainWindow() const { return m_mainWindow.get(); }
Workspace* workspace() const;
ContextBar* contextBar() const;
Timeline* timeline() const;
Preferences& preferences() const;
Extensions& extensions() const;
crash::DataRecovery* dataRecovery() const;
AppBrushes& brushes() {
ASSERT(m_brushes.get());
return *m_brushes;
}
void showNotification(INotificationDelegate* del);
void showBackupNotification(bool state);
void updateDisplayTitleBar();
InputChain& inputChain();
InputChain& inputChain();
#ifdef ENABLE_SCRIPTING
script::Engine* scriptEngine() { return m_engine.get(); }
script::Engine* scriptEngine() { return m_engine.get(); }
#endif
const std::string& memoryDumpFilename() const { return m_memoryDumpFilename; }
void memoryDumpFilename(const std::string& fn) { m_memoryDumpFilename = fn; }
const std::string& memoryDumpFilename() const { return m_memoryDumpFilename; }
void memoryDumpFilename(const std::string& fn) { m_memoryDumpFilename = fn; }
// App Signals
obs::signal<void()> Exit;
obs::signal<void()> ExitGui;
obs::signal<void()> PaletteChange;
obs::signal<void()> ColorSpaceChange;
obs::signal<void()> PalettePresetsChange;
// App Signals
obs::signal<void()> Exit;
obs::signal<void()> ExitGui;
obs::signal<void()> PaletteChange;
obs::signal<void()> ColorSpaceChange;
obs::signal<void()> PalettePresetsChange;
private:
class CoreModules;
class LoadLanguage;
class Modules;
private:
class CoreModules;
class LoadLanguage;
class Modules;
static App* m_instance;
static App* m_instance;
AppMod* m_mod;
std::unique_ptr<ui::UISystem> m_uiSystem;
std::unique_ptr<CoreModules> m_coreModules;
std::unique_ptr<Modules> m_modules;
std::unique_ptr<LegacyModules> m_legacy;
std::unique_ptr<AppMenus> m_appMenus;
bool m_isGui;
bool m_isShell;
AppMod* m_mod;
std::unique_ptr<ui::UISystem> m_uiSystem;
std::unique_ptr<CoreModules> m_coreModules;
std::unique_ptr<Modules> m_modules;
std::unique_ptr<LegacyModules> m_legacy;
std::unique_ptr<AppMenus> m_appMenus;
bool m_isGui;
bool m_isShell;
#if !LAF_SKIA
bool m_showCliOnlyWarning = false;
bool m_showCliOnlyWarning = false;
#endif
#ifdef ENABLE_STEAM
bool m_inAppSteam = true;
bool m_inAppSteam = true;
#endif
std::unique_ptr<MainWindow> m_mainWindow;
base::paths m_files;
std::unique_ptr<AppBrushes> m_brushes;
std::unique_ptr<BackupIndicator> m_backupIndicator;
std::unique_ptr<MainWindow> m_mainWindow;
base::paths m_files;
std::unique_ptr<AppBrushes> m_brushes;
std::unique_ptr<BackupIndicator> m_backupIndicator;
#ifdef ENABLE_SCRIPTING
std::unique_ptr<script::Engine> m_engine;
std::unique_ptr<script::Engine> m_engine;
#endif
// Set the memory dump filename to show in the Preferences dialog
// or the "send crash" dialog. It's set by the SendCrash class.
std::string m_memoryDumpFilename;
};
// Set the memory dump filename to show in the Preferences dialog
// or the "send crash" dialog. It's set by the SendCrash class.
std::string m_memoryDumpFilename;
};
void app_refresh_screen();
void app_rebuild_documents_tabs();
PixelFormat app_get_current_pixel_format();
int app_get_color_to_clear_layer(doc::Layer* layer);
void app_configure_drm();
void app_refresh_screen();
void app_rebuild_documents_tabs();
PixelFormat app_get_current_pixel_format();
int app_get_color_to_clear_layer(doc::Layer* layer);
void app_configure_drm();
} // namespace app

View File

@ -6,7 +6,7 @@
// the End-User License Agreement for Aseprite.
#ifdef HAVE_CONFIG_H
#include "config.h"
#include "config.h"
#endif
#include "app/app_brushes.h"
@ -41,9 +41,8 @@ ImageRef load_xml_image(const XMLElement* imageElem)
ImageRef image;
int w, h;
if (imageElem->QueryIntAttribute("width", &w) != XML_SUCCESS ||
imageElem->QueryIntAttribute("height", &h) != XML_SUCCESS ||
w < 0 || w > 9999 ||
h < 0 || h > 9999)
imageElem->QueryIntAttribute("height", &h) != XML_SUCCESS || w < 0 || w > 9999 || h < 0 ||
h > 9999)
return image;
auto formatValue = imageElem->Attribute("format");
@ -66,10 +65,14 @@ ImageRef load_xml_image(const XMLElement* imageElem)
if ((end - it) < 4)
break;
int r = *it; ++it;
int g = *it; ++it;
int b = *it; ++it;
int a = *it; ++it;
int r = *it;
++it;
int g = *it;
++it;
int b = *it;
++it;
int a = *it;
++it;
pixel = doc::rgba(r, g, b, a);
}
@ -81,8 +84,10 @@ ImageRef load_xml_image(const XMLElement* imageElem)
if ((end - it) < 2)
break;
int v = *it; ++it;
int a = *it; ++it;
int v = *it;
++it;
int a = *it;
++it;
pixel = doc::graya(v, a);
}
@ -121,10 +126,10 @@ void save_xml_image(XMLElement* imageElem, const Image* image)
std::string format;
switch (image->pixelFormat()) {
case IMAGE_RGB: format = "rgba"; break;
case IMAGE_RGB: format = "rgba"; break;
case IMAGE_GRAYSCALE: format = "grayscale"; break;
case IMAGE_INDEXED: format = "indexed"; break;
case IMAGE_BITMAP: format = "bitmap"; break; // TODO add "bitmap" format
case IMAGE_INDEXED: format = "indexed"; break;
case IMAGE_BITMAP: format = "bitmap"; break; // TODO add "bitmap" format
}
ASSERT(!format.empty());
if (!format.empty())
@ -133,7 +138,7 @@ void save_xml_image(XMLElement* imageElem, const Image* image)
base::buffer data;
data.reserve(h * image->widthBytes());
switch (image->pixelFormat()) {
case IMAGE_RGB:{
case IMAGE_RGB: {
const LockImageBits<RgbTraits> pixels(image);
for (const auto& pixel : pixels) {
data.push_back(doc::rgba_getr(pixel));
@ -143,7 +148,7 @@ void save_xml_image(XMLElement* imageElem, const Image* image)
}
break;
}
case IMAGE_GRAYSCALE:{
case IMAGE_GRAYSCALE: {
const LockImageBits<GrayscaleTraits> pixels(image);
for (const auto& pixel : pixels) {
data.push_back(doc::graya_getv(pixel));
@ -173,7 +178,7 @@ void save_xml_image(XMLElement* imageElem, const Image* image)
imageElem->InsertNewText(data_base64.c_str());
}
} // anonymous namespace
} // anonymous namespace
AppBrushes::AppBrushes()
{
@ -187,8 +192,7 @@ AppBrushes::AppBrushes()
load(fn);
}
catch (const std::exception& ex) {
LOG(ERROR, "BRSH: Error loading user brushes from '%s': %s\n",
fn.c_str(), ex.what());
LOG(ERROR, "BRSH: Error loading user brushes from '%s': %s\n", fn.c_str(), ex.what());
}
}
m_userBrushesFilename = fn;
@ -202,8 +206,10 @@ AppBrushes::~AppBrushes()
}
// We cannot throw exceptions from a destructor
catch (const std::exception& ex) {
LOG(ERROR, "BRSH: Error saving user brushes to '%s': %s\n",
m_userBrushesFilename.c_str(), ex.what());
LOG(ERROR,
"BRSH: Error saving user brushes to '%s': %s\n",
m_userBrushesFilename.c_str(),
ex.what());
}
}
}
@ -211,10 +217,10 @@ AppBrushes::~AppBrushes()
AppBrushes::slot_id AppBrushes::addBrushSlot(const BrushSlot& brush)
{
// Use an empty slot
for (size_t i=0; i<m_slots.size(); ++i) {
for (size_t i = 0; i < m_slots.size(); ++i) {
if (!m_slots[i].locked() || m_slots[i].isEmpty()) {
m_slots[i] = brush;
return i+1;
return i + 1;
}
}
@ -230,8 +236,7 @@ void AppBrushes::removeBrushSlot(slot_id slot)
m_slots[slot] = BrushSlot();
// Erase empty trailing slots
while (!m_slots.empty() &&
m_slots[m_slots.size()-1].isEmpty())
while (!m_slots.empty() && m_slots[m_slots.size() - 1].isEmpty())
m_slots.erase(--m_slots.end());
ItemsChange();
@ -249,8 +254,7 @@ void AppBrushes::removeAllBrushSlots()
bool AppBrushes::hasBrushSlot(slot_id slot) const
{
--slot;
return (slot >= 0 && slot < (int)m_slots.size() &&
!m_slots[slot].isEmpty());
return (slot >= 0 && slot < (int)m_slots.size() && !m_slots[slot].isEmpty());
}
BrushSlot AppBrushes::getBrushSlot(slot_id slot) const
@ -274,8 +278,7 @@ void AppBrushes::setBrushSlot(slot_id slot, const BrushSlot& brush)
void AppBrushes::lockBrushSlot(slot_id slot)
{
--slot;
if (slot >= 0 && slot < (int)m_slots.size() &&
!m_slots[slot].isEmpty()) {
if (slot >= 0 && slot < (int)m_slots.size() && !m_slots[slot].isEmpty()) {
m_slots[slot].setLocked(true);
}
}
@ -283,8 +286,7 @@ void AppBrushes::lockBrushSlot(slot_id slot)
void AppBrushes::unlockBrushSlot(slot_id slot)
{
--slot;
if (slot >= 0 && slot < (int)m_slots.size() &&
!m_slots[slot].isEmpty()) {
if (slot >= 0 && slot < (int)m_slots.size() && !m_slots[slot].isEmpty()) {
m_slots[slot].setLocked(false);
}
}
@ -292,26 +294,22 @@ void AppBrushes::unlockBrushSlot(slot_id slot)
bool AppBrushes::isBrushSlotLocked(slot_id slot) const
{
--slot;
if (slot >= 0 && slot < (int)m_slots.size() &&
!m_slots[slot].isEmpty()) {
if (slot >= 0 && slot < (int)m_slots.size() && !m_slots[slot].isEmpty()) {
return m_slots[slot].locked();
}
else
return false;
}
static const int kBrushFlags =
int(BrushSlot::Flags::BrushType) |
int(BrushSlot::Flags::BrushSize) |
int(BrushSlot::Flags::BrushAngle);
static const int kBrushFlags = int(BrushSlot::Flags::BrushType) | int(BrushSlot::Flags::BrushSize) |
int(BrushSlot::Flags::BrushAngle);
void AppBrushes::load(const std::string& filename)
{
XMLDocumentRef doc = app::open_xml(filename);
XMLHandle handle(doc.get());
XMLElement* brushElem = handle
.FirstChildElement("brushes")
.FirstChildElement("brush").ToElement();
XMLElement* brushElem =
handle.FirstChildElement("brushes").FirstChildElement("brush").ToElement();
while (brushElem) {
// flags
@ -329,14 +327,15 @@ void AppBrushes::load(const std::string& filename)
const char* size = brushElem->Attribute("size");
const char* angle = brushElem->Attribute("angle");
if (type || size || angle) {
if (type) flags |= int(BrushSlot::Flags::BrushType);
if (size) flags |= int(BrushSlot::Flags::BrushSize);
if (angle) flags |= int(BrushSlot::Flags::BrushAngle);
brush.reset(
new Brush(
(type ? string_id_to_brush_type(type): kFirstBrushType),
(size ? base::convert_to<int>(std::string(size)): 1),
(angle ? base::convert_to<int>(std::string(angle)): 0)));
if (type)
flags |= int(BrushSlot::Flags::BrushType);
if (size)
flags |= int(BrushSlot::Flags::BrushSize);
if (angle)
flags |= int(BrushSlot::Flags::BrushAngle);
brush.reset(new Brush((type ? string_id_to_brush_type(type) : kFirstBrushType),
(size ? base::convert_to<int>(std::string(size)) : 1),
(angle ? base::convert_to<int>(std::string(angle)) : 0)));
}
// Brush image
@ -397,16 +396,19 @@ void AppBrushes::load(const std::string& filename)
}
// Image color (enabled by default for backward compatibility)
if (!brushElem->Attribute("imagecolor") ||
bool_attr(brushElem, "imagecolor", false))
if (!brushElem->Attribute("imagecolor") || bool_attr(brushElem, "imagecolor", false))
flags |= int(BrushSlot::Flags::ImageColor);
if (flags != 0)
flags |= int(BrushSlot::Flags::Locked);
BrushSlot brushSlot(BrushSlot::Flags(flags),
brush, fgColor, bgColor,
inkType, inkOpacity, shade,
brush,
fgColor,
bgColor,
inkType,
inkOpacity,
shade,
pixelPerfect);
m_slots.push_back(brushSlot);
@ -437,8 +439,7 @@ void AppBrushes::save(const std::string& filename) const
ASSERT(slot.brush());
if (flags & int(BrushSlot::Flags::BrushType)) {
brushElem->SetAttribute(
"type", brush_type_to_string_id(slot.brush()->type()).c_str());
brushElem->SetAttribute("type", brush_type_to_string_id(slot.brush()->type()).c_str());
}
if (flags & int(BrushSlot::Flags::BrushSize)) {
@ -449,8 +450,7 @@ void AppBrushes::save(const std::string& filename) const
brushElem->SetAttribute("angle", slot.brush()->angle());
}
if (slot.brush()->type() == kImageBrushType &&
slot.brush()->originalImage()) {
if (slot.brush()->type() == kImageBrushType && slot.brush()->originalImage()) {
XMLElement* elem = brushElem->InsertNewChildElement("image");
save_xml_image(elem, slot.brush()->originalImage());
@ -460,9 +460,8 @@ void AppBrushes::save(const std::string& filename) const
}
// Image color
brushElem->SetAttribute(
"imagecolor",
(flags & int(BrushSlot::Flags::ImageColor)) ? "true": "false");
brushElem->SetAttribute("imagecolor",
(flags & int(BrushSlot::Flags::ImageColor)) ? "true" : "false");
}
}
@ -480,8 +479,7 @@ void AppBrushes::save(const std::string& filename) const
// Ink
if (flags & int(BrushSlot::Flags::InkType)) {
XMLElement* elem = brushElem->InsertNewChildElement("inktype");
elem->SetAttribute(
"value", app::tools::ink_type_to_string_id(slot.inkType()).c_str());
elem->SetAttribute("value", app::tools::ink_type_to_string_id(slot.inkType()).c_str());
}
if (flags & int(BrushSlot::Flags::InkOpacity)) {
@ -498,7 +496,7 @@ void AppBrushes::save(const std::string& filename) const
// Pixel-perfect
if (flags & int(BrushSlot::Flags::PixelPerfect)) {
XMLElement* elem = brushElem->InsertNewChildElement("pixelperfect");
elem->SetAttribute("value", slot.pixelPerfect() ? "true": "false");
elem->SetAttribute("value", slot.pixelPerfect() ? "true" : "false");
}
}
}

View File

@ -18,41 +18,41 @@
namespace app {
class AppBrushes {
public:
// Number of slot (a range from 1 to AppBrushes::size() inclusive)
typedef int slot_id;
typedef std::vector<BrushSlot> BrushSlots;
class AppBrushes {
public:
// Number of slot (a range from 1 to AppBrushes::size() inclusive)
typedef int slot_id;
typedef std::vector<BrushSlot> BrushSlots;
AppBrushes();
~AppBrushes();
AppBrushes();
~AppBrushes();
// Adds a new brush and returns the slot number where the brush
// is now available.
slot_id addBrushSlot(const BrushSlot& brush);
void removeBrushSlot(slot_id slot);
void removeAllBrushSlots();
bool hasBrushSlot(slot_id slot) const;
const doc::Brushes& getStandardBrushes() { return m_standard; }
BrushSlot getBrushSlot(slot_id slot) const;
void setBrushSlot(slot_id slot, const BrushSlot& brush);
const BrushSlots& getBrushSlots() const { return m_slots; }
// Adds a new brush and returns the slot number where the brush
// is now available.
slot_id addBrushSlot(const BrushSlot& brush);
void removeBrushSlot(slot_id slot);
void removeAllBrushSlots();
bool hasBrushSlot(slot_id slot) const;
const doc::Brushes& getStandardBrushes() { return m_standard; }
BrushSlot getBrushSlot(slot_id slot) const;
void setBrushSlot(slot_id slot, const BrushSlot& brush);
const BrushSlots& getBrushSlots() const { return m_slots; }
void lockBrushSlot(slot_id slot);
void unlockBrushSlot(slot_id slot);
bool isBrushSlotLocked(slot_id slot) const;
void lockBrushSlot(slot_id slot);
void unlockBrushSlot(slot_id slot);
bool isBrushSlotLocked(slot_id slot) const;
obs::signal<void()> ItemsChange;
obs::signal<void()> ItemsChange;
private:
void load(const std::string& filename);
void save(const std::string& filename) const;
static std::string userBrushesFilename();
private:
void load(const std::string& filename);
void save(const std::string& filename) const;
static std::string userBrushesFilename();
doc::Brushes m_standard;
BrushSlots m_slots;
std::string m_userBrushesFilename;
};
doc::Brushes m_standard;
BrushSlots m_slots;
std::string m_userBrushesFilename;
};
} // namespace app

View File

@ -6,7 +6,7 @@
// the End-User License Agreement for Aseprite.
#ifdef HAVE_CONFIG_H
#include "config.h"
#include "config.h"
#endif
#include "app/app_menus.h"
@ -37,11 +37,11 @@
#include "tinyxml2.h"
#include <algorithm>
#include <cctype>
#include <cstdlib>
#include <cstring>
#include <string>
#include <algorithm>
#include <cstdlib>
#define MENUS_TRACE(...) // TRACEARGS
@ -53,18 +53,18 @@ using namespace ui;
namespace {
// TODO Move this to "os" layer
const int kUnicodeEsc = 27;
const int kUnicodeEnter = '\r'; // 10
const int kUnicodeInsert = 0xF727; // NSInsertFunctionKey
const int kUnicodeDel = 0xF728; // NSDeleteFunctionKey
const int kUnicodeHome = 0xF729; // NSHomeFunctionKey
const int kUnicodeEnd = 0xF72B; // NSEndFunctionKey
const int kUnicodePageUp = 0xF72C; // NSPageUpFunctionKey
const int kUnicodeEsc = 27;
const int kUnicodeEnter = '\r'; // 10
const int kUnicodeInsert = 0xF727; // NSInsertFunctionKey
const int kUnicodeDel = 0xF728; // NSDeleteFunctionKey
const int kUnicodeHome = 0xF729; // NSHomeFunctionKey
const int kUnicodeEnd = 0xF72B; // NSEndFunctionKey
const int kUnicodePageUp = 0xF72C; // NSPageUpFunctionKey
const int kUnicodePageDown = 0xF72D; // NSPageDownFunctionKey
const int kUnicodeLeft = 0xF702; // NSLeftArrowFunctionKey
const int kUnicodeRight = 0xF703; // NSRightArrowFunctionKey
const int kUnicodeUp = 0xF700; // NSUpArrowFunctionKey
const int kUnicodeDown = 0xF701; // NSDownArrowFunctionKey
const int kUnicodeLeft = 0xF702; // NSLeftArrowFunctionKey
const int kUnicodeRight = 0xF703; // NSRightArrowFunctionKey
const int kUnicodeUp = 0xF700; // NSUpArrowFunctionKey
const int kUnicodeDown = 0xF701; // NSDownArrowFunctionKey
const char* kFileRecentListGroup = "file_recent_list";
@ -75,22 +75,12 @@ bool is_text_entry_shortcut(const os::Shortcut& shortcut)
const int lchr = std::tolower(chr);
bool result =
((mod == os::KeyModifiers::kKeyNoneModifier ||
mod == os::KeyModifiers::kKeyShiftModifier) &&
chr >= 32 && chr < 0xF000)
||
((mod == os::KeyModifiers::kKeyCmdModifier ||
mod == os::KeyModifiers::kKeyCtrlModifier) &&
(lchr == 'a' || lchr == 'c' || lchr == 'v' || lchr == 'x'))
||
(chr == kUnicodeInsert ||
chr == kUnicodeDel ||
chr == kUnicodeHome ||
chr == kUnicodeEnd ||
chr == kUnicodeLeft ||
chr == kUnicodeRight ||
chr == kUnicodeEsc ||
chr == kUnicodeEnter);
((mod == os::KeyModifiers::kKeyNoneModifier || mod == os::KeyModifiers::kKeyShiftModifier) &&
chr >= 32 && chr < 0xF000) ||
((mod == os::KeyModifiers::kKeyCmdModifier || mod == os::KeyModifiers::kKeyCtrlModifier) &&
(lchr == 'a' || lchr == 'c' || lchr == 'v' || lchr == 'x')) ||
(chr == kUnicodeInsert || chr == kUnicodeDel || chr == kUnicodeHome || chr == kUnicodeEnd ||
chr == kUnicodeLeft || chr == kUnicodeRight || chr == kUnicodeEsc || chr == kUnicodeEnter);
return result;
}
@ -120,8 +110,7 @@ bool can_call_global_shortcut(const AppMenuItem::Native* native)
// prefer text input, so we cannot call shortcuts without
// modifiers (e.g. F or T keystrokes) to trigger a global command
// in a text field.
(focus == nullptr ||
focus->type() != ui::kEntryWidget ||
(focus == nullptr || focus->type() != ui::kEntryWidget ||
!is_text_entry_shortcut(native->shortcut)) &&
(native->keyContext == KeyContext::Any ||
native->keyContext == KeyboardShortcuts::instance()->getCurrentKeyContext());
@ -132,133 +121,133 @@ bool can_call_global_shortcut(const AppMenuItem::Native* native)
int from_scancode_to_unicode(KeyScancode scancode)
{
static int map[] = {
0, // kKeyNil
'a', // kKeyA
'b', // kKeyB
'c', // kKeyC
'd', // kKeyD
'e', // kKeyE
'f', // kKeyF
'g', // kKeyG
'h', // kKeyH
'i', // kKeyI
'j', // kKeyJ
'k', // kKeyK
'l', // kKeyL
'm', // kKeyM
'n', // kKeyN
'o', // kKeyO
'p', // kKeyP
'q', // kKeyQ
'r', // kKeyR
's', // kKeyS
't', // kKeyT
'u', // kKeyU
'v', // kKeyV
'w', // kKeyW
'x', // kKeyX
'y', // kKeyY
'z', // kKeyZ
'0', // kKey0
'1', // kKey1
'2', // kKey2
'3', // kKey3
'4', // kKey4
'5', // kKey5
'6', // kKey6
'7', // kKey7
'8', // kKey8
'9', // kKey9
0, // kKey0Pad
0, // kKey1Pad
0, // kKey2Pad
0, // kKey3Pad
0, // kKey4Pad
0, // kKey5Pad
0, // kKey6Pad
0, // kKey7Pad
0, // kKey8Pad
0, // kKey9Pad
0xF704, // kKeyF1 (NSF1FunctionKey)
0xF705, // kKeyF2
0xF706, // kKeyF3
0xF707, // kKeyF4
0xF708, // kKeyF5
0xF709, // kKeyF6
0xF70A, // kKeyF7
0xF70B, // kKeyF8
0xF70C, // kKeyF9
0xF70D, // kKeyF10
0xF70E, // kKeyF11
0xF70F, // kKeyF12
kUnicodeEsc, // kKeyEsc
'~', // kKeyTilde
'-', // kKeyMinus
'=', // kKeyEquals
8, // kKeyBackspace
9, // kKeyTab
'[', // kKeyOpenbrace
']', // kKeyClosebrace
kUnicodeEnter, // kKeyEnter
':', // kKeyColon
'\'', // kKeyQuote
'\\', // kKeyBackslash
0, // kKeyBackslash2
',', // kKeyComma
'.', // kKeyStop
'/', // kKeySlash
' ', // kKeySpace
kUnicodeInsert, // kKeyInsert (NSInsertFunctionKey)
kUnicodeDel, // kKeyDel (NSDeleteFunctionKey)
kUnicodeHome, // kKeyHome (NSHomeFunctionKey)
kUnicodeEnd, // kKeyEnd (NSEndFunctionKey)
kUnicodePageUp, // kKeyPageUp (NSPageUpFunctionKey)
0, // kKeyNil
'a', // kKeyA
'b', // kKeyB
'c', // kKeyC
'd', // kKeyD
'e', // kKeyE
'f', // kKeyF
'g', // kKeyG
'h', // kKeyH
'i', // kKeyI
'j', // kKeyJ
'k', // kKeyK
'l', // kKeyL
'm', // kKeyM
'n', // kKeyN
'o', // kKeyO
'p', // kKeyP
'q', // kKeyQ
'r', // kKeyR
's', // kKeyS
't', // kKeyT
'u', // kKeyU
'v', // kKeyV
'w', // kKeyW
'x', // kKeyX
'y', // kKeyY
'z', // kKeyZ
'0', // kKey0
'1', // kKey1
'2', // kKey2
'3', // kKey3
'4', // kKey4
'5', // kKey5
'6', // kKey6
'7', // kKey7
'8', // kKey8
'9', // kKey9
0, // kKey0Pad
0, // kKey1Pad
0, // kKey2Pad
0, // kKey3Pad
0, // kKey4Pad
0, // kKey5Pad
0, // kKey6Pad
0, // kKey7Pad
0, // kKey8Pad
0, // kKey9Pad
0xF704, // kKeyF1 (NSF1FunctionKey)
0xF705, // kKeyF2
0xF706, // kKeyF3
0xF707, // kKeyF4
0xF708, // kKeyF5
0xF709, // kKeyF6
0xF70A, // kKeyF7
0xF70B, // kKeyF8
0xF70C, // kKeyF9
0xF70D, // kKeyF10
0xF70E, // kKeyF11
0xF70F, // kKeyF12
kUnicodeEsc, // kKeyEsc
'~', // kKeyTilde
'-', // kKeyMinus
'=', // kKeyEquals
8, // kKeyBackspace
9, // kKeyTab
'[', // kKeyOpenbrace
']', // kKeyClosebrace
kUnicodeEnter, // kKeyEnter
':', // kKeyColon
'\'', // kKeyQuote
'\\', // kKeyBackslash
0, // kKeyBackslash2
',', // kKeyComma
'.', // kKeyStop
'/', // kKeySlash
' ', // kKeySpace
kUnicodeInsert, // kKeyInsert (NSInsertFunctionKey)
kUnicodeDel, // kKeyDel (NSDeleteFunctionKey)
kUnicodeHome, // kKeyHome (NSHomeFunctionKey)
kUnicodeEnd, // kKeyEnd (NSEndFunctionKey)
kUnicodePageUp, // kKeyPageUp (NSPageUpFunctionKey)
kUnicodePageDown, // kKeyPageDown (NSPageDownFunctionKey)
kUnicodeLeft, // kKeyLeft (NSLeftArrowFunctionKey)
kUnicodeRight, // kKeyRight (NSRightArrowFunctionKey)
kUnicodeUp, // kKeyUp (NSUpArrowFunctionKey)
kUnicodeDown, // kKeyDown (NSDownArrowFunctionKey)
'/', // kKeySlashPad
'*', // kKeyAsterisk
0, // kKeyMinusPad
0, // kKeyPlusPad
0, // kKeyDelPad
0, // kKeyEnterPad
0, // kKeyPrtscr
0, // kKeyPause
0, // kKeyAbntC1
0, // kKeyYen
0, // kKeyKana
0, // kKeyConvert
0, // kKeyNoconvert
0, // kKeyAt
0, // kKeyCircumflex
0, // kKeyColon2
0, // kKeyKanji
0, // kKeyEqualsPad
'`', // kKeyBackquote
0, // kKeySemicolon
0, // kKeyUnknown1
0, // kKeyUnknown2
0, // kKeyUnknown3
0, // kKeyUnknown4
0, // kKeyUnknown5
0, // kKeyUnknown6
0, // kKeyUnknown7
0, // kKeyUnknown8
0, // kKeyLShift
0, // kKeyRShift
0, // kKeyLControl
0, // kKeyRControl
0, // kKeyAlt
0, // kKeyAltGr
0, // kKeyLWin
0, // kKeyRWin
0, // kKeyMenu
0, // kKeyCommand
0, // kKeyScrLock
0, // kKeyNumLock
0, // kKeyCapsLock
kUnicodeLeft, // kKeyLeft (NSLeftArrowFunctionKey)
kUnicodeRight, // kKeyRight (NSRightArrowFunctionKey)
kUnicodeUp, // kKeyUp (NSUpArrowFunctionKey)
kUnicodeDown, // kKeyDown (NSDownArrowFunctionKey)
'/', // kKeySlashPad
'*', // kKeyAsterisk
0, // kKeyMinusPad
0, // kKeyPlusPad
0, // kKeyDelPad
0, // kKeyEnterPad
0, // kKeyPrtscr
0, // kKeyPause
0, // kKeyAbntC1
0, // kKeyYen
0, // kKeyKana
0, // kKeyConvert
0, // kKeyNoconvert
0, // kKeyAt
0, // kKeyCircumflex
0, // kKeyColon2
0, // kKeyKanji
0, // kKeyEqualsPad
'`', // kKeyBackquote
0, // kKeySemicolon
0, // kKeyUnknown1
0, // kKeyUnknown2
0, // kKeyUnknown3
0, // kKeyUnknown4
0, // kKeyUnknown5
0, // kKeyUnknown6
0, // kKeyUnknown7
0, // kKeyUnknown8
0, // kKeyLShift
0, // kKeyRShift
0, // kKeyLControl
0, // kKeyRControl
0, // kKeyAlt
0, // kKeyAltGr
0, // kKeyLWin
0, // kKeyRWin
0, // kKeyMenu
0, // kKeyCommand
0, // kKeyScrLock
0, // kKeyNumLock
0, // kKeyCapsLock
};
if (scancode >= 0 && scancode < sizeof(map) / sizeof(map[0]))
return map[scancode];
@ -266,9 +255,8 @@ int from_scancode_to_unicode(KeyScancode scancode)
return 0;
}
AppMenuItem::Native get_native_shortcut_for_command(
const char* commandId,
const Params& params = Params())
AppMenuItem::Native get_native_shortcut_for_command(const char* commandId,
const Params& params = Params())
{
AppMenuItem::Native native;
KeyPtr key = KeyboardShortcuts::instance()->command(commandId, params);
@ -307,8 +295,7 @@ os::Shortcut get_os_shortcut_from_key(const Key* key)
#endif
return os::Shortcut(
(accel.unicodeChar() ? accel.unicodeChar():
from_scancode_to_unicode(accel.scancode())),
(accel.unicodeChar() ? accel.unicodeChar() : from_scancode_to_unicode(accel.scancode())),
accel.modifiers());
}
else
@ -323,15 +310,11 @@ AppMenus* AppMenus::instance()
return s_instance;
}
AppMenus::AppMenus(RecentFiles* recentFiles)
: m_recentFilesPlaceholder(nullptr)
, m_osMenu(nullptr)
AppMenus::AppMenus(RecentFiles* recentFiles) : m_recentFilesPlaceholder(nullptr), m_osMenu(nullptr)
{
ASSERT(s_instance == nullptr);
s_instance = this;
m_recentFilesConn =
recentFiles->Changed.connect(
[this]{ rebuildRecentList(); });
m_recentFilesConn = recentFiles->Changed.connect([this] { rebuildRecentList(); });
}
AppMenus::~AppMenus()
@ -386,8 +369,7 @@ void AppMenus::reload()
// Add one menu item to run each script from the user scripts/ folder
{
MenuItem* scriptsMenu = dynamic_cast<MenuItem*>(
m_rootMenu->findItemById("scripts_menu"));
MenuItem* scriptsMenu = dynamic_cast<MenuItem*>(m_rootMenu->findItemById("scripts_menu"));
#ifdef ENABLE_SCRIPTING
// Load scripts
ResourceFinder rf;
@ -455,9 +437,7 @@ void AppMenus::reload()
LOG("MENU: Loading commands keyboard shortcuts from %s\n", path);
XMLElement* xmlKey = handle
.FirstChildElement("gui")
.FirstChildElement("keyboard").ToElement();
XMLElement* xmlKey = handle.FirstChildElement("gui").FirstChildElement("keyboard").ToElement();
// From a fresh start, load the default keys
KeyboardShortcuts::instance()->clear();
@ -465,11 +445,9 @@ void AppMenus::reload()
// Load extension-defined keys
for (const Extension* ext : App::instance()->extensions()) {
if (ext->isEnabled() &&
ext->hasKeys()) {
if (ext->isEnabled() && ext->hasKeys()) {
for (const auto& kv : ext->keys()) {
KeyboardShortcuts::instance()->importFile(
kv.second, KeySource::ExtensionDefined);
KeyboardShortcuts::instance()->importFile(kv.second, KeySource::ExtensionDefined);
}
}
}
@ -489,15 +467,12 @@ void AppMenus::reload()
}
#ifdef ENABLE_SCRIPTING
void AppMenus::loadScriptsSubmenu(ui::Menu* menu,
const std::string& dir,
const bool rootLevel)
void AppMenus::loadScriptsSubmenu(ui::Menu* menu, const std::string& dir, const bool rootLevel)
{
auto files = base::list_files(dir);
std::sort(files.begin(), files.end(),
[](const std::string& a, const std::string& b) {
return base::compare_filenames(a, b) < 0;
});
std::sort(files.begin(), files.end(), [](const std::string& a, const std::string& b) {
return base::compare_filenames(a, b) < 0;
});
int insertPos = 0;
for (auto fn : files) {
std::string fullFn = base::join_path(dir, fn);
@ -510,18 +485,15 @@ void AppMenus::loadScriptsSubmenu(ui::Menu* menu,
if (base::string_to_lower(base::get_file_extension(fn)) == "lua") {
Params params;
params.set("filename", fullFn.c_str());
menuitem = new AppMenuItem(
base::get_file_title(fn).c_str(),
CommandId::RunScript(),
params);
menuitem =
new AppMenuItem(base::get_file_title(fn).c_str(), CommandId::RunScript(), params);
}
}
else if (base::is_directory(fullFn)) {
Menu* submenu = new Menu();
loadScriptsSubmenu(submenu, fullFn, false);
menuitem = new AppMenuItem(
base::get_file_title(fn).c_str());
menuitem = new AppMenuItem(base::get_file_title(fn).c_str());
menuitem->setSubmenu(submenu);
}
if (menuitem) {
@ -543,7 +515,8 @@ void AppMenus::initTheme()
bool AppMenus::rebuildRecentList()
{
MENUS_TRACE("MENUS: AppMenus::rebuildRecentList m_recentFilesPlaceholder=", m_recentFilesPlaceholder);
MENUS_TRACE("MENUS: AppMenus::rebuildRecentList m_recentFilesPlaceholder=",
m_recentFilesPlaceholder);
if (!m_recentFilesPlaceholder)
return true;
@ -563,21 +536,15 @@ bool AppMenus::rebuildRecentList()
auto recent = App::instance()->recentFiles();
base::paths files;
files.insert(files.end(),
recent->pinnedFiles().begin(),
recent->pinnedFiles().end());
files.insert(files.end(),
recent->recentFiles().begin(),
recent->recentFiles().end());
files.insert(files.end(), recent->pinnedFiles().begin(), recent->pinnedFiles().end());
files.insert(files.end(), recent->recentFiles().begin(), recent->recentFiles().end());
if (!files.empty()) {
Params params;
for (const auto& fn : files) {
params.set("filename", fn.c_str());
std::unique_ptr<AppMenuItem> menuitem(
new AppMenuItem(base::get_file_name(fn).c_str(),
CommandId::OpenFile(),
params));
new AppMenuItem(base::get_file_name(fn).c_str(), CommandId::OpenFile(), params));
menuitem->setIsRecentFileItem(true);
m_recentMenuItems.push_back(menuitem.get());
@ -585,9 +552,8 @@ bool AppMenus::rebuildRecentList()
}
}
else {
std::unique_ptr<AppMenuItem> menuitem(
new AppMenuItem(
Strings::main_menu_file_no_recent_file()));
std::unique_ptr<AppMenuItem> menuitem(
new AppMenuItem(Strings::main_menu_file_no_recent_file()));
menuitem->setIsRecentFileItem(true);
menuitem->setEnabled(false);
@ -596,10 +562,9 @@ bool AppMenus::rebuildRecentList()
}
// Sync native menus
if (owner->native() &&
owner->native()->menuItem) {
if (owner->native() && owner->native()->menuItem) {
auto menus = os::System::instance()->menus();
os::MenuRef osMenu = (menus ? menus->makeMenu(): nullptr);
os::MenuRef osMenu = (menus ? menus->makeMenu() : nullptr);
if (osMenu) {
createNativeSubmenus(osMenu.get(), menu);
owner->native()->menuItem->setSubmenu(osMenu);
@ -611,16 +576,14 @@ bool AppMenus::rebuildRecentList()
Menu* AppMenus::getAnimationMenu()
{
auto menuItem =
dynamic_cast<MenuItem*>(m_rootMenu->findItemById("animation_menu"));
auto menuItem = dynamic_cast<MenuItem*>(m_rootMenu->findItemById("animation_menu"));
if (menuItem)
return menuItem->getSubmenu();
else
return nullptr;
}
void AppMenus::addMenuGroup(const std::string& groupId,
MenuItem* menuItem)
void AppMenus::addMenuGroup(const std::string& groupId, MenuItem* menuItem)
{
GroupInfo& group = m_groups[groupId];
ASSERT(group.menu == nullptr);
@ -639,22 +602,20 @@ void AppMenus::removeMenuGroup(const std::string& groupId)
if (group.menu->getOwnerMenuItem()) {
ui::MenuItem* item = group.menu->getOwnerMenuItem();
removeMenuItemFromGroup(
[item](Widget* i){
return item == i;
});
removeMenuItemFromGroup([item](Widget* i) { return item == i; });
}
m_groups.erase(it);
}
}
void AppMenus::addMenuItemIntoGroup(const std::string& groupId,
std::unique_ptr<Widget>&& menuItem)
void AppMenus::addMenuItemIntoGroup(const std::string& groupId, std::unique_ptr<Widget>&& menuItem)
{
auto it = m_groups.find(groupId);
if (it == m_groups.end()) {
LOG(ERROR, "MENU: An extension tried to add a command (%s) in a non-existent group (%s)\n",
menuItem->text().c_str(), groupId.c_str());
LOG(ERROR,
"MENU: An extension tried to add a command (%s) in a non-existent group (%s)\n",
menuItem->text().c_str(),
groupId.c_str());
menuItem.release();
return;
}
@ -666,7 +627,7 @@ void AppMenus::addMenuItemIntoGroup(const std::string& groupId,
if (group.end) {
int insertIndex = menu->getChildIndex(group.end);
ASSERT(insertIndex >= 0);
menu->insertChild(insertIndex+1, menuItem.get());
menu->insertChild(insertIndex + 1, menuItem.get());
}
else {
menu->addChild(menuItem.get());
@ -683,7 +644,7 @@ void AppMenus::removeMenuItemFromGroup(Pred pred)
{
for (auto& it : m_groups) {
GroupInfo& group = it.second;
for (auto it=group.items.begin(); it != group.items.end(); ) {
for (auto it = group.items.begin(); it != group.items.end();) {
auto& item = *it;
if (pred(item)) {
if (item == group.end)
@ -702,19 +663,15 @@ void AppMenus::removeMenuItemFromGroup(Pred pred)
void AppMenus::removeMenuItemFromGroup(Command* cmd)
{
removeMenuItemFromGroup(
[cmd](Widget* item){
auto appMenuItem = dynamic_cast<AppMenuItem*>(item);
return (appMenuItem && appMenuItem->getCommand() == cmd);
});
removeMenuItemFromGroup([cmd](Widget* item) {
auto appMenuItem = dynamic_cast<AppMenuItem*>(item);
return (appMenuItem && appMenuItem->getCommand() == cmd);
});
}
void AppMenus::removeMenuItemFromGroup(Widget* menuItem)
{
removeMenuItemFromGroup(
[menuItem](Widget* item){
return (item == menuItem);
});
removeMenuItemFromGroup([menuItem](Widget* item) { return (item == menuItem); });
}
Menu* AppMenus::loadMenuById(XMLHandle& handle, const char* id)
@ -722,10 +679,8 @@ Menu* AppMenus::loadMenuById(XMLHandle& handle, const char* id)
ASSERT(id != NULL);
// <gui><menus><menu>
XMLElement* xmlMenu = handle
.FirstChildElement("gui")
.FirstChildElement("menus")
.FirstChildElement("menu").ToElement();
XMLElement* xmlMenu =
handle.FirstChildElement("gui").FirstChildElement("menus").FirstChildElement("menu").ToElement();
while (xmlMenu) {
const char* menuId = xmlMenu->Attribute("id");
@ -785,9 +740,7 @@ Widget* AppMenus::convertXmlelemToMenuitem(XMLElement* elem, Menu* menu)
}
const char* commandId = elem->Attribute("command");
Command* command =
(commandId ? Commands::instance()->byId(commandId):
nullptr);
Command* command = (commandId ? Commands::instance()->byId(commandId) : nullptr);
// load params
Params params;
@ -805,9 +758,8 @@ Widget* AppMenus::convertXmlelemToMenuitem(XMLElement* elem, Menu* menu)
}
// Create the item
AppMenuItem* menuitem = new AppMenuItem(m_xmlTranslator(elem, "text"),
(command ? command->id(): ""),
params);
AppMenuItem* menuitem =
new AppMenuItem(m_xmlTranslator(elem, "text"), (command ? command->id() : ""), params);
if (!menuitem)
return nullptr;
@ -821,7 +773,8 @@ Widget* AppMenus::convertXmlelemToMenuitem(XMLElement* elem, Menu* menu)
menuitem->processMnemonicFromText();
}
if (id) menuitem->setId(id);
if (id)
menuitem->setId(id);
if (group) {
m_groups[group].menu = menu;
m_groups[group].end = menuitem;
@ -876,8 +829,7 @@ void AppMenus::applyShortcutToMenuitemsWithCommand(Menu* menu,
const std::string& mi_commandId = menuitem->getCommandId();
const Params& mi_params = menuitem->getParams();
if ((base::utf8_icmp(mi_commandId, command->id()) == 0) &&
(mi_params == params)) {
if ((base::utf8_icmp(mi_commandId, command->id()) == 0) && (mi_params == params)) {
// Set the keyboard shortcut to be shown in this menu-item
menuitem->setKey(key);
}
@ -928,38 +880,38 @@ void AppMenus::updateMenusList()
void AppMenus::createNativeMenus()
{
os::Menus* menus = os::System::instance()->menus();
if (!menus) // This platform doesn't support native menu items
if (!menus) // This platform doesn't support native menu items
return;
// Save a reference to the old menu to avoid destroying it.
os::MenuRef oldOSMenu = m_osMenu;
m_osMenu = menus->makeMenu();
#if LAF_MACOS // Create default macOS app menus (App ... Window)
#if LAF_MACOS // Create default macOS app menus (App ... Window)
{
os::MenuItemInfo about(fmt::format("About {}", get_app_name()));
auto native = get_native_shortcut_for_command(CommandId::About());
about.shortcut = native.shortcut;
about.execute = [native]{
about.execute = [native] {
if (can_call_global_shortcut(&native)) {
Command* cmd = Commands::instance()->byId(CommandId::About());
UIContext::instance()->executeCommandFromMenuOrShortcut(cmd);
}
};
about.validate = [native](os::MenuItem* item){
about.validate = [native](os::MenuItem* item) {
item->setEnabled(can_call_global_shortcut(&native));
};
os::MenuItemInfo preferences("Preferences...");
native = get_native_shortcut_for_command(CommandId::Options());
preferences.shortcut = native.shortcut;
preferences.execute = [native]{
preferences.execute = [native] {
if (can_call_global_shortcut(&native)) {
Command* cmd = Commands::instance()->byId(CommandId::Options());
UIContext::instance()->executeCommandFromMenuOrShortcut(cmd);
}
};
preferences.validate = [native](os::MenuItem* item){
preferences.validate = [native](os::MenuItem* item) {
item->setEnabled(can_call_global_shortcut(&native));
};
@ -975,7 +927,8 @@ void AppMenus::createNativeMenus()
appMenu->addItem(menus->makeMenuItem(preferences));
appMenu->addItem(menus->makeMenuItem(os::MenuItemInfo(os::MenuItemInfo::Separator)));
appMenu->addItem(menus->makeMenuItem(hide));
appMenu->addItem(menus->makeMenuItem(os::MenuItemInfo("Hide Others", os::MenuItemInfo::HideOthers)));
appMenu->addItem(
menus->makeMenuItem(os::MenuItemInfo("Hide Others", os::MenuItemInfo::HideOthers)));
appMenu->addItem(menus->makeMenuItem(os::MenuItemInfo("Show All", os::MenuItemInfo::ShowAll)));
appMenu->addItem(menus->makeMenuItem(os::MenuItemInfo(os::MenuItemInfo::Separator)));
appMenu->addItem(menus->makeMenuItem(quit));
@ -1013,7 +966,7 @@ void AppMenus::createNativeMenus()
// We use helpIndex+1 because the first index in m_osMenu is the
// App menu.
m_osMenu->insertItem(helpIndex+1, windowItem);
m_osMenu->insertItem(helpIndex + 1, windowItem);
}
#endif
@ -1022,8 +975,7 @@ void AppMenus::createNativeMenus()
oldOSMenu.reset();
}
void AppMenus::createNativeSubmenus(os::Menu* osMenu,
const ui::Menu* uiMenu)
void AppMenus::createNativeSubmenus(os::Menu* osMenu, const ui::Menu* uiMenu)
{
os::Menus* menus = os::System::instance()->menus();
@ -1036,17 +988,15 @@ void AppMenus::createNativeSubmenus(os::Menu* osMenu,
info.type = os::MenuItemInfo::Separator;
}
else if (child->type() == kMenuItemWidget) {
if (appMenuItem &&
appMenuItem->getCommand()) {
native = get_native_shortcut_for_command(
appMenuItem->getCommandId().c_str(),
appMenuItem->getParams());
if (appMenuItem && appMenuItem->getCommand()) {
native = get_native_shortcut_for_command(appMenuItem->getCommandId().c_str(),
appMenuItem->getParams());
}
info.type = os::MenuItemInfo::Normal;
info.text = child->text();
info.shortcut = native.shortcut;
info.execute = [appMenuItem]{
info.execute = [appMenuItem] {
if (can_call_global_shortcut(appMenuItem->native()))
appMenuItem->executeClick();
};
@ -1063,7 +1013,7 @@ void AppMenus::createNativeSubmenus(os::Menu* osMenu,
};
}
else {
ASSERT(false); // Unsupported menu item type
ASSERT(false); // Unsupported menu item type
continue;
}
@ -1075,8 +1025,7 @@ void AppMenus::createNativeSubmenus(os::Menu* osMenu,
appMenuItem->setNative(native);
}
if (child->type() == ui::kMenuItemWidget &&
((ui::MenuItem*)child)->hasSubmenu()) {
if (child->type() == ui::kMenuItemWidget && ((ui::MenuItem*)child)->hasSubmenu()) {
os::MenuRef osSubmenu = menus->makeMenu();
createNativeSubmenus(osSubmenu.get(), ((ui::MenuItem*)child)->getSubmenu());
osItem->setSubmenu(osSubmenu);

View File

@ -21,117 +21,115 @@
#include <memory>
namespace tinyxml2 {
class XMLElement;
class XMLHandle;
}
class XMLElement;
class XMLHandle;
} // namespace tinyxml2
namespace app {
class Command;
class Params;
class RecentFiles;
class Command;
class Params;
class RecentFiles;
using namespace ui;
using namespace ui;
// Class to handle/get/reload available menus in gui.xml file.
class AppMenus {
DISABLE_COPYING(AppMenus);
// Class to handle/get/reload available menus in gui.xml file.
class AppMenus {
DISABLE_COPYING(AppMenus);
public:
static AppMenus* instance();
public:
static AppMenus* instance();
AppMenus(RecentFiles* recentFiles);
~AppMenus();
AppMenus(RecentFiles* recentFiles);
~AppMenus();
void reload();
void initTheme();
void reload();
void initTheme();
// Updates the menu of recent files.
bool rebuildRecentList();
// Updates the menu of recent files.
bool rebuildRecentList();
Menu* getRootMenu() { return m_rootMenu.get(); }
Menu* getTabPopupMenu() { return m_tabPopupMenu.get(); }
Menu* getDocumentTabPopupMenu() { return m_documentTabPopupMenu.get(); }
Menu* getLayerPopupMenu() { return m_layerPopupMenu.get(); }
Menu* getFramePopupMenu() { return m_framePopupMenu.get(); }
Menu* getCelPopupMenu() { return m_celPopupMenu.get(); }
Menu* getCelMovementPopupMenu() { return m_celMovementPopupMenu.get(); }
Menu* getTagPopupMenu() { return m_tagPopupMenu.get(); }
Menu* getSlicePopupMenu() { return m_slicePopupMenu.get(); }
Menu* getPalettePopupMenu() { return m_palettePopupMenu.get(); }
Menu* getInkPopupMenu() { return m_inkPopupMenu.get(); }
Menu* getAnimationMenu();
Menu* getNewFrameMenu() { return m_newFramePopupMenu.get(); }
Menu* getRootMenu() { return m_rootMenu.get(); }
Menu* getTabPopupMenu() { return m_tabPopupMenu.get(); }
Menu* getDocumentTabPopupMenu() { return m_documentTabPopupMenu.get(); }
Menu* getLayerPopupMenu() { return m_layerPopupMenu.get(); }
Menu* getFramePopupMenu() { return m_framePopupMenu.get(); }
Menu* getCelPopupMenu() { return m_celPopupMenu.get(); }
Menu* getCelMovementPopupMenu() { return m_celMovementPopupMenu.get(); }
Menu* getTagPopupMenu() { return m_tagPopupMenu.get(); }
Menu* getSlicePopupMenu() { return m_slicePopupMenu.get(); }
Menu* getPalettePopupMenu() { return m_palettePopupMenu.get(); }
Menu* getInkPopupMenu() { return m_inkPopupMenu.get(); }
Menu* getAnimationMenu();
Menu* getNewFrameMenu() { return m_newFramePopupMenu.get(); }
void applyShortcutToMenuitemsWithCommand(Command* command, const Params& params,
const KeyPtr& key);
void syncNativeMenuItemKeyShortcuts();
void applyShortcutToMenuitemsWithCommand(Command* command,
const Params& params,
const KeyPtr& key);
void syncNativeMenuItemKeyShortcuts();
// Menu item handling in groups
void addMenuGroup(const std::string& groupId,
MenuItem* menuItem);
void removeMenuGroup(const std::string& groupId);
void addMenuItemIntoGroup(const std::string& groupId,
std::unique_ptr<Widget>&& menuItem);
void removeMenuItemFromGroup(Command* cmd);
void removeMenuItemFromGroup(Widget* menuItem);
// Menu item handling in groups
void addMenuGroup(const std::string& groupId, MenuItem* menuItem);
void removeMenuGroup(const std::string& groupId);
void addMenuItemIntoGroup(const std::string& groupId, std::unique_ptr<Widget>&& menuItem);
void removeMenuItemFromGroup(Command* cmd);
void removeMenuItemFromGroup(Widget* menuItem);
private:
template<typename Pred>
void removeMenuItemFromGroup(Pred pred);
private:
template<typename Pred>
void removeMenuItemFromGroup(Pred pred);
Menu* loadMenuById(tinyxml2::XMLHandle& handle, const char *id);
Menu* convertXmlelemToMenu(tinyxml2::XMLElement* elem);
Widget* convertXmlelemToMenuitem(tinyxml2::XMLElement* elem, Menu* menu);
void applyShortcutToMenuitemsWithCommand(Menu* menu, Command* command, const Params& params,
const KeyPtr& key);
void syncNativeMenuItemKeyShortcuts(Menu* menu);
void updateMenusList();
void createNativeMenus();
void createNativeSubmenus(os::Menu* osMenu,
const ui::Menu* uiMenu);
Menu* loadMenuById(tinyxml2::XMLHandle& handle, const char* id);
Menu* convertXmlelemToMenu(tinyxml2::XMLElement* elem);
Widget* convertXmlelemToMenuitem(tinyxml2::XMLElement* elem, Menu* menu);
void applyShortcutToMenuitemsWithCommand(Menu* menu,
Command* command,
const Params& params,
const KeyPtr& key);
void syncNativeMenuItemKeyShortcuts(Menu* menu);
void updateMenusList();
void createNativeMenus();
void createNativeSubmenus(os::Menu* osMenu, const ui::Menu* uiMenu);
#ifdef ENABLE_SCRIPTING
void loadScriptsSubmenu(ui::Menu* menu,
const std::string& dir,
const bool rootLevel);
void loadScriptsSubmenu(ui::Menu* menu, const std::string& dir, const bool rootLevel);
#endif
struct GroupInfo {
Menu* menu = nullptr;
Widget* end = nullptr;
WidgetsList items;
};
std::unique_ptr<Menu> m_rootMenu;
Widget* m_recentFilesPlaceholder;
MenuItem* m_helpMenuitem;
std::unique_ptr<Menu> m_tabPopupMenu;
std::unique_ptr<Menu> m_documentTabPopupMenu;
std::unique_ptr<Menu> m_layerPopupMenu;
std::unique_ptr<Menu> m_framePopupMenu;
std::unique_ptr<Menu> m_celPopupMenu;
std::unique_ptr<Menu> m_celMovementPopupMenu;
std::unique_ptr<Menu> m_tagPopupMenu;
std::unique_ptr<Menu> m_slicePopupMenu;
std::unique_ptr<Menu> m_palettePopupMenu;
std::unique_ptr<Menu> m_inkPopupMenu;
std::unique_ptr<Menu> m_newFramePopupMenu;
obs::scoped_connection m_recentFilesConn;
std::vector<Menu*> m_menus;
// List of recent menu items pointing to recent files.
WidgetsList m_recentMenuItems;
// Extension points for plugins (each group is a place where new
// menu items can be added).
std::map<std::string, GroupInfo> m_groups;
// Native main menu bar (== nullptr if the platform doesn't
// support native menus)
os::MenuRef m_osMenu;
XmlTranslator m_xmlTranslator;
static AppMenus* s_instance;
struct GroupInfo {
Menu* menu = nullptr;
Widget* end = nullptr;
WidgetsList items;
};
os::Shortcut get_os_shortcut_from_key(const Key* key);
std::unique_ptr<Menu> m_rootMenu;
Widget* m_recentFilesPlaceholder;
MenuItem* m_helpMenuitem;
std::unique_ptr<Menu> m_tabPopupMenu;
std::unique_ptr<Menu> m_documentTabPopupMenu;
std::unique_ptr<Menu> m_layerPopupMenu;
std::unique_ptr<Menu> m_framePopupMenu;
std::unique_ptr<Menu> m_celPopupMenu;
std::unique_ptr<Menu> m_celMovementPopupMenu;
std::unique_ptr<Menu> m_tagPopupMenu;
std::unique_ptr<Menu> m_slicePopupMenu;
std::unique_ptr<Menu> m_palettePopupMenu;
std::unique_ptr<Menu> m_inkPopupMenu;
std::unique_ptr<Menu> m_newFramePopupMenu;
obs::scoped_connection m_recentFilesConn;
std::vector<Menu*> m_menus;
// List of recent menu items pointing to recent files.
WidgetsList m_recentMenuItems;
// Extension points for plugins (each group is a place where new
// menu items can be added).
std::map<std::string, GroupInfo> m_groups;
// Native main menu bar (== nullptr if the platform doesn't
// support native menus)
os::MenuRef m_osMenu;
XmlTranslator m_xmlTranslator;
static AppMenus* s_instance;
};
os::Shortcut get_os_shortcut_from_key(const Key* key);
} // namespace app

View File

@ -9,13 +9,13 @@
#pragma once
namespace app {
class MainWindow;
class MainWindow;
class AppMod {
public:
virtual ~AppMod() { }
virtual void modMainWindow(MainWindow* mainWindow) = 0;
};
class AppMod {
public:
virtual ~AppMod() {}
virtual void modMainWindow(MainWindow* mainWindow) = 0;
};
} // namespace app

View File

@ -4,9 +4,8 @@
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
#ifdef HAVE_CONFIG_H
#include "config.h"
#include "config.h"
#endif
#include <gtest/gtest.h>
@ -45,10 +44,8 @@ TEST(App, ExitCommand)
app::App app;
app.initialize(options);
ui::execute_from_ui_thread([&app] {
app.context()->executeCommand(
Commands::instance()->byId(CommandId::Exit()));
});
ui::execute_from_ui_thread(
[&app] { app.context()->executeCommand(Commands::instance()->byId(CommandId::Exit())); });
app.run();
}
@ -64,10 +61,8 @@ TEST(App, ExitWithOneDoc)
ui::execute_from_ui_thread([&app] {
Params params;
params.set("ui", "false");
app.context()->executeCommand(
Commands::instance()->byId(CommandId::NewFile()), params);
app.context()->executeCommand(
Commands::instance()->byId(CommandId::Exit()));
app.context()->executeCommand(Commands::instance()->byId(CommandId::NewFile()), params);
app.context()->executeCommand(Commands::instance()->byId(CommandId::Exit()));
});
app.run();

View File

@ -19,17 +19,17 @@ namespace app {
class BrushSlot {
public:
enum class Flags {
Locked = 0x0001,
BrushType = 0x0002,
BrushSize = 0x0004,
BrushAngle = 0x0008,
FgColor = 0x0010,
BgColor = 0x0020,
InkType = 0x0040,
InkOpacity = 0x0080,
Shade = 0x0100,
Locked = 0x0001,
BrushType = 0x0002,
BrushSize = 0x0004,
BrushAngle = 0x0008,
FgColor = 0x0010,
BgColor = 0x0020,
InkType = 0x0040,
InkOpacity = 0x0080,
Shade = 0x0100,
PixelPerfect = 0x0200,
ImageColor = 0x0400,
ImageColor = 0x0400,
};
BrushSlot(Flags flags = Flags(0),
@ -47,26 +47,21 @@ public:
, m_inkType(inkType)
, m_inkOpacity(inkOpacity)
, m_shade(shade)
, m_pixelPerfect(pixelPerfect) {
, m_pixelPerfect(pixelPerfect)
{
}
Flags flags() const { return m_flags; }
void setFlags(Flags flags) { m_flags = flags; }
bool isEmpty() const {
return int(m_flags) == 0;
}
bool isEmpty() const { return int(m_flags) == 0; }
bool hasFlag(Flags flag) const {
return ((int(m_flags) & int(flag)) == int(flag));
}
bool hasFlag(Flags flag) const { return ((int(m_flags) & int(flag)) == int(flag)); }
bool hasBrush() const {
return
(brush() &&
(hasFlag(Flags::BrushType) ||
hasFlag(Flags::BrushSize) ||
hasFlag(Flags::BrushAngle)));
bool hasBrush() const
{
return (brush() &&
(hasFlag(Flags::BrushType) || hasFlag(Flags::BrushSize) || hasFlag(Flags::BrushAngle)));
}
// Can be null if the user deletes the brush.
@ -80,11 +75,10 @@ public:
// True if the user locked the brush using the shortcut key to
// access it.
bool locked() const {
return hasFlag(Flags::Locked);
}
bool locked() const { return hasFlag(Flags::Locked); }
void setLocked(bool locked) {
void setLocked(bool locked)
{
if (locked)
m_flags = static_cast<Flags>(int(m_flags) | int(Flags::Locked));
else

View File

@ -6,28 +6,28 @@
// the End-User License Agreement for Aseprite.
#ifdef HAVE_CONFIG_H
#include "config.h"
#include "config.h"
#endif
#ifdef ENABLE_UPDATER
#include "app/check_update.h"
#include "app/check_update.h"
#include "app/check_update_delegate.h"
#include "app/pref/preferences.h"
#include "base/convert_to.h"
#include "base/launcher.h"
#include "base/replace_string.h"
#include "base/thread.h"
#include "base/version.h"
#include "ver/info.h"
#include "app/check_update_delegate.h"
#include "app/pref/preferences.h"
#include "base/convert_to.h"
#include "base/launcher.h"
#include "base/replace_string.h"
#include "base/thread.h"
#include "base/version.h"
#include "ver/info.h"
#if ENABLE_SENTRY
#include "app/sentry_wrapper.h"
#endif
#if ENABLE_SENTRY
#include "app/sentry_wrapper.h"
#endif
#include <ctime>
#include <sstream>
#include <ctime>
#include <sstream>
static const int kMonitoringPeriod = 100;
@ -35,27 +35,22 @@ namespace app {
class CheckUpdateBackgroundJob : public updater::CheckUpdateDelegate {
public:
CheckUpdateBackgroundJob()
: m_received(false) { }
CheckUpdateBackgroundJob() : m_received(false) {}
void abort() {
m_checker.abort();
}
void abort() { m_checker.abort(); }
bool isReceived() const {
return m_received;
}
bool isReceived() const { return m_received; }
void sendRequest(const updater::Uuid& uuid, const std::string& extraParams) {
void sendRequest(const updater::Uuid& uuid, const std::string& extraParams)
{
m_checker.checkNewVersion(uuid, extraParams, this);
}
const updater::CheckUpdateResponse& getResponse() const {
return m_response;
}
const updater::CheckUpdateResponse& getResponse() const { return m_response; }
private:
void onResponse(updater::CheckUpdateResponse& data) override {
void onResponse(updater::CheckUpdateResponse& data) override
{
m_response = data;
m_received = true;
}
@ -72,11 +67,11 @@ CheckUpdateThreadLauncher::CheckUpdateThreadLauncher(CheckUpdateDelegate* delega
, m_received(false)
, m_inits(m_preferences.updater.inits())
, m_exits(m_preferences.updater.exits())
#ifdef _DEBUG
#ifdef _DEBUG
, m_isDeveloper(true)
#else
#else
, m_isDeveloper(m_preferences.updater.isDeveloper())
#endif
#endif
, m_timer(kMonitoringPeriod, NULL)
{
// Get how many days we have to wait for the next "check for update"
@ -87,15 +82,16 @@ CheckUpdateThreadLauncher::CheckUpdateThreadLauncher(CheckUpdateDelegate* delega
time_t now = std::time(NULL);
// Verify if we are in the "WaitDays" period...
if (now < lastCheck+int(double(60*60*24*waitDays)) &&
now > lastCheck) { // <- Avoid broken clocks
if (now < lastCheck + int(double(60 * 60 * 24 * waitDays)) && now > lastCheck) { // <- Avoid
// broken
// clocks
// So we do not check for updates.
m_doCheck = false;
}
}
// Minimal stats: number of initializations
m_preferences.updater.inits(m_inits+1);
m_preferences.updater.inits(m_inits + 1);
m_preferences.save();
}
@ -112,7 +108,7 @@ CheckUpdateThreadLauncher::~CheckUpdateThreadLauncher()
}
// Minimal stats: number of exits
m_preferences.updater.exits(m_exits+1);
m_preferences.updater.exits(m_exits + 1);
m_preferences.save();
}
@ -122,9 +118,9 @@ void CheckUpdateThreadLauncher::launch()
m_uuid = m_preferences.updater.uuid();
if (!m_uuid.empty()) {
#if ENABLE_SENTRY
#if ENABLE_SENTRY
Sentry::setUserID(m_uuid);
#endif
#endif
LOG(VERBOSE, "APP: Saved UUID %s\n", m_uuid.c_str());
}
@ -138,7 +134,7 @@ void CheckUpdateThreadLauncher::launch()
m_delegate->onCheckingUpdates();
m_bgJob.reset(new CheckUpdateBackgroundJob);
m_thread.reset(new std::thread([this]{ checkForUpdates(); }));
m_thread.reset(new std::thread([this] { checkForUpdates(); }));
// Start a timer to monitoring the progress of the background job
// executed in "m_thread". The "onMonitoringTick" method will be
@ -156,11 +152,10 @@ void CheckUpdateThreadLauncher::onMonitoringTick()
{
// If we do not receive a response yet...
if (!m_received)
return; // Skip and wait the next call.
return; // Skip and wait the next call.
// Depending on the type of update received
switch (m_response.getUpdateType()) {
case updater::CheckUpdateResponse::NoUpdate:
// Clear
m_preferences.updater.newVersion("");
@ -182,9 +177,9 @@ void CheckUpdateThreadLauncher::onMonitoringTick()
m_preferences.updater.uuid(m_uuid);
if (!m_uuid.empty()) {
#if ENABLE_SENTRY
#if ENABLE_SENTRY
Sentry::setUserID(m_uuid);
#endif
#endif
LOG(VERBOSE, "APP: New UUID %s\n", m_uuid.c_str());
}
}
@ -207,8 +202,7 @@ void CheckUpdateThreadLauncher::checkForUpdates()
// Add mini-stats in the request
std::stringstream extraParams;
extraParams << "inits=" << m_inits
<< "&exits=" << m_exits;
extraParams << "inits=" << m_inits << "&exits=" << m_exits;
if (m_isDeveloper)
extraParams << "&dev=1";
@ -235,8 +229,7 @@ void CheckUpdateThreadLauncher::showUI()
}
if (newVer) {
m_delegate->onNewUpdate(m_preferences.updater.newUrl(),
m_preferences.updater.newVersion());
m_delegate->onNewUpdate(m_preferences.updater.newUrl(), m_preferences.updater.newVersion());
}
else {
// If the program was updated, reset the "exits" counter
@ -249,6 +242,6 @@ void CheckUpdateThreadLauncher::showUI()
}
}
}
} // namespace app
#endif // ENABLE_UPDATER

View File

@ -11,56 +11,53 @@
#ifdef ENABLE_UPDATER
#include "ui/timer.h"
#include "updater/check_update.h"
#include "ui/timer.h"
#include "updater/check_update.h"
#include <atomic>
#include <memory>
#include <thread>
#include <atomic>
#include <memory>
#include <thread>
namespace app {
class CheckUpdateDelegate;
class CheckUpdateBackgroundJob;
class Preferences;
class CheckUpdateDelegate;
class CheckUpdateBackgroundJob;
class Preferences;
class CheckUpdateThreadLauncher {
public:
CheckUpdateThreadLauncher(CheckUpdateDelegate* delegate);
~CheckUpdateThreadLauncher();
class CheckUpdateThreadLauncher {
public:
CheckUpdateThreadLauncher(CheckUpdateDelegate* delegate);
~CheckUpdateThreadLauncher();
void launch();
void launch();
bool isReceived() const;
bool isReceived() const;
const updater::CheckUpdateResponse& getResponse() const
{
return m_response;
}
const updater::CheckUpdateResponse& getResponse() const { return m_response; }
private:
void onMonitoringTick();
void checkForUpdates();
void showUI();
private:
void onMonitoringTick();
void checkForUpdates();
void showUI();
CheckUpdateDelegate* m_delegate;
Preferences& m_preferences;
updater::Uuid m_uuid;
std::unique_ptr<std::thread> m_thread;
std::unique_ptr<CheckUpdateBackgroundJob> m_bgJob;
bool m_doCheck;
std::atomic<bool> m_received;
CheckUpdateDelegate* m_delegate;
Preferences& m_preferences;
updater::Uuid m_uuid;
std::unique_ptr<std::thread> m_thread;
std::unique_ptr<CheckUpdateBackgroundJob> m_bgJob;
bool m_doCheck;
std::atomic<bool> m_received;
// Mini-stats
int m_inits;
int m_exits;
// Mini-stats
int m_inits;
int m_exits;
// True if this is a developer
bool m_isDeveloper;
// True if this is a developer
bool m_isDeveloper;
updater::CheckUpdateResponse m_response;
ui::Timer m_timer;
};
updater::CheckUpdateResponse m_response;
ui::Timer m_timer;
};
} // namespace app

View File

@ -10,17 +10,17 @@
#ifdef ENABLE_UPDATER
#include <string>
#include <string>
namespace app {
class CheckUpdateDelegate {
public:
virtual ~CheckUpdateDelegate() { }
virtual void onCheckingUpdates() = 0;
virtual void onUpToDate() = 0;
virtual void onNewUpdate(const std::string& url, const std::string& version) = 0;
};
class CheckUpdateDelegate {
public:
virtual ~CheckUpdateDelegate() {}
virtual void onCheckingUpdates() = 0;
virtual void onUpToDate() = 0;
virtual void onNewUpdate(const std::string& url, const std::string& version) = 0;
};
} // namespace app

View File

@ -6,7 +6,7 @@
// the End-User License Agreement for Aseprite.
#ifdef HAVE_CONFIG_H
#include "config.h"
#include "config.h"
#endif
#include "app/cli/app_options.h"
@ -29,60 +29,145 @@ AppOptions::AppOptions(int argc, const char* argv[])
, m_shell(m_po.add("shell").description("Start an interactive console to execute scripts"))
#endif
, m_batch(m_po.add("batch").mnemonic('b').description("Do not start the UI"))
, m_preview(m_po.add("preview").mnemonic('p').description("Do not execute actions, just print what will be\ndone"))
, m_saveAs(m_po.add("save-as").requiresValue("<filename>").description("Save the last given sprite with other format"))
, m_palette(m_po.add("palette").requiresValue("<filename>").description("Change the palette of the last given sprite"))
, m_scale(m_po.add("scale").requiresValue("<factor>").description("Resize all previously opened sprites"))
, m_ditheringAlgorithm(m_po.add("dithering-algorithm").requiresValue("<algorithm>").description("Dithering algorithm used in --color-mode\nto convert images from RGB to Indexed\n none\n ordered\n old"))
, m_ditheringMatrix(m_po.add("dithering-matrix").requiresValue("<id>").description("Matrix used in ordered dithering algorithm\n bayer2x2\n bayer4x4\n bayer8x8\n filename.png"))
, m_colorMode(m_po.add("color-mode").requiresValue("<mode>").description("Change color mode of all previously\nopened sprites:\n rgb\n grayscale\n indexed"))
, m_shrinkTo(m_po.add("shrink-to").requiresValue("width,height").description("Shrink each sprite if it is\nlarger than width or height"))
, m_data(m_po.add("data").requiresValue("<filename.json>").description("File to store the sprite sheet metadata"))
, m_format(m_po.add("format").requiresValue("<format>").description("Format to export the data file\n(json-hash, json-array)"))
, m_sheet(m_po.add("sheet").requiresValue("<filename.png>").description("Image file to save the texture"))
, m_sheetType(m_po.add("sheet-type").requiresValue("<type>").description("Algorithm to create the sprite sheet:\n horizontal\n vertical\n rows\n columns\n packed"))
, m_preview(m_po.add("preview").mnemonic('p').description(
"Do not execute actions, just print what will be\ndone"))
, m_saveAs(m_po.add("save-as")
.requiresValue("<filename>")
.description("Save the last given sprite with other format"))
, m_palette(m_po.add("palette")
.requiresValue("<filename>")
.description("Change the palette of the last given sprite"))
, m_scale(m_po.add("scale")
.requiresValue("<factor>")
.description("Resize all previously opened sprites"))
, m_ditheringAlgorithm(
m_po.add("dithering-algorithm")
.requiresValue("<algorithm>")
.description(
"Dithering algorithm used in --color-mode\nto convert images from RGB to Indexed\n none\n ordered\n old"))
, m_ditheringMatrix(
m_po.add("dithering-matrix")
.requiresValue("<id>")
.description(
"Matrix used in ordered dithering algorithm\n bayer2x2\n bayer4x4\n bayer8x8\n filename.png"))
, m_colorMode(
m_po.add("color-mode")
.requiresValue("<mode>")
.description(
"Change color mode of all previously\nopened sprites:\n rgb\n grayscale\n indexed"))
, m_shrinkTo(m_po.add("shrink-to")
.requiresValue("width,height")
.description("Shrink each sprite if it is\nlarger than width or height"))
, m_data(m_po.add("data")
.requiresValue("<filename.json>")
.description("File to store the sprite sheet metadata"))
, m_format(m_po.add("format")
.requiresValue("<format>")
.description("Format to export the data file\n(json-hash, json-array)"))
, m_sheet(m_po.add("sheet")
.requiresValue("<filename.png>")
.description("Image file to save the texture"))
, m_sheetType(
m_po.add("sheet-type")
.requiresValue("<type>")
.description(
"Algorithm to create the sprite sheet:\n horizontal\n vertical\n rows\n columns\n packed"))
, m_sheetPack(m_po.add("sheet-pack").description("Same as -sheet-type packed"))
, m_sheetWidth(m_po.add("sheet-width").requiresValue("<pixels>").description("Sprite sheet width"))
, m_sheetHeight(m_po.add("sheet-height").requiresValue("<pixels>").description("Sprite sheet height"))
, m_sheetColumns(m_po.add("sheet-columns").requiresValue("<columns>").description("Fixed # of columns for -sheet-type rows"))
, m_sheetRows(m_po.add("sheet-rows").requiresValue("<rows>").description("Fixed # of rows for -sheet-type columns"))
, m_splitLayers(m_po.add("split-layers").description("Save each visible layer of sprites\nas separated images in the sheet\n"))
, m_sheetWidth(
m_po.add("sheet-width").requiresValue("<pixels>").description("Sprite sheet width"))
, m_sheetHeight(
m_po.add("sheet-height").requiresValue("<pixels>").description("Sprite sheet height"))
, m_sheetColumns(m_po.add("sheet-columns")
.requiresValue("<columns>")
.description("Fixed # of columns for -sheet-type rows"))
, m_sheetRows(m_po.add("sheet-rows")
.requiresValue("<rows>")
.description("Fixed # of rows for -sheet-type columns"))
, m_splitLayers(
m_po.add("split-layers")
.description("Save each visible layer of sprites\nas separated images in the sheet\n"))
, m_splitTags(m_po.add("split-tags").description("Save each tag as a separated file"))
, m_splitSlices(m_po.add("split-slices").description("Save each slice as a separated file"))
, m_splitGrid(m_po.add("split-grid").description("Save each grid tile as a separated file"))
, m_layer(m_po.add("layer").alias("import-layer").requiresValue("<name>").description("Include just the given layer in the sheet\nor save as operation"))
, m_allLayers(m_po.add("all-layers").description("Make all layers visible\nBy default hidden layers will be ignored"))
, m_ignoreLayer(m_po.add("ignore-layer").requiresValue("<name>").description("Exclude the given layer in the sheet\nor save as operation"))
, m_tag(m_po.add("tag").alias("frame-tag").requiresValue("<name>").description("Include tagged frames in the sheet"))
, m_playSubtags(m_po.add("play-subtags").description("Play subtags and repeats when saving the frames of an animated sprite"))
, m_frameRange(m_po.add("frame-range").requiresValue("from,to").description("Only export frames in the [from,to] range"))
, m_layer(m_po.add("layer")
.alias("import-layer")
.requiresValue("<name>")
.description("Include just the given layer in the sheet\nor save as operation"))
, m_allLayers(m_po.add("all-layers")
.description("Make all layers visible\nBy default hidden layers will be ignored"))
, m_ignoreLayer(m_po.add("ignore-layer")
.requiresValue("<name>")
.description("Exclude the given layer in the sheet\nor save as operation"))
, m_tag(m_po.add("tag")
.alias("frame-tag")
.requiresValue("<name>")
.description("Include tagged frames in the sheet"))
, m_playSubtags(
m_po.add("play-subtags")
.description("Play subtags and repeats when saving the frames of an animated sprite"))
, m_frameRange(m_po.add("frame-range")
.requiresValue("from,to")
.description("Only export frames in the [from,to] range"))
, m_ignoreEmpty(m_po.add("ignore-empty").description("Do not export empty frames/cels"))
, m_mergeDuplicates(m_po.add("merge-duplicates").description("Merge all duplicate frames into one in the sprite sheet"))
, m_borderPadding(m_po.add("border-padding").requiresValue("<value>").description("Add padding on the texture borders"))
, m_shapePadding(m_po.add("shape-padding").requiresValue("<value>").description("Add padding between frames"))
, m_innerPadding(m_po.add("inner-padding").requiresValue("<value>").description("Add padding inside each frame"))
, m_trim(m_po.add("trim").description("Trim whole sprite for --save-as\nor individual frames for --sheet"))
, m_trimSprite(m_po.add("trim-sprite").description("Trim the whole sprite (for --save-as and --sheet)"))
, m_trimByGrid(m_po.add("trim-by-grid").description("Trim all images by its correspondent grid boundaries before exporting"))
, m_mergeDuplicates(m_po.add("merge-duplicates")
.description("Merge all duplicate frames into one in the sprite sheet"))
, m_borderPadding(m_po.add("border-padding")
.requiresValue("<value>")
.description("Add padding on the texture borders"))
, m_shapePadding(
m_po.add("shape-padding").requiresValue("<value>").description("Add padding between frames"))
, m_innerPadding(m_po.add("inner-padding")
.requiresValue("<value>")
.description("Add padding inside each frame"))
, m_trim(m_po.add("trim").description(
"Trim whole sprite for --save-as\nor individual frames for --sheet"))
, m_trimSprite(
m_po.add("trim-sprite").description("Trim the whole sprite (for --save-as and --sheet)"))
, m_trimByGrid(
m_po.add("trim-by-grid")
.description("Trim all images by its correspondent grid boundaries before exporting"))
, m_extrude(m_po.add("extrude").description("Extrude all images duplicating all edges one pixel"))
, m_crop(m_po.add("crop").requiresValue("x,y,width,height").description("Crop all the images to the given rectangle"))
, m_slice(m_po.add("slice").requiresValue("<name>").description("Crop the sprite to the given slice area"))
, m_filenameFormat(m_po.add("filename-format").requiresValue("<fmt>").description("Special format to generate filenames"))
, m_tagnameFormat(m_po.add("tagname-format").requiresValue("<fmt>").description("Special format to generate tagnames in JSON data"))
, m_crop(m_po.add("crop")
.requiresValue("x,y,width,height")
.description("Crop all the images to the given rectangle"))
, m_slice(m_po.add("slice").requiresValue("<name>").description(
"Crop the sprite to the given slice area"))
, m_filenameFormat(m_po.add("filename-format")
.requiresValue("<fmt>")
.description("Special format to generate filenames"))
, m_tagnameFormat(m_po.add("tagname-format")
.requiresValue("<fmt>")
.description("Special format to generate tagnames in JSON data"))
#ifdef ENABLE_SCRIPTING
, m_script(m_po.add("script").requiresValue("<filename>").description("Execute a specific script"))
, m_scriptParam(m_po.add("script-param").requiresValue("name=value").description("Parameter for a script executed from the\nCLI that you can access with app.params"))
, m_script(
m_po.add("script").requiresValue("<filename>").description("Execute a specific script"))
, m_scriptParam(
m_po.add("script-param")
.requiresValue("name=value")
.description(
"Parameter for a script executed from the\nCLI that you can access with app.params"))
#endif
, m_listLayers(m_po.add("list-layers").description("List layers of the next given sprite\nor include layers in JSON data"))
, m_listLayerHierarchy(m_po.add("list-layer-hierarchy").description("List layers with groups of the next given sprite\nor include layers hierarchy in JSON data"))
, m_listTags(m_po.add("list-tags").description("List tags of the next given sprite\nor include frame tags in JSON data"))
, m_listSlices(m_po.add("list-slices").description("List slices of the next given sprite\nor include slices in JSON data"))
, m_listLayers(
m_po.add("list-layers")
.description("List layers of the next given sprite\nor include layers in JSON data"))
, m_listLayerHierarchy(
m_po.add("list-layer-hierarchy")
.description(
"List layers with groups of the next given sprite\nor include layers hierarchy in JSON data"))
, m_listTags(
m_po.add("list-tags")
.description("List tags of the next given sprite\nor include frame tags in JSON data"))
, m_listSlices(
m_po.add("list-slices")
.description("List slices of the next given sprite\nor include slices in JSON data"))
, m_oneFrame(m_po.add("oneframe").description("Load just the first frame"))
, m_exportTileset(m_po.add("export-tileset").description("Export only tilesets from visible tilemap layers"))
, m_exportTileset(
m_po.add("export-tileset").description("Export only tilesets from visible tilemap layers"))
, m_verbose(m_po.add("verbose").mnemonic('v').description("Explain what is being done"))
, m_debug(m_po.add("debug").description("Extreme verbose mode and\ncopy log to desktop"))
#ifdef ENABLE_STEAM
, m_noInApp(m_po.add("noinapp").description("Disable \"in game\" visibility on Steam\nDoesn't count playtime"))
, m_noInApp(m_po.add("noinapp").description(
"Disable \"in game\" visibility on Steam\nDoesn't count playtime"))
#endif
#ifdef _WIN32
, m_disableWintab(m_po.add("disable-wintab").description("Don't load wintab32.dll library"))
@ -105,10 +190,7 @@ AppOptions::AppOptions(int argc, const char* argv[])
m_showHelp = m_po.enabled(m_help);
m_showVersion = m_po.enabled(m_version);
if (m_startShell ||
m_showHelp ||
m_showVersion ||
m_po.enabled(m_batch)) {
if (m_startShell || m_showHelp || m_showVersion || m_po.enabled(m_batch)) {
m_startUI = false;
}
}
@ -121,9 +203,7 @@ AppOptions::AppOptions(int argc, const char* argv[])
bool AppOptions::hasExporterParams() const
{
return
m_po.enabled(m_data) ||
m_po.enabled(m_sheet);
return m_po.enabled(m_data) || m_po.enabled(m_sheet);
}
#ifdef ENABLE_STEAM
@ -140,4 +220,4 @@ bool AppOptions::disableWintab() const
}
#endif
}
} // namespace app

View File

@ -21,8 +21,8 @@ class AppOptions {
public:
enum VerboseLevel {
kNoVerbose,
kVerbose, // --verbose
kHighlyVerbose, // --debug
kVerbose, // --verbose
kHighlyVerbose, // --debug
};
typedef base::ProgramOptions PO;
@ -41,9 +41,7 @@ public:
bool showVersion() const { return m_showVersion; }
VerboseLevel verboseLevel() const { return m_verboseLevel; }
const ValueList& values() const {
return m_po.values();
}
const ValueList& values() const { return m_po.values(); }
// Export options
const Option& saveAs() const { return m_saveAs; }
@ -181,7 +179,6 @@ private:
#endif
Option& m_help;
Option& m_version;
};
} // namespace app

View File

@ -13,32 +13,29 @@
namespace app {
class AppOptions;
class Context;
class DocExporter;
class Params;
struct CliOpenFile;
class AppOptions;
class Context;
class DocExporter;
class Params;
struct CliOpenFile;
class CliDelegate {
public:
virtual ~CliDelegate() { }
virtual void showHelp(const AppOptions& options) { }
virtual void showVersion() { }
virtual void uiMode() { }
virtual void shellMode() { }
virtual void batchMode() { }
virtual void beforeOpenFile(const CliOpenFile& cof) { }
virtual void afterOpenFile(const CliOpenFile& cof) { }
virtual void saveFile(Context* ctx, const CliOpenFile& cof) { }
virtual void loadPalette(Context* ctx, const std::string& filename) { }
virtual void exportFiles(Context* ctx, DocExporter& exporter) { }
class CliDelegate {
public:
virtual ~CliDelegate() {}
virtual void showHelp(const AppOptions& options) {}
virtual void showVersion() {}
virtual void uiMode() {}
virtual void shellMode() {}
virtual void batchMode() {}
virtual void beforeOpenFile(const CliOpenFile& cof) {}
virtual void afterOpenFile(const CliOpenFile& cof) {}
virtual void saveFile(Context* ctx, const CliOpenFile& cof) {}
virtual void loadPalette(Context* ctx, const std::string& filename) {}
virtual void exportFiles(Context* ctx, DocExporter& exporter) {}
#ifdef ENABLE_SCRIPTING
virtual int execScript(const std::string& filename,
const Params& params) {
return 0;
}
virtual int execScript(const std::string& filename, const Params& params) { return 0; }
#endif // ENABLE_SCRIPTING
};
};
} // namespace app

View File

@ -6,7 +6,7 @@
// the End-User License Agreement for Aseprite.
#ifdef HAVE_CONFIG_H
#include "config.h"
#include "config.h"
#endif
#include "app/cli/cli_open_file.h"

View File

@ -17,56 +17,47 @@
namespace app {
class Doc;
class FileOpROI;
class Doc;
class FileOpROI;
struct CliOpenFile {
Doc* document = nullptr;
std::string filename;
std::string filenameFormat;
std::string tagnameFormat;
std::string tag;
std::string slice;
std::vector<std::string> includeLayers;
std::vector<std::string> excludeLayers;
doc::frame_t fromFrame = -1;
doc::frame_t toFrame = -1;
bool splitLayers = false;
bool splitTags = false;
bool splitSlices = false;
bool splitGrid = false;
bool allLayers = false;
bool listLayers = false;
bool listLayerHierarchy = false;
bool listTags = false;
bool listSlices = false;
bool ignoreEmpty = false;
bool trim = false;
bool trimByGrid = false;
bool oneFrame = false;
bool exportTileset = false;
bool playSubtags = false;
gfx::Rect crop;
struct CliOpenFile {
Doc* document = nullptr;
std::string filename;
std::string filenameFormat;
std::string tagnameFormat;
std::string tag;
std::string slice;
std::vector<std::string> includeLayers;
std::vector<std::string> excludeLayers;
doc::frame_t fromFrame = -1;
doc::frame_t toFrame = -1;
bool splitLayers = false;
bool splitTags = false;
bool splitSlices = false;
bool splitGrid = false;
bool allLayers = false;
bool listLayers = false;
bool listLayerHierarchy = false;
bool listTags = false;
bool listSlices = false;
bool ignoreEmpty = false;
bool trim = false;
bool trimByGrid = false;
bool oneFrame = false;
bool exportTileset = false;
bool playSubtags = false;
gfx::Rect crop;
bool hasTag() const {
return (!tag.empty());
}
bool hasTag() const { return (!tag.empty()); }
bool hasSlice() const {
return (!slice.empty());
}
bool hasSlice() const { return (!slice.empty()); }
bool hasFrameRange() const {
return (fromFrame >= 0 && toFrame >= 0);
}
bool hasFrameRange() const { return (fromFrame >= 0 && toFrame >= 0); }
bool hasLayersFilter() const {
return (!includeLayers.empty() ||
!excludeLayers.empty());
}
bool hasLayersFilter() const { return (!includeLayers.empty() || !excludeLayers.empty()); }
FileOpROI roi() const;
};
FileOpROI roi() const;
};
} // namespace app

View File

@ -6,7 +6,7 @@
// the End-User License Agreement for Aseprite.
#ifdef HAVE_CONFIG_H
#include "config.h"
#include "config.h"
#endif
#include "app/cli/cli_processor.h"
@ -44,9 +44,7 @@ namespace app {
namespace {
bool match_path(const std::string& filter,
const std::string& layer_path,
const bool exclude)
bool match_path(const std::string& filter, const std::string& layer_path, const bool exclude)
{
if (filter == layer_path)
return true;
@ -55,21 +53,18 @@ bool match_path(const std::string& filter,
base::split_string(filter, a, "/");
base::split_string(layer_path, b, "/");
for (std::size_t i=0; i<a.size() && i<b.size(); ++i) {
for (std::size_t i = 0; i < a.size() && i < b.size(); ++i) {
if (a[i] != b[i] && a[i] != "*")
return false;
}
const bool wildcard = (!a.empty() && a[a.size()-1] == "*");
const bool wildcard = (!a.empty() && a[a.size() - 1] == "*");
// Exclude group itself when all children are excluded. This special
// case is only for exclusion because if we leave the group
// selected, the propagation of the selection will include all
// visible children too (see SelectedLayers::propagateSelection()).
if (exclude &&
a.size() > 1 &&
a.size() == b.size()+1 &&
wildcard) {
if (exclude && a.size() > 1 && a.size() == b.size() + 1 && wildcard) {
return true;
}
@ -95,9 +90,8 @@ bool filter_layer(const std::string& layer_path,
// If there is one layer with the given name "filter", we can convert
// the filter to a full path to the layer (e.g. to match child layers
// of a group).
std::string convert_filter_to_layer_path_if_possible(
const Sprite* sprite,
const std::string& filter)
std::string convert_filter_to_layer_path_if_possible(const Sprite* sprite,
const std::string& filter)
{
std::string fullName;
std::queue<Layer*> layers;
@ -107,8 +101,7 @@ std::string convert_filter_to_layer_path_if_possible(
const Layer* layer = layers.front();
layers.pop();
if (layer != sprite->root() &&
layer->name() == filter) {
if (layer != sprite->root() && layer->name() == filter) {
if (fullName.empty()) {
fullName = get_layer_path(layer);
}
@ -152,16 +145,14 @@ void CliProcessor::FilterLayers(const Sprite* sprite,
(!includes.empty() && !filter_layer(layer_path, includes, true)))
continue;
if (!excludes.empty() &&
!filter_layer(layer_path, excludes, false))
if (!excludes.empty() && !filter_layer(layer_path, excludes, false))
continue;
filteredLayers.insert(layer);
}
}
CliProcessor::CliProcessor(CliDelegate* delegate,
const AppOptions& options)
CliProcessor::CliProcessor(CliDelegate* delegate, const AppOptions& options)
: m_delegate(delegate)
, m_options(options)
, m_exporter(nullptr)
@ -307,7 +298,7 @@ int CliProcessor::process(Context* ctx)
"E.g. --frame-range 0,99");
cof.fromFrame = base::convert_to<frame_t>(splitRange[0]);
cof.toFrame = base::convert_to<frame_t>(splitRange[1]);
cof.toFrame = base::convert_to<frame_t>(splitRange[1]);
}
// --ignore-empty
else if (opt == &m_options.ignoreEmpty()) {
@ -403,7 +394,7 @@ int CliProcessor::process(Context* ctx)
// in case the output filename already contains {layer},
// {tag}, or {slice} template elements.
bool hasLayerTemplate = (is_layer_in_filename_format(fn) ||
is_group_in_filename_format(fn));
is_group_in_filename_format(fn));
bool hasTagTemplate = is_tag_in_filename_format(fn);
bool hasSliceTemplate = is_slice_in_filename_format(fn);
@ -451,8 +442,7 @@ int CliProcessor::process(Context* ctx)
// Scale all sprites
for (auto doc : ctx->documents()) {
ctx->setActiveDocument(doc);
ctx->executeCommand(Commands::instance()->byId(CommandId::SpriteSize()),
params);
ctx->executeCommand(Commands::instance()->byId(CommandId::SpriteSize()), params);
}
}
// --dithering-algorithm <algorithm>
@ -466,9 +456,10 @@ int CliProcessor::process(Context* ctx)
else if (value.value() == "error-diffusion")
ditheringAlgorithm = render::DitheringAlgorithm::ErrorDiffusion;
else
throw std::runtime_error("--dithering-algorithm needs a valid algorithm name\n"
"Usage: --dithering-algorithm <algorithm>\n"
"Where <algorithm> can be none, ordered, old, or error-diffusion");
throw std::runtime_error(
"--dithering-algorithm needs a valid algorithm name\n"
"Usage: --dithering-algorithm <algorithm>\n"
"Where <algorithm> can be none, ordered, old, or error-diffusion");
}
// --dithering-matrix <id>
else if (opt == &m_options.ditheringMatrix()) {
@ -487,15 +478,9 @@ int CliProcessor::process(Context* ctx)
else if (value.value() == "indexed") {
params.set("format", "indexed");
switch (ditheringAlgorithm) {
case render::DitheringAlgorithm::None:
params.set("dithering", "none");
break;
case render::DitheringAlgorithm::Ordered:
params.set("dithering", "ordered");
break;
case render::DitheringAlgorithm::Old:
params.set("dithering", "old");
break;
case render::DitheringAlgorithm::None: params.set("dithering", "none"); break;
case render::DitheringAlgorithm::Ordered: params.set("dithering", "ordered"); break;
case render::DitheringAlgorithm::Old: params.set("dithering", "old"); break;
case render::DitheringAlgorithm::ErrorDiffusion:
params.set("dithering", "error-diffusion");
break;
@ -539,8 +524,7 @@ int CliProcessor::process(Context* ctx)
scale = std::min(scaleWidth, scaleHeight);
Params params;
params.set("scale", base::convert_to<std::string>(scale).c_str());
ctx->executeCommand(Commands::instance()->byId(CommandId::SpriteSize()),
params);
ctx->executeCommand(Commands::instance()->byId(CommandId::SpriteSize()), params);
}
}
}
@ -564,8 +548,7 @@ int CliProcessor::process(Context* ctx)
const std::string& v = value.value();
auto i = v.find('=');
if (i != std::string::npos)
scriptParams.set(v.substr(0, i).c_str(),
v.substr(i+1).c_str());
scriptParams.set(v.substr(0, i).c_str(), v.substr(i + 1).c_str());
else
scriptParams.set(v.c_str(), "1");
}
@ -612,11 +595,11 @@ int CliProcessor::process(Context* ctx)
cof.document = nullptr;
cof.filename = base::normalize_path(value.value());
if (// Check that the filename wasn't used loading a sequence
// of images as one sprite
m_usedFiles.find(cof.filename) == m_usedFiles.end() &&
// Open sprite
openFile(ctx, cof)) {
if ( // Check that the filename wasn't used loading a sequence
// of images as one sprite
m_usedFiles.find(cof.filename) == m_usedFiles.end() &&
// Open sprite
openFile(ctx, cof)) {
lastDoc = cof.document;
}
}
@ -652,9 +635,7 @@ bool CliProcessor::openFile(Context* ctx, CliOpenFile& cof)
Doc* oldDoc = ctx->activeDocument();
m_batch.open(ctx,
cof.filename,
cof.oneFrame);
m_batch.open(ctx, cof.filename, cof.oneFrame);
// Mark used file names as "already processed" so we don't try to
// open then again
@ -691,9 +672,8 @@ bool CliProcessor::openFile(Context* ctx, CliOpenFile& cof)
if (cof.hasFrameRange()) {
// --frame-range with --frame-tag
if (tag) {
selFrames.insert(
tag->fromFrame()+std::clamp(cof.fromFrame, 0, tag->frames()-1),
tag->fromFrame()+std::clamp(cof.toFrame, 0, tag->frames()-1));
selFrames.insert(tag->fromFrame() + std::clamp(cof.fromFrame, 0, tag->frames() - 1),
tag->fromFrame() + std::clamp(cof.toFrame, 0, tag->frames() - 1));
}
// --frame-range without --frame-tag
else {
@ -706,25 +686,23 @@ bool CliProcessor::openFile(Context* ctx, CliOpenFile& cof)
filterLayers(doc->sprite(), cof, filteredLayers);
if (cof.exportTileset) {
m_exporter->addTilesetsSamples(
doc,
(cof.hasLayersFilter() ? &filteredLayers: nullptr));
m_exporter->addTilesetsSamples(doc, (cof.hasLayersFilter() ? &filteredLayers : nullptr));
}
else {
m_exporter->addDocumentSamples(
doc, tag,
cof.splitLayers,
cof.splitTags,
cof.splitGrid,
(cof.hasLayersFilter() ? &filteredLayers: nullptr),
(!selFrames.empty() ? &selFrames: nullptr));
m_exporter->addDocumentSamples(doc,
tag,
cof.splitLayers,
cof.splitTags,
cof.splitGrid,
(cof.hasLayersFilter() ? &filteredLayers : nullptr),
(!selFrames.empty() ? &selFrames : nullptr));
}
}
}
m_delegate->afterOpenFile(cof);
return (doc ? true: false);
return (doc ? true : false);
}
void CliProcessor::saveFile(Context* ctx, const CliOpenFile& cof)
@ -742,21 +720,18 @@ void CliProcessor::saveFile(Context* ctx, const CliOpenFile& cof)
cropParams.set("y", base::convert_to<std::string>(cof.crop.y).c_str());
cropParams.set("width", base::convert_to<std::string>(cof.crop.w).c_str());
cropParams.set("height", base::convert_to<std::string>(cof.crop.h).c_str());
ctx->executeCommand(
Commands::instance()->byId(CommandId::CropSprite()),
cropParams);
ctx->executeCommand(Commands::instance()->byId(CommandId::CropSprite()), cropParams);
}
std::string fn = cof.filename;
std::string filenameFormat = cof.filenameFormat;
if (filenameFormat.empty()) { // Default format
bool hasFrames = (cof.roi().frames() > 1);
filenameFormat = get_default_filename_format(
fn,
true, // With path
hasFrames, // Has frames
cof.splitLayers, // Has layer
cof.splitTags); // Has frame tag
filenameFormat = get_default_filename_format(fn,
true, // With path
hasFrames, // Has frames
cof.splitLayers, // Has layer
cof.splitTags); // Has frame tag
}
SelectedLayers filteredLayers;
@ -777,8 +752,7 @@ void CliProcessor::saveFile(Context* ctx, const CliOpenFile& cof)
std::vector<doc::Tag*> tags;
if (cof.hasTag()) {
tags.push_back(
doc->sprite()->tags().getByName(cof.tag));
tags.push_back(doc->sprite()->tags().getByName(cof.tag));
}
else {
doc::Tags& origTags = cof.document->sprite()->tags();
@ -786,8 +760,7 @@ void CliProcessor::saveFile(Context* ctx, const CliOpenFile& cof)
for (doc::Tag* tag : origTags) {
// In case the tag is outside the given --frame-range
if (cof.hasFrameRange()) {
if (tag->toFrame() < cof.fromFrame ||
tag->fromFrame() > cof.toFrame)
if (tag->toFrame() < cof.fromFrame || tag->fromFrame() > cof.toFrame)
continue;
}
tags.push_back(tag);
@ -799,8 +772,7 @@ void CliProcessor::saveFile(Context* ctx, const CliOpenFile& cof)
std::vector<doc::Slice*> slices;
if (cof.hasSlice()) {
slices.push_back(
doc->sprite()->slices().getByName(cof.slice));
slices.push_back(doc->sprite()->slices().getByName(cof.slice));
}
else {
doc::Slices& origSlices = cof.document->sprite()->slices();
@ -826,7 +798,7 @@ void CliProcessor::saveFile(Context* ctx, const CliOpenFile& cof)
// If the user doesn't want all layers and this one is hidden.
if (!layer->isVisible())
continue; // Just ignore this layer.
continue; // Just ignore this layer.
// Make this layer ("show") the only one visible.
layersVisibility.showLayer(layer);
@ -868,9 +840,7 @@ void CliProcessor::saveFile(Context* ctx, const CliOpenFile& cof)
itemCof.includeLayers.push_back(layer->name());
}
if (tag) {
fnInfo
.innerTagName(tag->name())
.outerTagName(tag->name());
fnInfo.innerTagName(tag->name()).outerTagName(tag->name());
itemCof.tag = tag->name();
}
if (slice) {

View File

@ -21,51 +21,47 @@
#include <vector>
namespace doc {
class Sprite;
class Sprite;
}
namespace app {
class AppOptions;
class Context;
class DocExporter;
class AppOptions;
class Context;
class DocExporter;
class CliProcessor {
public:
CliProcessor(CliDelegate* delegate,
const AppOptions& options);
int process(Context* ctx);
class CliProcessor {
public:
CliProcessor(CliDelegate* delegate, const AppOptions& options);
int process(Context* ctx);
// Public so it can be tested
static void FilterLayers(const doc::Sprite* sprite,
// By value because these vectors will be modified inside
std::vector<std::string> includes,
std::vector<std::string> excludes,
doc::SelectedLayers& filteredLayers);
// Public so it can be tested
static void FilterLayers(const doc::Sprite* sprite,
// By value because these vectors will be modified inside
std::vector<std::string> includes,
std::vector<std::string> excludes,
doc::SelectedLayers& filteredLayers);
private:
bool openFile(Context* ctx, CliOpenFile& cof);
void saveFile(Context* ctx, const CliOpenFile& cof);
private:
bool openFile(Context* ctx, CliOpenFile& cof);
void saveFile(Context* ctx, const CliOpenFile& cof);
void filterLayers(const doc::Sprite* sprite,
const CliOpenFile& cof,
doc::SelectedLayers& filteredLayers) {
CliProcessor::FilterLayers(
sprite,
cof.includeLayers,
cof.excludeLayers,
filteredLayers);
}
void filterLayers(const doc::Sprite* sprite,
const CliOpenFile& cof,
doc::SelectedLayers& filteredLayers)
{
CliProcessor::FilterLayers(sprite, cof.includeLayers, cof.excludeLayers, filteredLayers);
}
CliDelegate* m_delegate;
const AppOptions& m_options;
std::unique_ptr<DocExporter> m_exporter;
CliDelegate* m_delegate;
const AppOptions& m_options;
std::unique_ptr<DocExporter> m_exporter;
// Files already used in the CLI processing (e.g. when used to
// load a sequence of files) so we don't ask for them again.
std::set<std::string> m_usedFiles;
OpenBatchOfFiles m_batch;
};
// Files already used in the CLI processing (e.g. when used to
// load a sequence of files) so we don't ask for them again.
std::set<std::string> m_usedFiles;
OpenBatchOfFiles m_batch;
};
} // namespace app

View File

@ -17,7 +17,8 @@ using namespace app;
class CliTestDelegate : public CliDelegate {
public:
CliTestDelegate() {
CliTestDelegate()
{
m_helpWasShown = false;
m_versionWasShown = false;
m_uiMode = false;
@ -30,15 +31,12 @@ public:
void uiMode() override { m_uiMode = true; }
void shellMode() override { m_shellMode = true; }
void batchMode() override { m_batchMode = true; }
void beforeOpenFile(const CliOpenFile& cof) override { }
void afterOpenFile(const CliOpenFile& cof) override { }
void saveFile(Context* ctx, const CliOpenFile& cof) override { }
void exportFiles(Context* ctx, DocExporter& exporter) override { }
void beforeOpenFile(const CliOpenFile& cof) override {}
void afterOpenFile(const CliOpenFile& cof) override {}
void saveFile(Context* ctx, const CliOpenFile& cof) override {}
void exportFiles(Context* ctx, DocExporter& exporter) override {}
#ifdef ENABLE_SCRIPTING
int execScript(const std::string& filename,
const Params& params) override {
return 0;
}
int execScript(const std::string& filename, const Params& params) override { return 0; }
#endif
bool helpWasShown() const { return m_helpWasShown; }
@ -52,12 +50,13 @@ private:
bool m_batchMode;
};
std::unique_ptr<AppOptions> args(std::initializer_list<const char*> l) {
int argc = l.size()+1;
std::unique_ptr<AppOptions> args(std::initializer_list<const char*> l)
{
int argc = l.size() + 1;
const char** argv = new const char*[argc];
argv[0] = "aseprite.exe";
auto it = l.begin();
for (int i=1; i<argc; ++i, ++it) {
for (int i = 1; i < argc; ++i, ++it) {
argv[i] = *it;
TRACE("argv[%d] = %s\n", i, argv[i]);
}
@ -69,7 +68,7 @@ std::unique_ptr<AppOptions> args(std::initializer_list<const char*> l) {
TEST(Cli, None)
{
CliTestDelegate d;
auto a = args({ });
auto a = args({});
CliProcessor p(&d, *a);
p.process(nullptr);
EXPECT_TRUE(!d.helpWasShown());

View File

@ -6,7 +6,7 @@
// the End-User License Agreement for Aseprite.
#ifdef HAVE_CONFIG_H
#include "config.h"
#include "config.h"
#endif
#include "app/cli/default_cli_delegate.h"
@ -42,16 +42,12 @@ namespace app {
void DefaultCliDelegate::showHelp(const AppOptions& options)
{
std::cout
<< get_app_name() << " v" << get_app_version()
<< " | A pixel art program\n"
<< get_app_copyright()
<< "\n\nUsage:\n"
<< " " << options.exeName() << " [OPTIONS] [FILES]...\n\n"
<< "Options:\n"
<< options.programOptions()
<< "\nFind more information in " << get_app_name()
<< " web site: " << get_app_url() << "\n\n";
std::cout << get_app_name() << " v" << get_app_version() << " | A pixel art program\n"
<< get_app_copyright() << "\n\nUsage:\n"
<< " " << options.exeName() << " [OPTIONS] [FILES]...\n\n"
<< "Options:\n"
<< options.programOptions() << "\nFind more information in " << get_app_name()
<< " web site: " << get_app_url() << "\n\n";
}
void DefaultCliDelegate::showVersion()
@ -61,7 +57,7 @@ void DefaultCliDelegate::showVersion()
void DefaultCliDelegate::afterOpenFile(const CliOpenFile& cof)
{
if (!cof.document) // Do nothing
if (!cof.document) // Do nothing
return;
if (cof.listLayers) {
@ -111,8 +107,7 @@ void DefaultCliDelegate::saveFile(Context* ctx, const CliOpenFile& cof)
ctx->executeCommand(saveAsCommand, params);
}
void DefaultCliDelegate::loadPalette(Context* ctx,
const std::string& filename)
void DefaultCliDelegate::loadPalette(Context* ctx, const std::string& filename)
{
std::unique_ptr<doc::Palette> palette(load_palette(filename.c_str()));
if (palette) {
@ -123,8 +118,7 @@ void DefaultCliDelegate::loadPalette(Context* ctx,
ctx->executeCommand(loadPalCommand, params);
}
else {
Console().printf("Error loading palette in --palette '%s'\n",
filename.c_str());
Console().printf("Error loading palette in --palette '%s'\n", filename.c_str());
}
}
@ -133,8 +127,7 @@ void DefaultCliDelegate::exportFiles(Context* ctx, DocExporter& exporter)
LOG("APP: Exporting sheet...\n");
base::task_token token;
std::unique_ptr<Doc> spriteSheet(
exporter.exportSheet(ctx, token));
std::unique_ptr<Doc> spriteSheet(exporter.exportSheet(ctx, token));
// Sprite sheet isn't used, we just delete it.
@ -142,8 +135,7 @@ void DefaultCliDelegate::exportFiles(Context* ctx, DocExporter& exporter)
}
#ifdef ENABLE_SCRIPTING
int DefaultCliDelegate::execScript(const std::string& filename,
const Params& params)
int DefaultCliDelegate::execScript(const std::string& filename, const Params& params)
{
ScriptInputChain scriptInputChain;
if (!App::instance()->isGui()) {

View File

@ -13,19 +13,18 @@
namespace app {
class DefaultCliDelegate : public CliDelegate {
public:
void showHelp(const AppOptions& programOptions) override;
void showVersion() override;
void afterOpenFile(const CliOpenFile& cof) override;
void saveFile(Context* ctx, const CliOpenFile& cof) override;
void loadPalette(Context* ctx, const std::string& filename) override;
void exportFiles(Context* ctx, DocExporter& exporter) override;
class DefaultCliDelegate : public CliDelegate {
public:
void showHelp(const AppOptions& programOptions) override;
void showVersion() override;
void afterOpenFile(const CliOpenFile& cof) override;
void saveFile(Context* ctx, const CliOpenFile& cof) override;
void loadPalette(Context* ctx, const std::string& filename) override;
void exportFiles(Context* ctx, DocExporter& exporter) override;
#ifdef ENABLE_SCRIPTING
int execScript(const std::string& filename,
const Params& params) override;
int execScript(const std::string& filename, const Params& params) override;
#endif
};
};
} // namespace app

View File

@ -15,8 +15,7 @@ using namespace doc;
class FilterLayers : public ::testing::Test {
public:
FilterLayers()
: sprite(ImageSpec(ColorMode::RGB, 32, 32))
FilterLayers() : sprite(ImageSpec(ColorMode::RGB, 32, 32))
{
a->setName("a");
b->setName("b");
@ -33,12 +32,9 @@ public:
b->addLayer(bb);
}
void filter(
std::vector<std::string> includes,
std::vector<std::string> excludes)
void filter(std::vector<std::string> includes, std::vector<std::string> excludes)
{
CliProcessor::FilterLayers(
&sprite, std::move(includes), std::move(excludes), sel);
CliProcessor::FilterLayers(&sprite, std::move(includes), std::move(excludes), sel);
}
Sprite sprite;

View File

@ -6,7 +6,7 @@
// the End-User License Agreement for Aseprite.
#ifdef HAVE_CONFIG_H
#include "config.h"
#include "config.h"
#endif
#include "app/cli/preview_cli_delegate.h"
@ -94,10 +94,7 @@ void PreviewCliDelegate::saveFile(Context* ctx, const CliOpenFile& cof)
<< " - Sprite: '" << cof.document->filename() << "'\n";
if (!cof.crop.isEmpty()) {
std::cout << " - Crop: "
<< cof.crop.x << ","
<< cof.crop.y << " "
<< cof.crop.w << "x"
std::cout << " - Crop: " << cof.crop.x << "," << cof.crop.y << " " << cof.crop.w << "x"
<< cof.crop.h << "\n";
}
@ -112,8 +109,7 @@ void PreviewCliDelegate::saveFile(Context* ctx, const CliOpenFile& cof)
std::cout << " - Ignore empty frames\n";
}
std::cout << " - Size: "
<< cof.document->sprite()->width() << "x"
std::cout << " - Size: " << cof.document->sprite()->width() << "x"
<< cof.document->sprite()->height() << "\n";
showLayersFilter(cof);
@ -136,8 +132,7 @@ void PreviewCliDelegate::saveFile(Context* ctx, const CliOpenFile& cof)
const auto& selFrames = cof.roi().framesSequence();
if (!selFrames.empty()) {
if (selFrames.ranges() == 1)
std::cout << " - Frame range from "
<< selFrames.firstFrame() << " to "
std::cout << " - Frame range from " << selFrames.firstFrame() << " to "
<< selFrames.lastFrame() << "\n";
else {
std::cout << " - Specific frames:";
@ -151,13 +146,11 @@ void PreviewCliDelegate::saveFile(Context* ctx, const CliOpenFile& cof)
if (!cof.filenameFormat.empty())
std::cout << " - Filename format: '" << cof.filenameFormat << "'\n";
std::unique_ptr<FileOp> fop(
FileOp::createSaveDocumentOperation(
ctx,
cof.roi(),
cof.filename,
cof.filenameFormat,
cof.ignoreEmpty));
std::unique_ptr<FileOp> fop(FileOp::createSaveDocumentOperation(ctx,
cof.roi(),
cof.filename,
cof.filenameFormat,
cof.ignoreEmpty));
if (fop) {
base::paths files;
@ -173,8 +166,7 @@ void PreviewCliDelegate::saveFile(Context* ctx, const CliOpenFile& cof)
std::cout << " - No output\n";
}
void PreviewCliDelegate::loadPalette(Context* ctx,
const std::string& filename)
void PreviewCliDelegate::loadPalette(Context* ctx, const std::string& filename)
{
std::cout << "- Load palette:\n"
<< " - Palette: '" << filename << "'\n";
@ -185,10 +177,10 @@ void PreviewCliDelegate::exportFiles(Context* ctx, DocExporter& exporter)
std::string type = "None";
switch (exporter.spriteSheetType()) {
case SpriteSheetType::Horizontal: type = "Horizontal"; break;
case SpriteSheetType::Vertical: type = "Vertical"; break;
case SpriteSheetType::Rows: type = "Rows"; break;
case SpriteSheetType::Columns: type = "Columns"; break;
case SpriteSheetType::Packed: type = "Packed"; break;
case SpriteSheetType::Vertical: type = "Vertical"; break;
case SpriteSheetType::Rows: type = "Rows"; break;
case SpriteSheetType::Columns: type = "Columns"; break;
case SpriteSheetType::Packed: type = "Packed"; break;
}
gfx::Size size = exporter.calculateSheetSize();
@ -197,29 +189,26 @@ void PreviewCliDelegate::exportFiles(Context* ctx, DocExporter& exporter)
<< " - Size: " << size.w << "x" << size.h << "\n";
if (!exporter.textureFilename().empty()) {
std::cout << " - Save texture file: '"
<< exporter.textureFilename() << "'\n";
std::cout << " - Save texture file: '" << exporter.textureFilename() << "'\n";
}
if (!exporter.dataFilename().empty()) {
std::string format = "Unknown";
switch (exporter.dataFormat()) {
case SpriteSheetDataFormat::JsonHash: format = "JSON Hash"; break;
case SpriteSheetDataFormat::JsonHash: format = "JSON Hash"; break;
case SpriteSheetDataFormat::JsonArray: format = "JSON Array"; break;
}
std::cout << " - Save data file: '" << exporter.dataFilename() << "'\n"
<< " - Data format: " << format << "\n";
if (!exporter.filenameFormat().empty()) {
std::cout << " - Filename format for JSON items: '"
<< exporter.filenameFormat() << "'\n";
std::cout << " - Filename format for JSON items: '" << exporter.filenameFormat() << "'\n";
}
}
}
#ifdef ENABLE_SCRIPTING
int PreviewCliDelegate::execScript(const std::string& filename,
const Params& params)
int PreviewCliDelegate::execScript(const std::string& filename, const Params& params)
{
std::cout << "- Run script: '" << filename << "'\n";
if (!params.empty()) {
@ -257,8 +246,7 @@ void PreviewCliDelegate::showLayerVisibility(const doc::LayerGroup* group,
continue;
std::cout << indent << "- " << layer->name() << "\n";
if (layer->isGroup())
showLayerVisibility(static_cast<const LayerGroup*>(layer),
indent + " ");
showLayerVisibility(static_cast<const LayerGroup*>(layer), indent + " ");
}
}

View File

@ -14,33 +14,31 @@
#include <string>
namespace doc {
class LayerGroup;
class LayerGroup;
}
namespace app {
class PreviewCliDelegate : public CliDelegate {
public:
void showHelp(const AppOptions& programOptions) override;
void showVersion() override;
void uiMode() override;
void shellMode() override;
void batchMode() override;
void beforeOpenFile(const CliOpenFile& cof) override;
void afterOpenFile(const CliOpenFile& cof) override;
void saveFile(Context* ctx, const CliOpenFile& cof) override;
void loadPalette(Context* ctx, const std::string& filename) override;
void exportFiles(Context* ctx, DocExporter& exporter) override;
class PreviewCliDelegate : public CliDelegate {
public:
void showHelp(const AppOptions& programOptions) override;
void showVersion() override;
void uiMode() override;
void shellMode() override;
void batchMode() override;
void beforeOpenFile(const CliOpenFile& cof) override;
void afterOpenFile(const CliOpenFile& cof) override;
void saveFile(Context* ctx, const CliOpenFile& cof) override;
void loadPalette(Context* ctx, const std::string& filename) override;
void exportFiles(Context* ctx, DocExporter& exporter) override;
#ifdef ENABLE_SCRIPTING
int execScript(const std::string& filename,
const Params& params) override;
int execScript(const std::string& filename, const Params& params) override;
#endif // ENABLE_SCRIPTING
private:
void showLayersFilter(const CliOpenFile& cof);
void showLayerVisibility(const doc::LayerGroup* group,
const std::string& indent);
};
private:
void showLayersFilter(const CliOpenFile& cof);
void showLayerVisibility(const doc::LayerGroup* group, const std::string& indent);
};
} // namespace app

View File

@ -5,7 +5,7 @@
// the End-User License Agreement for Aseprite.
#ifdef HAVE_CONFIG_H
#include "config.h"
#include "config.h"
#endif
#include "app/closed_docs.h"
@ -20,22 +20,23 @@
namespace app {
ClosedDocs::ClosedDocs(const Preferences& pref)
: m_done(false)
ClosedDocs::ClosedDocs(const Preferences& pref) : m_done(false)
{
if (pref.general.dataRecovery())
m_dataRecoveryPeriodMSecs = int(1000.0*60.0*pref.general.dataRecoveryPeriod());
m_dataRecoveryPeriodMSecs = int(1000.0 * 60.0 * pref.general.dataRecoveryPeriod());
else
m_dataRecoveryPeriodMSecs = 0;
if (pref.general.keepClosedSpriteOnMemory())
m_keepClosedDocAliveForMSecs = int(1000.0*60.0*pref.general.keepClosedSpriteOnMemoryFor());
m_keepClosedDocAliveForMSecs = int(1000.0 * 60.0 * pref.general.keepClosedSpriteOnMemoryFor());
else
m_keepClosedDocAliveForMSecs = 0;
CLOSEDOC_TRACE("CLOSEDOC: Init",
"dataRecoveryPeriod", m_dataRecoveryPeriodMSecs,
"keepClosedDocs", m_keepClosedDocAliveForMSecs);
"dataRecoveryPeriod",
m_dataRecoveryPeriodMSecs,
"keepClosedDocs",
m_keepClosedDocAliveForMSecs);
}
ClosedDocs::~ClosedDocs()
@ -62,8 +63,7 @@ bool ClosedDocs::hasClosedDocs()
std::unique_lock<std::mutex> lock(m_mutex);
result = !m_docs.empty();
}
CLOSEDOC_TRACE("CLOSEDOC: Has closed docs?",
(result ? "true": "false"));
CLOSEDOC_TRACE("CLOSEDOC: Has closed docs?", (result ? "true" : "false"));
return result;
}
@ -80,7 +80,7 @@ void ClosedDocs::addClosedDoc(Doc* doc)
m_docs.insert(m_docs.begin(), std::move(closedDoc));
if (!m_thread.joinable())
m_thread = std::thread([this]{ backgroundThread(); });
m_thread = std::thread([this] { backgroundThread(); });
else
m_cv.notify_one();
}
@ -126,18 +126,18 @@ void ClosedDocs::backgroundThread()
base::tick_t now = base::current_tick();
base::tick_t waitForMSecs = std::numeric_limits<base::tick_t>::max();
for (auto it=m_docs.begin(); it != m_docs.end(); ) {
for (auto it = m_docs.begin(); it != m_docs.end();) {
const ClosedDoc& closedDoc = *it;
auto doc = closedDoc.doc;
base::tick_t diff = now - closedDoc.timestamp;
if (diff >= m_keepClosedDocAliveForMSecs) {
if (// If we backup process is disabled
m_dataRecoveryPeriodMSecs == 0 ||
// Or this document doesn't need a backup (e.g. an unmodified document)
!doc->needsBackup() ||
// Or the document already has the backup done
doc->isFullyBackedUp()) {
if ( // If we backup process is disabled
m_dataRecoveryPeriodMSecs == 0 ||
// Or this document doesn't need a backup (e.g. an unmodified document)
!doc->needsBackup() ||
// Or the document already has the backup done
doc->isFullyBackedUp()) {
// Finally delete the document (this is the place where we
// delete all documents created/loaded by the user)
CLOSEDOC_TRACE("CLOSEDOC: [BG] Delete doc", doc);
@ -150,7 +150,7 @@ void ClosedDocs::backgroundThread()
}
}
else {
waitForMSecs = std::min(waitForMSecs, m_keepClosedDocAliveForMSecs-diff);
waitForMSecs = std::min(waitForMSecs, m_keepClosedDocAliveForMSecs - diff);
++it;
}
}

View File

@ -18,47 +18,47 @@
namespace app {
class Doc;
class Preferences;
class Doc;
class Preferences;
// Handle the list of closed docs:
// * When a document is closed, we keep it for some time so the user
// can undo the close command without losing the undo history.
// * For the first closed document, a thread is launched to wait
// until we can definitely delete the doc after X minutes (like a
// garbage collector).
// * If the document was not restore, we delete it from memory, if
// the document was restore, we remove it from the m_docs.
class ClosedDocs {
public:
ClosedDocs(const Preferences& pref);
~ClosedDocs();
// Handle the list of closed docs:
// * When a document is closed, we keep it for some time so the user
// can undo the close command without losing the undo history.
// * For the first closed document, a thread is launched to wait
// until we can definitely delete the doc after X minutes (like a
// garbage collector).
// * If the document was not restore, we delete it from memory, if
// the document was restore, we remove it from the m_docs.
class ClosedDocs {
public:
ClosedDocs(const Preferences& pref);
~ClosedDocs();
bool hasClosedDocs();
void addClosedDoc(Doc* doc);
Doc* reopenLastClosedDoc();
bool hasClosedDocs();
void addClosedDoc(Doc* doc);
Doc* reopenLastClosedDoc();
// Called at the very end to get all closed docs, remove them from
// the list of closed docs, and stop the thread.
std::vector<Doc*> getAndRemoveAllClosedDocs();
// Called at the very end to get all closed docs, remove them from
// the list of closed docs, and stop the thread.
std::vector<Doc*> getAndRemoveAllClosedDocs();
private:
void backgroundThread();
private:
void backgroundThread();
struct ClosedDoc {
Doc* doc;
base::tick_t timestamp;
};
std::atomic<bool> m_done;
base::tick_t m_dataRecoveryPeriodMSecs;
base::tick_t m_keepClosedDocAliveForMSecs;
std::vector<ClosedDoc> m_docs;
std::mutex m_mutex;
std::condition_variable m_cv;
std::thread m_thread;
struct ClosedDoc {
Doc* doc;
base::tick_t timestamp;
};
std::atomic<bool> m_done;
base::tick_t m_dataRecoveryPeriodMSecs;
base::tick_t m_keepClosedDocAliveForMSecs;
std::vector<ClosedDoc> m_docs;
std::mutex m_mutex;
std::condition_variable m_cv;
std::thread m_thread;
};
} // namespace app
#endif

View File

@ -5,7 +5,7 @@
// the End-User License Agreement for Aseprite.
#ifdef HAVE_CONFIG_H
#include "config.h"
#include "config.h"
#endif
#include "app/cmd.h"
@ -115,7 +115,8 @@ std::string Cmd::onLabel() const
return "";
}
size_t Cmd::onMemSize() const {
size_t Cmd::onMemSize() const
{
return sizeof(*this);
}

View File

@ -16,44 +16,44 @@
namespace app {
class Context;
class Context;
class Cmd : public undo::UndoCommand {
public:
Cmd();
virtual ~Cmd();
class Cmd : public undo::UndoCommand {
public:
Cmd();
virtual ~Cmd();
void execute(Context* ctx);
void execute(Context* ctx);
// undo::UndoCommand impl
void undo() override;
void redo() override;
void dispose() override;
// undo::UndoCommand impl
void undo() override;
void redo() override;
void dispose() override;
std::string label() const;
size_t memSize() const;
std::string label() const;
size_t memSize() const;
Context* context() const { return m_ctx; }
Context* context() const { return m_ctx; }
protected:
virtual void onExecute();
virtual void onUndo();
virtual void onRedo();
virtual void onFireNotifications();
virtual std::string onLabel() const;
virtual size_t onMemSize() const;
protected:
virtual void onExecute();
virtual void onUndo();
virtual void onRedo();
virtual void onFireNotifications();
virtual std::string onLabel() const;
virtual size_t onMemSize() const;
private:
// TODO I think we could just remove this field (but we'll need to
// include the Context* in all onEvent() member functions)
Context* m_ctx;
private:
// TODO I think we could just remove this field (but we'll need to
// include the Context* in all onEvent() member functions)
Context* m_ctx;
#if _DEBUG
enum class State { NotExecuted, Executed, Undone, Redone };
State m_state;
enum class State { NotExecuted, Executed, Undone, Redone };
State m_state;
#endif
DISABLE_COPYING(Cmd);
};
DISABLE_COPYING(Cmd);
};
} // namespace app

View File

@ -6,7 +6,7 @@
// the End-User License Agreement for Aseprite.
#ifdef HAVE_CONFIG_H
#include "config.h"
#include "config.h"
#endif
#include "app/cmd/add_cel.h"
@ -21,17 +21,13 @@
#include "doc/layer.h"
#include "doc/subobjects_io.h"
namespace app {
namespace cmd {
namespace app { namespace cmd {
using namespace base::serialization;
using namespace base::serialization::little_endian;
using namespace doc;
AddCel::AddCel(Layer* layer, Cel* cel)
: WithLayer(layer)
, WithCel(cel)
, m_size(0)
AddCel::AddCel(Layer* layer, Cel* cel) : WithLayer(layer), WithCel(cel), m_size(0)
{
}
@ -54,7 +50,7 @@ void AddCel::onUndo()
// Save the CelData only if the cel isn't linked
bool has_data = (cel->links() == 0);
write8(m_stream, has_data ? 1: 0);
write8(m_stream, has_data ? 1 : 0);
if (has_data) {
write_image(m_stream, cel->image());
write_celdata(m_stream, cel->data());
@ -119,5 +115,4 @@ void AddCel::removeCel(Layer* layer, Cel* cel)
delete cel;
}
} // namespace cmd
} // namespace app
}} // namespace app::cmd

View File

@ -15,37 +15,33 @@
#include <sstream>
namespace doc {
class Cel;
class Layer;
}
class Cel;
class Layer;
} // namespace doc
namespace app {
namespace cmd {
using namespace doc;
namespace app { namespace cmd {
using namespace doc;
class AddCel : public Cmd
, public WithLayer
, public WithCel {
public:
AddCel(Layer* layer, Cel* cel);
class AddCel : public Cmd,
public WithLayer,
public WithCel {
public:
AddCel(Layer* layer, Cel* cel);
protected:
void onExecute() override;
void onUndo() override;
void onRedo() override;
size_t onMemSize() const override {
return sizeof(*this) + m_size;
}
protected:
void onExecute() override;
void onUndo() override;
void onRedo() override;
size_t onMemSize() const override { return sizeof(*this) + m_size; }
private:
void addCel(Layer* layer, Cel* cel);
void removeCel(Layer* layer, Cel* cel);
private:
void addCel(Layer* layer, Cel* cel);
void removeCel(Layer* layer, Cel* cel);
size_t m_size;
std::stringstream m_stream;
};
size_t m_size;
std::stringstream m_stream;
};
} // namespace cmd
} // namespace app
}} // namespace app::cmd
#endif

View File

@ -5,7 +5,7 @@
// the End-User License Agreement for Aseprite.
#ifdef HAVE_CONFIG_H
#include "config.h"
#include "config.h"
#endif
#include "app/cmd/add_frame.h"
@ -18,8 +18,7 @@
#include "doc/primitives.h"
#include "doc/sprite.h"
namespace app {
namespace cmd {
namespace app { namespace cmd {
using namespace doc;
@ -77,5 +76,4 @@ void AddFrame::onUndo()
doc->notify_observers<DocEvent&>(&DocObserver::onRemoveFrame, ev);
}
} // namespace cmd
} // namespace app
}} // namespace app::cmd

View File

@ -16,34 +16,29 @@
#include <memory>
namespace doc {
class Sprite;
class Sprite;
}
namespace app {
namespace cmd {
using namespace doc;
namespace app { namespace cmd {
using namespace doc;
class AddFrame : public Cmd
, public WithSprite {
public:
AddFrame(Sprite* sprite, frame_t frame);
class AddFrame : public Cmd,
public WithSprite {
public:
AddFrame(Sprite* sprite, frame_t frame);
protected:
void onExecute() override;
void onUndo() override;
size_t onMemSize() const override {
return sizeof(*this) +
(m_addCel ? m_addCel->memSize() : 0);
}
protected:
void onExecute() override;
void onUndo() override;
size_t onMemSize() const override { return sizeof(*this) + (m_addCel ? m_addCel->memSize() : 0); }
private:
void moveFrames(Layer* layer, frame_t fromThis, frame_t delta);
private:
void moveFrames(Layer* layer, frame_t fromThis, frame_t delta);
frame_t m_newFrame;
std::unique_ptr<AddCel> m_addCel;
};
frame_t m_newFrame;
std::unique_ptr<AddCel> m_addCel;
};
} // namespace cmd
} // namespace app
}} // namespace app::cmd
#endif

View File

@ -5,7 +5,7 @@
// the End-User License Agreement for Aseprite.
#ifdef HAVE_CONFIG_H
#include "config.h"
#include "config.h"
#endif
#include "app/cmd/add_layer.h"
@ -16,8 +16,7 @@
#include "doc/layer_io.h"
#include "doc/subobjects_io.h"
namespace app {
namespace cmd {
namespace app { namespace cmd {
using namespace doc;
@ -93,5 +92,4 @@ void AddLayer::removeLayer(Layer* group, Layer* layer)
delete layer;
}
} // namespace cmd
} // namespace app
}} // namespace app::cmd

View File

@ -14,37 +14,33 @@
#include <sstream>
namespace doc {
class Layer;
class Layer;
}
namespace app {
namespace cmd {
using namespace doc;
namespace app { namespace cmd {
using namespace doc;
class AddLayer : public Cmd {
public:
AddLayer(Layer* group, Layer* newLayer, Layer* afterThis);
class AddLayer : public Cmd {
public:
AddLayer(Layer* group, Layer* newLayer, Layer* afterThis);
protected:
void onExecute() override;
void onUndo() override;
void onRedo() override;
size_t onMemSize() const override {
return sizeof(*this) + m_size;
}
protected:
void onExecute() override;
void onUndo() override;
void onRedo() override;
size_t onMemSize() const override { return sizeof(*this) + m_size; }
private:
void addLayer(Layer* group, Layer* newLayer, Layer* afterThis);
void removeLayer(Layer* group, Layer* layer);
private:
void addLayer(Layer* group, Layer* newLayer, Layer* afterThis);
void removeLayer(Layer* group, Layer* layer);
WithLayer m_group;
WithLayer m_newLayer;
WithLayer m_afterThis;
size_t m_size;
std::stringstream m_stream;
};
WithLayer m_group;
WithLayer m_newLayer;
WithLayer m_afterThis;
size_t m_size;
std::stringstream m_stream;
};
} // namespace cmd
} // namespace app
}} // namespace app::cmd
#endif

View File

@ -5,17 +5,16 @@
// the End-User License Agreement for Aseprite.
#ifdef HAVE_CONFIG_H
#include "config.h"
#include "config.h"
#endif
#include "app/cmd/add_palette.h"
#include "doc/sprite.h"
#include "doc/palette.h"
#include "doc/palette_io.h"
#include "doc/sprite.h"
namespace app {
namespace cmd {
namespace app { namespace cmd {
using namespace doc;
@ -47,5 +46,4 @@ void AddPalette::onUndo()
sprite->incrementVersion();
}
} // namespace cmd
} // namespace app
}} // namespace app::cmd

View File

@ -15,33 +15,29 @@
#include <sstream>
namespace doc {
class Palette;
class Sprite;
}
class Palette;
class Sprite;
} // namespace doc
namespace app {
namespace cmd {
using namespace doc;
namespace app { namespace cmd {
using namespace doc;
class AddPalette : public Cmd
, public WithSprite {
public:
AddPalette(Sprite* sprite, Palette* pal);
class AddPalette : public Cmd,
public WithSprite {
public:
AddPalette(Sprite* sprite, Palette* pal);
protected:
void onExecute() override;
void onUndo() override;
size_t onMemSize() const override {
return sizeof(*this) + m_size;
}
protected:
void onExecute() override;
void onUndo() override;
size_t onMemSize() const override { return sizeof(*this) + m_size; }
private:
size_t m_size;
std::stringstream m_stream;
frame_t m_frame;
};
private:
size_t m_size;
std::stringstream m_stream;
frame_t m_frame;
};
} // namespace cmd
} // namespace app
}} // namespace app::cmd
#endif // CMD_ADD_PALETTE_H_INCLUDED
#endif // CMD_ADD_PALETTE_H_INCLUDED

View File

@ -6,7 +6,7 @@
// the End-User License Agreement for Aseprite.
#ifdef HAVE_CONFIG_H
#include "config.h"
#include "config.h"
#endif
#include "app/cmd/add_slice.h"
@ -17,15 +17,11 @@
#include "doc/slice_io.h"
#include "doc/sprite.h"
namespace app {
namespace cmd {
namespace app { namespace cmd {
using namespace doc;
AddSlice::AddSlice(Sprite* sprite, Slice* slice)
: WithSprite(sprite)
, WithSlice(slice)
, m_size(0)
AddSlice::AddSlice(Sprite* sprite, Slice* slice) : WithSprite(sprite), WithSlice(slice), m_size(0)
{
}
@ -84,5 +80,4 @@ void AddSlice::removeSlice(Sprite* sprite, Slice* slice)
delete slice;
}
} // namespace cmd
} // namespace app
}} // namespace app::cmd

View File

@ -15,33 +15,29 @@
#include <sstream>
namespace app {
namespace cmd {
using namespace doc;
namespace app { namespace cmd {
using namespace doc;
class AddSlice : public Cmd
, public WithSprite
, public WithSlice {
public:
AddSlice(Sprite* sprite, Slice* slice);
class AddSlice : public Cmd,
public WithSprite,
public WithSlice {
public:
AddSlice(Sprite* sprite, Slice* slice);
protected:
void onExecute() override;
void onUndo() override;
void onRedo() override;
size_t onMemSize() const override {
return sizeof(*this) + m_size;
}
protected:
void onExecute() override;
void onUndo() override;
void onRedo() override;
size_t onMemSize() const override { return sizeof(*this) + m_size; }
private:
void addSlice(Sprite* sprite, Slice* slice);
void removeSlice(Sprite* sprite, Slice* slice);
private:
void addSlice(Sprite* sprite, Slice* slice);
void removeSlice(Sprite* sprite, Slice* slice);
size_t m_size;
std::stringstream m_stream;
};
size_t m_size;
std::stringstream m_stream;
};
} // namespace cmd
} // namespace app
}} // namespace app::cmd
#endif

View File

@ -6,7 +6,7 @@
// the End-User License Agreement for Aseprite.
#ifdef HAVE_CONFIG_H
#include "config.h"
#include "config.h"
#endif
#include "app/cmd/add_tag.h"
@ -17,15 +17,11 @@
#include "doc/tag.h"
#include "doc/tag_io.h"
namespace app {
namespace cmd {
namespace app { namespace cmd {
using namespace doc;
AddTag::AddTag(Sprite* sprite, Tag* tag)
: WithSprite(sprite)
, WithTag(tag)
, m_size(0)
AddTag::AddTag(Sprite* sprite, Tag* tag) : WithSprite(sprite), WithTag(tag), m_size(0)
{
}
@ -86,5 +82,4 @@ void AddTag::onRedo()
doc->notify_observers<DocEvent&>(&DocObserver::onAddTag, ev);
}
} // namespace cmd
} // namespace app
}} // namespace app::cmd

View File

@ -10,35 +10,31 @@
#pragma once
#include "app/cmd.h"
#include "app/cmd/with_tag.h"
#include "app/cmd/with_sprite.h"
#include "app/cmd/with_tag.h"
#include <sstream>
namespace app {
namespace cmd {
using namespace doc;
namespace app { namespace cmd {
using namespace doc;
class AddTag : public Cmd
, public WithSprite
, public WithTag {
public:
AddTag(Sprite* sprite, Tag* tag);
class AddTag : public Cmd,
public WithSprite,
public WithTag {
public:
AddTag(Sprite* sprite, Tag* tag);
protected:
void onExecute() override;
void onUndo() override;
void onRedo() override;
size_t onMemSize() const override {
return sizeof(*this) + m_size;
}
protected:
void onExecute() override;
void onUndo() override;
void onRedo() override;
size_t onMemSize() const override { return sizeof(*this) + m_size; }
private:
size_t m_size;
std::stringstream m_stream;
};
private:
size_t m_size;
std::stringstream m_stream;
};
} // namespace cmd
} // namespace app
}} // namespace app::cmd
#endif

View File

@ -5,7 +5,7 @@
// the End-User License Agreement for Aseprite.
#ifdef HAVE_CONFIG_H
#include "config.h"
#include "config.h"
#endif
#include "app/cmd/add_tile.h"
@ -16,12 +16,9 @@
#include "doc/tileset.h"
#include "doc/tilesets.h"
namespace app {
namespace cmd {
namespace app { namespace cmd {
AddTile::AddTile(doc::Tileset* tileset,
const doc::ImageRef& image,
const doc::UserData& userData)
AddTile::AddTile(doc::Tileset* tileset, const doc::ImageRef& image, const doc::UserData& userData)
: WithTileset(tileset)
, WithImage(image.get())
, m_size(0)
@ -31,8 +28,7 @@ AddTile::AddTile(doc::Tileset* tileset,
{
}
AddTile::AddTile(doc::Tileset* tileset,
const doc::tile_index ti)
AddTile::AddTile(doc::Tileset* tileset, const doc::tile_index ti)
: WithTileset(tileset)
, WithImage(tileset->get(ti).get())
, m_size(0)
@ -94,8 +90,7 @@ void AddTile::onFireNotifications()
doc::Tileset* tileset = this->tileset();
// Notify that the tileset's changed
static_cast<Doc*>(tileset->sprite()->document())
->notifyTilesetChanged(tileset);
static_cast<Doc*>(tileset->sprite()->document())->notifyTilesetChanged(tileset);
}
void AddTile::addTile(doc::Tileset* tileset,
@ -111,5 +106,4 @@ void AddTile::addTile(doc::Tileset* tileset,
tileset->incrementVersion();
}
} // namespace cmd
} // namespace app
}} // namespace app::cmd

View File

@ -18,47 +18,43 @@
#include <sstream>
namespace doc {
class Tileset;
class Tileset;
}
namespace app {
namespace cmd {
namespace app { namespace cmd {
class AddTile : public Cmd
, public WithTileset
, public WithImage {
public:
AddTile(doc::Tileset* tileset,
const doc::ImageRef& image,
const doc::UserData& userData = UserData());
AddTile(doc::Tileset* tileset,
const doc::tile_index ti);
class AddTile : public Cmd,
public WithTileset,
public WithImage {
public:
AddTile(doc::Tileset* tileset,
const doc::ImageRef& image,
const doc::UserData& userData = UserData());
AddTile(doc::Tileset* tileset, const doc::tile_index ti);
doc::tile_index tileIndex() const { return m_tileIndex; }
doc::tile_index tileIndex() const { return m_tileIndex; }
protected:
void onExecute() override;
void onUndo() override;
void onRedo() override;
void onFireNotifications() override;
size_t onMemSize() const override {
// TODO add m_userData size
return sizeof(*this) + m_size;
}
protected:
void onExecute() override;
void onUndo() override;
void onRedo() override;
void onFireNotifications() override;
size_t onMemSize() const override
{
// TODO add m_userData size
return sizeof(*this) + m_size;
}
private:
void addTile(doc::Tileset* tileset,
const doc::ImageRef& image,
const doc::UserData& userData);
private:
void addTile(doc::Tileset* tileset, const doc::ImageRef& image, const doc::UserData& userData);
size_t m_size;
std::stringstream m_stream;
doc::tile_index m_tileIndex;
doc::ImageRef m_imageRef;
doc::UserData m_userData;
};
size_t m_size;
std::stringstream m_stream;
doc::tile_index m_tileIndex;
doc::ImageRef m_imageRef;
doc::UserData m_userData;
};
} // namespace cmd
} // namespace app
}} // namespace app::cmd
#endif

View File

@ -5,7 +5,7 @@
// the End-User License Agreement for Aseprite.
#ifdef HAVE_CONFIG_H
#include "config.h"
#include "config.h"
#endif
#include "app/cmd/add_tileset.h"
@ -16,8 +16,7 @@
#include "doc/tileset_io.h"
#include "doc/tilesets.h"
namespace app {
namespace cmd {
namespace app { namespace cmd {
using namespace doc;
@ -84,5 +83,4 @@ void AddTileset::addTileset(doc::Tileset* tileset)
sprite->tilesets()->incrementVersion();
}
} // namespace cmd
} // namespace app
}} // namespace app::cmd

View File

@ -16,38 +16,34 @@
#include <sstream>
namespace doc {
class Tileset;
class Tileset;
}
namespace app {
namespace cmd {
namespace app { namespace cmd {
class AddTileset : public Cmd
, public WithSprite
, public WithTileset {
public:
AddTileset(doc::Sprite* sprite, doc::Tileset* tileset);
AddTileset(doc::Sprite* sprite, const doc::tileset_index tsi);
class AddTileset : public Cmd,
public WithSprite,
public WithTileset {
public:
AddTileset(doc::Sprite* sprite, doc::Tileset* tileset);
AddTileset(doc::Sprite* sprite, const doc::tileset_index tsi);
doc::tileset_index tilesetIndex() const { return m_tilesetIndex; }
doc::tileset_index tilesetIndex() const { return m_tilesetIndex; }
protected:
void onExecute() override;
void onUndo() override;
void onRedo() override;
size_t onMemSize() const override {
return sizeof(*this) + m_size;
}
protected:
void onExecute() override;
void onUndo() override;
void onRedo() override;
size_t onMemSize() const override { return sizeof(*this) + m_size; }
private:
void addTileset(doc::Tileset* tileset);
private:
void addTileset(doc::Tileset* tileset);
size_t m_size;
std::stringstream m_stream;
doc::tileset_index m_tilesetIndex;
};
size_t m_size;
std::stringstream m_stream;
doc::tileset_index m_tilesetIndex;
};
} // namespace cmd
} // namespace app
}} // namespace app::cmd
#endif

View File

@ -5,7 +5,7 @@
// the End-User License Agreement for Aseprite.
#ifdef HAVE_CONFIG_H
#include "config.h"
#include "config.h"
#endif
#include "app/cmd/assign_color_profile.h"
@ -14,8 +14,7 @@
#include "app/doc_event.h"
#include "doc/sprite.h"
namespace app {
namespace cmd {
namespace app { namespace cmd {
AssignColorProfile::AssignColorProfile(doc::Sprite* sprite, const gfx::ColorSpaceRef& cs)
: WithSprite(sprite)
@ -45,5 +44,4 @@ void AssignColorProfile::onFireNotifications()
doc->notifyColorSpaceChanged();
}
} // namespace cmd
} // namespace app
}} // namespace app::cmd

View File

@ -12,31 +12,27 @@
#include "app/cmd/with_sprite.h"
#include "gfx/color_space.h"
namespace app {
namespace cmd {
namespace app { namespace cmd {
class AssignColorProfile : public Cmd,
public WithSprite {
public:
AssignColorProfile(doc::Sprite* sprite, const gfx::ColorSpaceRef& cs);
class AssignColorProfile : public Cmd,
public WithSprite {
public:
AssignColorProfile(doc::Sprite* sprite, const gfx::ColorSpaceRef& cs);
protected:
void onExecute() override;
void onUndo() override;
void onFireNotifications() override;
size_t onMemSize() const override {
return sizeof(*this) +
2*sizeof(gfx::ColorSpace) +
m_oldCS->iccSize() +
m_newCS->iccSize();
}
protected:
void onExecute() override;
void onUndo() override;
void onFireNotifications() override;
size_t onMemSize() const override
{
return sizeof(*this) + 2 * sizeof(gfx::ColorSpace) + m_oldCS->iccSize() + m_newCS->iccSize();
}
private:
gfx::ColorSpaceRef m_oldCS;
gfx::ColorSpaceRef m_newCS;
};
private:
gfx::ColorSpaceRef m_oldCS;
gfx::ColorSpaceRef m_newCS;
};
} // namespace cmd
} // namespace app
}} // namespace app::cmd
#endif

View File

@ -6,7 +6,7 @@
// the End-User License Agreement for Aseprite.
#ifdef HAVE_CONFIG_H
#include "config.h"
#include "config.h"
#endif
#include "app/cmd/background_from_layer.h"
@ -25,11 +25,9 @@
#include "doc/sprite.h"
#include "render/render.h"
namespace app {
namespace cmd {
namespace app { namespace cmd {
BackgroundFromLayer::BackgroundFromLayer(Layer* layer)
: WithLayer(layer)
BackgroundFromLayer::BackgroundFromLayer(Layer* layer) : WithLayer(layer)
{
ASSERT(layer);
ASSERT(layer->isVisible());
@ -42,7 +40,7 @@ BackgroundFromLayer::BackgroundFromLayer(Layer* layer)
void BackgroundFromLayer::onExecute()
{
Layer* layer = this->layer();
ASSERT(!layer->isTilemap()); // TODO support background tilemaps
ASSERT(!layer->isTilemap()); // TODO support background tilemaps
Sprite* sprite = layer->sprite();
auto doc = static_cast<Doc*>(sprite->document());
@ -60,12 +58,13 @@ void BackgroundFromLayer::onExecute()
ASSERT(cel_image->pixelFormat() != IMAGE_TILEMAP);
clear_image(bg_image.get(), bgcolor);
render::composite_image(
bg_image.get(), cel_image,
sprite->palette(cel->frame()),
cel->x(), cel->y(),
std::clamp(cel->opacity(), 0, 255),
static_cast<LayerImage*>(layer)->blendMode());
render::composite_image(bg_image.get(),
cel_image,
sprite->palette(cel->frame()),
cel->x(),
cel->y(),
std::clamp(cel->opacity(), 0, 255),
static_cast<LayerImage*>(layer)->blendMode());
// now we have to copy the new image (bg_image) to the cel...
executeAndAdd(new cmd::SetCelPosition(cel, 0, 0));
@ -76,10 +75,8 @@ void BackgroundFromLayer::onExecute()
// Same size of cel image and background image, we can just
// replace pixels.
if (bg_image->width() == cel_image->width() &&
bg_image->height() == cel_image->height()) {
executeAndAdd(new CopyRect(cel_image, bg_image.get(),
gfx::Clip(0, 0, cel_image->bounds())));
if (bg_image->width() == cel_image->width() && bg_image->height() == cel_image->height()) {
executeAndAdd(new CopyRect(cel_image, bg_image.get(), gfx::Clip(0, 0, cel_image->bounds())));
}
// In other case we have to replace the whole image (this is the
// most common case, a smaller transparent cel that is converted
@ -91,11 +88,10 @@ void BackgroundFromLayer::onExecute()
}
// Fill all empty cels with a flat image filled with bgcolor
for (frame_t frame(0); frame<sprite->totalFrames(); ++frame) {
for (frame_t frame(0); frame < sprite->totalFrames(); ++frame) {
Cel* cel = layer->cel(frame);
if (!cel) {
ImageRef cel_image(Image::create(sprite->pixelFormat(),
sprite->width(), sprite->height()));
ImageRef cel_image(Image::create(sprite->pixelFormat(), sprite->width(), sprite->height()));
clear_image(cel_image.get(), bgcolor);
// Create the new cel and add it to the new background layer
@ -107,5 +103,4 @@ void BackgroundFromLayer::onExecute()
executeAndAdd(new cmd::ConfigureBackground(layer));
}
} // namespace cmd
} // namespace app
}} // namespace app::cmd

View File

@ -11,20 +11,18 @@
#include "app/cmd/with_layer.h"
#include "app/cmd_sequence.h"
namespace app {
namespace cmd {
using namespace doc;
namespace app { namespace cmd {
using namespace doc;
class BackgroundFromLayer : public CmdSequence
, public WithLayer {
public:
BackgroundFromLayer(Layer* layer);
class BackgroundFromLayer : public CmdSequence,
public WithLayer {
public:
BackgroundFromLayer(Layer* layer);
protected:
void onExecute() override;
};
protected:
void onExecute() override;
};
} // namespace cmd
} // namespace app
}} // namespace app::cmd
#endif

View File

@ -5,7 +5,7 @@
// the End-User License Agreement for Aseprite.
#ifdef HAVE_CONFIG_H
#include "config.h"
#include "config.h"
#endif
#include "app/cmd/clear_cel.h"
@ -16,13 +16,11 @@
#include "doc/cel.h"
#include "doc/layer.h"
namespace app {
namespace cmd {
namespace app { namespace cmd {
using namespace doc;
ClearCel::ClearCel(Cel* cel)
: WithCel(cel)
ClearCel::ClearCel(Cel* cel) : WithCel(cel)
{
Doc* doc = static_cast<Doc*>(cel->document());
@ -30,8 +28,7 @@ ClearCel::ClearCel(Cel* cel)
Image* image = cel->image();
ASSERT(image);
if (image)
m_seq.add(new cmd::ClearImage(image,
doc->bgColor(cel->layer())));
m_seq.add(new cmd::ClearImage(image, doc->bgColor(cel->layer())));
}
else {
m_seq.add(new cmd::RemoveCel(cel));
@ -53,5 +50,4 @@ void ClearCel::onRedo()
m_seq.redo();
}
} // namespace cmd
} // namespace app
}} // namespace app::cmd

View File

@ -12,28 +12,24 @@
#include "app/cmd/with_cel.h"
#include "app/cmd_sequence.h"
namespace app {
namespace cmd {
using namespace doc;
namespace app { namespace cmd {
using namespace doc;
class ClearCel : public Cmd
, public WithCel {
public:
ClearCel(Cel* cel);
class ClearCel : public Cmd,
public WithCel {
public:
ClearCel(Cel* cel);
protected:
void onExecute() override;
void onUndo() override;
void onRedo() override;
size_t onMemSize() const override {
return sizeof(*this) + m_seq.memSize();
}
protected:
void onExecute() override;
void onUndo() override;
void onRedo() override;
size_t onMemSize() const override { return sizeof(*this) + m_seq.memSize(); }
private:
CmdSequence m_seq;
};
private:
CmdSequence m_seq;
};
} // namespace cmd
} // namespace app
}} // namespace app::cmd
#endif

View File

@ -5,7 +5,7 @@
// the End-User License Agreement for Aseprite.
#ifdef HAVE_CONFIG_H
#include "config.h"
#include "config.h"
#endif
#include "app/cmd/clear_image.h"
@ -14,14 +14,11 @@
#include "doc/image.h"
#include "doc/primitives.h"
namespace app {
namespace cmd {
namespace app { namespace cmd {
using namespace doc;
ClearImage::ClearImage(Image* image, color_t color)
: WithImage(image)
, m_color(color)
ClearImage::ClearImage(Image* image, color_t color) : WithImage(image), m_color(color)
{
}
@ -46,5 +43,4 @@ void ClearImage::onUndo()
image->incrementVersion();
}
} // namespace cmd
} // namespace app
}} // namespace app::cmd

View File

@ -13,28 +13,24 @@
#include "doc/color.h"
#include "doc/image_ref.h"
namespace app {
namespace cmd {
using namespace doc;
namespace app { namespace cmd {
using namespace doc;
class ClearImage : public Cmd
, public WithImage {
public:
ClearImage(Image* image, color_t color);
class ClearImage : public Cmd,
public WithImage {
public:
ClearImage(Image* image, color_t color);
protected:
void onExecute() override;
void onUndo() override;
size_t onMemSize() const override {
return sizeof(*this) + (m_copy ? m_copy->getMemSize(): 0);
}
protected:
void onExecute() override;
void onUndo() override;
size_t onMemSize() const override { return sizeof(*this) + (m_copy ? m_copy->getMemSize() : 0); }
private:
ImageRef m_copy;
color_t m_color;
};
private:
ImageRef m_copy;
color_t m_color;
};
} // namespace cmd
} // namespace app
}} // namespace app::cmd
#endif

View File

@ -6,7 +6,7 @@
// the End-User License Agreement for Aseprite.
#ifdef HAVE_CONFIG_H
#include "config.h"
#include "config.h"
#endif
#include "app/cmd/clear_mask.h"
@ -21,13 +21,11 @@
#include "doc/mask.h"
#include "doc/primitives.h"
namespace app {
namespace cmd {
namespace app { namespace cmd {
using namespace doc;
ClearMask::ClearMask(Cel* cel)
: WithCel(cel)
ClearMask::ClearMask(Cel* cel) : WithCel(cel)
{
Doc* doc = static_cast<Doc*>(cel->document());
@ -51,8 +49,7 @@ ClearMask::ClearMask(Cel* cel)
gfx::Rect maskBounds;
if (image->pixelFormat() == IMAGE_TILEMAP) {
auto grid = cel->grid();
imageBounds = gfx::Rect(grid.canvasToTile(cel->position()),
cel->image()->size());
imageBounds = gfx::Rect(grid.canvasToTile(cel->position()), cel->image()->size());
maskBounds = grid.canvasToTile(mask->bounds());
m_bgcolor = doc::notile; // TODO configurable empty tile
}
@ -100,12 +97,11 @@ void ClearMask::clear()
Mask* mask = doc->mask();
Grid grid = cel->grid();
doc::algorithm::fill_selection(
cel->image(),
cel->bounds(),
mask,
m_bgcolor,
(cel->image()->isTilemap() ? &grid: nullptr));
doc::algorithm::fill_selection(cel->image(),
cel->bounds(),
mask,
m_bgcolor,
(cel->image()->isTilemap() ? &grid : nullptr));
}
void ClearMask::restore()
@ -114,11 +110,7 @@ void ClearMask::restore()
return;
Cel* cel = this->cel();
copy_image(cel->image(),
m_copy.get(),
m_cropPos.x,
m_cropPos.y);
copy_image(cel->image(), m_copy.get(), m_cropPos.x, m_cropPos.y);
}
} // namespace cmd
} // namespace app
}} // namespace app::cmd

View File

@ -18,35 +18,33 @@
#include <memory>
namespace app {
namespace cmd {
using namespace doc;
namespace app { namespace cmd {
using namespace doc;
class ClearMask : public Cmd
, public WithCel {
public:
ClearMask(Cel* cel);
class ClearMask : public Cmd,
public WithCel {
public:
ClearMask(Cel* cel);
protected:
void onExecute() override;
void onUndo() override;
void onRedo() override;
size_t onMemSize() const override {
return sizeof(*this) + m_seq.memSize() +
(m_copy ? m_copy->getMemSize(): 0);
}
protected:
void onExecute() override;
void onUndo() override;
void onRedo() override;
size_t onMemSize() const override
{
return sizeof(*this) + m_seq.memSize() + (m_copy ? m_copy->getMemSize() : 0);
}
private:
void clear();
void restore();
private:
void clear();
void restore();
CmdSequence m_seq;
ImageRef m_copy;
gfx::Point m_cropPos;
color_t m_bgcolor;
};
CmdSequence m_seq;
ImageRef m_copy;
gfx::Point m_cropPos;
color_t m_bgcolor;
};
} // namespace cmd
} // namespace app
}} // namespace app::cmd
#endif

View File

@ -5,7 +5,7 @@
// the End-User License Agreement for Aseprite.
#ifdef HAVE_CONFIG_H
#include "config.h"
#include "config.h"
#endif
#include "app/cmd/clear_rect.h"
@ -16,8 +16,7 @@
#include "doc/layer.h"
#include "doc/primitives.h"
namespace app {
namespace cmd {
namespace app { namespace cmd {
using namespace doc;
@ -32,11 +31,8 @@ ClearRect::ClearRect(Cel* cel, const gfx::Rect& bounds)
m_offsetX = bounds.x - cel->x();
m_offsetY = bounds.y - cel->y();
gfx::Rect bounds2 =
image->bounds().createIntersection(
gfx::Rect(
m_offsetX, m_offsetY,
bounds.w, bounds.h));
gfx::Rect bounds2 = image->bounds().createIntersection(
gfx::Rect(m_offsetX, m_offsetY, bounds.w, bounds.h));
if (bounds.isEmpty())
return;
@ -45,8 +41,7 @@ ClearRect::ClearRect(Cel* cel, const gfx::Rect& bounds)
Doc* doc = static_cast<Doc*>(cel->document());
m_bgcolor = doc->bgColor(cel->layer());
m_copy.reset(crop_image(image,
bounds2.x, bounds2.y, bounds2.w, bounds2.h, m_bgcolor));
m_copy.reset(crop_image(image, bounds2.x, bounds2.y, bounds2.w, bounds2.h, m_bgcolor));
}
void ClearRect::onExecute()
@ -73,7 +68,8 @@ void ClearRect::onRedo()
void ClearRect::clear()
{
fill_rect(m_dstImage->image(),
m_offsetX, m_offsetY,
m_offsetX,
m_offsetY,
m_offsetX + m_copy->width() - 1,
m_offsetY + m_copy->height() - 1,
m_bgcolor);
@ -84,5 +80,4 @@ void ClearRect::restore()
copy_image(m_dstImage->image(), m_copy.get(), m_offsetX, m_offsetY);
}
} // namespace cmd
} // namespace app
}} // namespace app::cmd

View File

@ -17,38 +17,36 @@
#include <memory>
namespace doc {
class Cel;
class Cel;
}
namespace app {
namespace cmd {
using namespace doc;
namespace app { namespace cmd {
using namespace doc;
class ClearRect : public Cmd {
public:
ClearRect(Cel* cel, const gfx::Rect& bounds);
class ClearRect : public Cmd {
public:
ClearRect(Cel* cel, const gfx::Rect& bounds);
protected:
void onExecute() override;
void onUndo() override;
void onRedo() override;
size_t onMemSize() const override {
return sizeof(*this) + m_seq.memSize() +
(m_copy ? m_copy->getMemSize(): 0);
}
protected:
void onExecute() override;
void onUndo() override;
void onRedo() override;
size_t onMemSize() const override
{
return sizeof(*this) + m_seq.memSize() + (m_copy ? m_copy->getMemSize() : 0);
}
private:
void clear();
void restore();
private:
void clear();
void restore();
CmdSequence m_seq;
std::unique_ptr<WithImage> m_dstImage;
ImageRef m_copy;
int m_offsetX, m_offsetY;
color_t m_bgcolor;
};
CmdSequence m_seq;
std::unique_ptr<WithImage> m_dstImage;
ImageRef m_copy;
int m_offsetX, m_offsetY;
color_t m_bgcolor;
};
} // namespace cmd
} // namespace app
}} // namespace app::cmd
#endif

View File

@ -5,7 +5,7 @@
// the End-User License Agreement for Aseprite.
#ifdef HAVE_CONFIG_H
#include "config.h"
#include "config.h"
#endif
#include "app/cmd/clear_slices.h"
@ -20,8 +20,7 @@
#include "doc/layer_list.h"
#include "doc/primitives.h"
namespace app {
namespace cmd {
namespace app { namespace cmd {
using namespace doc;
@ -29,8 +28,8 @@ ClearSlices::ClearSlices(const Site& site,
const LayerList& layers,
frame_t frame,
const std::vector<SliceKey>& slicesKeys)
: m_tilemapMode(site.tilemapMode())
, m_tilesetMode(site.tilesetMode())
: m_tilemapMode(site.tilemapMode())
, m_tilesetMode(site.tilesetMode())
{
if (layers.empty())
return;
@ -58,8 +57,7 @@ ClearSlices::ClearSlices(const Site& site,
color_t bgcolor = doc->bgColor(layer);
if (image->pixelFormat() == IMAGE_TILEMAP) {
auto grid = cel->grid();
imageBounds = gfx::Rect(grid.canvasToTile(cel->position()),
cel->image()->size());
imageBounds = gfx::Rect(grid.canvasToTile(cel->position()), cel->image()->size());
maskBounds = grid.canvasToTile(maskBounds);
bgcolor = doc::notile; // TODO configurable empty tile
}
@ -101,36 +99,34 @@ void ClearSlices::clear()
if (!sc.copy)
continue;
if (sc.cel()->layer()->isTilemap() && m_tilemapMode == TilemapMode::Pixels) {
Doc* doc = static_cast<Doc*>(sc.cel()->document());
color_t bgcolor = doc->bgColor(sc.cel()->layer());
modify_tilemap_cel_region(
&m_seq, sc.cel(), nullptr,
&m_seq,
sc.cel(),
nullptr,
gfx::Region(sc.mask.bounds()),
m_tilesetMode,
[sc, bgcolor](const doc::ImageRef& origTile,
const gfx::Rect& tileBoundsInCanvas) -> doc::ImageRef {
doc::ImageRef modified(doc::Image::createCopy(origTile.get()));
doc::algorithm::fill_selection(
modified.get(),
tileBoundsInCanvas,
&sc.mask,
bgcolor,
nullptr);
doc::algorithm::fill_selection(modified.get(),
tileBoundsInCanvas,
&sc.mask,
bgcolor,
nullptr);
return modified;
});
}
else {
Grid grid = sc.cel()->grid();
doc::algorithm::fill_selection(
sc.cel()->image(),
sc.cel()->bounds(),
&sc.mask,
sc.bgcolor,
(sc.cel()->image()->isTilemap() ? &grid: nullptr));
doc::algorithm::fill_selection(sc.cel()->image(),
sc.cel()->bounds(),
&sc.mask,
sc.bgcolor,
(sc.cel()->image()->isTilemap() ? &grid : nullptr));
}
}
}
@ -141,12 +137,8 @@ void ClearSlices::restore()
if (!sc.copy)
continue;
copy_image(sc.cel()->image(),
sc.copy.get(),
sc.cropPos.x,
sc.cropPos.y);
copy_image(sc.cel()->image(), sc.copy.get(), sc.cropPos.x, sc.cropPos.y);
}
}
} // namespace cmd
} // namespace app
}} // namespace app::cmd

View File

@ -9,8 +9,8 @@
#pragma once
#include "app/cmd.h"
#include "app/cmd_sequence.h"
#include "app/cmd/with_cel.h"
#include "app/cmd_sequence.h"
#include "app/tilemap_mode.h"
#include "app/tileset_mode.h"
#include "doc/cel.h"
@ -23,55 +23,54 @@
namespace app {
class Site;
class Site;
namespace cmd {
using namespace doc;
using namespace doc;
// Clears the enclosed content of the passed slices for each layer in the
// layers list for the specified frame.
class ClearSlices : public Cmd {
public:
ClearSlices(const Site& site,
const LayerList& layers,
frame_t frame,
const std::vector<SliceKey>& slicesKeys);
// Clears the enclosed content of the passed slices for each layer in the
// layers list for the specified frame.
class ClearSlices : public Cmd {
public:
ClearSlices(const Site& site,
const LayerList& layers,
frame_t frame,
const std::vector<SliceKey>& slicesKeys);
protected:
void onExecute() override;
void onUndo() override;
void onRedo() override;
size_t onMemSize() const override {
size_t sliceContentsSize = 0;
for (const auto& sc : m_slicesContents) {
sliceContentsSize += sc.memSize();
}
return sizeof(*this) + m_seq.memSize() + sliceContentsSize;
protected:
void onExecute() override;
void onUndo() override;
void onRedo() override;
size_t onMemSize() const override
{
size_t sliceContentsSize = 0;
for (const auto& sc : m_slicesContents) {
sliceContentsSize += sc.memSize();
}
return sizeof(*this) + m_seq.memSize() + sliceContentsSize;
}
private:
struct SlicesContent : public WithCel {
SlicesContent(Cel* cel) : WithCel(cel) {}
// Image having a copy of the content of each selected slice.
ImageRef copy = nullptr;
Mask mask;
gfx::Point cropPos;
color_t bgcolor;
size_t memSize() const {
return sizeof(*this) + (copy ? copy->getMemSize(): 0);
}
};
void clear();
void restore();
CmdSequence m_seq;
// Slices content for each selected layer's cel
std::vector<SlicesContent> m_slicesContents;
TilemapMode m_tilemapMode;
TilesetMode m_tilesetMode;
private:
struct SlicesContent : public WithCel {
SlicesContent(Cel* cel) : WithCel(cel) {}
// Image having a copy of the content of each selected slice.
ImageRef copy = nullptr;
Mask mask;
gfx::Point cropPos;
color_t bgcolor;
size_t memSize() const { return sizeof(*this) + (copy ? copy->getMemSize() : 0); }
};
void clear();
void restore();
CmdSequence m_seq;
// Slices content for each selected layer's cel
std::vector<SlicesContent> m_slicesContents;
TilemapMode m_tilemapMode;
TilesetMode m_tilesetMode;
};
} // namespace cmd
} // namespace app

View File

@ -5,7 +5,7 @@
// the End-User License Agreement for Aseprite.
#ifdef HAVE_CONFIG_H
#include "config.h"
#include "config.h"
#endif
#include "app/cmd/configure_background.h"
@ -16,25 +16,21 @@
#include "app/cmd/set_layer_opacity.h"
#include "doc/sprite.h"
namespace app {
namespace cmd {
namespace app { namespace cmd {
ConfigureBackground::ConfigureBackground(Layer* layer)
{
// Add "Background" and "LockMove" flags
LayerFlags newFlags = LayerFlags(int(layer->flags())
| int(LayerFlags::BackgroundLayerFlags));
LayerFlags newFlags = LayerFlags(int(layer->flags()) | int(LayerFlags::BackgroundLayerFlags));
add(new cmd::SetLayerFlags(layer, newFlags));
add(new cmd::SetLayerName(layer, "Background"));
if (layer->isImage() &&
static_cast<LayerImage*>(layer)->opacity() < 255) {
if (layer->isImage() && static_cast<LayerImage*>(layer)->opacity() < 255) {
add(new cmd::SetLayerOpacity(static_cast<LayerImage*>(layer), 255));
}
add(new cmd::MoveLayer(layer, layer->sprite()->root(), nullptr));
}
} // namespace cmd
} // namespace app
}} // namespace app::cmd

View File

@ -11,19 +11,17 @@
#include "app/cmd_sequence.h"
namespace doc {
class Layer;
class Layer;
}
namespace app {
namespace cmd {
using namespace doc;
namespace app { namespace cmd {
using namespace doc;
class ConfigureBackground : public CmdSequence {
public:
ConfigureBackground(Layer* layer);
};
class ConfigureBackground : public CmdSequence {
public:
ConfigureBackground(Layer* layer);
};
} // namespace cmd
} // namespace app
}} // namespace app::cmd
#endif

View File

@ -5,7 +5,7 @@
// the End-User License Agreement for Aseprite.
#ifdef HAVE_CONFIG_H
#include "config.h"
#include "config.h"
#endif
#include "app/cmd/convert_color_profile.h"
@ -20,8 +20,7 @@
#include "os/color_space.h"
#include "os/system.h"
namespace app {
namespace cmd {
namespace app { namespace cmd {
static doc::ImageRef convert_image_color_space(const doc::Image* srcImage,
const gfx::ColorSpaceRef& newCS,
@ -37,7 +36,7 @@ static doc::ImageRef convert_image_color_space(const doc::Image* srcImage,
}
if (spec.colorMode() == doc::ColorMode::RGB) {
for (int y=0; y<spec.height(); ++y) {
for (int y = 0; y < spec.height(); ++y) {
conversion->convertRgba((uint32_t*)dstImage->getPixelAddress(0, y),
(const uint32_t*)srcImage->getPixelAddress(0, y),
spec.width());
@ -47,22 +46,22 @@ static doc::ImageRef convert_image_color_space(const doc::Image* srcImage,
// TODO create a set of functions to create pixel format
// conversions (this should be available when we add new kind of
// pixel formats).
std::vector<uint8_t> buf(spec.width()*spec.height());
std::vector<uint8_t> buf(spec.width() * spec.height());
auto it = buf.begin();
for (int y=0; y<spec.height(); ++y) {
for (int y = 0; y < spec.height(); ++y) {
auto srcPtr = (const uint16_t*)srcImage->getPixelAddress(0, y);
for (int x=0; x<spec.width(); ++x, ++srcPtr, ++it)
for (int x = 0; x < spec.width(); ++x, ++srcPtr, ++it)
*it = doc::graya_getv(*srcPtr);
}
conversion->convertGray(&buf[0], &buf[0], spec.width()*spec.height());
conversion->convertGray(&buf[0], &buf[0], spec.width() * spec.height());
it = buf.begin();
for (int y=0; y<spec.height(); ++y) {
for (int y = 0; y < spec.height(); ++y) {
auto srcPtr = (const uint16_t*)srcImage->getPixelAddress(0, y);
auto dstPtr = (uint16_t*)dstImage->getPixelAddress(0, y);
for (int x=0; x<spec.width(); ++x, ++dstPtr, ++srcPtr, ++it)
for (int x = 0; x < spec.width(); ++x, ++dstPtr, ++srcPtr, ++it)
*dstPtr = doc::graya(*it, doc::graya_geta(*srcPtr));
}
}
@ -70,8 +69,7 @@ static doc::ImageRef convert_image_color_space(const doc::Image* srcImage,
return dstImage;
}
void convert_color_profile(doc::Sprite* sprite,
const gfx::ColorSpaceRef& newCS)
void convert_color_profile(doc::Sprite* sprite, const gfx::ColorSpaceRef& newCS)
{
ASSERT(sprite->colorSpace());
ASSERT(newCS);
@ -89,8 +87,7 @@ void convert_color_profile(doc::Sprite* sprite,
for (Cel* cel : sprite->uniqueCels()) {
ImageRef old_image = cel->imageRef();
if (old_image.get()->pixelFormat() != IMAGE_TILEMAP) {
ImageRef new_image = convert_image_color_space(
old_image.get(), newCS, conversion.get());
ImageRef new_image = convert_image_color_space(old_image.get(), newCS, conversion.get());
sprite->replaceImage(old_image->id(), new_image);
}
@ -103,11 +100,10 @@ void convert_color_profile(doc::Sprite* sprite,
for (auto& pal : sprite->getPalettes()) {
Palette newPal(pal->frame(), pal->size());
for (int i=0; i<pal->size(); ++i) {
for (int i = 0; i < pal->size(); ++i) {
color_t oldCol = pal->entry(i);
color_t newCol = pal->entry(i);
conversion->convertRgba((uint32_t*)&newCol,
(const uint32_t*)&oldCol, 1);
conversion->convertRgba((uint32_t*)&newCol, (const uint32_t*)&oldCol, 1);
newPal.setEntry(i, newCol);
}
@ -142,19 +138,17 @@ void convert_color_profile(doc::Image* image,
switch (image->pixelFormat()) {
case doc::IMAGE_RGB:
case doc::IMAGE_GRAYSCALE: {
ImageRef newImage = convert_image_color_space(
image, newCS, conversion.get());
ImageRef newImage = convert_image_color_space(image, newCS, conversion.get());
image->copy(newImage.get(), gfx::Clip(image->bounds()));
break;
}
case doc::IMAGE_INDEXED: {
for (int i=0; i<palette->size(); ++i) {
for (int i = 0; i < palette->size(); ++i) {
color_t oldCol, newCol;
oldCol = newCol = palette->entry(i);
conversion->convertRgba((uint32_t*)&newCol,
(const uint32_t*)&oldCol, 1);
conversion->convertRgba((uint32_t*)&newCol, (const uint32_t*)&oldCol, 1);
palette->setEntry(i, newCol);
}
break;
@ -184,8 +178,7 @@ ConvertColorProfile::ConvertColorProfile(doc::Sprite* sprite, const gfx::ColorSp
for (Cel* cel : sprite->uniqueCels()) {
ImageRef old_image = cel->imageRef();
if (old_image.get()->pixelFormat() != IMAGE_TILEMAP) {
ImageRef new_image = convert_image_color_space(
old_image.get(), newCS, conversion.get());
ImageRef new_image = convert_image_color_space(old_image.get(), newCS, conversion.get());
m_seq.add(new cmd::ReplaceImage(sprite, old_image, new_image));
}
@ -198,11 +191,10 @@ ConvertColorProfile::ConvertColorProfile(doc::Sprite* sprite, const gfx::ColorSp
for (auto& pal : sprite->getPalettes()) {
Palette newPal(pal->frame(), pal->size());
for (int i=0; i<pal->size(); ++i) {
for (int i = 0; i < pal->size(); ++i) {
color_t oldCol = pal->entry(i);
color_t newCol = pal->entry(i);
conversion->convertRgba((uint32_t*)&newCol,
(const uint32_t*)&oldCol, 1);
conversion->convertRgba((uint32_t*)&newCol, (const uint32_t*)&oldCol, 1);
newPal.setEntry(i, newCol);
}
@ -230,5 +222,4 @@ void ConvertColorProfile::onRedo()
m_seq.redo();
}
} // namespace cmd
} // namespace app
}} // namespace app::cmd

View File

@ -14,45 +14,40 @@
#include "gfx/color_space.h"
namespace gfx {
class ColorSpace;
class ColorSpace;
}
namespace doc {
class Image;
class Palette;
}
class Image;
class Palette;
} // namespace doc
namespace app {
namespace cmd {
namespace app { namespace cmd {
class ConvertColorProfile : public Cmd,
public WithSprite {
public:
ConvertColorProfile(doc::Sprite* sprite, const gfx::ColorSpaceRef& newCS);
class ConvertColorProfile : public Cmd,
public WithSprite {
public:
ConvertColorProfile(doc::Sprite* sprite, const gfx::ColorSpaceRef& newCS);
protected:
void onExecute() override;
void onUndo() override;
void onRedo() override;
size_t onMemSize() const override {
return sizeof(*this) + m_seq.memSize();
}
protected:
void onExecute() override;
void onUndo() override;
void onRedo() override;
size_t onMemSize() const override { return sizeof(*this) + m_seq.memSize(); }
private:
CmdSequence m_seq;
};
private:
CmdSequence m_seq;
};
// Converts the sprite to the new color profile without undo information.
// TODO how to merge this function with cmd::ConvertColorProfile
void convert_color_profile(doc::Sprite* sprite,
const gfx::ColorSpaceRef& newCS);
// Converts the sprite to the new color profile without undo information.
// TODO how to merge this function with cmd::ConvertColorProfile
void convert_color_profile(doc::Sprite* sprite, const gfx::ColorSpaceRef& newCS);
void convert_color_profile(doc::Image* image,
doc::Palette* palette,
const gfx::ColorSpaceRef& oldCS,
const gfx::ColorSpaceRef& newCS);
void convert_color_profile(doc::Image* image,
doc::Palette* palette,
const gfx::ColorSpaceRef& oldCS,
const gfx::ColorSpaceRef& newCS);
} // namespace cmd
} // namespace app
}} // namespace app::cmd
#endif

View File

@ -6,7 +6,7 @@
// the End-User License Agreement for Aseprite.
#ifdef HAVE_CONFIG_H
#include "config.h"
#include "config.h"
#endif
#include "app/cmd/copy_cel.h"
@ -27,14 +27,15 @@
#include "render/rasterize.h"
#include "render/render.h"
namespace app {
namespace cmd {
namespace app { namespace cmd {
using namespace doc;
CopyCel::CopyCel(
Layer* srcLayer, frame_t srcFrame,
Layer* dstLayer, frame_t dstFrame, bool continuous)
CopyCel::CopyCel(Layer* srcLayer,
frame_t srcFrame,
Layer* dstLayer,
frame_t dstFrame,
bool continuous)
: m_srcLayer(srcLayer)
, m_dstLayer(dstLayer)
, m_srcFrame(srcFrame)
@ -73,24 +74,22 @@ void CopyCel::onExecute()
while (dstSprite->totalFrames() <= m_dstFrame)
executeAndAdd(new cmd::AddFrame(dstSprite, dstSprite->totalFrames()));
Image* srcImage = (srcCel ? srcCel->image(): NULL);
Image* srcImage = (srcCel ? srcCel->image() : NULL);
ImageRef dstImage;
dstCel = dstLayer->cel(m_dstFrame);
if (dstCel)
dstImage = dstCel->imageRef();
bool createLink =
(srcLayer == dstLayer && m_continuous);
bool createLink = (srcLayer == dstLayer && m_continuous);
// For background layer
if (dstLayer->isBackground()) {
ASSERT(dstCel);
ASSERT(dstImage);
if (!dstCel || !dstImage ||
!srcCel || !srcImage)
if (!dstCel || !dstImage || !srcCel || !srcImage)
return;
ASSERT(!dstLayer->isTilemap()); // TODO support background tilemaps
ASSERT(!dstLayer->isTilemap()); // TODO support background tilemaps
if (createLink) {
executeAndAdd(new cmd::SetCelData(dstCel, srcCel->dataRef()));
@ -102,15 +101,16 @@ void CopyCel::onExecute()
executeAndAdd(new cmd::CopyRect(dstImage.get(), tmp.get(), gfx::Clip(tmp->bounds())));
}
else {
BlendMode blend = (srcLayer->isBackground() ?
BlendMode::SRC:
BlendMode::NORMAL);
BlendMode blend = (srcLayer->isBackground() ? BlendMode::SRC : BlendMode::NORMAL);
ImageRef tmp(Image::createCopy(dstImage.get()));
render::composite_image(
tmp.get(), srcImage,
srcSprite->palette(m_srcFrame),
srcCel->x(), srcCel->y(), 255, blend);
render::composite_image(tmp.get(),
srcImage,
srcSprite->palette(m_srcFrame),
srcCel->x(),
srcCel->y(),
255,
blend);
executeAndAdd(new cmd::CopyRect(dstImage.get(), tmp.get(), gfx::Clip(tmp->bounds())));
}
}
@ -137,15 +137,12 @@ void CopyCel::onFireNotifications()
// The m_srcLayer can be nullptr now because the layer from where we
// copied this cel might not exist anymore (e.g. if we copied the
// cel from another document that is already closed)
//ASSERT(m_srcLayer.layer());
// ASSERT(m_srcLayer.layer());
ASSERT(m_dstLayer.layer());
static_cast<Doc*>(m_dstLayer.layer()->sprite()->document())
->notifyCelCopied(
m_srcLayer.layer(), m_srcFrame,
m_dstLayer.layer(), m_dstFrame);
->notifyCelCopied(m_srcLayer.layer(), m_srcFrame, m_dstLayer.layer(), m_dstFrame);
}
} // namespace cmd
} // namespace app
}} // namespace app::cmd

View File

@ -14,27 +14,23 @@
#include "doc/color.h"
#include "doc/frame.h"
namespace app {
namespace cmd {
using namespace doc;
namespace app { namespace cmd {
using namespace doc;
class CopyCel : public CmdSequence {
public:
CopyCel(
Layer* srcLayer, frame_t srcFrame,
Layer* dstLayer, frame_t dstFrame, bool continuous);
class CopyCel : public CmdSequence {
public:
CopyCel(Layer* srcLayer, frame_t srcFrame, Layer* dstLayer, frame_t dstFrame, bool continuous);
protected:
void onExecute() override;
void onFireNotifications() override;
protected:
void onExecute() override;
void onFireNotifications() override;
private:
WithLayer m_srcLayer, m_dstLayer;
frame_t m_srcFrame, m_dstFrame;
bool m_continuous;
};
private:
WithLayer m_srcLayer, m_dstLayer;
frame_t m_srcFrame, m_dstFrame;
bool m_continuous;
};
} // namespace cmd
} // namespace app
}} // namespace app::cmd
#endif

View File

@ -6,7 +6,7 @@
// the End-User License Agreement for Aseprite.
#ifdef HAVE_CONFIG_H
#include "config.h"
#include "config.h"
#endif
#include "app/cmd/copy_frame.h"
@ -14,11 +14,10 @@
#include "app/cmd/add_frame.h"
#include "app/cmd/copy_cel.h"
#include "app/cmd/set_frame_duration.h"
#include "doc/sprite.h"
#include "doc/layer.h"
#include "doc/sprite.h"
namespace app {
namespace cmd {
namespace app { namespace cmd {
using namespace doc;
@ -41,5 +40,4 @@ void CopyFrame::onExecute()
// Do not copy cels (cmd::CopyCel must be called from outside)
}
} // namespace cmd
} // namespace app
}} // namespace app::cmd

View File

@ -8,32 +8,30 @@
#define APP_CMD_COPY_FRAME_H_INCLUDED
#pragma once
#include "app/cmd_sequence.h"
#include "app/cmd/with_sprite.h"
#include "app/cmd_sequence.h"
#include "doc/frame.h"
namespace app {
namespace cmd {
using namespace doc;
namespace app { namespace cmd {
using namespace doc;
class CopyFrame : public CmdSequence
, public WithSprite {
public:
CopyFrame(Sprite* sprite, frame_t fromFrame, frame_t newFrame);
class CopyFrame : public CmdSequence,
public WithSprite {
public:
CopyFrame(Sprite* sprite, frame_t fromFrame, frame_t newFrame);
protected:
void onExecute() override;
size_t onMemSize() const override {
return sizeof(*this) +
CmdSequence::onMemSize() - sizeof(CmdSequence);
}
protected:
void onExecute() override;
size_t onMemSize() const override
{
return sizeof(*this) + CmdSequence::onMemSize() - sizeof(CmdSequence);
}
private:
frame_t m_fromFrame;
frame_t m_newFrame;
};
private:
frame_t m_fromFrame;
frame_t m_newFrame;
};
} // namespace cmd
} // namespace app
}} // namespace app::cmd
#endif

View File

@ -6,7 +6,7 @@
// the End-User License Agreement for Aseprite.
#ifdef HAVE_CONFIG_H
#include "config.h"
#include "config.h"
#endif
#include "app/cmd/copy_rect.h"
@ -15,16 +15,13 @@
#include <algorithm>
namespace app {
namespace cmd {
namespace app { namespace cmd {
CopyRect::CopyRect(Image* dst, const Image* src, const gfx::Clip& clip)
: WithImage(dst)
, m_clip(clip)
{
if (!m_clip.clip(
dst->width(), dst->height(),
src->width(), src->height()))
if (!m_clip.clip(dst->width(), dst->height(), src->width(), src->height()))
return;
// Fill m_data with "src" data
@ -33,11 +30,10 @@ CopyRect::CopyRect(Image* dst, const Image* src, const gfx::Clip& clip)
m_data.resize(lineSize * m_clip.size.h);
auto it = m_data.begin();
for (int v=0; v<m_clip.size.h; ++v) {
uint8_t* addr = src->getPixelAddress(
m_clip.dst.x, m_clip.dst.y+v);
for (int v = 0; v < m_clip.size.h; ++v) {
uint8_t* addr = src->getPixelAddress(m_clip.dst.x, m_clip.dst.y + v);
std::copy(addr, addr+lineSize, it);
std::copy(addr, addr + lineSize, it);
it += lineSize;
}
}
@ -67,12 +63,11 @@ void CopyRect::swap()
std::vector<uint8_t> tmp(lineSize);
auto it = m_data.begin();
for (int v=0; v<m_clip.size.h; ++v) {
uint8_t* addr = image->getPixelAddress(
m_clip.dst.x, m_clip.dst.y+v);
for (int v = 0; v < m_clip.size.h; ++v) {
uint8_t* addr = image->getPixelAddress(m_clip.dst.x, m_clip.dst.y + v);
std::copy(addr, addr+lineSize, tmp.begin());
std::copy(it, it+lineSize, addr);
std::copy(addr, addr + lineSize, tmp.begin());
std::copy(it, it + lineSize, addr);
std::copy(tmp.begin(), tmp.end(), it);
it += lineSize;
@ -86,5 +81,4 @@ int CopyRect::lineSize()
return image()->bytesPerPixel() * m_clip.size.w;
}
} // namespace cmd
} // namespace app
}} // namespace app::cmd

View File

@ -15,35 +15,31 @@
#include <vector>
namespace doc {
class Image;
class Image;
}
namespace app {
namespace cmd {
using namespace doc;
namespace app { namespace cmd {
using namespace doc;
class CopyRect : public Cmd
, public WithImage {
public:
CopyRect(Image* dst, const Image* src, const gfx::Clip& clip);
class CopyRect : public Cmd,
public WithImage {
public:
CopyRect(Image* dst, const Image* src, const gfx::Clip& clip);
protected:
void onExecute() override;
void onUndo() override;
void onRedo() override;
size_t onMemSize() const override {
return sizeof(*this) + m_data.size();
}
protected:
void onExecute() override;
void onUndo() override;
void onRedo() override;
size_t onMemSize() const override { return sizeof(*this) + m_data.size(); }
private:
void swap();
int lineSize();
private:
void swap();
int lineSize();
gfx::Clip m_clip;
std::vector<uint8_t> m_data;
};
gfx::Clip m_clip;
std::vector<uint8_t> m_data;
};
} // namespace cmd
} // namespace app
}} // namespace app::cmd
#endif

View File

@ -6,7 +6,7 @@
// the End-User License Agreement for Aseprite.
#ifdef HAVE_CONFIG_H
#include "config.h"
#include "config.h"
#endif
#include "app/cmd/copy_region.h"
@ -17,10 +17,10 @@
#include "doc/sprite.h"
#include "doc/tileset.h"
namespace app {
namespace cmd {
namespace app { namespace cmd {
CopyRegion::CopyRegion(Image* dst, const Image* src,
CopyRegion::CopyRegion(Image* dst,
const Image* src,
const gfx::Region& region,
const gfx::Point& dstPos,
bool alreadyCopied)
@ -30,12 +30,8 @@ CopyRegion::CopyRegion(Image* dst, const Image* src,
ASSERT(!region.isEmpty());
gfx::Rect rc = region.bounds();
gfx::Clip clip(
rc.x+dstPos.x, rc.y+dstPos.y,
rc.x, rc.y, rc.w, rc.h);
if (clip.clip(
dst->width(), dst->height(),
src->width(), src->height())) {
gfx::Clip clip(rc.x + dstPos.x, rc.y + dstPos.y, rc.x, rc.y, rc.w, rc.h);
if (clip.clip(dst->width(), dst->height(), src->width(), src->height())) {
// Create region to save/swap later
m_region = region;
m_region.offset(dstPos);
@ -45,7 +41,8 @@ CopyRegion::CopyRegion(Image* dst, const Image* src,
save_image_region_in_buffer(m_region, src, dstPos, m_buffer);
}
CopyTileRegion::CopyTileRegion(Image* dst, const Image* src,
CopyTileRegion::CopyTileRegion(Image* dst,
const Image* src,
const gfx::Region& region,
const gfx::Point& dstPos,
bool alreadyCopied,
@ -53,7 +50,7 @@ CopyTileRegion::CopyTileRegion(Image* dst, const Image* src,
const doc::Tileset* tileset)
: CopyRegion(dst, src, region, dstPos, alreadyCopied)
, m_tileIndex(tileIndex)
, m_tilesetId(tileset ? tileset->id(): NullId)
, m_tilesetId(tileset ? tileset->id() : NullId)
{
}
@ -96,11 +93,9 @@ void CopyTileRegion::rehash()
tileset->notifyTileContentChange(m_tileIndex);
// Notify that the tileset changed
static_cast<Doc*>(tileset->sprite()->document())
->notifyTilesetChanged(tileset);
static_cast<Doc*>(tileset->sprite()->document())->notifyTilesetChanged(tileset);
}
}
}
} // namespace cmd
} // namespace app
}} // namespace app::cmd

View File

@ -17,59 +17,57 @@
#include "gfx/region.h"
namespace doc {
class Tileset;
class Tileset;
}
namespace app {
namespace cmd {
using namespace doc;
namespace app { namespace cmd {
using namespace doc;
class CopyRegion : public Cmd
, public WithImage {
public:
// If alreadyCopied is false, it means that onExecute() will copy
// pixels from src to dst. If it's true, it means that "onExecute"
// should do nothing, because modified pixels are alreadt on "dst"
// (so we use "src" as the original image).
CopyRegion(Image* dst, const Image* src,
const gfx::Region& region,
const gfx::Point& dstPos,
bool alreadyCopied = false);
class CopyRegion : public Cmd,
public WithImage {
public:
// If alreadyCopied is false, it means that onExecute() will copy
// pixels from src to dst. If it's true, it means that "onExecute"
// should do nothing, because modified pixels are alreadt on "dst"
// (so we use "src" as the original image).
CopyRegion(Image* dst,
const Image* src,
const gfx::Region& region,
const gfx::Point& dstPos,
bool alreadyCopied = false);
protected:
void onExecute() override;
void onUndo() override;
void onRedo() override;
size_t onMemSize() const override {
return sizeof(*this) + m_buffer.size();
}
protected:
void onExecute() override;
void onUndo() override;
void onRedo() override;
size_t onMemSize() const override { return sizeof(*this) + m_buffer.size(); }
private:
void swap();
virtual void rehash() { }
private:
void swap();
virtual void rehash() {}
bool m_alreadyCopied;
gfx::Region m_region;
base::buffer m_buffer;
};
bool m_alreadyCopied;
gfx::Region m_region;
base::buffer m_buffer;
};
class CopyTileRegion : public CopyRegion {
public:
CopyTileRegion(Image* dst, const Image* src,
const gfx::Region& region,
const gfx::Point& dstPos,
bool alreadyCopied,
const doc::tile_index tileIndex,
const doc::Tileset* tileset);
class CopyTileRegion : public CopyRegion {
public:
CopyTileRegion(Image* dst,
const Image* src,
const gfx::Region& region,
const gfx::Point& dstPos,
bool alreadyCopied,
const doc::tile_index tileIndex,
const doc::Tileset* tileset);
private:
void rehash() override;
private:
void rehash() override;
doc::tile_index m_tileIndex;
doc::ObjectId m_tilesetId;
};
doc::tile_index m_tileIndex;
doc::ObjectId m_tilesetId;
};
} // namespace cmd
} // namespace app
}} // namespace app::cmd
#endif

View File

@ -6,7 +6,7 @@
// the End-User License Agreement for Aseprite.
#ifdef HAVE_CONFIG_H
#include "config.h"
#include "config.h"
#endif
#include "app/cmd/crop_cel.h"
@ -16,8 +16,7 @@
#include "doc/layer_tilemap.h"
#include "doc/primitives.h"
namespace app {
namespace cmd {
namespace app { namespace cmd {
using namespace doc;
@ -45,8 +44,7 @@ void CropCel::onUndo()
}
// Crops the cel image leaving the same ID in the image.
void CropCel::cropImage(const gfx::Point& origin,
const gfx::Rect& bounds)
void CropCel::cropImage(const gfx::Point& origin, const gfx::Rect& bounds)
{
Cel* cel = this->cel();
@ -60,8 +58,10 @@ void CropCel::cropImage(const gfx::Point& origin,
}
if (bounds != cel->image()->bounds()) {
ImageRef image(crop_image(cel->image(),
localBounds.x, localBounds.y,
localBounds.w, localBounds.h,
localBounds.x,
localBounds.y,
localBounds.w,
localBounds.h,
cel->image()->maskColor()));
ObjectId id = cel->image()->id();
ObjectVersion ver = cel->image()->version();
@ -80,5 +80,4 @@ void CropCel::cropImage(const gfx::Point& origin,
}
}
} // namespace cmd
} // namespace app
}} // namespace app::cmd

View File

@ -14,32 +14,27 @@
#include "gfx/point.h"
#include "gfx/rect.h"
namespace app {
namespace cmd {
namespace app { namespace cmd {
class CropCel : public Cmd
, public WithCel {
public:
CropCel(doc::Cel* cel, const gfx::Rect& newBounds);
class CropCel : public Cmd,
public WithCel {
public:
CropCel(doc::Cel* cel, const gfx::Rect& newBounds);
protected:
void onExecute() override;
void onUndo() override;
size_t onMemSize() const override {
return sizeof(*this);
}
protected:
void onExecute() override;
void onUndo() override;
size_t onMemSize() const override { return sizeof(*this); }
private:
void cropImage(const gfx::Point& origin,
const gfx::Rect& bounds);
private:
void cropImage(const gfx::Point& origin, const gfx::Rect& bounds);
gfx::Point m_oldOrigin;
gfx::Point m_newOrigin;
gfx::Rect m_oldBounds;
gfx::Rect m_newBounds;
};
gfx::Point m_oldOrigin;
gfx::Point m_newOrigin;
gfx::Rect m_oldBounds;
gfx::Rect m_newBounds;
};
} // namespace cmd
} // namespace app
}} // namespace app::cmd
#endif

View File

@ -6,7 +6,7 @@
// the End-User License Agreement for Aseprite.
#ifdef HAVE_CONFIG_H
#include "config.h"
#include "config.h"
#endif
#include "app/cmd/deselect_mask.h"
@ -15,18 +15,16 @@
#include "app/doc.h"
#include "doc/mask.h"
namespace app {
namespace cmd {
namespace app { namespace cmd {
DeselectMask::DeselectMask(Doc* doc)
: WithDocument(doc)
DeselectMask::DeselectMask(Doc* doc) : WithDocument(doc)
{
}
void DeselectMask::onExecute()
{
Doc* doc = document();
m_oldMask.reset(doc->isMaskVisible() ? new Mask(*doc->mask()): nullptr);
m_oldMask.reset(doc->isMaskVisible() ? new Mask(*doc->mask()) : nullptr);
doc->setMaskVisible(false);
doc->notifySelectionChanged();
}
@ -46,8 +44,7 @@ void DeselectMask::onUndo()
size_t DeselectMask::onMemSize() const
{
return sizeof(*this) + (m_oldMask ? m_oldMask->getMemSize(): 0);
return sizeof(*this) + (m_oldMask ? m_oldMask->getMemSize() : 0);
}
} // namespace cmd
} // namespace app
}} // namespace app::cmd

View File

@ -14,28 +14,26 @@
#include <memory>
namespace doc {
class Mask;
class Mask;
}
namespace app {
namespace cmd {
using namespace doc;
namespace app { namespace cmd {
using namespace doc;
class DeselectMask : public Cmd
, public WithDocument {
public:
DeselectMask(Doc* doc);
class DeselectMask : public Cmd,
public WithDocument {
public:
DeselectMask(Doc* doc);
protected:
void onExecute() override;
void onUndo() override;
size_t onMemSize() const override;
protected:
void onExecute() override;
void onUndo() override;
size_t onMemSize() const override;
private:
std::unique_ptr<Mask> m_oldMask;
};
private:
std::unique_ptr<Mask> m_oldMask;
};
} // namespace cmd
} // namespace app
}} // namespace app::cmd
#endif

View File

@ -5,45 +5,45 @@
// the End-User License Agreement for Aseprite.
#ifdef HAVE_CONFIG_H
#include "config.h"
#include "config.h"
#endif
#include "app/cmd/drop_on_timeline.h"
#include "app/cmd/add_layer.h"
#include "app/cmd/set_pixel_format.h"
#include "app/cmd/move_cel.h"
#include "app/context_flags.h"
#include "app/cmd/set_pixel_format.h"
#include "app/console.h"
#include "app/context_flags.h"
#include "app/doc.h"
#include "app/doc_event.h"
#include "app/file/file.h"
#include "app/tx.h"
#include "app/util/layer_utils.h"
#include "app/util/open_file_job.h"
#include "app/tx.h"
#include "doc/layer_list.h"
#include "render/dithering.h"
#include <algorithm>
namespace app {
namespace cmd {
namespace app { namespace cmd {
DropOnTimeline::DropOnTimeline(app::Doc* doc,
doc::frame_t frame,
doc::layer_t layerIndex,
InsertionPoint insert,
DroppedOn droppedOn,
const base::paths& paths) : WithDocument(doc)
, m_size(0)
, m_paths(paths)
, m_frame(frame)
, m_layerIndex(layerIndex)
, m_insert(insert)
, m_droppedOn(droppedOn)
const base::paths& paths)
: WithDocument(doc)
, m_size(0)
, m_paths(paths)
, m_frame(frame)
, m_layerIndex(layerIndex)
, m_insert(insert)
, m_droppedOn(droppedOn)
{
ASSERT(m_layerIndex >= 0);
for(const auto& path : m_paths)
for (const auto& path : m_paths)
m_size += path.size();
}
@ -52,13 +52,14 @@ DropOnTimeline::DropOnTimeline(app::Doc* doc,
doc::layer_t layerIndex,
InsertionPoint insert,
DroppedOn droppedOn,
const doc::ImageRef& image) : WithDocument(doc)
, m_size(0)
, m_image(image)
, m_frame(frame)
, m_layerIndex(layerIndex)
, m_insert(insert)
, m_droppedOn(droppedOn)
const doc::ImageRef& image)
: WithDocument(doc)
, m_size(0)
, m_image(image)
, m_frame(frame)
, m_layerIndex(layerIndex)
, m_insert(insert)
, m_droppedOn(droppedOn)
{
ASSERT(m_layerIndex >= 0);
}
@ -66,7 +67,7 @@ DropOnTimeline::DropOnTimeline(app::Doc* doc,
void DropOnTimeline::setupInsertionLayer(Layer** layer, LayerGroup** group)
{
const LayerList& allLayers = document()->sprite()->allLayers();
*layer = allLayers[m_layerIndex];
*layer = allLayers[m_layerIndex];
if (m_insert == InsertionPoint::BeforeLayer && (*layer)->isGroup()) {
*group = static_cast<LayerGroup*>(*layer);
// The user is trying to drop layers into an empty group, so there is no after
@ -79,7 +80,7 @@ void DropOnTimeline::setupInsertionLayer(Layer** layer, LayerGroup** group)
m_insert = InsertionPoint::AfterLayer;
}
*group = (*layer)->parent();
*group = (*layer)->parent();
}
bool DropOnTimeline::hasPendingWork()
@ -106,11 +107,10 @@ bool DropOnTimeline::getNextDocFromPaths(Doc** srcDoc)
{
Console console;
Context* context = document()->context();
int flags = FILE_LOAD_DATA_FILE | FILE_LOAD_AVOID_BACKGROUND_LAYER |
FILE_LOAD_CREATE_PALETTE | FILE_LOAD_SEQUENCE_YES;
int flags = FILE_LOAD_DATA_FILE | FILE_LOAD_AVOID_BACKGROUND_LAYER | FILE_LOAD_CREATE_PALETTE |
FILE_LOAD_SEQUENCE_YES;
std::unique_ptr<FileOp> fop(
FileOp::createLoadDocumentOperation(context, m_paths.front(), flags));
std::unique_ptr<FileOp> fop(FileOp::createLoadDocumentOperation(context, m_paths.front(), flags));
// Remove the path that is currently being processed
m_paths.erase(m_paths.begin());
@ -161,7 +161,7 @@ void DropOnTimeline::onExecute()
m_previousTotalFrames = destDoc->sprite()->totalFrames();
int docsProcessed = 0;
while(hasPendingWork()) {
while (hasPendingWork()) {
Doc* srcDoc;
if (!getNextDoc(&srcDoc))
return;
@ -174,13 +174,13 @@ void DropOnTimeline::onExecute()
// Execute in a source doc transaction because we don't need undo/redo
// this.
Tx tx(srcDoc);
tx(new cmd::SetPixelFormat(
srcDoc->sprite(), destDoc->sprite()->pixelFormat(),
render::Dithering(),
Preferences::instance().quantization.rgbmapAlgorithm(),
nullptr,
nullptr,
FitCriteria::DEFAULT));
tx(new cmd::SetPixelFormat(srcDoc->sprite(),
destDoc->sprite()->pixelFormat(),
render::Dithering(),
Preferences::instance().quantization.rgbmapAlgorithm(),
nullptr,
nullptr,
FitCriteria::DEFAULT));
tx.commit();
}
@ -197,8 +197,8 @@ void DropOnTimeline::onExecute()
// If there is no room for the source frames, add frames to the
// destination sprite.
if (m_frame+srcDoc->sprite()->totalFrames() > destDoc->sprite()->totalFrames()) {
destDoc->sprite()->setTotalFrames(m_frame+srcDoc->sprite()->totalFrames());
if (m_frame + srcDoc->sprite()->totalFrames() > destDoc->sprite()->totalFrames()) {
destDoc->sprite()->setTotalFrames(m_frame + srcDoc->sprite()->totalFrames());
}
// Save dropped layers from source document.
@ -314,11 +314,8 @@ bool DropOnTimeline::canMoveCelFrom(app::Doc* srcDoc)
{
auto* srcLayer = srcDoc->sprite()->firstLayer();
auto* destLayer = document()->sprite()->allLayers()[m_layerIndex];
return m_droppedOn == DroppedOn::Cel &&
srcDoc->sprite()->allLayersCount() == 1 &&
srcDoc->sprite()->totalFrames() == 1 &&
srcLayer->isImage() &&
destLayer->isImage();
return m_droppedOn == DroppedOn::Cel && srcDoc->sprite()->allLayersCount() == 1 &&
srcDoc->sprite()->totalFrames() == 1 && srcLayer->isImage() && destLayer->isImage();
}
void DropOnTimeline::notifyDocObservers(Layer* layer)
@ -341,5 +338,4 @@ void DropOnTimeline::notifyDocObservers(Layer* layer)
doc->notify_observers<DocEvent&>(&DocObserver::onAfterRemoveLayer, ev);
}
} // namespace cmd
} // namespace app
}} // namespace app::cmd

View File

@ -8,8 +8,8 @@
#define APP_CMD_drop_on_timeline_H_INCLUDED
#pragma once
#include "app/cmd_sequence.h"
#include "app/cmd/with_document.h"
#include "app/cmd_sequence.h"
#include "app/doc_observer.h"
#include "base/paths.h"
#include "doc/frame.h"
@ -17,71 +17,75 @@
#include "doc/layer.h"
#include "doc/layer_list.h"
namespace app {
namespace cmd {
namespace app { namespace cmd {
class DropOnTimeline : public CmdSequence
, public WithDocument {
public:
enum class InsertionPoint {
BeforeLayer,
AfterLayer,
};
enum class DroppedOn {
Unspecified,
Frame,
Layer,
Cel,
};
// Inserts the layers and frames of the documents pointed by the specified
// paths, at the specified frame and before or after the specified layer index.
DropOnTimeline(app::Doc* doc, doc::frame_t frame, doc::layer_t layerIndex,
InsertionPoint insert, DroppedOn droppedOn, const base::paths& paths);
// Inserts the image as if it were a document with just one layer and one
// frame, at the specified frame and before or after the specified layer index.
DropOnTimeline(app::Doc* doc, doc::frame_t frame, doc::layer_t layerIndex,
InsertionPoint insert, DroppedOn droppedOn, const doc::ImageRef& image);
protected:
void onExecute() override;
void onUndo() override;
void onRedo() override;
size_t onMemSize() const override {
return sizeof(*this) + m_size;
}
private:
void setupInsertionLayer(doc::Layer** layer, doc::LayerGroup** group);
void insertDroppedLayers(bool incGroupVersion);
bool canMoveCelFrom(app::Doc* srcDoc);
void notifyAddLayer(doc::Layer* layer);
void notifyDocObservers(doc::Layer* layer);
bool hasPendingWork();
// Sets srcDoc's Doc* pointer to the next document to be processed.
// Returns false when the user cancelled the process, or true when the
// process must go on.
bool getNextDoc(Doc** srcDoc);
bool getNextDocFromImage(Doc** srcDoc);
bool getNextDocFromPaths(Doc** srcDoc);
size_t m_size;
base::paths m_paths;
doc::ImageRef m_image = nullptr;
doc::frame_t m_frame;
doc::layer_t m_layerIndex;
InsertionPoint m_insert;
DroppedOn m_droppedOn;
// Holds the list of layers dropped into the document. Used to support
// undo/redo without having to read all the files again.
doc::LayerList m_droppedLayers;
// Number of frames the doc had before dropping.
doc::frame_t m_previousTotalFrames;
class DropOnTimeline : public CmdSequence,
public WithDocument {
public:
enum class InsertionPoint {
BeforeLayer,
AfterLayer,
};
} // namespace cmd
} // namespace app
enum class DroppedOn {
Unspecified,
Frame,
Layer,
Cel,
};
// Inserts the layers and frames of the documents pointed by the specified
// paths, at the specified frame and before or after the specified layer index.
DropOnTimeline(app::Doc* doc,
doc::frame_t frame,
doc::layer_t layerIndex,
InsertionPoint insert,
DroppedOn droppedOn,
const base::paths& paths);
// Inserts the image as if it were a document with just one layer and one
// frame, at the specified frame and before or after the specified layer index.
DropOnTimeline(app::Doc* doc,
doc::frame_t frame,
doc::layer_t layerIndex,
InsertionPoint insert,
DroppedOn droppedOn,
const doc::ImageRef& image);
protected:
void onExecute() override;
void onUndo() override;
void onRedo() override;
size_t onMemSize() const override { return sizeof(*this) + m_size; }
private:
void setupInsertionLayer(doc::Layer** layer, doc::LayerGroup** group);
void insertDroppedLayers(bool incGroupVersion);
bool canMoveCelFrom(app::Doc* srcDoc);
void notifyAddLayer(doc::Layer* layer);
void notifyDocObservers(doc::Layer* layer);
bool hasPendingWork();
// Sets srcDoc's Doc* pointer to the next document to be processed.
// Returns false when the user cancelled the process, or true when the
// process must go on.
bool getNextDoc(Doc** srcDoc);
bool getNextDocFromImage(Doc** srcDoc);
bool getNextDocFromPaths(Doc** srcDoc);
size_t m_size;
base::paths m_paths;
doc::ImageRef m_image = nullptr;
doc::frame_t m_frame;
doc::layer_t m_layerIndex;
InsertionPoint m_insert;
DroppedOn m_droppedOn;
// Holds the list of layers dropped into the document. Used to support
// undo/redo without having to read all the files again.
doc::LayerList m_droppedLayers;
// Number of frames the doc had before dropping.
doc::frame_t m_previousTotalFrames;
};
}} // namespace app::cmd
#endif

View File

@ -6,24 +6,24 @@
// the End-User License Agreement for Aseprite.
#ifdef HAVE_CONFIG_H
#include "config.h"
#include "config.h"
#endif
#include "app/cmd/flatten_layers.h"
#include "app/cmd/add_layer.h"
#include "app/cmd/add_cel.h"
#include "app/cmd/add_layer.h"
#include "app/cmd/configure_background.h"
#include "app/cmd/move_layer.h"
#include "app/cmd/remove_layer.h"
#include "app/cmd/remove_cel.h"
#include "app/cmd/remove_layer.h"
#include "app/cmd/replace_image.h"
#include "app/cmd/set_cel_opacity.h"
#include "app/cmd/set_cel_position.h"
#include "app/cmd/set_cel_zindex.h"
#include "app/cmd/set_layer_blend_mode.h"
#include "app/cmd/set_layer_name.h"
#include "app/cmd/set_layer_opacity.h"
#include "app/cmd/set_layer_blend_mode.h"
#include "app/cmd/set_cel_opacity.h"
#include "app/cmd/set_cel_zindex.h"
#include "app/cmd/set_cel_position.h"
#include "app/cmd/unlink_cel.h"
#include "app/doc.h"
#include "app/i18n/strings.h"
@ -37,8 +37,7 @@
#include <algorithm>
namespace app {
namespace cmd {
namespace app { namespace cmd {
FlattenLayers::FlattenLayers(doc::Sprite* sprite,
const doc::SelectedLayers& layers0,
@ -72,14 +71,14 @@ void FlattenLayers::onExecute()
LayerList list = layers.toBrowsableLayerList();
if (list.empty())
return; // Do nothing
return; // Do nothing
// Set the drawable area to a union of all cel bounds
// when this option is enabled
ImageSpec spec = sprite->spec();
gfx::Rect area;
if (m_options.dynamicCanvas) {
for (frame_t frame(0); frame<sprite->totalFrames(); ++frame) {
for (frame_t frame(0); frame < sprite->totalFrames(); ++frame) {
for (Layer* layer : layers) {
Cel* cel = layer->cel(frame);
if (cel)
@ -96,8 +95,8 @@ void FlattenLayers::onExecute()
// Create a temporary image.
ImageRef image(Image::create(spec));
LayerImage* flatLayer; // The layer onto which everything will be flattened.
color_t bgcolor; // The background color to use for flatLayer.
LayerImage* flatLayer; // The layer onto which everything will be flattened.
color_t bgcolor; // The background color to use for flatLayer.
bool newFlatLayer = false;
flatLayer = sprite->backgroundLayer();
@ -136,15 +135,14 @@ void FlattenLayers::onExecute()
const gfx::ClipF area_to_image(0, 0, area);
// Copy all frames to the background.
for (frame_t frame(0); frame<sprite->totalFrames(); ++frame) {
for (frame_t frame(0); frame < sprite->totalFrames(); ++frame) {
// If the flatLayer is the only cel in this frame, we can skip
// this frame to keep existing links in the flatLayer.
const bool anotherCelExists =
std::any_of(visibleLayers.begin(),
visibleLayers.end(),
[flatLayer, frame](const Layer* other) {
return (flatLayer != other && other->cel(frame));
});
const bool anotherCelExists = std::any_of(visibleLayers.begin(),
visibleLayers.end(),
[flatLayer, frame](const Layer* other) {
return (flatLayer != other && other->cel(frame));
});
if (!anotherCelExists)
continue;
@ -154,9 +152,11 @@ void FlattenLayers::onExecute()
// Get exact bounds for rendered frame
gfx::Rect bounds = image->bounds();
const bool shrink = doc::algorithm::shrink_bounds(
image.get(), image->maskColor(), nullptr,
image->bounds(), bounds);
const bool shrink = doc::algorithm::shrink_bounds(image.get(),
image->maskColor(),
nullptr,
image->bounds(),
bounds);
// Skip when fully transparent
Cel* cel = flatLayer->cel(frame);
@ -168,12 +168,10 @@ void FlattenLayers::onExecute()
}
// Apply shrunk bounds to new image
const ImageRef new_image(doc::crop_image(
image.get(), bounds, image->maskColor()));
const ImageRef new_image(doc::crop_image(image.get(), bounds, image->maskColor()));
// Replace image on existing cel
if (cel) {
// TODO Keep cel links when possible
if (cel->links())
@ -190,8 +188,7 @@ void FlattenLayers::onExecute()
if (cel->zIndex() != 0)
executeAndAdd(new cmd::SetCelZIndex(cel, 0));
executeAndAdd(new cmd::SetCelPosition(cel,
area.x+bounds.x, area.y+bounds.y));
executeAndAdd(new cmd::SetCelPosition(cel, area.x + bounds.x, area.y + bounds.y));
}
// Modify destination cel
@ -200,7 +197,7 @@ void FlattenLayers::onExecute()
// Add new cel on null
else {
cel = new Cel(frame, new_image);
cel->setPosition(area.x+bounds.x, area.y+bounds.y);
cel->setPosition(area.x + bounds.x, area.y + bounds.y);
// No need to undo adding this cel when flattening onto
// a new layer, as the layer itself would be destroyed,
@ -221,9 +218,7 @@ void FlattenLayers::onExecute()
// Add new flatten layer
if (newFlatLayer) {
executeAndAdd(new cmd::AddLayer(
list.front()->parent(), flatLayer, list.front()));
executeAndAdd(new cmd::AddLayer(list.front()->parent(), flatLayer, list.front()));
}
// Reset layer properties when flattening in-place
else {
@ -231,8 +226,7 @@ void FlattenLayers::onExecute()
executeAndAdd(new cmd::SetLayerOpacity(flatLayer, 255));
if (flatLayer->blendMode() != doc::BlendMode::NORMAL)
executeAndAdd(new cmd::SetLayerBlendMode(
flatLayer, doc::BlendMode::NORMAL));
executeAndAdd(new cmd::SetLayerBlendMode(flatLayer, doc::BlendMode::NORMAL));
}
// Delete flattened layers.
@ -245,5 +239,4 @@ void FlattenLayers::onExecute()
}
}
} // namespace cmd
} // namespace app
}} // namespace app::cmd

View File

@ -14,40 +14,30 @@
#include "doc/object_ids.h"
#include "doc/selected_layers.h"
namespace app {
namespace cmd {
namespace app { namespace cmd {
class FlattenLayers : public CmdSequence
, public WithSprite {
public:
class FlattenLayers : public CmdSequence,
public WithSprite {
public:
struct Options {
bool newBlendMethod : 1;
bool inplace : 1;
bool mergeDown : 1;
bool dynamicCanvas : 1;
struct Options {
bool newBlendMethod: 1;
bool inplace: 1;
bool mergeDown: 1;
bool dynamicCanvas: 1;
Options():
newBlendMethod(false),
inplace(false),
mergeDown(false),
dynamicCanvas(false) {
}
};
FlattenLayers(doc::Sprite* sprite,
const doc::SelectedLayers& layers,
const Options options);
protected:
void onExecute() override;
private:
doc::ObjectIds m_layerIds;
Options m_options;
Options() : newBlendMethod(false), inplace(false), mergeDown(false), dynamicCanvas(false) {}
};
} // namespace cmd
} // namespace app
FlattenLayers(doc::Sprite* sprite, const doc::SelectedLayers& layers, const Options options);
protected:
void onExecute() override;
private:
doc::ObjectIds m_layerIds;
Options m_options;
};
}} // namespace app::cmd
#endif

View File

@ -5,16 +5,15 @@
// the End-User License Agreement for Aseprite.
#ifdef HAVE_CONFIG_H
#include "config.h"
#include "config.h"
#endif
#include "app/cmd/flip_image.h"
#include "doc/image.h"
#include "doc/algorithm/flip_image.h"
#include "doc/image.h"
namespace app {
namespace cmd {
namespace app { namespace cmd {
FlipImage::FlipImage(Image* image, const gfx::Rect& bounds, doc::algorithm::FlipType flipType)
: WithImage(image)
@ -43,5 +42,4 @@ void FlipImage::swap()
image->incrementVersion();
}
} // namespace cmd
} // namespace app
}} // namespace app::cmd

View File

@ -16,34 +16,29 @@
#include <vector>
namespace doc {
class Image;
class Image;
}
namespace app {
namespace cmd {
using namespace doc;
namespace app { namespace cmd {
using namespace doc;
class FlipImage : public Cmd
, public WithImage {
public:
FlipImage(Image* image, const gfx::Rect& bounds,
doc::algorithm::FlipType flipType);
class FlipImage : public Cmd,
public WithImage {
public:
FlipImage(Image* image, const gfx::Rect& bounds, doc::algorithm::FlipType flipType);
protected:
void onExecute() override;
void onUndo() override;
size_t onMemSize() const override {
return sizeof(*this);
}
protected:
void onExecute() override;
void onUndo() override;
size_t onMemSize() const override { return sizeof(*this); }
private:
void swap();
private:
void swap();
gfx::Rect m_bounds;
doc::algorithm::FlipType m_flipType;
};
gfx::Rect m_bounds;
doc::algorithm::FlipType m_flipType;
};
} // namespace cmd
} // namespace app
}} // namespace app::cmd
#endif

View File

@ -6,7 +6,7 @@
// the End-User License Agreement for Aseprite.
#ifdef HAVE_CONFIG_H
#include "config.h"
#include "config.h"
#endif
#include "app/cmd/flip_mask.h"
@ -15,8 +15,7 @@
#include "doc/algorithm/flip_image.h"
#include "doc/mask.h"
namespace app {
namespace cmd {
namespace app { namespace cmd {
using namespace doc;
@ -46,12 +45,10 @@ void FlipMask::swap()
return;
mask->freeze();
doc::algorithm::flip_image(mask->bitmap(),
mask->bitmap()->bounds(), m_flipType);
doc::algorithm::flip_image(mask->bitmap(), mask->bitmap()->bounds(), m_flipType);
mask->unfreeze();
doc->notifySelectionChanged();
}
} // namespace cmd
} // namespace app
}} // namespace app::cmd

View File

@ -12,29 +12,25 @@
#include "app/cmd/with_document.h"
#include "doc/algorithm/flip_type.h"
namespace app {
namespace cmd {
using namespace doc;
namespace app { namespace cmd {
using namespace doc;
class FlipMask : public Cmd
, public WithDocument {
public:
FlipMask(Doc* doc, doc::algorithm::FlipType flipType);
class FlipMask : public Cmd,
public WithDocument {
public:
FlipMask(Doc* doc, doc::algorithm::FlipType flipType);
protected:
void onExecute() override;
void onUndo() override;
size_t onMemSize() const override {
return sizeof(*this);
}
protected:
void onExecute() override;
void onUndo() override;
size_t onMemSize() const override { return sizeof(*this); }
private:
void swap();
private:
void swap();
doc::algorithm::FlipType m_flipType;
};
doc::algorithm::FlipType m_flipType;
};
} // namespace cmd
} // namespace app
}} // namespace app::cmd
#endif

View File

@ -5,7 +5,7 @@
// the End-User License Agreement for Aseprite.
#ifdef HAVE_CONFIG_H
#include "config.h"
#include "config.h"
#endif
#include "app/cmd/flip_masked_cel.h"
@ -19,8 +19,7 @@
#include "doc/layer.h"
#include "doc/mask.h"
namespace app {
namespace cmd {
namespace app { namespace cmd {
FlipMaskedCel::FlipMaskedCel(Cel* cel, doc::algorithm::FlipType flipType)
{
@ -36,16 +35,13 @@ FlipMaskedCel::FlipMaskedCel(Cel* cel, doc::algorithm::FlipType flipType)
int x = cel->x();
int y = cel->y();
mask->offsetOrigin(-x, -y);
doc::algorithm::flip_image_with_mask(
copy.get(), mask, flipType, bgcolor);
doc::algorithm::flip_image_with_mask(copy.get(), mask, flipType, bgcolor);
mask->offsetOrigin(x, y);
int x1, y1, x2, y2;
if (get_shrink_rect2(&x1, &y1, &x2, &y2, image, copy.get())) {
add(new cmd::CopyRect(image, copy.get(),
gfx::Clip(x1, y1, x1, y1, x2-x1+1, y2-y1+1)));
add(new cmd::CopyRect(image, copy.get(), gfx::Clip(x1, y1, x1, y1, x2 - x1 + 1, y2 - y1 + 1)));
}
}
} // namespace cmd
} // namespace app
}} // namespace app::cmd

View File

@ -13,19 +13,17 @@
#include "doc/color.h"
namespace doc {
class Cel;
class Cel;
}
namespace app {
namespace cmd {
using namespace doc;
namespace app { namespace cmd {
using namespace doc;
class FlipMaskedCel : public CmdSequence {
public:
FlipMaskedCel(Cel* cel, doc::algorithm::FlipType flipType);
};
class FlipMaskedCel : public CmdSequence {
public:
FlipMaskedCel(Cel* cel, doc::algorithm::FlipType flipType);
};
} // namespace cmd
} // namespace app
}} // namespace app::cmd
#endif

View File

@ -5,7 +5,7 @@
// the End-User License Agreement for Aseprite.
#ifdef HAVE_CONFIG_H
#include "config.h"
#include "config.h"
#endif
#include "app/cmd/layer_from_background.h"
@ -15,8 +15,7 @@
#include "doc/layer.h"
#include "doc/sprite.h"
namespace app {
namespace cmd {
namespace app { namespace cmd {
LayerFromBackground::LayerFromBackground(Layer* layer)
{
@ -29,12 +28,10 @@ LayerFromBackground::LayerFromBackground(Layer* layer)
ASSERT(layer->sprite()->backgroundLayer() != NULL);
// Remove "Background" and "LockMove" flags
LayerFlags newFlags = LayerFlags(int(layer->flags())
& ~int(LayerFlags::BackgroundLayerFlags));
LayerFlags newFlags = LayerFlags(int(layer->flags()) & ~int(LayerFlags::BackgroundLayerFlags));
add(new cmd::SetLayerFlags(layer, newFlags));
add(new cmd::SetLayerName(layer, "Layer 0"));
}
} // namespace cmd
} // namespace app
}} // namespace app::cmd

View File

@ -11,19 +11,17 @@
#include "app/cmd_sequence.h"
namespace doc {
class Layer;
class Layer;
}
namespace app {
namespace cmd {
using namespace doc;
namespace app { namespace cmd {
using namespace doc;
class LayerFromBackground : public CmdSequence {
public:
LayerFromBackground(Layer* layer);
};
class LayerFromBackground : public CmdSequence {
public:
LayerFromBackground(Layer* layer);
};
} // namespace cmd
} // namespace app
}} // namespace app::cmd
#endif

View File

@ -6,7 +6,7 @@
// the End-User License Agreement for Aseprite.
#ifdef HAVE_CONFIG_H
#include "config.h"
#include "config.h"
#endif
#include "app/cmd/move_cel.h"
@ -29,14 +29,15 @@
#include "render/rasterize.h"
#include "render/render.h"
namespace app {
namespace cmd {
namespace app { namespace cmd {
using namespace doc;
MoveCel::MoveCel(
LayerImage* srcLayer, frame_t srcFrame,
LayerImage* dstLayer, frame_t dstFrame, bool continuous)
MoveCel::MoveCel(LayerImage* srcLayer,
frame_t srcFrame,
LayerImage* dstLayer,
frame_t dstFrame,
bool continuous)
: m_srcLayer(srcLayer)
, m_dstLayer(dstLayer)
, m_srcFrame(srcFrame)
@ -75,24 +76,22 @@ void MoveCel::onExecute()
while (dstSprite->totalFrames() <= m_dstFrame)
executeAndAdd(new cmd::AddFrame(dstSprite, dstSprite->totalFrames()));
Image* srcImage = (srcCel ? srcCel->image(): NULL);
Image* srcImage = (srcCel ? srcCel->image() : NULL);
ImageRef dstImage;
dstCel = dstLayer->cel(m_dstFrame);
if (dstCel)
dstImage = dstCel->imageRef();
bool createLink =
(srcLayer == dstLayer && m_continuous);
bool createLink = (srcLayer == dstLayer && m_continuous);
// For background layer
if (dstLayer->isBackground()) {
ASSERT(dstCel);
ASSERT(dstImage);
if (!dstCel || !dstImage ||
!srcCel || !srcImage)
if (!dstCel || !dstImage || !srcCel || !srcImage)
return;
ASSERT(!dstLayer->isTilemap()); // TODO support background tilemaps
ASSERT(!dstLayer->isTilemap()); // TODO support background tilemaps
if (createLink) {
executeAndAdd(new cmd::SetCelData(dstCel, srcCel->dataRef()));
@ -105,15 +104,16 @@ void MoveCel::onExecute()
executeAndAdd(new cmd::CopyRect(dstImage.get(), tmp.get(), gfx::Clip(tmp->bounds())));
}
else {
BlendMode blend = (srcLayer->isBackground() ?
BlendMode::SRC:
BlendMode::NORMAL);
BlendMode blend = (srcLayer->isBackground() ? BlendMode::SRC : BlendMode::NORMAL);
ImageRef tmp(Image::createCopy(dstImage.get()));
render::composite_image(
tmp.get(), srcImage,
srcSprite->palette(m_srcFrame),
srcCel->x(), srcCel->y(), 255, blend);
render::composite_image(tmp.get(),
srcImage,
srcSprite->palette(m_srcFrame),
srcCel->x(),
srcCel->y(),
255,
blend);
executeAndAdd(new cmd::CopyRect(dstImage.get(), tmp.get(), gfx::Clip(tmp->bounds())));
}
executeAndAdd(new cmd::ClearCel(srcCel));
@ -141,10 +141,7 @@ void MoveCel::onFireNotifications()
{
CmdSequence::onFireNotifications();
static_cast<Doc*>(m_dstLayer.layer()->sprite()->document())
->notifyCelMoved(
m_srcLayer.layer(), m_srcFrame,
m_dstLayer.layer(), m_dstFrame);
->notifyCelMoved(m_srcLayer.layer(), m_srcFrame, m_dstLayer.layer(), m_dstFrame);
}
} // namespace cmd
} // namespace app
}} // namespace app::cmd

Some files were not shown because too many files have changed in this diff Show More