mirror of
https://github.com/aseprite/aseprite.git
synced 2025-03-14 13:21:34 +00:00
[lua] Add initial version Dialog:canvas() (aseprite/api#87)
Right now it just creates a plain widget, but now we can specify hexpand/vexpand arguments too so we can create a canvas with a fixed size or with dynamic size (e.g. to use the whole dialog client area). The onpaint event is not functional yet.
This commit is contained in:
parent
3c77928a6f
commit
6e13e59aff
@ -165,6 +165,7 @@ if(ENABLE_SCRIPTING)
|
||||
script/app_fs_object.cpp
|
||||
script/app_object.cpp
|
||||
script/brush_class.cpp
|
||||
script/canvas_widget.cpp
|
||||
script/cel_class.cpp
|
||||
script/cels_class.cpp
|
||||
script/color_class.cpp
|
||||
|
80
src/app/script/canvas_widget.cpp
Normal file
80
src/app/script/canvas_widget.cpp
Normal file
@ -0,0 +1,80 @@
|
||||
// Aseprite
|
||||
// Copyright (c) 2022 Igara Studio S.A.
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
// the End-User License Agreement for Aseprite.
|
||||
|
||||
#include "app/script/canvas_widget.h"
|
||||
|
||||
#include "app/ui/skin/skin_theme.h"
|
||||
#include "os/system.h"
|
||||
#include "ui/message.h"
|
||||
#include "ui/paint_event.h"
|
||||
#include "ui/resize_event.h"
|
||||
#include "ui/size_hint_event.h"
|
||||
|
||||
#ifdef ENABLE_UI
|
||||
|
||||
namespace app {
|
||||
namespace script {
|
||||
|
||||
// static
|
||||
ui::WidgetType Canvas::Type()
|
||||
{
|
||||
static ui::WidgetType type = ui::kGenericWidget;
|
||||
if (type == ui::kGenericWidget)
|
||||
type = ui::register_widget_type();
|
||||
return type;
|
||||
}
|
||||
|
||||
Canvas::Canvas() : ui::Widget(Type())
|
||||
{
|
||||
}
|
||||
|
||||
void Canvas::onInitTheme(ui::InitThemeEvent& ev)
|
||||
{
|
||||
Widget::onInitTheme(ev);
|
||||
|
||||
gfx::Color bg;
|
||||
if (auto theme = skin::SkinTheme::get(this))
|
||||
bg = theme->colors.windowFace();
|
||||
else
|
||||
bg = gfx::rgba(0, 0, 0);
|
||||
setBgColor(bg);
|
||||
}
|
||||
|
||||
void Canvas::onResize(ui::ResizeEvent& ev)
|
||||
{
|
||||
Widget::onResize(ev);
|
||||
if (os::instance() && !ev.bounds().isEmpty()) {
|
||||
const int w = ev.bounds().w;
|
||||
const int h = ev.bounds().h;
|
||||
|
||||
if (!m_surface ||
|
||||
m_surface->width() != w ||
|
||||
m_surface->height() != h) {
|
||||
m_surface = os::instance()->makeSurface(w, h);
|
||||
|
||||
os::Paint p;
|
||||
p.color(bgColor());
|
||||
m_surface->drawRect(m_surface->bounds(), p);
|
||||
}
|
||||
}
|
||||
else
|
||||
m_surface.reset();
|
||||
}
|
||||
|
||||
void Canvas::onPaint(ui::PaintEvent& ev)
|
||||
{
|
||||
Paint(ev);
|
||||
|
||||
auto g = ev.graphics();
|
||||
const gfx::Rect rc = clientBounds();
|
||||
if (m_surface)
|
||||
g->drawSurface(m_surface.get(), rc.x, rc.y);
|
||||
}
|
||||
|
||||
} // namespace script
|
||||
} // namespace app
|
||||
|
||||
#endif // ENABLE_UI
|
38
src/app/script/canvas_widget.h
Normal file
38
src/app/script/canvas_widget.h
Normal file
@ -0,0 +1,38 @@
|
||||
// Aseprite
|
||||
// Copyright (c) 2022 Igara Studio S.A.
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
// the End-User License Agreement for Aseprite.
|
||||
|
||||
#ifndef APP_SCRIPT_CANVAS_H_INCLUDED
|
||||
#define APP_SCRIPT_CANVAS_H_INCLUDED
|
||||
#pragma once
|
||||
|
||||
#include "os/surface.h"
|
||||
#include "ui/widget.h"
|
||||
|
||||
namespace app {
|
||||
namespace script {
|
||||
|
||||
// The canvas widget of a Dialog() created with Dialog:canvas{ ... }
|
||||
// This is a generic widget where all its events can be listened.
|
||||
class Canvas : public ui::Widget {
|
||||
public:
|
||||
static ui::WidgetType Type();
|
||||
|
||||
Canvas();
|
||||
|
||||
obs::signal<void(ui::PaintEvent&)> Paint;
|
||||
|
||||
private:
|
||||
void onInitTheme(ui::InitThemeEvent& ev) override;
|
||||
void onResize(ui::ResizeEvent& ev) override;
|
||||
void onPaint(ui::PaintEvent& ev) override;
|
||||
|
||||
os::SurfaceRef m_surface;
|
||||
};
|
||||
|
||||
} // namespace script
|
||||
} // namespace app
|
||||
|
||||
#endif
|
@ -13,6 +13,7 @@
|
||||
#include "app/color.h"
|
||||
#include "app/color_utils.h"
|
||||
#include "app/file_selector.h"
|
||||
#include "app/script/canvas_widget.h"
|
||||
#include "app/script/engine.h"
|
||||
#include "app/script/luacpp.h"
|
||||
#include "app/ui/color_button.h"
|
||||
@ -334,6 +335,9 @@ int Dialog_add_widget(lua_State* L, Widget* widget)
|
||||
const char* label = nullptr;
|
||||
std::string id;
|
||||
bool visible = true;
|
||||
bool hexpand = true;
|
||||
// Canvas is vertically expansive by default too
|
||||
bool vexpand = (widget->type() == Canvas::Type());
|
||||
|
||||
// This is to separate different kind of widgets without label in
|
||||
// different rows.
|
||||
@ -380,6 +384,15 @@ int Dialog_add_widget(lua_State* L, Widget* widget)
|
||||
widget->setVisible(visible);
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
|
||||
// Expand horizontally/vertically, it allows to indicate that a
|
||||
// specific widget is not expansive (e.g. a canvas with a fixed
|
||||
// size)
|
||||
type = lua_getfield(L, 2, "hexpand");
|
||||
type = lua_getfield(L, 2, "vexpand");
|
||||
if (type != LUA_TNIL) hexpand = lua_toboolean(L, -2);
|
||||
if (type != LUA_TNIL) vexpand = lua_toboolean(L, -1);
|
||||
lua_pop(L, 2);
|
||||
}
|
||||
|
||||
if (label || !dlg->hbox) {
|
||||
@ -398,11 +411,15 @@ int Dialog_add_widget(lua_State* L, Widget* widget)
|
||||
auto hbox = new ui::HBox;
|
||||
if (widget->type() == ui::kButtonWidget)
|
||||
hbox->enableFlags(ui::HOMOGENEOUS);
|
||||
dlg->grid.addChildInCell(hbox, 1, 1, ui::HORIZONTAL | ui::TOP);
|
||||
|
||||
dlg->grid.addChildInCell(
|
||||
hbox, 1, 1,
|
||||
ui::HORIZONTAL | (vexpand ? ui::VERTICAL: ui::TOP));
|
||||
|
||||
dlg->hbox = hbox;
|
||||
}
|
||||
|
||||
widget->setExpansive(true);
|
||||
widget->setExpansive(hexpand);
|
||||
dlg->hbox->addChild(widget);
|
||||
|
||||
lua_pushvalue(L, 1);
|
||||
@ -872,6 +889,43 @@ int Dialog_file(lua_State* L)
|
||||
return Dialog_add_widget(L, widget);
|
||||
}
|
||||
|
||||
int Dialog_canvas(lua_State* L)
|
||||
{
|
||||
auto widget = new Canvas;
|
||||
|
||||
if (lua_istable(L, 2)) {
|
||||
gfx::Size sz(0, 0);
|
||||
|
||||
int type = lua_getfield(L, 2, "width");
|
||||
if (type != LUA_TNIL) {
|
||||
sz.w = lua_tointegerx(L, -1, nullptr);
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
|
||||
type = lua_getfield(L, 2, "height");
|
||||
if (type != LUA_TNIL) {
|
||||
sz.h = lua_tointegerx(L, -1, nullptr);
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
|
||||
widget->setSizeHint(sz);
|
||||
|
||||
if (lua_istable(L, 2)) {
|
||||
int type = lua_getfield(L, 2, "onpaint");
|
||||
if (type == LUA_TFUNCTION) {
|
||||
Dialog_connect_signal(
|
||||
L, 1, widget->Paint,
|
||||
[](lua_State* L, ui::PaintEvent& ev) {
|
||||
// TODO
|
||||
});
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
}
|
||||
|
||||
return Dialog_add_widget(L, widget);
|
||||
}
|
||||
|
||||
int Dialog_modify(lua_State* L)
|
||||
{
|
||||
auto dlg = get_obj<Dialog>(L, 1);
|
||||
@ -1275,6 +1329,7 @@ const luaL_Reg Dialog_methods[] = {
|
||||
{ "color", Dialog_color },
|
||||
{ "shades", Dialog_shades },
|
||||
{ "file", Dialog_file },
|
||||
{ "canvas", Dialog_canvas },
|
||||
{ "modify", Dialog_modify },
|
||||
{ nullptr, nullptr }
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user