mirror of
https://github.com/aseprite/aseprite.git
synced 2025-02-23 18:39:55 +00:00
lua: Add Brush class and app.useTool{ brush } parameter
This commit is contained in:
parent
0bf5d1de30
commit
8a821c83fd
@ -150,6 +150,7 @@ if(ENABLE_SCRIPTING)
|
||||
commands/cmd_run_script.cpp
|
||||
script/app_command_object.cpp
|
||||
script/app_object.cpp
|
||||
script/brush_class.cpp
|
||||
script/cel_class.cpp
|
||||
script/cels_class.cpp
|
||||
script/color_class.cpp
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "app/tools/tool_loop.h"
|
||||
#include "app/tools/tool_loop_manager.h"
|
||||
#include "app/tx.h"
|
||||
#include "app/ui/context_bar.h"
|
||||
#include "app/ui/doc_view.h"
|
||||
#include "app/ui/editor/editor.h"
|
||||
#include "app/ui/editor/tool_loop_impl.h"
|
||||
@ -287,11 +288,25 @@ int App_useTool(lua_State* L)
|
||||
color = convert_args_into_color(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
// Default brush is the active brush in the context bar
|
||||
BrushRef brush(nullptr);
|
||||
#ifdef ENABLE_UI
|
||||
if (App::instance()->isGui() &&
|
||||
App::instance()->contextBar())
|
||||
brush = App::instance()->contextBar()->activeBrush(tool, ink);
|
||||
#endif
|
||||
type = lua_getfield(L, 1, "brush");
|
||||
if (type != LUA_TNIL)
|
||||
brush = get_brush_from_arg(L, -1);
|
||||
lua_pop(L, 1);
|
||||
if (!brush)
|
||||
brush.reset(new Brush(BrushType::kCircleBrushType, 1, 0));
|
||||
|
||||
// Do the tool loop
|
||||
type = lua_getfield(L, 1, "points");
|
||||
if (type == LUA_TTABLE) {
|
||||
std::unique_ptr<tools::ToolLoop> loop(
|
||||
create_tool_loop_for_script(ctx, site, tool, ink, color));
|
||||
create_tool_loop_for_script(ctx, site, tool, ink, color, brush));
|
||||
if (!loop)
|
||||
return luaL_error(L, "cannot draw in the active site");
|
||||
|
||||
@ -478,6 +493,27 @@ int App_get_apiVersion(lua_State* L)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int App_get_activeTool(lua_State* L)
|
||||
{
|
||||
tools::Tool* tool = App::instance()->activeToolManager()->activeTool();
|
||||
push_tool(L, tool);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int App_get_activeBrush(lua_State* L)
|
||||
{
|
||||
#if ENABLE_UI
|
||||
App* app = App::instance();
|
||||
if (app->isGui()) {
|
||||
doc::BrushRef brush = app->contextBar()->activeBrush();
|
||||
push_brush(L, brush);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
push_brush(L, doc::BrushRef(new doc::Brush()));
|
||||
return 1;
|
||||
}
|
||||
|
||||
int App_set_activeSprite(lua_State* L)
|
||||
{
|
||||
auto sprite = get_docobj<Sprite>(L, 2);
|
||||
@ -524,13 +560,6 @@ int App_set_activeImage(lua_State* L)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int App_get_activeTool(lua_State* L)
|
||||
{
|
||||
tools::Tool* tool = App::instance()->activeToolManager()->activeTool();
|
||||
push_tool(L, tool);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int App_set_activeTool(lua_State* L)
|
||||
{
|
||||
if (auto tool = get_tool_from_arg(L, 2))
|
||||
@ -538,6 +567,18 @@ int App_set_activeTool(lua_State* L)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int App_set_activeBrush(lua_State* L)
|
||||
{
|
||||
#if ENABLE_UI
|
||||
if (auto brush = get_brush_from_arg(L, 2)) {
|
||||
App* app = App::instance();
|
||||
if (app->isGui())
|
||||
app->contextBar()->setActiveBrush(brush);
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
const luaL_Reg App_methods[] = {
|
||||
{ "open", App_open },
|
||||
{ "exit", App_exit },
|
||||
@ -558,6 +599,7 @@ const Property App_properties[] = {
|
||||
{ "activeImage", App_get_activeImage, App_set_activeImage },
|
||||
{ "activeTag", App_get_activeTag, nullptr },
|
||||
{ "activeTool", App_get_activeTool, App_set_activeTool },
|
||||
{ "activeBrush", App_get_activeBrush, App_set_activeBrush },
|
||||
{ "sprites", App_get_sprites, nullptr },
|
||||
{ "fgColor", App_get_fgColor, App_set_fgColor },
|
||||
{ "bgColor", App_get_bgColor, App_set_bgColor },
|
||||
|
238
src/app/script/brush_class.cpp
Normal file
238
src/app/script/brush_class.cpp
Normal file
@ -0,0 +1,238 @@
|
||||
// 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/engine.h"
|
||||
#include "app/script/luacpp.h"
|
||||
#include "doc/brush.h"
|
||||
#include "doc/image.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace app {
|
||||
namespace script {
|
||||
|
||||
namespace {
|
||||
|
||||
using namespace doc;
|
||||
|
||||
struct BrushObj {
|
||||
BrushRef brush;
|
||||
BrushObj(const BrushRef& brush)
|
||||
: brush(brush) {
|
||||
}
|
||||
};
|
||||
|
||||
BrushRef Brush_new(lua_State* L, int index)
|
||||
{
|
||||
BrushRef brush;
|
||||
if (auto brush2 = may_get_obj<BrushObj>(L, index)) {
|
||||
ASSERT(brush2->brush);
|
||||
if (brush2->brush)
|
||||
brush.reset(new Brush(*brush2->brush));
|
||||
}
|
||||
else if (auto image = may_get_image_from_arg(L, index)) {
|
||||
if (image) {
|
||||
brush.reset(new Brush(kImageBrushType, 1, 0));
|
||||
brush->setImage(image, nullptr);
|
||||
brush->setPattern(BrushPattern::DEFAULT_FOR_SCRIPTS);
|
||||
}
|
||||
}
|
||||
else if (lua_istable(L, index)) {
|
||||
Image* image = nullptr;
|
||||
if (lua_getfield(L, index, "image") != LUA_TNIL) {
|
||||
image = may_get_image_from_arg(L, -1);
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
|
||||
BrushType type = (image ? BrushType::kImageBrushType:
|
||||
BrushType::kCircleBrushType);
|
||||
if (lua_getfield(L, index, "type") != LUA_TNIL)
|
||||
type = (BrushType)lua_tointeger(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
int size = 1;
|
||||
if (lua_getfield(L, index, "size") != LUA_TNIL) {
|
||||
size = lua_tointeger(L, -1);
|
||||
size = std::max(1, size);
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
|
||||
int angle = 0;
|
||||
if (lua_getfield(L, index, "angle") != LUA_TNIL)
|
||||
angle = lua_tointeger(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
brush.reset(new Brush(type, size, angle));
|
||||
if (image)
|
||||
brush->setImage(image, nullptr);
|
||||
|
||||
if (lua_getfield(L, index, "center") != LUA_TNIL) {
|
||||
gfx::Point center = convert_args_into_point(L, -1);
|
||||
brush->setCenter(center);
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
|
||||
if (lua_getfield(L, index, "pattern") != LUA_TNIL) {
|
||||
BrushPattern pattern = (BrushPattern)lua_tointeger(L, -1);
|
||||
brush->setPattern(pattern);
|
||||
}
|
||||
else {
|
||||
brush->setPattern(BrushPattern::DEFAULT_FOR_SCRIPTS);
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
|
||||
if (lua_getfield(L, index, "patternOrigin") != LUA_TNIL) {
|
||||
gfx::Point patternOrigin = convert_args_into_point(L, -1);
|
||||
brush->setPatternOrigin(patternOrigin);
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
else {
|
||||
int size = lua_tointeger(L, index);
|
||||
size = std::max(1, size);
|
||||
brush.reset(new Brush(BrushType::kCircleBrushType, size, 0));
|
||||
brush->setPattern(BrushPattern::DEFAULT_FOR_SCRIPTS);
|
||||
}
|
||||
return brush;
|
||||
}
|
||||
|
||||
int Brush_new(lua_State* L)
|
||||
{
|
||||
BrushRef brush = Brush_new(L, 1);
|
||||
if (brush)
|
||||
push_new<BrushObj>(L, brush);
|
||||
else
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int Brush_gc(lua_State* L)
|
||||
{
|
||||
get_obj<BrushObj>(L, 1)->~BrushObj();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Brush_setFgColor(lua_State* L)
|
||||
{
|
||||
auto obj = get_obj<BrushObj>(L, 1);
|
||||
if (obj->brush) {
|
||||
const doc::color_t color = convert_args_into_pixel_color(L, 2);
|
||||
obj->brush->setImageColor(Brush::ImageColor::MainColor, color);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Brush_setBgColor(lua_State* L)
|
||||
{
|
||||
auto obj = get_obj<BrushObj>(L, 1);
|
||||
if (obj->brush) {
|
||||
const doc::color_t color = convert_args_into_pixel_color(L, 2);
|
||||
obj->brush->setImageColor(Brush::ImageColor::BackgroundColor, color);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Brush_get_type(lua_State* L)
|
||||
{
|
||||
const auto obj = get_obj<BrushObj>(L, 1);
|
||||
lua_pushinteger(L, (int)obj->brush->type());
|
||||
return 1;
|
||||
}
|
||||
|
||||
int Brush_get_size(lua_State* L)
|
||||
{
|
||||
const auto obj = get_obj<BrushObj>(L, 1);
|
||||
lua_pushinteger(L, obj->brush->size());
|
||||
return 1;
|
||||
}
|
||||
|
||||
int Brush_get_angle(lua_State* L)
|
||||
{
|
||||
const auto obj = get_obj<BrushObj>(L, 1);
|
||||
lua_pushinteger(L, obj->brush->angle());
|
||||
return 1;
|
||||
}
|
||||
|
||||
int Brush_get_image(lua_State* L)
|
||||
{
|
||||
const auto obj = get_obj<BrushObj>(L, 1);
|
||||
if (obj->brush->type() == BrushType::kImageBrushType)
|
||||
push_image(L, Image::createCopy(obj->brush->image()));
|
||||
else
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int Brush_get_center(lua_State* L)
|
||||
{
|
||||
const auto obj = get_obj<BrushObj>(L, 1);
|
||||
push_obj(L, obj->brush->center());
|
||||
return 1;
|
||||
}
|
||||
|
||||
int Brush_get_pattern(lua_State* L)
|
||||
{
|
||||
const auto obj = get_obj<BrushObj>(L, 1);
|
||||
lua_pushinteger(L, (int)obj->brush->pattern());
|
||||
return 1;
|
||||
}
|
||||
|
||||
int Brush_get_patternOrigin(lua_State* L)
|
||||
{
|
||||
const auto obj = get_obj<BrushObj>(L, 1);
|
||||
push_obj(L, obj->brush->patternOrigin());
|
||||
return 1;
|
||||
}
|
||||
|
||||
const luaL_Reg Brush_methods[] = {
|
||||
{ "__gc", Brush_gc },
|
||||
{ "setFgColor", Brush_setFgColor },
|
||||
{ "setBgColor", Brush_setBgColor },
|
||||
{ nullptr, nullptr }
|
||||
};
|
||||
|
||||
const Property Brush_properties[] = {
|
||||
{ "type", Brush_get_type, nullptr },
|
||||
{ "size", Brush_get_size, nullptr },
|
||||
{ "angle", Brush_get_angle, nullptr },
|
||||
{ "image", Brush_get_image, nullptr },
|
||||
{ "center", Brush_get_center, nullptr },
|
||||
{ "pattern", Brush_get_pattern, nullptr },
|
||||
{ "patternOrigin", Brush_get_patternOrigin, nullptr },
|
||||
{ nullptr, nullptr, nullptr }
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
DEF_MTNAME(BrushObj);
|
||||
|
||||
void register_brush_class(lua_State* L)
|
||||
{
|
||||
using Brush = BrushObj;
|
||||
REG_CLASS(L, Brush);
|
||||
REG_CLASS_NEW(L, Brush);
|
||||
REG_CLASS_PROPERTIES(L, Brush);
|
||||
}
|
||||
|
||||
void push_brush(lua_State* L, const BrushRef& brush)
|
||||
{
|
||||
push_new<BrushObj>(L, brush);
|
||||
}
|
||||
|
||||
BrushRef get_brush_from_arg(lua_State* L, int index)
|
||||
{
|
||||
if (auto obj = may_get_obj<BrushObj>(L, index))
|
||||
return obj->brush;
|
||||
else
|
||||
return Brush_new(L, index);
|
||||
}
|
||||
|
||||
} // namespace script
|
||||
} // namespace app
|
@ -1,4 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2019 Igara Studio S.A.
|
||||
// Copyright (C) 2018 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
@ -137,7 +138,7 @@ app::Color Color_new(lua_State* L, int index)
|
||||
}
|
||||
// raw color into app color
|
||||
else if (!lua_isnone(L, index)) {
|
||||
if (lua_isinteger(L, index) && lua_isnone(L, index+1)) {
|
||||
if (lua_isinteger(L, index) && (index < 0 || lua_isnone(L, index+1))) {
|
||||
doc::color_t docColor = lua_tointeger(L, index);
|
||||
switch (app_get_current_pixel_format()) {
|
||||
case IMAGE_RGB:
|
||||
@ -155,7 +156,7 @@ app::Color Color_new(lua_State* L, int index)
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
else if (index >= 0) {
|
||||
color = app::Color::fromRgb(lua_tointeger(L, index),
|
||||
lua_tointeger(L, index+1),
|
||||
lua_tointeger(L, index+2),
|
||||
|
@ -136,6 +136,7 @@ void register_app_object(lua_State* L);
|
||||
void register_app_pixel_color_object(lua_State* L);
|
||||
void register_app_command_object(lua_State* L);
|
||||
|
||||
void register_brush_class(lua_State* L);
|
||||
void register_cel_class(lua_State* L);
|
||||
void register_cels_class(lua_State* L);
|
||||
void register_color_class(lua_State* L);
|
||||
@ -298,7 +299,25 @@ Engine::Engine()
|
||||
setfield_integer(L, "JSON_ARRAY", DocExporter::JsonArrayDataFormat);
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_newtable(L);
|
||||
lua_pushvalue(L, -1);
|
||||
lua_setglobal(L, "BrushType");
|
||||
setfield_integer(L, "CIRCLE", doc::kCircleBrushType);
|
||||
setfield_integer(L, "SQUARE", doc::kSquareBrushType);
|
||||
setfield_integer(L, "LINE", doc::kLineBrushType);
|
||||
setfield_integer(L, "IMAGE", doc::kImageBrushType);
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_newtable(L);
|
||||
lua_pushvalue(L, -1);
|
||||
lua_setglobal(L, "BrushPattern");
|
||||
setfield_integer(L, "ORIGIN", doc::BrushPattern::ALIGNED_TO_SRC);
|
||||
setfield_integer(L, "TARGET", doc::BrushPattern::ALIGNED_TO_DST);
|
||||
setfield_integer(L, "NONE", doc::BrushPattern::PAINT_BRUSH);
|
||||
lua_pop(L, 1);
|
||||
|
||||
// Register classes/prototypes
|
||||
register_brush_class(L);
|
||||
register_cel_class(L);
|
||||
register_cels_class(L);
|
||||
register_color_class(L);
|
||||
|
@ -15,6 +15,7 @@
|
||||
|
||||
#include "app/color.h"
|
||||
#include "app/commands/params.h"
|
||||
#include "doc/brush.h"
|
||||
#include "doc/frame.h"
|
||||
#include "doc/object_ids.h"
|
||||
#include "gfx/fwd.h"
|
||||
@ -108,6 +109,7 @@ namespace app {
|
||||
};
|
||||
|
||||
int push_image_iterator_function(lua_State* L, const doc::Image* image, int extraArgIndex);
|
||||
void push_brush(lua_State* L, const doc::BrushRef& brush);
|
||||
void push_cel_image(lua_State* L, doc::Cel* cel);
|
||||
void push_cels(lua_State* L, const doc::ObjectIds& cels);
|
||||
void push_cels(lua_State* L, doc::Layer* layer);
|
||||
@ -143,6 +145,7 @@ namespace app {
|
||||
doc::frame_t get_frame_number_from_arg(lua_State* L, int index);
|
||||
const doc::Mask* get_mask_from_arg(lua_State* L, int index);
|
||||
tools::Tool* get_tool_from_arg(lua_State* L, int index);
|
||||
doc::BrushRef get_brush_from_arg(lua_State* L, int index);
|
||||
|
||||
// Used by App.open(), Sprite{ fromFile }, and Image{ fromFile }
|
||||
enum class LoadSpriteFromFileParam { FullAniAsSprite,
|
||||
|
@ -42,7 +42,6 @@
|
||||
#include "app/ui/status_bar.h"
|
||||
#include "app/ui_context.h"
|
||||
#include "app/util/expand_cel_canvas.h"
|
||||
#include "doc/brush.h"
|
||||
#include "doc/cel.h"
|
||||
#include "doc/image.h"
|
||||
#include "doc/layer.h"
|
||||
@ -689,7 +688,8 @@ tools::ToolLoop* create_tool_loop_for_script(
|
||||
const Site& site,
|
||||
tools::Tool* tool,
|
||||
tools::Ink* ink,
|
||||
const app::Color& color)
|
||||
const app::Color& color,
|
||||
const doc::BrushRef& brush)
|
||||
{
|
||||
ASSERT(tool);
|
||||
ASSERT(ink);
|
||||
@ -699,13 +699,6 @@ tools::ToolLoop* create_tool_loop_for_script(
|
||||
try {
|
||||
const tools::ToolLoop::Button toolLoopButton = tools::ToolLoop::Left;
|
||||
tools::Controller* controller = tool->getController(toolLoopButton);
|
||||
BrushRef brush(nullptr);
|
||||
#ifdef ENABLE_UI
|
||||
if (App::instance()->contextBar())
|
||||
brush = App::instance()->contextBar()->activeBrush(tool, ink);
|
||||
#endif
|
||||
if (!brush)
|
||||
brush = BrushRef(new Brush(BrushType::kCircleBrushType, 1, 0));
|
||||
|
||||
return new ToolLoopImpl(
|
||||
nullptr, site, context,
|
||||
|
@ -10,6 +10,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "app/tools/pointer.h"
|
||||
#include "doc/brush.h"
|
||||
#include "doc/image_ref.h"
|
||||
#include "gfx/fwd.h"
|
||||
|
||||
@ -40,7 +41,8 @@ namespace app {
|
||||
const Site& site,
|
||||
tools::Tool* tool,
|
||||
tools::Ink* ink,
|
||||
const app::Color& color);
|
||||
const app::Color& color,
|
||||
const doc::BrushRef& brush);
|
||||
|
||||
tools::ToolLoop* create_tool_loop_preview(
|
||||
Editor* editor,
|
||||
|
@ -1,5 +1,6 @@
|
||||
// Aseprite Document Library
|
||||
// Copyright (c) 2001-2016 David Capello
|
||||
// Copyright (C) 2019 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2016 David Capello
|
||||
//
|
||||
// This file is released under the terms of the MIT license.
|
||||
// Read LICENSE.txt for more information.
|
||||
@ -29,7 +30,7 @@ Brush::Brush()
|
||||
m_type = kCircleBrushType;
|
||||
m_size = 1;
|
||||
m_angle = 0;
|
||||
m_pattern = BrushPattern::DEFAULT;
|
||||
m_pattern = BrushPattern::DEFAULT_FOR_UI;
|
||||
m_gen = 0;
|
||||
|
||||
regenerate();
|
||||
@ -40,7 +41,7 @@ Brush::Brush(BrushType type, int size, int angle)
|
||||
m_type = type;
|
||||
m_size = size;
|
||||
m_angle = angle;
|
||||
m_pattern = BrushPattern::DEFAULT;
|
||||
m_pattern = BrushPattern::DEFAULT_FOR_UI;
|
||||
m_gen = 0;
|
||||
|
||||
regenerate();
|
||||
@ -279,6 +280,14 @@ void Brush::setImageColor(ImageColor imageColor, color_t color)
|
||||
}
|
||||
}
|
||||
|
||||
void Brush::setCenter(const gfx::Point& center)
|
||||
{
|
||||
m_center = center;
|
||||
m_bounds = gfx::Rect(-m_center,
|
||||
gfx::Size(m_image->width(),
|
||||
m_image->height()));
|
||||
}
|
||||
|
||||
// Cleans the brush's data (image and region).
|
||||
void Brush::clean()
|
||||
{
|
||||
|
@ -1,5 +1,6 @@
|
||||
// Aseprite Document Library
|
||||
// Copyright (c) 2001-2018 David Capello
|
||||
// Copyright (C) 2019 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2018 David Capello
|
||||
//
|
||||
// This file is released under the terms of the MIT license.
|
||||
// Read LICENSE.txt for more information.
|
||||
@ -57,6 +58,7 @@ namespace doc {
|
||||
void setPatternOrigin(const gfx::Point& patternOrigin) {
|
||||
m_patternOrigin = patternOrigin;
|
||||
}
|
||||
void setCenter(const gfx::Point& center);
|
||||
|
||||
private:
|
||||
void clean();
|
||||
|
@ -1,5 +1,6 @@
|
||||
// Aseprite Document Library
|
||||
// Copyright (c) 2001-2015 David Capello
|
||||
// Copyright (C) 2019 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2015 David Capello
|
||||
//
|
||||
// This file is released under the terms of the MIT license.
|
||||
// Read LICENSE.txt for more information.
|
||||
@ -11,10 +12,13 @@
|
||||
namespace doc {
|
||||
|
||||
enum class BrushPattern {
|
||||
DEFAULT = 0,
|
||||
ALIGNED_TO_SRC = 0,
|
||||
ALIGNED_TO_DST = 1,
|
||||
PAINT_BRUSH = 2,
|
||||
|
||||
DEFAULT = ALIGNED_TO_SRC, // Default for preferences
|
||||
DEFAULT_FOR_UI = ALIGNED_TO_SRC,
|
||||
DEFAULT_FOR_SCRIPTS = PAINT_BRUSH,
|
||||
};
|
||||
|
||||
} // namespace doc
|
||||
|
Loading…
x
Reference in New Issue
Block a user