diff options
Diffstat (limited to 'indra/newview/scripts/lua/require/UI.lua')
-rw-r--r-- | indra/newview/scripts/lua/require/UI.lua | 243 |
1 files changed, 243 insertions, 0 deletions
diff --git a/indra/newview/scripts/lua/require/UI.lua b/indra/newview/scripts/lua/require/UI.lua new file mode 100644 index 0000000000..cf2695917e --- /dev/null +++ b/indra/newview/scripts/lua/require/UI.lua @@ -0,0 +1,243 @@ +-- Engage the viewer's UI + +local leap = require 'leap' +local mapargs = require 'mapargs' +local result_view = require 'result_view' +local Timer = (require 'timers').Timer +local util = require 'util' + +-- Allow lazily accessing UI submodules on demand, e.g. a reference to +-- UI.Floater lazily loads the UI/Floater module. +local UI = util.submoduledir({}, '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.callables() + return leap.request('UI', {op='callables'}).callables +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 + +-- *************************************************************************** +-- Snapshot +-- *************************************************************************** +-- UI.snapshot{filename=filename -- extension may be specified: bmp, jpeg, png +-- [, type='COLOR' | 'DEPTH'] +-- [, width=width][, height=height] -- uses current window size if not specified +-- [, showui=true][, showhud=true] +-- [, rebuild=false]} +function UI.snapshot(...) + local args = mapargs('filename,width,height,showui,showhud,rebuild,type', ...) + args.op = 'saveSnapshot' + return leap.request('LLViewerWindow', args).result +end + +-- *************************************************************************** +-- Top menu +-- *************************************************************************** + +function UI.getTopMenus() + return leap.request('UI', {op='getTopMenus'}).menus +end + +function UI.addMenu(...) + local args = mapargs('name,label', ...) + args.op = 'addMenu' + return leap.request('UI', args) +end + +function UI.setMenuVisible(name, visible) + return leap.request('UI', {op='setMenuVisible', name=name, visible=visible}) +end + +function UI.addMenuBranch(...) + local args = mapargs('name,label,parent_menu', ...) + args.op = 'addMenuBranch' + return leap.request('UI', args) +end + +-- see UI.callables() for valid values of 'func' +function UI.addMenuItem(...) + local args = mapargs('name,label,parent_menu,func,param,pos', ...) + args.op = 'addMenuItem' + return leap.request('UI', args) +end + +function UI.addMenuSeparator(...) + local args = mapargs('parent_menu,pos', ...) + args.op = 'addMenuSeparator' + return leap.request('UI', args) +end + +-- *************************************************************************** +-- Toolbar buttons +-- *************************************************************************** +-- Clears all buttons off the toolbars +function UI.clearAllToolbars() + leap.send('UI', {op='clearAllToolbars'}) +end + +function UI.defaultToolbars() + leap.send('UI', {op='defaultToolbars'}) +end + +-- UI.addToolbarBtn{btn_name=btn_name +-- [, toolbar= bottom] -- left, right, bottom -- default is bottom +-- [, rank=1]} -- position on the toolbar, starts at 0 (0 - first position, 1 - second position etc.) +function UI.addToolbarBtn(...) + local args = mapargs('btn_name,toolbar,rank', ...) + args.op = 'addToolbarBtn' + return leap.request('UI', args) +end + +-- Returns the rank(position) of the command in the original list +function UI.removeToolbarBtn(btn_name) + return leap.request('UI', {op = 'removeToolbarBtn', btn_name=btn_name}).rank +end + +function UI.getToolbarBtnNames() + return leap.request('UI', {op = 'getToolbarBtnNames'}).cmd_names +end + +-- *************************************************************************** +-- Floaters +-- *************************************************************************** +function UI.showFloater(floater_name) + leap.send("LLFloaterReg", {op = "showInstance", name = floater_name}) +end + +function UI.hideFloater(floater_name) + leap.send("LLFloaterReg", {op = "hideInstance", name = floater_name}) +end + +function UI.toggleFloater(floater_name) + leap.send("LLFloaterReg", {op = "toggleInstance", name = floater_name}) +end + +function UI.isFloaterVisible(floater_name) + return leap.request("LLFloaterReg", {op = "instanceVisible", name = floater_name}).visible +end + +function UI.closeAllFloaters() + return leap.send("UI", {op = "closeAllFloaters"}) +end + +function UI.getFloaterNames() + local key_length = leap.request("LLFloaterReg", {op = "getFloaterNames"}).floaters + local view = result_view(key_length) + return LL.setdtor('registered floater names', view, view.close) +end + +return UI |