Skip to content

Commit 17d1005

Browse files
authored
Merge pull request #100 from yuchanns/feat/node-remove
feat(yoga): add node_remove
2 parents 59f5d0d + 70e6047 commit 17d1005

7 files changed

Lines changed: 172 additions & 0 deletions

File tree

docs/app.lua

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,30 @@
1414
---@class soluna.app
1515
local app = {}
1616

17+
---@alias soluna.app.MouseCursor
18+
---| '"default"'
19+
---| '"arrow"'
20+
---| '"ibeam"'
21+
---| '"crosshair"'
22+
---| '"pointing_hand"'
23+
---| '"resize_ew"'
24+
---| '"resize_ns"'
25+
---| '"resize_nwse"'
26+
---| '"resize_nesw"'
27+
---| '"resize_all"'
28+
---| '"not_allowed"'
29+
1730
---请求应用优雅退出
1831
---Requests graceful application quit.
1932
function app.quit()
2033
end
2134

35+
---设置系统鼠标光标样式;nil 恢复默认样式。
36+
---Sets the system mouse cursor; nil restores the default cursor.
37+
---@param cursor? soluna.app.MouseCursor
38+
function app.set_mouse_cursor(cursor)
39+
end
40+
2241
---设置输入法字体
2342
---Sets the IME font face and pixel size.
2443
---@overload fun()

docs/soluna.lua

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,8 @@ end
117117
---@field version_api integer API 版本号 / API version number
118118
local soluna = {}
119119

120+
---@alias soluna.MouseCursor soluna.app.MouseCursor
121+
120122
---返回 `.game` 设置表
121123
---Returns the `.game` settings table.
122124
---@return table settings 游戏设置 / Game settings
@@ -129,6 +131,12 @@ end
129131
function soluna.set_window_title(text)
130132
end
131133

134+
---设置系统鼠标光标样式;nil 恢复默认样式。
135+
---Sets the system mouse cursor; nil restores the default cursor.
136+
---@param cursor? soluna.MouseCursor
137+
function soluna.set_mouse_cursor(cursor)
138+
end
139+
132140
---设置窗口图标
133141
---Sets one icon image or an icon image list.
134142
---@param data soluna.IconImage|soluna.IconImage[] 图标数据 / Icon data

src/entry.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,37 @@ lset_window_title(lua_State *L) {
226226
return 0;
227227
}
228228

