mirror of
https://github.com/aseprite/aseprite.git
synced 2025-01-27 06:35:16 +00:00
Add setting/preference classes/enums generator
Changes: * Add a class (Option<T>) to get/set/listen changes to one specific preference option * Add data/pref.xml with the metadata to generate types/classes (not it's quite easy to add new preferences) * Modify the generator to support generation of .h and .cpp files of preference types * Add code to migrate old options to new ones (and functions to delete old values) * Only a couple of options were migrated at the moment, it is a WIP, in the future we should completely remove ISettings and direct calls to set/get_config_*
This commit is contained in:
parent
65da03d181
commit
73658399cc
2
TODO.md
2
TODO.md
@ -43,8 +43,6 @@
|
||||
|
||||
# Refactoring
|
||||
|
||||
* Merge everything related to configuration/settings in one class
|
||||
(allow configuration per document). Use cfg.cpp and settings/ dir.
|
||||
* Refactor src/file/ in several layers.
|
||||
* Use streams instead of FILEs.
|
||||
* Destroy modules/gui.h.
|
||||
|
135
data/pref.xml
Normal file
135
data/pref.xml
Normal file
@ -0,0 +1,135 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<preferences>
|
||||
|
||||
<types>
|
||||
<enum id="InkType">
|
||||
<value id="DEFAULT" value="0" />
|
||||
<value id="SET_ALPHA" value="1" />
|
||||
<value id="LOCK_ALPHA" value="2" />
|
||||
</enum>
|
||||
<enum id="RightClickMode">
|
||||
<value id="PAINT_BGCOLOR" value="0" />
|
||||
<value id="PICK_FGCOLOR" value="1" />
|
||||
<value id="ERASE" value="2" />
|
||||
</enum>
|
||||
<enum id="TiledMode">
|
||||
<value id="NONE" value="0" />
|
||||
<value id="X_AXIS" value="1" />
|
||||
<value id="Y_AXIS" value="2" />
|
||||
<value id="BOTH" value="3" />
|
||||
</enum>
|
||||
<enum id="OnionskinType">
|
||||
<value id="MERGE" value="0" />
|
||||
<value id="RED_BLUE_TINT" value="1" />
|
||||
</enum>
|
||||
<enum id="AniDir">
|
||||
<value id="FORWARD" value="0" />
|
||||
<value id="REVERSE" value="1" />
|
||||
<value id="PING_PONG" value="2" />
|
||||
</enum>
|
||||
<enum id="FreehandAlgorithm">
|
||||
<value id="REGULAR" value="0" />
|
||||
<value id="PIXEL_PERFECT" value="1" />
|
||||
<value id="DOTS" value="2" />
|
||||
</enum>
|
||||
<enum id="BrushType">
|
||||
<value id="CIRCLE" value="0" />
|
||||
<value id="SQUARE" value="1" />
|
||||
<value id="LINE" value="2" />
|
||||
</enum>
|
||||
<enum id="SelectionMode">
|
||||
<value id="DEFAULT" value="0" />
|
||||
<value id="ADD" value="1" />
|
||||
<value id="SUBTRACT" value="2" />
|
||||
</enum>
|
||||
<enum id="RotationAlgorithm">
|
||||
<value id="FAST" value="0" />
|
||||
<value id="ROTSPRITE" value="1" />
|
||||
</enum>
|
||||
</types>
|
||||
|
||||
<global>
|
||||
<section id="general">
|
||||
<option id="autoshow_timeline" type="bool" default="true" migrate="Options.AutoShowTimeline" />
|
||||
<option id="expand_menubar_on_mouseover" type="bool" default="false" migrate="Options.ExpandMenuBarOnMouseover" />
|
||||
</section>
|
||||
<section id="undo" text="Undo">
|
||||
<option id="size_limit" type="int" default="0" />
|
||||
<option id="goto_modified" type="bool" default="false" />
|
||||
</section>
|
||||
<section id="editor" text="Editor">
|
||||
<option id="zoom_with_scroll_wheel" type="bool" default="false" form="" />
|
||||
<option id="center_on_zoom" type="bool" default="false" />
|
||||
<option id="show_scrollbars" type="bool" default="false" />
|
||||
<option id="right_click_mode" type="RightClickMode" default="RightClickMode::PAINT_BGCOLOR" />
|
||||
<option id="grab_alpha" type="bool" default="false" />
|
||||
<option id="auto_select_layer" type="bool" default="false" />
|
||||
<option id="fg_color" type="app::Color" />
|
||||
<option id="bg_color" type="app::Color" />
|
||||
<option id="current_tool" type="std::string" default=""pencil"" />
|
||||
</section>
|
||||
<section id="experimental" text="Experimental">
|
||||
<option id="use_native_cursor" type="bool" default="false" />
|
||||
<option id="flash_layer" type="bool" default="false" />
|
||||
</section>
|
||||
</global>
|
||||
|
||||
<tool>
|
||||
<option id="opacity" type="int" default="255" />
|
||||
<option id="tolerance" type="int" default="0" />
|
||||
<option id="contiguous" type="bool" default="true" />
|
||||
<option id="filled" type="bool" default="false" />
|
||||
<option id="filled_preview" type="bool" default="false" />
|
||||
<option id="ink" type="InkType" />
|
||||
<option id="freehand_algorithm" type="FreehandAlgorithm" />
|
||||
<section id="brush">
|
||||
<option id="type" type="BrushType" />
|
||||
<option id="size" type="int" />
|
||||
<option id="angle" type="int" />
|
||||
</section>
|
||||
<section id="spray">
|
||||
<option id="width" type="int" default="16" />
|
||||
<option id="speed" type="int" default="32" />
|
||||
</section>
|
||||
<section id="selection">
|
||||
<option id="mode" type="SelectionMode" />
|
||||
<option id="transparent_color" type="app::Color" />
|
||||
<option id="rotation_algorithm" type="RotationAlgorithm" />
|
||||
</section>
|
||||
</tool>
|
||||
|
||||
<document>
|
||||
<section id="tiled">
|
||||
<option id="tiled_mode" type="TiledMode" default="TiledMode::NONE" />
|
||||
</section>
|
||||
<section id="grid">
|
||||
<option id="snap" type="bool" default="false" />
|
||||
<option id="visible" type="bool" default="false" />
|
||||
<option id="bounds" type="gfx::Rect" default="gfx::Rect(0, 0, 16, 16)" />
|
||||
<option id="color" type="app::Color" default="app::Color::fromRgb(0, 0, 255)" />
|
||||
<option id="opacity" type="int" default="160" />
|
||||
<option id="auto_opacity" type="bool" default="true" />
|
||||
</section>
|
||||
<section id="pixel_grid">
|
||||
<option id="visible" type="bool" default="false" />
|
||||
<option id="color" type="app::Color" default="app::Color::fromRgb(200, 200, 200)" />
|
||||
<option id="opacity" type="int" default="160" />
|
||||
<option id="auto_opacity" type="bool" default="true" />
|
||||
</section>
|
||||
<section id="onionskin">
|
||||
<option id="active" type="bool" default="false" />
|
||||
<option id="prev_frames" type="int" default="1" />
|
||||
<option id="next_frames" type="int" default="1" />
|
||||
<option id="opacity_base" type="int" default="68" />
|
||||
<option id="opacity_step" type="int" default="28" />
|
||||
<option id="type" type="OnionskinType" default="OnionskinType::MERGE" />
|
||||
</section>
|
||||
<section id="loop">
|
||||
<option id="visible" type="bool" default="false" />
|
||||
<option id="from" type="doc::FrameNumber" default="doc::FrameNumber(0)" />
|
||||
<option id="to" type="doc::FrameNumber" default="doc::FrameNumber(1)" />
|
||||
<option id="ani_dir" type="AniDir" default="AniDir::FORWARD" />
|
||||
</section>
|
||||
</document>
|
||||
|
||||
</preferences>
|
@ -7,7 +7,6 @@
|
||||
file(GLOB widget_files ${CMAKE_SOURCE_DIR}/data/widgets/*.xml)
|
||||
foreach(widget_file ${widget_files})
|
||||
get_filename_component(widget_name ${widget_file} NAME_WE)
|
||||
set(target_name generated_${widget_name})
|
||||
set(output_fn ${CMAKE_CURRENT_BINARY_DIR}/generated_${widget_name}.h)
|
||||
|
||||
add_custom_command(
|
||||
@ -17,9 +16,30 @@ foreach(widget_file ${widget_files})
|
||||
MAIN_DEPENDENCY ${widget_file}
|
||||
DEPENDS gen)
|
||||
|
||||
list(APPEND generated_header_files ${output_fn})
|
||||
list(APPEND generated_files ${output_fn})
|
||||
endforeach()
|
||||
|
||||
# pref.h and pref.cpp
|
||||
set(pref_xml ${CMAKE_SOURCE_DIR}/data/pref.xml)
|
||||
|
||||
set(output_fn ${CMAKE_CURRENT_BINARY_DIR}/generated_pref_types.h)
|
||||
add_custom_command(
|
||||
OUTPUT ${output_fn}
|
||||
COMMAND ${CMAKE_BINARY_DIR}/bin/gen --input ${pref_xml} --pref-h > ${output_fn}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||
MAIN_DEPENDENCY ${pref_xml}
|
||||
DEPENDS gen)
|
||||
list(APPEND generated_files ${output_fn})
|
||||
|
||||
set(output_fn ${CMAKE_CURRENT_BINARY_DIR}/generated_pref_types.cpp)
|
||||
add_custom_command(
|
||||
OUTPUT ${output_fn}
|
||||
COMMAND ${CMAKE_BINARY_DIR}/bin/gen --input ${pref_xml} --pref-cpp > ${output_fn}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||
MAIN_DEPENDENCY ${pref_xml}
|
||||
DEPENDS gen)
|
||||
list(APPEND generated_files ${output_fn})
|
||||
|
||||
# Directory where generated files by "gen" utility will stay.
|
||||
include_directories(${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
@ -169,6 +189,7 @@ add_library(app-lib
|
||||
modules/gui.cpp
|
||||
modules/palettes.cpp
|
||||
objects_container_impl.cpp
|
||||
pref/preferences.cpp
|
||||
project.cpp
|
||||
recent_files.cpp
|
||||
res/palettes_loader_delegate.cpp
|
||||
@ -288,4 +309,4 @@ add_library(app-lib
|
||||
xml_document.cpp
|
||||
xml_exception.cpp
|
||||
zoom.cpp
|
||||
${generated_header_files})
|
||||
${generated_files})
|
||||
|
@ -46,6 +46,7 @@
|
||||
#include "app/modules/gfx.h"
|
||||
#include "app/modules/gui.h"
|
||||
#include "app/modules/palettes.h"
|
||||
#include "app/pref/preferences.h"
|
||||
#include "app/recent_files.h"
|
||||
#include "app/resource_finder.h"
|
||||
#include "app/send_crash.h"
|
||||
@ -93,9 +94,14 @@ namespace app {
|
||||
|
||||
using namespace ui;
|
||||
|
||||
class App::Modules {
|
||||
class App::CoreModules {
|
||||
public:
|
||||
ConfigModule m_configModule;
|
||||
Preferences m_preferences;
|
||||
};
|
||||
|
||||
class App::Modules {
|
||||
public:
|
||||
LoggerModule m_loggerModule;
|
||||
FileSystemModule m_file_system_module;
|
||||
tools::ToolBox m_toolbox;
|
||||
@ -114,7 +120,8 @@ public:
|
||||
App* App::m_instance = NULL;
|
||||
|
||||
App::App()
|
||||
: m_modules(NULL)
|
||||
: m_coreModules(NULL)
|
||||
, m_modules(NULL)
|
||||
, m_legacy(NULL)
|
||||
, m_isGui(false)
|
||||
, m_isShell(false)
|
||||
@ -131,6 +138,7 @@ void App::initialize(const AppOptions& options)
|
||||
|
||||
// Initializes the application loading the modules, setting the
|
||||
// graphics mode, loading the configuration and resources, etc.
|
||||
m_coreModules = new CoreModules;
|
||||
m_modules = new Modules(!options.startUI(), options.verbose());
|
||||
m_isGui = options.startUI();
|
||||
m_isShell = options.startShell();
|
||||
@ -476,6 +484,7 @@ App::~App()
|
||||
|
||||
delete m_legacy;
|
||||
delete m_modules;
|
||||
delete m_coreModules;
|
||||
|
||||
// Destroy the loaded gui.xml data.
|
||||
delete KeyboardShortcuts::instance();
|
||||
@ -515,6 +524,11 @@ RecentFiles* App::getRecentFiles() const
|
||||
return &m_modules->m_recent_files;
|
||||
}
|
||||
|
||||
Preferences& App::preferences() const
|
||||
{
|
||||
return m_coreModules->m_preferences;
|
||||
}
|
||||
|
||||
void App::showNotification(INotificationDelegate* del)
|
||||
{
|
||||
m_mainWindow->showNotification(del);
|
||||
|
@ -45,6 +45,7 @@ namespace app {
|
||||
class LegacyModules;
|
||||
class LoggerModule;
|
||||
class MainWindow;
|
||||
class Preferences;
|
||||
class RecentFiles;
|
||||
|
||||
namespace tools {
|
||||
@ -75,6 +76,7 @@ namespace app {
|
||||
tools::ToolBox* getToolBox() const;
|
||||
RecentFiles* getRecentFiles() const;
|
||||
MainWindow* getMainWindow() const { return m_mainWindow; }
|
||||
Preferences& preferences() const;
|
||||
|
||||
void showNotification(INotificationDelegate* del);
|
||||
void updateDisplayTitleBar();
|
||||
@ -90,11 +92,13 @@ namespace app {
|
||||
|
||||
private:
|
||||
typedef std::vector<std::string> FileList;
|
||||
class CoreModules;
|
||||
class Modules;
|
||||
|
||||
static App* m_instance;
|
||||
|
||||
base::UniquePtr<ui::GuiSystem> m_guiSystem;
|
||||
CoreModules* m_coreModules;
|
||||
Modules* m_modules;
|
||||
LegacyModules* m_legacy;
|
||||
bool m_isGui;
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "app/load_widget.h"
|
||||
#include "app/modules/editors.h"
|
||||
#include "app/modules/gui.h"
|
||||
#include "app/pref/preferences.h"
|
||||
#include "app/resource_finder.h"
|
||||
#include "app/send_crash.h"
|
||||
#include "app/settings/document_settings.h"
|
||||
@ -59,6 +60,8 @@ public:
|
||||
, m_gridColor(new ColorButton(m_docSettings->getGridColor(), IMAGE_RGB))
|
||||
, m_cursorColor(new ColorButton(Editor::get_cursor_color(), IMAGE_RGB))
|
||||
{
|
||||
Preferences& preferences = App::instance()->preferences();
|
||||
|
||||
sectionListbox()->ChangeSelectedItem.connect(Bind<void>(&OptionsWindow::onChangeSection, this));
|
||||
cursorColorBox()->addChild(m_cursorColor);
|
||||
|
||||
@ -75,11 +78,10 @@ public:
|
||||
pixelGridAutoOpacity()->setSelected(m_docSettings->getPixelGridAutoOpacity());
|
||||
|
||||
// Others
|
||||
if (get_config_bool("Options", "AutoShowTimeline", true))
|
||||
if (preferences.general.autoshowTimeline())
|
||||
autotimeline()->setSelected(true);
|
||||
|
||||
if (get_config_bool("Options", "ExpandMenuBarOnMouseover",
|
||||
ui::MenuBar::expandOnMouseover()))
|
||||
if (preferences.general.expandMenubarOnMouseover())
|
||||
expandMenubarOnMouseover()->setSelected(true);
|
||||
|
||||
if (m_settings->getCenterOnZoom())
|
||||
@ -151,6 +153,8 @@ public:
|
||||
}
|
||||
|
||||
void saveConfig() {
|
||||
Preferences& preferences = App::instance()->preferences();
|
||||
|
||||
Editor::set_cursor_color(m_cursorColor->getColor());
|
||||
m_docSettings->setGridColor(m_gridColor->getColor());
|
||||
m_docSettings->setGridOpacity(gridOpacity()->getValue());
|
||||
@ -159,10 +163,10 @@ public:
|
||||
m_docSettings->setPixelGridOpacity(pixelGridOpacity()->getValue());
|
||||
m_docSettings->setPixelGridAutoOpacity(pixelGridAutoOpacity()->isSelected());
|
||||
|
||||
set_config_bool("Options", "AutoShowTimeline", autotimeline()->isSelected());
|
||||
preferences.general.autoshowTimeline(autotimeline()->isSelected());
|
||||
|
||||
bool expandOnMouseover = expandMenubarOnMouseover()->isSelected();
|
||||
set_config_bool("Options", "ExpandMenuBarOnMouseover", expandOnMouseover);
|
||||
preferences.general.expandMenubarOnMouseover(expandOnMouseover);
|
||||
ui::MenuBar::setExpandOnMouseover(expandOnMouseover);
|
||||
|
||||
m_settings->setCenterOnZoom(centerOnZoom()->isSelected());
|
||||
@ -259,9 +263,10 @@ OptionsCommand::OptionsCommand()
|
||||
"Options",
|
||||
CmdUIOnlyFlag)
|
||||
{
|
||||
Preferences& preferences = App::instance()->preferences();
|
||||
|
||||
ui::MenuBar::setExpandOnMouseover(
|
||||
get_config_bool("Options", "ExpandMenuBarOnMouseover",
|
||||
ui::MenuBar::expandOnMouseover()));
|
||||
preferences.general.expandMenubarOnMouseover());
|
||||
}
|
||||
|
||||
void OptionsCommand::onExecute(Context* context)
|
||||
|
@ -179,4 +179,9 @@ void set_config_color(const char* section, const char* name, const app::Color& v
|
||||
set_config_string(section, name, value.toString().c_str());
|
||||
}
|
||||
|
||||
void del_config_value(const char* section, const char* name)
|
||||
{
|
||||
g_configs.back()->deleteValue(section, name);
|
||||
}
|
||||
|
||||
} // namespace app
|
||||
|
@ -56,6 +56,76 @@ namespace app {
|
||||
app::Color get_config_color(const char* section, const char* name, const app::Color& value);
|
||||
void set_config_color(const char* section, const char* name, const app::Color& value);
|
||||
|
||||
void del_config_value(const char* section, const char* name);
|
||||
|
||||
// Generic get/set_config_value functions
|
||||
|
||||
inline const char* get_config_value(const char* section, const char* name, const char* value) {
|
||||
return get_config_string(section, name, value);
|
||||
}
|
||||
|
||||
inline std::string get_config_value(const char* section, const char* name, const std::string& value) {
|
||||
return get_config_string(section, name, value.c_str());
|
||||
}
|
||||
|
||||
inline bool get_config_value(const char* section, const char* name, bool value) {
|
||||
return get_config_bool(section, name, value);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline T get_config_value(const char* section, const char* name, const T& value) {
|
||||
return static_cast<T>(get_config_int(section, name, static_cast<int>(value)));
|
||||
}
|
||||
|
||||
inline float get_config_value(const char* section, const char* name, float value) {
|
||||
return get_config_float(section, name, value);
|
||||
}
|
||||
|
||||
inline double get_config_value(const char* section, const char* name, double value) {
|
||||
return get_config_float(section, name, value);
|
||||
}
|
||||
|
||||
inline gfx::Rect get_config_value(const char* section, const char* name, const gfx::Rect& value) {
|
||||
return get_config_rect(section, name, value);
|
||||
}
|
||||
|
||||
inline app::Color get_config_value(const char* section, const char* name, const app::Color& value) {
|
||||
return get_config_color(section, name, value);
|
||||
}
|
||||
|
||||
inline void set_config_value(const char* section, const char* name, const char* value) {
|
||||
set_config_string(section, name, value);
|
||||
}
|
||||
|
||||
inline void set_config_value(const char* section, const char* name, const std::string& value) {
|
||||
set_config_string(section, name, value.c_str());
|
||||
}
|
||||
|
||||
inline void set_config_value(const char* section, const char* name, bool value) {
|
||||
set_config_bool(section, name, value);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline void set_config_value(const char* section, const char* name, const T& value) {
|
||||
set_config_int(section, name, static_cast<int>(value));
|
||||
}
|
||||
|
||||
inline void set_config_value(const char* section, const char* name, float value) {
|
||||
set_config_float(section, name, value);
|
||||
}
|
||||
|
||||
inline void set_config_value(const char* section, const char* name, double value) {
|
||||
set_config_float(section, name, value);
|
||||
}
|
||||
|
||||
inline void set_config_value(const char* section, const char* name, const gfx::Rect& value) {
|
||||
set_config_rect(section, name, value);
|
||||
}
|
||||
|
||||
inline void set_config_value(const char* section, const char* name, const app::Color& value) {
|
||||
set_config_color(section, name, value);
|
||||
}
|
||||
|
||||
} // namespace app
|
||||
|
||||
#endif
|
||||
|
81
src/app/pref/option.h
Normal file
81
src/app/pref/option.h
Normal file
@ -0,0 +1,81 @@
|
||||
/* Aseprite
|
||||
* Copyright (C) 2001-2014 David Capello
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef APP_PREF_OPTION_H_INCLUDED
|
||||
#define APP_PREF_OPTION_H_INCLUDED
|
||||
#pragma once
|
||||
|
||||
#include "base/signal.h"
|
||||
#include "base/disable_copying.h"
|
||||
|
||||
namespace app {
|
||||
|
||||
template<typename T>
|
||||
class Option {
|
||||
public:
|
||||
Option(const char* section, const char* id, const T& defaultValue = T())
|
||||
: m_section(section)
|
||||
, m_id(id)
|
||||
, m_default(defaultValue)
|
||||
, m_value(defaultValue)
|
||||
, m_dirty(false) {
|
||||
}
|
||||
|
||||
const char* section() const { return m_section; }
|
||||
const char* id() const { return m_id; }
|
||||
const T& defaultValue() const { return m_default; }
|
||||
|
||||
bool isDirty() const { return m_dirty; }
|
||||
void forceDirtyFlag() { m_dirty = true; }
|
||||
void cleanDirtyFlag() { m_dirty = false; }
|
||||
|
||||
const T& operator()() const {
|
||||
return m_value;
|
||||
}
|
||||
|
||||
const T& operator()(const T& newValue) {
|
||||
if (m_value == newValue)
|
||||
return m_value;
|
||||
|
||||
BeforeChange(*this, newValue);
|
||||
|
||||
T oldValue = m_value;
|
||||
m_value = newValue;
|
||||
m_dirty = true;
|
||||
|
||||
AfterChange(*this, oldValue);
|
||||
return m_value;
|
||||
}
|
||||
|
||||
Signal2<void, Option&, const T&> BeforeChange;
|
||||
Signal2<void, Option&, const T&> AfterChange;
|
||||
|
||||
private:
|
||||
const char* m_section;
|
||||
const char* m_id;
|
||||
T m_default;
|
||||
T m_value;
|
||||
bool m_dirty;
|
||||
|
||||
Option();
|
||||
DISABLE_COPYING(Option);
|
||||
};
|
||||
|
||||
} // namespace app
|
||||
|
||||
#endif
|
60
src/app/pref/option_io.h
Normal file
60
src/app/pref/option_io.h
Normal file
@ -0,0 +1,60 @@
|
||||
/* Aseprite
|
||||
* Copyright (C) 2001-2014 David Capello
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef APP_PREF_OPTION_IO_H_INCLUDED
|
||||
#define APP_PREF_OPTION_IO_H_INCLUDED
|
||||
#pragma once
|
||||
|
||||
#include "app/ini_file.h"
|
||||
#include "app/pref/option.h"
|
||||
|
||||
namespace app {
|
||||
|
||||
// Load
|
||||
|
||||
template<typename T>
|
||||
void load_option(Option<T>& opt) {
|
||||
opt(get_config_value(opt.section(), opt.id(), opt.defaultValue()));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void load_option_with_migration(Option<T>& opt, const char* oldSection, const char* oldName) {
|
||||
if (get_config_string(oldSection, oldName, NULL)) {
|
||||
opt(get_config_value(oldSection, oldName, opt.defaultValue()));
|
||||
del_config_value(oldSection, oldName);
|
||||
|
||||
opt.forceDirtyFlag();
|
||||
}
|
||||
else
|
||||
opt(get_config_value(opt.section(), opt.id(), opt.defaultValue()));
|
||||
}
|
||||
|
||||
// Save
|
||||
|
||||
template<typename T>
|
||||
void save_option(Option<T>& opt) {
|
||||
if (!opt.isDirty())
|
||||
return;
|
||||
|
||||
set_config_value(opt.section(), opt.id(), opt());
|
||||
opt.cleanDirtyFlag();
|
||||
}
|
||||
|
||||
} // namespace app
|
||||
|
||||
#endif
|
130
src/app/pref/preferences.cpp
Normal file
130
src/app/pref/preferences.cpp
Normal file
@ -0,0 +1,130 @@
|
||||
/* Aseprite
|
||||
* Copyright (C) 2001-2014 David Capello
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "app/document.h"
|
||||
#include "app/ini_file.h"
|
||||
#include "app/pref/preferences.h"
|
||||
#include "app/resource_finder.h"
|
||||
#include "app/tools/tool.h"
|
||||
|
||||
namespace app {
|
||||
|
||||
Preferences::Preferences()
|
||||
: app::gen::GlobalPref("")
|
||||
{
|
||||
load();
|
||||
}
|
||||
|
||||
Preferences::~Preferences()
|
||||
{
|
||||
save();
|
||||
|
||||
for (auto& pair : m_tools)
|
||||
delete pair.second;
|
||||
|
||||
for (auto& pair : m_docs)
|
||||
delete pair.second;
|
||||
}
|
||||
|
||||
void Preferences::load()
|
||||
{
|
||||
app::gen::GlobalPref::load();
|
||||
}
|
||||
|
||||
void Preferences::save()
|
||||
{
|
||||
app::gen::GlobalPref::save();
|
||||
|
||||
for (auto& pair : m_tools)
|
||||
pair.second->save();
|
||||
|
||||
for (auto& pair : m_docs) {
|
||||
app::Document* doc = pair.first;
|
||||
bool specific_file = false;
|
||||
|
||||
if (doc && doc->isAssociatedToFile()) {
|
||||
push_config_state();
|
||||
set_config_file(docConfigFileName(doc).c_str());
|
||||
specific_file = true;
|
||||
}
|
||||
|
||||
pair.second->save();
|
||||
|
||||
if (specific_file) {
|
||||
flush_config_file();
|
||||
pop_config_state();
|
||||
}
|
||||
}
|
||||
|
||||
flush_config_file();
|
||||
}
|
||||
|
||||
ToolPreferences& Preferences::tool(tools::Tool* tool)
|
||||
{
|
||||
ASSERT(tool != NULL);
|
||||
|
||||
auto it = m_tools.find(tool->getId());
|
||||
if (it != m_tools.end()) {
|
||||
return *it->second;
|
||||
}
|
||||
else {
|
||||
std::string section = "tool.";
|
||||
section += tool->getId();
|
||||
|
||||
ToolPreferences* toolPref = new ToolPreferences(section);
|
||||
m_tools[tool->getId()] = toolPref;
|
||||
return *toolPref;
|
||||
}
|
||||
}
|
||||
|
||||
DocumentPreferences& Preferences::document(app::Document* document)
|
||||
{
|
||||
ASSERT(document != NULL);
|
||||
|
||||
auto it = m_docs.find(document);
|
||||
if (it != m_docs.end()) {
|
||||
return *it->second;
|
||||
}
|
||||
else {
|
||||
DocumentPreferences* docPref = new DocumentPreferences("");
|
||||
m_docs[document] = docPref;
|
||||
return *docPref;
|
||||
}
|
||||
}
|
||||
|
||||
std::string Preferences::docConfigFileName(app::Document* doc)
|
||||
{
|
||||
if (!doc)
|
||||
return "";
|
||||
|
||||
ResourceFinder rf;
|
||||
std::string fn = doc->filename();
|
||||
for (size_t i=0; i<fn.size(); ++i) {
|
||||
if (fn[i] == ' ' || fn[i] == '/' || fn[i] == '\\' || fn[i] == ':' || fn[i] == '.') {
|
||||
fn[i] = '-';
|
||||
}
|
||||
}
|
||||
rf.includeUserDir(("files/" + fn + ".ini").c_str());
|
||||
return rf.getFirstOrCreateDefault();
|
||||
}
|
||||
|
||||
} // namespace app
|
61
src/app/pref/preferences.h
Normal file
61
src/app/pref/preferences.h
Normal file
@ -0,0 +1,61 @@
|
||||
/* Aseprite
|
||||
* Copyright (C) 2001-2014 David Capello
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef APP_PREF_PREFERENCES_H_INCLUDED
|
||||
#define APP_PREF_PREFERENCES_H_INCLUDED
|
||||
#pragma once
|
||||
|
||||
#include "app/pref/option.h"
|
||||
|
||||
#include "generated_pref_types.h"
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace app {
|
||||
namespace tools {
|
||||
class Tool;
|
||||
}
|
||||
|
||||
class Document;
|
||||
|
||||
typedef app::gen::ToolPref ToolPreferences;
|
||||
typedef app::gen::DocPref DocumentPreferences;
|
||||
|
||||
class Preferences : public app::gen::GlobalPref {
|
||||
public:
|
||||
Preferences();
|
||||
~Preferences();
|
||||
|
||||
void load();
|
||||
void save();
|
||||
|
||||
ToolPreferences& tool(tools::Tool* tool);
|
||||
DocumentPreferences& document(app::Document* document);
|
||||
|
||||
private:
|
||||
std::string docConfigFileName(app::Document* doc);
|
||||
|
||||
std::map<std::string, app::ToolPreferences*> m_tools;
|
||||
std::map<app::Document*, app::DocumentPreferences*> m_docs;
|
||||
};
|
||||
|
||||
} // namespace app
|
||||
|
||||
#endif
|
@ -28,6 +28,7 @@
|
||||
#include "app/ini_file.h"
|
||||
#include "app/load_widget.h"
|
||||
#include "app/modules/editors.h"
|
||||
#include "app/pref/preferences.h"
|
||||
#include "app/settings/settings.h"
|
||||
#include "app/ui/color_bar.h"
|
||||
#include "app/ui/context_bar.h"
|
||||
@ -218,7 +219,9 @@ void MainWindow::setTimelineVisibility(bool visible)
|
||||
|
||||
void MainWindow::popTimeline()
|
||||
{
|
||||
if (!get_config_bool("Options", "AutoShowTimeline", true))
|
||||
Preferences& preferences = App::instance()->preferences();
|
||||
|
||||
if (!preferences.general.autoshowTimeline())
|
||||
return;
|
||||
|
||||
if (!getTimelineVisibility())
|
||||
|
@ -55,6 +55,10 @@ public:
|
||||
m_ini.SetDoubleValue(section, name, value);
|
||||
}
|
||||
|
||||
void deleteValue(const char* section, const char* name) {
|
||||
m_ini.Delete(section, name, true);
|
||||
}
|
||||
|
||||
void load(const std::string& filename) {
|
||||
m_filename = filename;
|
||||
|
||||
@ -135,6 +139,11 @@ void CfgFile::setDoubleValue(const char* section, const char* name, double value
|
||||
m_impl->setDoubleValue(section, name, value);
|
||||
}
|
||||
|
||||
void CfgFile::deleteValue(const char* section, const char* name)
|
||||
{
|
||||
m_impl->deleteValue(section, name);
|
||||
}
|
||||
|
||||
void CfgFile::load(const std::string& filename)
|
||||
{
|
||||
m_impl->load(filename);
|
||||
|
@ -29,6 +29,8 @@ namespace cfg {
|
||||
void setIntValue(const char* section, const char* name, int value);
|
||||
void setDoubleValue(const char* section, const char* name, double value);
|
||||
|
||||
void deleteValue(const char* section, const char* name);
|
||||
|
||||
void load(const std::string& filename);
|
||||
void save();
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
add_executable(gen
|
||||
gen.cpp
|
||||
pref_types.cpp
|
||||
ui_class.cpp)
|
||||
|
||||
if(MSVC)
|
||||
|
32
src/gen/common.h
Normal file
32
src/gen/common.h
Normal file
@ -0,0 +1,32 @@
|
||||
// Aseprite Code Generator
|
||||
// Copyright (c) 2014 David Capello
|
||||
//
|
||||
// This file is released under the terms of the MIT license.
|
||||
// Read LICENSE.txt for more information.
|
||||
|
||||
#ifndef GEN_COMMON_H_INCLUDED
|
||||
#define GEN_COMMON_H_INCLUDED
|
||||
#pragma once
|
||||
|
||||
#include <cctype>
|
||||
#include <string>
|
||||
|
||||
inline std::string convert_xmlid_to_cppid(const std::string& xmlid, bool firstLetterUpperCase)
|
||||
{
|
||||
bool firstLetter = firstLetterUpperCase;
|
||||
std::string cppid;
|
||||
for (size_t i=0; i<xmlid.size(); ++i) {
|
||||
if (xmlid[i] == '_') {
|
||||
firstLetter = true;
|
||||
}
|
||||
else if (firstLetter) {
|
||||
firstLetter = false;
|
||||
cppid += std::toupper(xmlid[i]);
|
||||
}
|
||||
else
|
||||
cppid += xmlid[i];
|
||||
}
|
||||
return cppid;
|
||||
}
|
||||
|
||||
#endif
|
@ -8,6 +8,7 @@
|
||||
#include "base/path.h"
|
||||
#include "base/program_options.h"
|
||||
#include "base/string.h"
|
||||
#include "gen/pref_types.h"
|
||||
#include "gen/ui_class.h"
|
||||
#include "tinyxml.h"
|
||||
|
||||
@ -20,6 +21,8 @@ static void run(int argc, const char* argv[])
|
||||
PO po;
|
||||
PO::Option& inputOpt = po.add("input").requiresValue("<filename>");
|
||||
PO::Option& widgetId = po.add("widgetid").requiresValue("<filename>");
|
||||
PO::Option& prefH = po.add("pref-h");
|
||||
PO::Option& prefCpp = po.add("pref-cpp");
|
||||
po.parse(argc, argv);
|
||||
|
||||
// Try to load the XML file
|
||||
@ -34,8 +37,14 @@ static void run(int argc, const char* argv[])
|
||||
throw std::runtime_error("invalid input file");
|
||||
}
|
||||
|
||||
if (doc && po.enabled(widgetId))
|
||||
gen_ui_class(doc, inputFilename, po.value_of(widgetId));
|
||||
if (doc) {
|
||||
if (po.enabled(widgetId))
|
||||
gen_ui_class(doc, inputFilename, po.value_of(widgetId));
|
||||
else if (po.enabled(prefH))
|
||||
gen_pref_header(doc, inputFilename);
|
||||
else if (po.enabled(prefCpp))
|
||||
gen_pref_impl(doc, inputFilename);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, const char* argv[])
|
||||
|
288
src/gen/pref_types.cpp
Normal file
288
src/gen/pref_types.cpp
Normal file
@ -0,0 +1,288 @@
|
||||
// Aseprite Code Generator
|
||||
// Copyright (c) 2014 David Capello
|
||||
//
|
||||
// This file is released under the terms of the MIT license.
|
||||
// Read LICENSE.txt for more information.
|
||||
|
||||
#include "base/exception.h"
|
||||
#include "base/file_handle.h"
|
||||
#include "base/path.h"
|
||||
#include "base/split_string.h"
|
||||
#include "base/string.h"
|
||||
#include "gen/common.h"
|
||||
#include "gen/pref_types.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
typedef std::vector<TiXmlElement*> XmlElements;
|
||||
|
||||
static void print_pref_class_def(TiXmlElement* elem, const std::string& className, const char* section, int indentSpaces)
|
||||
{
|
||||
std::string indent(indentSpaces, ' ');
|
||||
std::cout
|
||||
<< "\n"
|
||||
<< indent << "class " << className << " {\n"
|
||||
<< indent << " std::string m_section;\n"
|
||||
<< indent << "public:\n"
|
||||
<< indent << " " << className << "(const std::string& section);\n";
|
||||
|
||||
std::cout
|
||||
<< indent << " void load();\n"
|
||||
<< indent << " void save();\n";
|
||||
|
||||
TiXmlElement* child = (elem->FirstChild() ? elem->FirstChild()->ToElement(): NULL);
|
||||
while (child) {
|
||||
if (child->Value()) {
|
||||
std::string name = child->Value();
|
||||
const char* childId = child->Attribute("id");
|
||||
|
||||
if (name == "option") {
|
||||
if (!child->Attribute("type")) throw std::runtime_error("missing 'type' attr in <option>");
|
||||
if (!childId) throw std::runtime_error("missing 'id' attr in <option>");
|
||||
std::string memberName = convert_xmlid_to_cppid(childId, false);
|
||||
std::cout
|
||||
<< indent << " Option<" << child->Attribute("type") << "> " << memberName << ";\n";
|
||||
}
|
||||
else if (name == "section") {
|
||||
if (!childId) throw std::runtime_error("missing 'id' attr in <section>");
|
||||
std::string childClassName = convert_xmlid_to_cppid(childId, true);
|
||||
std::string memberName = convert_xmlid_to_cppid(childId, false);
|
||||
print_pref_class_def(child, childClassName, childId, indentSpaces+2);
|
||||
std::cout
|
||||
<< indent << " " << childClassName << " " << memberName << ";\n";
|
||||
}
|
||||
}
|
||||
child = child->NextSiblingElement();
|
||||
}
|
||||
|
||||
std::cout
|
||||
<< indent << "};\n";
|
||||
}
|
||||
|
||||
static void print_pref_class_impl(TiXmlElement* elem, const std::string& prefix, const std::string& className, const char* section)
|
||||
{
|
||||
std::cout
|
||||
<< "\n"
|
||||
<< prefix << className << "::" << className << "(const std::string& section)\n";
|
||||
|
||||
if (section)
|
||||
std::cout << " : m_section((!section.empty() ? section + \".\": section) + \"" << section << "\")\n";
|
||||
else
|
||||
std::cout << " : m_section(section)\n";
|
||||
|
||||
TiXmlElement* child = (elem->FirstChild() ? elem->FirstChild()->ToElement(): NULL);
|
||||
while (child) {
|
||||
if (child->Value()) {
|
||||
std::string name = child->Value();
|
||||
const char* childId = child->Attribute("id");
|
||||
|
||||
if (name == "option") {
|
||||
if (!child->Attribute("type")) throw std::runtime_error("missing 'type' attr in <option>");
|
||||
if (!childId) throw std::runtime_error("missing 'id' attr in <option>");
|
||||
std::string memberName = convert_xmlid_to_cppid(childId, false);
|
||||
std::cout << " , "
|
||||
<< memberName << "(m_section.c_str(), \"" << childId << "\"";
|
||||
if (child->Attribute("default"))
|
||||
std::cout << ", " << child->Attribute("default");
|
||||
std::cout << ")\n";
|
||||
}
|
||||
else if (name == "section") {
|
||||
if (!childId) throw std::runtime_error("missing 'id' attr in <option>");
|
||||
std::string memberName = convert_xmlid_to_cppid(childId, false);
|
||||
std::cout << " , " << memberName << "(m_section)\n";
|
||||
}
|
||||
}
|
||||
child = child->NextSiblingElement();
|
||||
}
|
||||
|
||||
std::cout
|
||||
<< "{\n"
|
||||
<< "}\n";
|
||||
|
||||
std::cout
|
||||
<< "\n"
|
||||
<< "void " << prefix << className << "::load()\n"
|
||||
<< "{\n";
|
||||
|
||||
child = (elem->FirstChild() ? elem->FirstChild()->ToElement(): NULL);
|
||||
while (child) {
|
||||
if (child->Value()) {
|
||||
std::string name = child->Value();
|
||||
const char* childId = child->Attribute("id");
|
||||
|
||||
if (name == "option") {
|
||||
std::string memberName = convert_xmlid_to_cppid(childId, false);
|
||||
|
||||
const char* migrate = child->Attribute("migrate");
|
||||
if (migrate) {
|
||||
std::vector<std::string> parts;
|
||||
base::split_string(migrate, parts, ".");
|
||||
|
||||
std::cout << " load_option_with_migration(" << memberName
|
||||
<< ", \"" << parts[0]
|
||||
<< "\", \"" << parts[1] << "\");\n";
|
||||
}
|
||||
else
|
||||
std::cout << " load_option(" << memberName << ");\n";
|
||||
}
|
||||
else if (name == "section") {
|
||||
std::string memberName = convert_xmlid_to_cppid(childId, false);
|
||||
std::cout << " " << memberName << ".load();\n";
|
||||
}
|
||||
}
|
||||
child = child->NextSiblingElement();
|
||||
}
|
||||
|
||||
std::cout
|
||||
<< "}\n"
|
||||
<< "\n"
|
||||
<< "void " << prefix << className << "::save()\n"
|
||||
<< "{\n";
|
||||
|
||||
child = (elem->FirstChild() ? elem->FirstChild()->ToElement(): NULL);
|
||||
while (child) {
|
||||
if (child->Value()) {
|
||||
std::string name = child->Value();
|
||||
if (name == "option") {
|
||||
std::string memberName = convert_xmlid_to_cppid(child->Attribute("id"), false);
|
||||
std::cout << " save_option(" << memberName << ");\n";
|
||||
}
|
||||
else if (name == "section") {
|
||||
std::string memberName = convert_xmlid_to_cppid(child->Attribute("id"), false);
|
||||
std::cout << " " << memberName << ".save();\n";
|
||||
}
|
||||
}
|
||||
child = child->NextSiblingElement();
|
||||
}
|
||||
|
||||
std::cout
|
||||
<< "}\n";
|
||||
|
||||
child = (elem->FirstChild() ? elem->FirstChild()->ToElement(): NULL);
|
||||
while (child) {
|
||||
if (child->Value()) {
|
||||
std::string name = child->Value();
|
||||
if (name == "section") {
|
||||
std::string childClassName = convert_xmlid_to_cppid(child->Attribute("id"), true);
|
||||
print_pref_class_impl(child, className + "::", childClassName, child->Attribute("id"));
|
||||
}
|
||||
}
|
||||
child = child->NextSiblingElement();
|
||||
}
|
||||
}
|
||||
|
||||
void gen_pref_header(TiXmlDocument* doc, const std::string& inputFn)
|
||||
{
|
||||
std::cout
|
||||
<< "// Don't modify, generated file from " << inputFn << "\n"
|
||||
<< "\n";
|
||||
|
||||
std::cout
|
||||
<< "#ifndef GENERATED_PREF_TYPES_H_INCLUDED\n"
|
||||
<< "#define GENERATED_PREF_TYPES_H_INCLUDED\n"
|
||||
<< "#pragma once\n"
|
||||
<< "\n"
|
||||
<< "#include \"app/color.h\"\n"
|
||||
<< "#include \"app/pref/option.h\"\n"
|
||||
<< "#include \"doc/frame_number.h\"\n"
|
||||
<< "#include \"gfx/rect.h\"\n"
|
||||
<< "\n"
|
||||
<< "#include <string>\n"
|
||||
<< "\n"
|
||||
<< "namespace app {\n"
|
||||
<< "namespace gen {\n";
|
||||
|
||||
TiXmlHandle handle(doc);
|
||||
TiXmlElement* elem = handle
|
||||
.FirstChild("preferences")
|
||||
.FirstChild("types")
|
||||
.FirstChild("enum").ToElement();
|
||||
while (elem) {
|
||||
if (!elem->Attribute("id")) throw std::runtime_error("missing 'id' attr in <enum>");
|
||||
std::cout
|
||||
<< "\n"
|
||||
<< " enum class " << elem->Attribute("id") << " {\n";
|
||||
|
||||
TiXmlElement* child = elem->FirstChildElement("value");
|
||||
while (child) {
|
||||
if (!child->Attribute("id")) throw std::runtime_error("missing 'id' attr in <value>");
|
||||
if (!child->Attribute("value")) throw std::runtime_error("missing 'value' attr in <value>");
|
||||
|
||||
std::cout << " " << child->Attribute("id") << " = "
|
||||
<< child->Attribute("value") << ",\n";
|
||||
child = child->NextSiblingElement("value");
|
||||
}
|
||||
|
||||
std::cout
|
||||
<< " };\n";
|
||||
|
||||
elem = elem->NextSiblingElement("enum");
|
||||
}
|
||||
|
||||
elem = handle
|
||||
.FirstChild("preferences")
|
||||
.FirstChild("global").ToElement();
|
||||
if (elem)
|
||||
print_pref_class_def(elem, "GlobalPref", NULL, 2);
|
||||
|
||||
elem = handle
|
||||
.FirstChild("preferences")
|
||||
.FirstChild("tool").ToElement();
|
||||
if (elem)
|
||||
print_pref_class_def(elem, "ToolPref", NULL, 2);
|
||||
|
||||
elem = handle
|
||||
.FirstChild("preferences")
|
||||
.FirstChild("document").ToElement();
|
||||
if (elem)
|
||||
print_pref_class_def(elem, "DocPref", NULL, 2);
|
||||
|
||||
std::cout
|
||||
<< "\n"
|
||||
<< "} // namespace gen\n"
|
||||
<< "} // namespace app\n"
|
||||
<< "\n"
|
||||
<< "#endif\n";
|
||||
}
|
||||
|
||||
void gen_pref_impl(TiXmlDocument* doc, const std::string& inputFn)
|
||||
{
|
||||
std::cout
|
||||
<< "// Don't modify, generated file from " << inputFn << "\n"
|
||||
<< "\n"
|
||||
<< "#ifdef HAVE_CONFIG_H\n"
|
||||
<< "#include \"config.h\"\n"
|
||||
<< "#endif\n"
|
||||
<< "\n"
|
||||
<< "#include \"generated_pref_types.h\"\n"
|
||||
<< "\n"
|
||||
<< "#include \"app/pref/option_io.h\"\n"
|
||||
<< "\n"
|
||||
<< "namespace app {\n"
|
||||
<< "namespace gen {\n";
|
||||
|
||||
TiXmlHandle handle(doc);
|
||||
TiXmlElement* elem = handle
|
||||
.FirstChild("preferences")
|
||||
.FirstChild("global").ToElement();
|
||||
if (elem)
|
||||
print_pref_class_impl(elem, "", "GlobalPref", NULL);
|
||||
|
||||
elem = handle
|
||||
.FirstChild("preferences")
|
||||
.FirstChild("tool").ToElement();
|
||||
if (elem)
|
||||
print_pref_class_impl(elem, "", "ToolPref", NULL);
|
||||
|
||||
elem = handle
|
||||
.FirstChild("preferences")
|
||||
.FirstChild("document").ToElement();
|
||||
if (elem)
|
||||
print_pref_class_impl(elem, "", "DocPref", NULL);
|
||||
|
||||
std::cout
|
||||
<< "\n"
|
||||
<< "} // namespace gen\n"
|
||||
<< "} // namespace app\n";
|
||||
}
|
17
src/gen/pref_types.h
Normal file
17
src/gen/pref_types.h
Normal file
@ -0,0 +1,17 @@
|
||||
// Aseprite Code Generator
|
||||
// Copyright (c) 2014 David Capello
|
||||
//
|
||||
// This file is released under the terms of the MIT license.
|
||||
// Read LICENSE.txt for more information.
|
||||
|
||||
#ifndef GEN_PREF_CLASS_H_INCLUDED
|
||||
#define GEN_PREF_CLASS_H_INCLUDED
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include "tinyxml.h"
|
||||
|
||||
void gen_pref_header(TiXmlDocument* doc, const std::string& inputFn);
|
||||
void gen_pref_impl(TiXmlDocument* doc, const std::string& inputFn);
|
||||
|
||||
#endif
|
@ -7,34 +7,15 @@
|
||||
#include "base/exception.h"
|
||||
#include "base/file_handle.h"
|
||||
#include "base/path.h"
|
||||
#include "base/program_options.h"
|
||||
#include "base/string.h"
|
||||
#include "gen/common.h"
|
||||
#include "gen/ui_class.h"
|
||||
|
||||
#include <cctype>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
typedef base::ProgramOptions PO;
|
||||
typedef std::vector<TiXmlElement*> XmlElements;
|
||||
|
||||
static std::string convert_xmlid_to_cppid(const std::string& xmlid, bool firstLetterUpperCase)
|
||||
{
|
||||
bool firstLetter = firstLetterUpperCase;
|
||||
std::string cppid;
|
||||
for (size_t i=0; i<xmlid.size(); ++i) {
|
||||
if (xmlid[i] == '_') {
|
||||
firstLetter = true;
|
||||
}
|
||||
else if (firstLetter) {
|
||||
firstLetter = false;
|
||||
cppid += std::toupper(xmlid[i]);
|
||||
}
|
||||
else
|
||||
cppid += xmlid[i];
|
||||
}
|
||||
return cppid;
|
||||
}
|
||||
|
||||
static TiXmlElement* find_element_by_id(TiXmlElement* elem, const std::string& thisId)
|
||||
{
|
||||
const char* id = elem->Attribute("id");
|
||||
|
Loading…
x
Reference in New Issue
Block a user