From 44182d0719c209aabe0d80aea291a9e3e45b1e59 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Tue, 11 Jun 2024 21:59:31 -0400 Subject: Add to UI.lua a set of 'LLWindow' listener operations. Add listviews(), viewinfo(), click(), doubleclick(), drag(), keypress() and type(). WIP: These are ported from Python LEAP equivalents, but the Lua implementation has only been partially tested. --- indra/newview/scripts/lua/UI.lua | 113 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 111 insertions(+), 2 deletions(-) (limited to 'indra/newview/scripts/lua/UI.lua') diff --git a/indra/newview/scripts/lua/UI.lua b/indra/newview/scripts/lua/UI.lua index 24f822bbd9..eb1a4017c7 100644 --- a/indra/newview/scripts/lua/UI.lua +++ b/indra/newview/scripts/lua/UI.lua @@ -1,9 +1,14 @@ --- Engage the UI LLEventAPI +-- Engage the viewer's UI -leap = require 'leap' +local leap = require 'leap' +local Timer = (require 'timers').Timer +local mapargs = require 'mapargs' local UI = {} +-- *************************************************************************** +-- registered menu actions +-- *************************************************************************** function UI.call(func, parameter) -- 'call' is fire-and-forget leap.request('UI', {op='call', ['function']=func, parameter=parameter}) @@ -13,4 +18,108 @@ function UI.getValue(path) return leap.request('UI', {op='getValue', path=path})['value'] end +-- *************************************************************************** +-- UI views +-- *************************************************************************** +-- Either: +-- wreq{op='Something', a=1, b=2, ...} +-- or: +-- (args should be local, as this wreq() call modifies it) +-- local args = {a=1, b=2, ...} +-- wreq('Something', args) +local function wreq(op_or_data, data_if_op) + if data_if_op ~= nil then + -- this is the wreq(op, data) form + data_if_op.op = op_or_data + op_or_data = data_if_op + end + return leap.request('LLWindow', op_or_data) +end + +-- omit 'parent' to list all view paths +function UI.listviews(parent) + return wreq{op='getPaths', under=parent} +end + +function UI.viewinfo(path) + return wreq{op='getInfo', path=path} +end + +-- *************************************************************************** +-- mouse actions +-- *************************************************************************** +-- pass a table: +-- UI.click{path=path +-- [, button='LEFT' | 'CENTER' | 'RIGHT'] +-- [, x=x, y=y] +-- [, hold=duration]} +function UI.click(...) + local args = mapargs('path,button,x,y,hold', ...) + args.button = args.button or 'LEFT' + local hold = args.hold or 1.0 + wreq('mouseMove', args) + wreq('mouseDown', args) + Timer(hold, 'wait') + wreq('mouseUp', args) +end + +-- pass a table as for UI.click() +function UI.doubleclick(...) + local args = mapargs('path,button,x,y', ...) + args.button = args.button or 'LEFT' + wreq('mouseDown', args) + wreq('mouseUp', args) + wreq('mouseDown', args) + wreq('mouseUp', args) +end + +-- UI.drag{path=, xoff=, yoff=} +function UI.drag(...) + local args = mapargs('path,xoff,yoff', ...) + -- query the specified path + local rect = UI.viewinfo(args.path).rect + local centerx = math.floor(rect.left + (rect.right - rect.left)/2) + local centery = math.floor(rect.bottom + (rect.top - rect.bottom)/2) + wreq{op='mouseMove', path=args.path, x=centerx, y=centery} + wreq{op='mouseDown', path=args.path, button='LEFT'} + wreq{op='mouseMove', path=args.path, x=centerx + args.xoff, y=centery + args.yoff} + wreq{op='mouseUp', path=args.path, button='LEFT'} +end + +-- *************************************************************************** +-- keyboard actions +-- *************************************************************************** +-- pass a table: +-- UI.keypress{ +-- [path=path] -- if omitted, default input field +-- [, char='x'] -- requires one of char, keycode, keysym +-- [, keycode=120] +-- keysym per https://github.com/secondlife/viewer/blob/main/indra/llwindow/llkeyboard.cpp#L68-L124 +-- [, keysym='Enter'] +-- [, mask={'SHIFT', 'CTL', 'ALT', 'MAC_CONTROL'}] -- some subset of these +-- } +function UI.keypress(...) + local args = mapargs('path,char,keycode,keysym,mask', ...) + if args.char == '\n' then + args.char = nil + args.keysym = 'Enter' + end + return wreq('keyDown', args) +end + +-- UI.type{text=, path=} +function UI.type(...) + local args = mapargs('text,path', ...) + if #args.text > 0 then + -- The caller's path may be specified in a way that requires recursively + -- searching parts of the LLView tree. No point in doing that more than + -- once. Capture the actual path found by that first call and use that for + -- subsequent calls. + local path = UI.keypress{path=args.path, char=string.sub(args.text, 1, 1)}.path + for i = 2, #args.text do + UI.keypress{path=path, char=string.sub(args.text, i, i)} + end + end +end + return UI -- cgit v1.2.3 From f7137765438f149cbae6f3b18da45dce75a25336 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Fri, 14 Jun 2024 12:16:12 -0400 Subject: Move Lua modules for 'require' to indra/newview/scripts/lua/require. Make viewer_manifest.py copy them into the viewer install image. Make the require() function look for them there. --- indra/newview/scripts/lua/UI.lua | 125 --------------------------------------- 1 file changed, 125 deletions(-) delete mode 100644 indra/newview/scripts/lua/UI.lua (limited to 'indra/newview/scripts/lua/UI.lua') diff --git a/indra/newview/scripts/lua/UI.lua b/indra/newview/scripts/lua/UI.lua deleted file mode 100644 index eb1a4017c7..0000000000 --- a/indra/newview/scripts/lua/UI.lua +++ /dev/null @@ -1,125 +0,0 @@ --- Engage the viewer's UI - -local leap = require 'leap' -local Timer = (require 'timers').Timer -local mapargs = require 'mapargs' - -local UI = {} - --- *************************************************************************** --- registered menu actions --- *************************************************************************** -function UI.call(func, parameter) - -- 'call' is fire-and-forget - leap.request('UI', {op='call', ['function']=func, parameter=parameter}) -end - -function UI.getValue(path) - return leap.request('UI', {op='getValue', path=path})['value'] -end - --- *************************************************************************** --- UI views --- *************************************************************************** --- Either: --- wreq{op='Something', a=1, b=2, ...} --- or: --- (args should be local, as this wreq() call modifies it) --- local args = {a=1, b=2, ...} --- wreq('Something', args) -local function wreq(op_or_data, data_if_op) - if data_if_op ~= nil then - -- this is the wreq(op, data) form - data_if_op.op = op_or_data - op_or_data = data_if_op - end - return leap.request('LLWindow', op_or_data) -end - --- omit 'parent' to list all view paths -function UI.listviews(parent) - return wreq{op='getPaths', under=parent} -end - -function UI.viewinfo(path) - return wreq{op='getInfo', path=path} -end - --- *************************************************************************** --- mouse actions --- *************************************************************************** --- pass a table: --- UI.click{path=path --- [, button='LEFT' | 'CENTER' | 'RIGHT'] --- [, x=x, y=y] --- [, hold=duration]} -function UI.click(...) - local args = mapargs('path,button,x,y,hold', ...) - args.button = args.button or 'LEFT' - local hold = args.hold or 1.0 - wreq('mouseMove', args) - wreq('mouseDown', args) - Timer(hold, 'wait') - wreq('mouseUp', args) -end - --- pass a table as for UI.click() -function UI.doubleclick(...) - local args = mapargs('path,button,x,y', ...) - args.button = args.button or 'LEFT' - wreq('mouseDown', args) - wreq('mouseUp', args) - wreq('mouseDown', args) - wreq('mouseUp', args) -end - --- UI.drag{path=, xoff=, yoff=} -function UI.drag(...) - local args = mapargs('path,xoff,yoff', ...) - -- query the specified path - local rect = UI.viewinfo(args.path).rect - local centerx = math.floor(rect.left + (rect.right - rect.left)/2) - local centery = math.floor(rect.bottom + (rect.top - rect.bottom)/2) - wreq{op='mouseMove', path=args.path, x=centerx, y=centery} - wreq{op='mouseDown', path=args.path, button='LEFT'} - wreq{op='mouseMove', path=args.path, x=centerx + args.xoff, y=centery + args.yoff} - wreq{op='mouseUp', path=args.path, button='LEFT'} -end - --- *************************************************************************** --- keyboard actions --- *************************************************************************** --- pass a table: --- UI.keypress{ --- [path=path] -- if omitted, default input field --- [, char='x'] -- requires one of char, keycode, keysym --- [, keycode=120] --- keysym per https://github.com/secondlife/viewer/blob/main/indra/llwindow/llkeyboard.cpp#L68-L124 --- [, keysym='Enter'] --- [, mask={'SHIFT', 'CTL', 'ALT', 'MAC_CONTROL'}] -- some subset of these --- } -function UI.keypress(...) - local args = mapargs('path,char,keycode,keysym,mask', ...) - if args.char == '\n' then - args.char = nil - args.keysym = 'Enter' - end - return wreq('keyDown', args) -end - --- UI.type{text=, path=} -function UI.type(...) - local args = mapargs('text,path', ...) - if #args.text > 0 then - -- The caller's path may be specified in a way that requires recursively - -- searching parts of the LLView tree. No point in doing that more than - -- once. Capture the actual path found by that first call and use that for - -- subsequent calls. - local path = UI.keypress{path=args.path, char=string.sub(args.text, 1, 1)}.path - for i = 2, #args.text do - UI.keypress{path=path, char=string.sub(args.text, i, i)} - end - end -end - -return UI -- cgit v1.2.3