229+
static const char *const MOUSE_CURSOR_NAMES[] = {
230+
"default",
231+
"arrow",
232+
"ibeam",
233+
"crosshair",
234+
"pointing_hand",
235+
"resize_ew",
236+
"resize_ns",
237+
"resize_nwse",
238+
"resize_nesw",
239+
"resize_all",
240+
"not_allowed",
241+
NULL,
242+
};
243+
244+
static sapp_mouse_cursor
245+
check_mouse_cursor(lua_State *L, int index) {
246+
if (lua_isnoneornil(L, index)) {
247+
return SAPP_MOUSECURSOR_DEFAULT;
248+
}
249+
return (sapp_mouse_cursor)luaL_checkoption(L, index, NULL, MOUSE_CURSOR_NAMES);
250+
}
251+
252+
static int
253+
lset_mouse_cursor(lua_State *L) {
254+
if (CTX == NULL)
255+
return 0;
256+
sapp_set_mouse_cursor(check_mouse_cursor(L, 1));
257+
return 0;
258+
}
259+
229260
struct icon_pixels {
230261
uint8_t *ptr;
231262
};
@@ -561,6 +592,7 @@ luaopen_soluna_app(lua_State *L) {
561592
{ "sendmessage", lmessage_send },
562593
{ "unpackevent", levent_unpack },
563594
{ "set_window_title", lset_window_title },
595+
{ "set_mouse_cursor", lset_mouse_cursor },
564596
{ "set_icon", lset_icon },
565597
{ "set_ime_rect", lset_ime_rect },
566598
{ "set_ime_font", lset_ime_font },

src/lualib/main.lua

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,10 @@ local function start(config)
106106
soluna_app.set_window_title(text)
107107
end
108108

109+
function appmsg.set_cursor(cursor)
110+
soluna_app.set_mouse_cursor(cursor)
111+
end
112+
109113
function appmsg.set_icon(data)
110114
soluna_app.set_icon(data)
111115
end

src/lualib/soluna.lua

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ function soluna.set_window_title(text)
3737
mqueue.send(app.mqueue(), ltask.pack("set_title", text))
3838
end
3939

40+
function soluna.set_mouse_cursor(cursor)
41+
mqueue.send(app.mqueue(), ltask.pack("set_cursor", cursor))
42+
end
43+
4044
function soluna.set_icon(data)
4145
mqueue.send(app.mqueue(), ltask.pack("set_icon", data))
4246
end

src/luayoga.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,14 @@ lnodeFree(lua_State *L) {
5959
return 0;
6060
}
6161

62+
static int
63+
lnodeRemove(lua_State *L) {
64+
YGNodeRef parent = lua_touserdata(L, 1);
65+
YGNodeRef node = lua_touserdata(L, 2);
66+
YGNodeRemoveChild(parent, node);
67+
return 0;
68+
}
69+
6270
static int
6371
lnodeCalc(lua_State *L) {
6472
YGNodeRef node = lua_touserdata(L, 1);
@@ -597,6 +605,7 @@ luaopen_layout_yoga(lua_State *L) {
597605
luaL_Reg l[] = {
598606
{ "node_new", lnodeNew },
599607
{ "node_free", lnodeFree },
608+
{ "node_remove", lnodeRemove },
600609
{ "node_calc", lnodeCalc },
601610
{ "node_get", lnodeGet },
602611
{ "node_set", NULL },

test/mouse_cursor.lua

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
local app = require "soluna.app"
2+
local soluna = require "soluna"
3+
local quad = require "soluna.material.quad"
4+
5+
local args = ...
6+
local batch = args.batch
7+
8+
local KEY_ESCAPE <const> = 256
9+
local KEYSTATE_PRESS <const> = 1
10+
local TILE_W <const> = 132
11+
local TILE_H <const> = 76
12+
local GAP <const> = 18
13+
local PADDING <const> = 28
14+
15+
local tiles <const> = {
16+
{ cursor = "default", color = 0xff39445f, hover = 0xff536181 },
17+
{ cursor = "arrow", color = 0xff3f4b6b, hover = 0xff5a6b95 },
18+
{ cursor = "ibeam", color = 0xff46506d, hover = 0xff64739c },
19+
{ cursor = "crosshair", color = 0xff40546b, hover = 0xff5c7895 },
20+
{ cursor = "pointing_hand", color = 0xff3e5960, hover = 0xff5a808a },
21+
{ cursor = "resize_ew", color = 0xff4f5364, hover = 0xff74798f },
22+
{ cursor = "resize_ns", color = 0xff4a5863, hover = 0xff6c808f },
23+
{ cursor = "resize_nwse", color = 0xff4b5064, hover = 0xff6f7692 },
24+
{ cursor = "resize_nesw", color = 0xff46556a, hover = 0xff667d9b },
25+
{ cursor = "resize_all", color = 0xff4f5961, hover = 0xff74828e },
26+
{ cursor = "not_allowed", color = 0xff5c4556, hover = 0xff8a657f },
27+
}
28+
29+
for _, tile in ipairs(tiles) do
30+
tile.fill = quad.quad(TILE_W, TILE_H, tile.color)
31+
tile.hover_fill = quad.quad(TILE_W, TILE_H, tile.hover)
32+
tile.outline = quad.quad(TILE_W + 4, TILE_H + 4, 0xff8fb2ff)
33+
end
34+
35+
soluna.set_window_title "soluna mouse cursor test"
36+
37+
local callback = {}
38+
local mouse_x = -1
39+
local mouse_y = -1
40+
local active_cursor
41+
42+
local function columns()
43+
return math.max(1, math.floor((args.width - PADDING * 2 + GAP) / (TILE_W + GAP)))
44+
end
45+
46+
local function tile_rect(index)
47+
local cols = columns()
48+
local col = (index - 1) % cols
49+
local row = math.floor((index - 1) / cols)
50+
return PADDING + col * (TILE_W + GAP), PADDING + row * (TILE_H + GAP)
51+
end
52+
53+
local function contains(x, y, left, top)
54+
return x >= left and x < left + TILE_W and y >= top and y < top + TILE_H
55+
end
56+
57+
local function cursor_at(x, y)
58+
for index, tile in ipairs(tiles) do
59+
local left, top = tile_rect(index)
60+
if contains(x, y, left, top) then
61+
return tile.cursor
62+
end
63+
end
64+
end
65+
66+
local function set_cursor(cursor)
67+
if cursor == active_cursor then
68+
return
69+
end
70+
active_cursor = cursor
71+
soluna.set_mouse_cursor(cursor)
72+
end
73+
74+
function callback.mouse_move(x, y)
75+
mouse_x, mouse_y = x, y
76+
set_cursor(cursor_at(x, y))
77+
end
78+
79+
function callback.key(keycode, state)
80+
if keycode == KEY_ESCAPE and state == KEYSTATE_PRESS then
81+
app.quit()
82+
end
83+
end
84+
85+
function callback.frame()
86+
for index, tile in ipairs(tiles) do
87+
local left, top = tile_rect(index)
88+
local hovered = contains(mouse_x, mouse_y, left, top)
89+
if hovered then
90+
batch:add(tile.outline, left - 2, top - 2)
91+
end
92+
batch:add(hovered and tile.hover_fill or tile.fill, left, top)
93+
end
94+
end
95+
96+
return callback

0 commit comments

Comments
 (0)