mirror of
https://github.com/aseprite/aseprite.git
synced 2025-04-16 05:42:32 +00:00
lua: Add app.preferences object
This commit is contained in:
parent
ad1a0af752
commit
0264964c4e
@ -345,6 +345,7 @@
|
|||||||
<option id="filled_preview" type="bool" default="false" />
|
<option id="filled_preview" type="bool" default="false" />
|
||||||
<option id="ink" type="app::tools::InkType" default="app::tools::InkType::DEFAULT" />
|
<option id="ink" type="app::tools::InkType" default="app::tools::InkType::DEFAULT" />
|
||||||
<option id="freehand_algorithm" type="app::tools::FreehandAlgorithm" default="app::tools::FreehandAlgorithm::DEFAULT" />
|
<option id="freehand_algorithm" type="app::tools::FreehandAlgorithm" default="app::tools::FreehandAlgorithm::DEFAULT" />
|
||||||
|
<!-- Update app::Preferences::resetToolPreferences() function if you add new sections here -->
|
||||||
<section id="brush">
|
<section id="brush">
|
||||||
<option id="type" type="BrushType" default="BrushType::CIRCLE" />
|
<option id="type" type="BrushType" default="BrushType::CIRCLE" />
|
||||||
<option id="size" type="int" default="1" />
|
<option id="size" type="int" default="1" />
|
||||||
|
@ -170,6 +170,7 @@ if(ENABLE_SCRIPTING)
|
|||||||
script/palettes_class.cpp
|
script/palettes_class.cpp
|
||||||
script/pixel_color_object.cpp
|
script/pixel_color_object.cpp
|
||||||
script/point_class.cpp
|
script/point_class.cpp
|
||||||
|
script/preferences_object.cpp
|
||||||
script/range_class.cpp
|
script/range_class.cpp
|
||||||
script/rectangle_class.cpp
|
script/rectangle_class.cpp
|
||||||
script/security.cpp
|
script/security.cpp
|
||||||
@ -183,6 +184,7 @@ if(ENABLE_SCRIPTING)
|
|||||||
script/tag_class.cpp
|
script/tag_class.cpp
|
||||||
script/tags_class.cpp
|
script/tags_class.cpp
|
||||||
script/tool_class.cpp
|
script/tool_class.cpp
|
||||||
|
script/values.cpp
|
||||||
script/version_class.cpp
|
script/version_class.cpp
|
||||||
shell.cpp
|
shell.cpp
|
||||||
${scripting_files_ui})
|
${scripting_files_ui})
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
|
// Copyright (C) 2019 Igara Studio S.A.
|
||||||
// Copyright (C) 2001-2018 David Capello
|
// Copyright (C) 2001-2018 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
@ -11,6 +12,10 @@
|
|||||||
#include "obs/signal.h"
|
#include "obs/signal.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#ifdef ENABLE_SCRIPTING
|
||||||
|
#include "app/script/values.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace app {
|
namespace app {
|
||||||
|
|
||||||
class OptionBase;
|
class OptionBase;
|
||||||
@ -40,6 +45,12 @@ namespace app {
|
|||||||
virtual ~OptionBase() { }
|
virtual ~OptionBase() { }
|
||||||
const char* section() const { return m_section->name(); }
|
const char* section() const { return m_section->name(); }
|
||||||
const char* id() const { return m_id; }
|
const char* id() const { return m_id; }
|
||||||
|
|
||||||
|
#ifdef ENABLE_SCRIPTING
|
||||||
|
virtual void pushLua(lua_State* L) = 0;
|
||||||
|
virtual void fromLua(lua_State* L, int index) = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Section* m_section;
|
Section* m_section;
|
||||||
const char* m_id;
|
const char* m_id;
|
||||||
@ -104,6 +115,15 @@ namespace app {
|
|||||||
m_section->AfterChange();
|
m_section->AfterChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLE_SCRIPTING
|
||||||
|
void pushLua(lua_State* L) override {
|
||||||
|
script::push_value_to_lua<T>(L, m_value);
|
||||||
|
}
|
||||||
|
void fromLua(lua_State* L, int index) override {
|
||||||
|
setValue(script::get_value_from_lua<T>(L, index));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
obs::signal<void(const T&)> BeforeChange;
|
obs::signal<void(const T&)> BeforeChange;
|
||||||
obs::signal<void(const T&)> AfterChange;
|
obs::signal<void(const T&)> AfterChange;
|
||||||
|
|
||||||
|
@ -158,6 +158,12 @@ void Preferences::resetToolPreferences(tools::Tool* tool)
|
|||||||
|
|
||||||
std::string section = std::string("tool.") + tool->getId();
|
std::string section = std::string("tool.") + tool->getId();
|
||||||
del_config_section(section.c_str());
|
del_config_section(section.c_str());
|
||||||
|
|
||||||
|
// TODO improve this, if we add new sections in pref.xml we have to
|
||||||
|
// update this manually :(
|
||||||
|
del_config_section((section + ".brush").c_str());
|
||||||
|
del_config_section((section + ".spray").c_str());
|
||||||
|
del_config_section((section + ".floodfill").c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Preferences::removeDocument(Doc* doc)
|
void Preferences::removeDocument(Doc* doc)
|
||||||
|
@ -135,6 +135,7 @@ int unsupported(lua_State* L)
|
|||||||
void register_app_object(lua_State* L);
|
void register_app_object(lua_State* L);
|
||||||
void register_app_pixel_color_object(lua_State* L);
|
void register_app_pixel_color_object(lua_State* L);
|
||||||
void register_app_command_object(lua_State* L);
|
void register_app_command_object(lua_State* L);
|
||||||
|
void register_app_preferences_object(lua_State* L);
|
||||||
|
|
||||||
void register_brush_class(lua_State* L);
|
void register_brush_class(lua_State* L);
|
||||||
void register_cel_class(lua_State* L);
|
void register_cel_class(lua_State* L);
|
||||||
@ -231,6 +232,7 @@ Engine::Engine()
|
|||||||
register_app_object(L);
|
register_app_object(L);
|
||||||
register_app_pixel_color_object(L);
|
register_app_pixel_color_object(L);
|
||||||
register_app_command_object(L);
|
register_app_command_object(L);
|
||||||
|
register_app_preferences_object(L);
|
||||||
|
|
||||||
// Register constants
|
// Register constants
|
||||||
lua_newtable(L);
|
lua_newtable(L);
|
||||||
|
152
src/app/script/preferences_object.cpp
Normal file
152
src/app/script/preferences_object.cpp
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
// Aseprite
|
||||||
|
// Copyright (C) 2019 Igara Studio S.A.
|
||||||
|
// Copyright (C) 2017-2018 David Capello
|
||||||
|
//
|
||||||
|
// This program is distributed under the terms of
|
||||||
|
// the End-User License Agreement for Aseprite.
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "app/app.h"
|
||||||
|
#include "app/doc.h"
|
||||||
|
#include "app/pref/option.h"
|
||||||
|
#include "app/pref/preferences.h"
|
||||||
|
#include "app/script/docobj.h"
|
||||||
|
#include "app/script/engine.h"
|
||||||
|
#include "app/script/luacpp.h"
|
||||||
|
#include "doc/sprite.h"
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
namespace app {
|
||||||
|
namespace script {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
struct AppPreferences { };
|
||||||
|
|
||||||
|
int Section_index(lua_State* L)
|
||||||
|
{
|
||||||
|
Section* section = get_ptr<Section>(L, 1);
|
||||||
|
|
||||||
|
const char* id = lua_tostring(L, 2);
|
||||||
|
if (!id)
|
||||||
|
return luaL_error(L, "optionName in 'app.preferences.%s.optionName' must be a string",
|
||||||
|
section->name());
|
||||||
|
|
||||||
|
OptionBase* option = section->option(id);
|
||||||
|
if (!option) {
|
||||||
|
Section* subSection = section->section(
|
||||||
|
(section->name() && *section->name() ? std::string(section->name()) + "." + id:
|
||||||
|
std::string(id)).c_str());
|
||||||
|
if (subSection) {
|
||||||
|
push_ptr(L, subSection);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return luaL_error(L, "option '%s' in section '%s' doesn't exist", id, section->name());
|
||||||
|
}
|
||||||
|
|
||||||
|
option->pushLua(L);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Section_newindex(lua_State* L)
|
||||||
|
{
|
||||||
|
Section* section = get_ptr<Section>(L, 1);
|
||||||
|
|
||||||
|
const char* id = lua_tostring(L, 2);
|
||||||
|
if (!id)
|
||||||
|
return luaL_error(L, "optionName in 'app.preferences.%s.optionName' must be a string",
|
||||||
|
section->name());
|
||||||
|
|
||||||
|
OptionBase* option = section->option(id);
|
||||||
|
if (!option)
|
||||||
|
return luaL_error(L, "option '%s' in section '%s' doesn't exist",
|
||||||
|
id, section->name());
|
||||||
|
|
||||||
|
option->fromLua(L, 3);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ToolPref_function(lua_State* L)
|
||||||
|
{
|
||||||
|
auto tool = get_tool_from_arg(L, 1);
|
||||||
|
if (!tool)
|
||||||
|
return luaL_error(L, "tool preferences not found");
|
||||||
|
|
||||||
|
// If we don't have the UI available, we reset the tools
|
||||||
|
// preferences, so scripts that are executed in batch mode have a
|
||||||
|
// reproducible behavior.
|
||||||
|
if (!App::instance()->isGui())
|
||||||
|
Preferences::instance().resetToolPreferences(tool);
|
||||||
|
|
||||||
|
ToolPreferences& toolPref = Preferences::instance().tool(tool);
|
||||||
|
push_ptr(L, (Section*)&toolPref);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int DocPref_function(lua_State* L)
|
||||||
|
{
|
||||||
|
auto sprite = get_docobj<Sprite>(L, 1);
|
||||||
|
DocumentPreferences& docPref =
|
||||||
|
Preferences::instance().document(
|
||||||
|
static_cast<const Doc*>(sprite->document()));
|
||||||
|
push_ptr(L, (Section*)&docPref);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int AppPreferences_index(lua_State* L)
|
||||||
|
{
|
||||||
|
const char* id = lua_tostring(L, 2);
|
||||||
|
if (!id)
|
||||||
|
return luaL_error(L, "id in 'app.preferences.id' must be a string");
|
||||||
|
|
||||||
|
if (std::strcmp(id, "tool") == 0) {
|
||||||
|
lua_pushcfunction(L, ToolPref_function);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else if (std::strcmp(id, "document") == 0) {
|
||||||
|
lua_pushcfunction(L, DocPref_function);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Section* section = Preferences::instance().section(id);
|
||||||
|
if (!section)
|
||||||
|
return luaL_error(L, "section '%s' in preferences doesn't exist", id);
|
||||||
|
|
||||||
|
push_ptr(L, section);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const luaL_Reg Section_methods[] = {
|
||||||
|
{ "__index", Section_index },
|
||||||
|
{ "__newindex", Section_newindex },
|
||||||
|
{ nullptr, nullptr }
|
||||||
|
};
|
||||||
|
|
||||||
|
const luaL_Reg AppPreferences_methods[] = {
|
||||||
|
{ "__index", AppPreferences_index },
|
||||||
|
{ nullptr, nullptr }
|
||||||
|
};
|
||||||
|
|
||||||
|
} // anonymous namespace
|
||||||
|
|
||||||
|
DEF_MTNAME(Section);
|
||||||
|
DEF_MTNAME(AppPreferences);
|
||||||
|
|
||||||
|
void register_app_preferences_object(lua_State* L)
|
||||||
|
{
|
||||||
|
REG_CLASS(L, Section);
|
||||||
|
REG_CLASS(L, AppPreferences);
|
||||||
|
|
||||||
|
lua_getglobal(L, "app");
|
||||||
|
lua_pushstring(L, "preferences");
|
||||||
|
push_new<AppPreferences>(L);
|
||||||
|
lua_rawset(L, -3);
|
||||||
|
lua_pop(L, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace script
|
||||||
|
} // namespace app
|
173
src/app/script/values.cpp
Normal file
173
src/app/script/values.cpp
Normal file
@ -0,0 +1,173 @@
|
|||||||
|
// Aseprite
|
||||||
|
// Copyright (C) 2019 Igara Studio S.A.
|
||||||
|
//
|
||||||
|
// This program is distributed under the terms of
|
||||||
|
// the End-User License Agreement for Aseprite.
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "app/script/values.h"
|
||||||
|
|
||||||
|
#include "app/pref/preferences.h"
|
||||||
|
#include "app/script/engine.h"
|
||||||
|
#include "app/script/luacpp.h"
|
||||||
|
|
||||||
|
namespace app {
|
||||||
|
namespace script {
|
||||||
|
|
||||||
|
// TODO this is similar to app::Param<> specializations::fromLua() specializations
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// bool
|
||||||
|
|
||||||
|
template<>
|
||||||
|
void push_value_to_lua(lua_State* L, const bool& value) {
|
||||||
|
lua_pushboolean(L, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
bool get_value_from_lua(lua_State* L, int index) {
|
||||||
|
return lua_toboolean(L, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// int
|
||||||
|
|
||||||
|
template<>
|
||||||
|
void push_value_to_lua(lua_State* L, const int& value) {
|
||||||
|
lua_pushinteger(L, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
int get_value_from_lua(lua_State* L, int index) {
|
||||||
|
return lua_tointeger(L, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// double
|
||||||
|
|
||||||
|
template<>
|
||||||
|
void push_value_to_lua(lua_State* L, const double& value) {
|
||||||
|
lua_pushnumber(L, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
double get_value_from_lua(lua_State* L, int index) {
|
||||||
|
return lua_tonumber(L, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// std::string
|
||||||
|
|
||||||
|
template<>
|
||||||
|
void push_value_to_lua(lua_State* L, const std::string& value) {
|
||||||
|
lua_pushstring(L, value.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
std::string get_value_from_lua(lua_State* L, int index) {
|
||||||
|
if (const char* v = lua_tostring(L, index))
|
||||||
|
return std::string(v);
|
||||||
|
else
|
||||||
|
return std::string();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Color
|
||||||
|
|
||||||
|
template<>
|
||||||
|
void push_value_to_lua(lua_State* L, const app::Color& value) {
|
||||||
|
push_obj(L, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
app::Color get_value_from_lua(lua_State* L, int index) {
|
||||||
|
return convert_args_into_color(L, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Point
|
||||||
|
|
||||||
|
template<>
|
||||||
|
void push_value_to_lua(lua_State* L, const gfx::Point& value) {
|
||||||
|
push_obj(L, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
gfx::Point get_value_from_lua(lua_State* L, int index) {
|
||||||
|
return convert_args_into_point(L, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Size
|
||||||
|
|
||||||
|
template<>
|
||||||
|
void push_value_to_lua(lua_State* L, const gfx::Size& value) {
|
||||||
|
push_obj(L, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
gfx::Size get_value_from_lua(lua_State* L, int index) {
|
||||||
|
return convert_args_into_size(L, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Rect
|
||||||
|
|
||||||
|
template<>
|
||||||
|
void push_value_to_lua(lua_State* L, const gfx::Rect& value) {
|
||||||
|
push_obj(L, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
gfx::Rect get_value_from_lua(lua_State* L, int index) {
|
||||||
|
return convert_args_into_rect(L, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// enums
|
||||||
|
|
||||||
|
#define FOR_ENUM(T) \
|
||||||
|
template<> \
|
||||||
|
void push_value_to_lua(lua_State* L, const T& value) { \
|
||||||
|
lua_pushinteger(L, static_cast<int>(value)); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
template<> \
|
||||||
|
T get_value_from_lua(lua_State* L, int index) { \
|
||||||
|
return static_cast<T>(lua_tointeger(L, index)); \
|
||||||
|
}
|
||||||
|
|
||||||
|
FOR_ENUM(app::CelsTarget)
|
||||||
|
FOR_ENUM(app::ColorBar::ColorSelector)
|
||||||
|
FOR_ENUM(app::DocExporter::DataFormat)
|
||||||
|
FOR_ENUM(app::SpriteSheetType)
|
||||||
|
FOR_ENUM(app::gen::BgType)
|
||||||
|
FOR_ENUM(app::gen::BrushPreview)
|
||||||
|
FOR_ENUM(app::gen::BrushType)
|
||||||
|
FOR_ENUM(app::gen::ColorProfileBehavior)
|
||||||
|
FOR_ENUM(app::gen::EyedropperChannel)
|
||||||
|
FOR_ENUM(app::gen::EyedropperSample)
|
||||||
|
FOR_ENUM(app::gen::FillReferTo)
|
||||||
|
FOR_ENUM(app::gen::HueSaturationMode)
|
||||||
|
FOR_ENUM(app::gen::OnionskinType)
|
||||||
|
FOR_ENUM(app::gen::PaintingCursorType)
|
||||||
|
FOR_ENUM(app::gen::PivotPosition)
|
||||||
|
FOR_ENUM(app::gen::RightClickMode)
|
||||||
|
FOR_ENUM(app::gen::SelectionMode)
|
||||||
|
FOR_ENUM(app::gen::StopAtGrid)
|
||||||
|
FOR_ENUM(app::gen::SymmetryMode)
|
||||||
|
FOR_ENUM(app::gen::TimelinePosition)
|
||||||
|
FOR_ENUM(app::tools::FreehandAlgorithm)
|
||||||
|
FOR_ENUM(app::tools::InkType)
|
||||||
|
FOR_ENUM(app::tools::RotationAlgorithm)
|
||||||
|
FOR_ENUM(doc::AniDir)
|
||||||
|
FOR_ENUM(doc::BrushPattern)
|
||||||
|
FOR_ENUM(doc::ColorMode)
|
||||||
|
FOR_ENUM(filters::TiledMode)
|
||||||
|
FOR_ENUM(render::OnionskinPosition)
|
||||||
|
|
||||||
|
} // namespace script
|
||||||
|
} // namespace app
|
29
src/app/script/values.h
Normal file
29
src/app/script/values.h
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
// Aseprite
|
||||||
|
// Copyright (C) 2019 Igara Studio S.A.
|
||||||
|
//
|
||||||
|
// This program is distributed under the terms of
|
||||||
|
// the End-User License Agreement for Aseprite.
|
||||||
|
|
||||||
|
#ifndef APP_SCRIPT_VALUES_H_INCLUDED
|
||||||
|
#define APP_SCRIPT_VALUES_H_INCLUDED
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifdef ENABLE_SCRIPTING
|
||||||
|
|
||||||
|
extern "C" struct lua_State;
|
||||||
|
|
||||||
|
namespace app {
|
||||||
|
namespace script {
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
T get_value_from_lua(lua_State* L, int index);
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void push_value_to_lua(lua_State* L, const T& value);
|
||||||
|
|
||||||
|
} // namespace script
|
||||||
|
} // namespace app
|
||||||
|
|
||||||
|
#endif // ENABLE_SCRIPTING
|
||||||
|
|
||||||
|
#endif
|
Loading…
x
Reference in New Issue
Block a user