summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2020-11-21 00:48:31 +0800
committerruki <[email protected]>2020-11-21 00:48:31 +0800
commit6aa64df1ce672b5d2cd37707d5673089c0a33e3f (patch)
tree41f213925bfe1e7f6d489a5da052bf08aa174c7e
parent96ce788dce7a63ab62c47750214f355c9c2eeced (diff)
support mouse for menuconf
-rw-r--r--CHANGELOG.md2
-rw-r--r--xmake/core/ui/action.lua1
-rw-r--r--xmake/core/ui/boxdialog.lua18
-rw-r--r--xmake/core/ui/button.lua7
-rw-r--r--xmake/core/ui/choicebox.lua7
-rw-r--r--xmake/core/ui/curses.lua5
-rw-r--r--xmake/core/ui/menuconf.lua7
-rw-r--r--xmake/core/ui/panel.lua32
-rw-r--r--xmake/core/ui/program.lua9
-rw-r--r--xmake/core/ui/view.lua1
10 files changed, 85 insertions, 4 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 571c8d164..a3f97eddc 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -11,6 +11,7 @@
* [#1016](https://github.com/xmake-io/xmake/issues/1016): Add license checking for target/packages
* [#1017](https://github.com/xmake-io/xmake/issues/1017): Support external/system include directories `add_sysincludedirs` for package and toolchains
* [#1020](https://github.com/xmake-io/xmake/issues/1020): Support to find and install pacman package on archlinux and msys2
+* Support mouse for `xmake f --menu`
### Change
@@ -870,6 +871,7 @@
* [#1016](https://github.com/xmake-io/xmake/issues/1016): 针对依赖包增加license兼容性检测
* [#1017](https://github.com/xmake-io/xmake/issues/1017): 支持外部/系统头文件支持 `add_sysincludedirs`,依赖包默认使用`-isystem`
* [#1020](https://github.com/xmake-io/xmake/issues/1020): 支持在 archlinux 和 msys2 上查找安装 pacman 包
+* 改进 `xmake f --menu` 菜单配置,支持鼠标操作
### 改进
diff --git a/xmake/core/ui/action.lua b/xmake/core/ui/action.lua
index cec30a2f4..f3bb87c7e 100644
--- a/xmake/core/ui/action.lua
+++ b/xmake/core/ui/action.lua
@@ -40,6 +40,7 @@ end
action:register("ac_max",
"ac_on_text_changed",
"ac_on_selected",
+ "ac_on_clicked",
"ac_on_resized",
"ac_on_enter",
"ac_on_load",
diff --git a/xmake/core/ui/boxdialog.lua b/xmake/core/ui/boxdialog.lua
index 89f481fbb..3aedc50dd 100644
--- a/xmake/core/ui/boxdialog.lua
+++ b/xmake/core/ui/boxdialog.lua
@@ -64,6 +64,24 @@ function boxdialog:init(name, bounds, title)
self:text():bounds().ey = self._TEXT_EY
self:box():bounds_set(rect{0, self._TEXT_EY, v:width(), v:height() - 1})
end)
+
+ -- on click for frame
+ self:frame():action_set(action.ac_on_clicked, function (v, x, y)
+
+ -- get relative coordinates
+ x, y = x - v:bounds().sx, y - v:bounds().sy
+ local panel, box = v:parent():panel(), v:parent():box()
+ local px, py = x - panel:bounds().sx, y - panel:bounds().sy
+
+ -- if coordinates don't match any view try box
+ if panel:option("mouseable") then
+ if panel:action_on(action.ac_on_clicked, x, y) then
+ return true
+ elseif box:option("mouseable") and not box:option("selectable") and box:bounds():contains(px, py) then
+ return box:action_on(action.ac_on_clicked, px, py)
+ end
+ end
+ end)
end
-- get box
diff --git a/xmake/core/ui/button.lua b/xmake/core/ui/button.lua
index 6ef5b0723..674bc7496 100644
--- a/xmake/core/ui/button.lua
+++ b/xmake/core/ui/button.lua
@@ -41,8 +41,13 @@ function button:init(name, bounds, text, on_action)
-- show cursor
self:cursor_show(true)
- -- init action
+ -- init actions
+ self:option_set("mouseable", true)
self:action_set(action.ac_on_enter, on_action)
+ self:action_set(action.ac_on_clicked, function (v)
+ v:action_on(action.ac_on_enter)
+ return true
+ end)
end
-- draw button
diff --git a/xmake/core/ui/choicebox.lua b/xmake/core/ui/choicebox.lua
index e93452228..1dd84159a 100644
--- a/xmake/core/ui/choicebox.lua
+++ b/xmake/core/ui/choicebox.lua
@@ -87,7 +87,12 @@ function choicebox:_do_insert(value, index, selected)
local text = (selected and "(X) " or "( ) ") .. tostring(value)
-- init a value item view
- local item = button:new("choicebox.value." .. self:count(), rect:new(0, self:count(), self:width(), 1), text)
+ local item = button:new("choicebox.value." .. self:count(),
+ rect:new(0, self:count(), self:width(), 1),
+ text,
+ function (v, e)
+ self:_do_select()
+ end)
-- attach this index
item:extra_set("index", index)
diff --git a/xmake/core/ui/curses.lua b/xmake/core/ui/curses.lua
index 332dcb5a4..d90c8f5c2 100644
--- a/xmake/core/ui/curses.lua
+++ b/xmake/core/ui/curses.lua
@@ -213,5 +213,10 @@ function curses.cursor_set(state)
end
end
+-- has mouse?
+function curses.has_mouse()
+ return curses.KEY_MOUSE and true or false
+end
+
-- return module: curses
return curses
diff --git a/xmake/core/ui/menuconf.lua b/xmake/core/ui/menuconf.lua
index 4ac2991fd..a086aa743 100644
--- a/xmake/core/ui/menuconf.lua
+++ b/xmake/core/ui/menuconf.lua
@@ -118,7 +118,12 @@ end
function menuconf:_do_insert(config)
-- init a config item view
- local item = button:new("menuconf.config." .. self:count(), rect:new(0, self:count(), self:width(), 1), tostring(config))
+ local item = button:new("menuconf.config." .. self:count(),
+ rect:new(0, self:count(), self:width(), 1),
+ tostring(config),
+ function (v, e)
+ self:_do_select()
+ end)
-- attach this config
item:extra_set("config", config)
diff --git a/xmake/core/ui/panel.lua b/xmake/core/ui/panel.lua
index f08bceade..d70cefa8f 100644
--- a/xmake/core/ui/panel.lua
+++ b/xmake/core/ui/panel.lua
@@ -25,6 +25,7 @@ local rect = require("ui/rect")
local event = require("ui/event")
local point = require("ui/point")
local curses = require("ui/curses")
+local action = require("ui/action")
local dlist = require("base/dlist")
-- define module
@@ -47,6 +48,32 @@ function panel:init(name, bounds)
-- init views cache
self._VIEWS_CACHE = {}
+
+ -- on click action
+ self:option_set("mouseable", true)
+ self:action_set(action.ac_on_clicked, function (v, x, y)
+
+ -- get relative coordinates
+ x, y = x - v:bounds().sx, y - v:bounds().sy
+
+ -- try focused first
+ local current = v:current()
+ if current and current:option("mouseable") and current:bounds():contains(x, y) then
+ return current:action_on(action.ac_on_clicked, x, y)
+ end
+
+ local p = v:last()
+ while p do
+ if p:option('selectable') and p:bounds():contains(x, y) then
+ if p:option("mouseable") then
+ v:select(p)
+ return p:action_on(action.ac_on_clicked, x, y)
+ end
+ return true
+ end
+ p = v:prev(p)
+ end
+ end)
end
-- get all child views
@@ -69,6 +96,11 @@ function panel:first()
return self._VIEWS:first()
end
+-- get the last view
+function panel:last()
+ return self._VIEWS:last()
+end
+
-- get the next view
function panel:next(v)
return self._VIEWS:next(v)
diff --git a/xmake/core/ui/program.lua b/xmake/core/ui/program.lua
index c5a73c474..42f5160db 100644
--- a/xmake/core/ui/program.lua
+++ b/xmake/core/ui/program.lua
@@ -25,6 +25,7 @@ local point = require("ui/point")
local panel = require("ui/panel")
local event = require("ui/event")
local curses = require("ui/curses")
+local action = require("ui/action")
-- define module
local program = program or panel()
@@ -45,7 +46,8 @@ function program:init(name, argv)
curses.nl(false)
-- init mouse support
- if curses.KEY_MOUSE then
+ if curses.has_mouse() then
+ -- curses.ALL_MOUSE_EVENTS may be set to mask unused events
curses.mousemask(curses.ALL_MOUSE_EVENTS)
end
@@ -186,6 +188,11 @@ function program:on_event(e)
elseif event.is_command(e, "cm_exit") then
self:quit()
return true
+ -- mouse events
+ elseif e.type == event.ev_mouse and curses.has_mouse() and self:option("mouseable") then
+ if e.btn_name == "BUTTON1_CLICKED" or e.btn_name == "BUTTON1_DOUBLE_CLICKED" then
+ self:action_on(action.ac_on_clicked, e.x, e.y)
+ end
end
end
diff --git a/xmake/core/ui/view.lua b/xmake/core/ui/view.lua
index e450e6766..ec5f841a2 100644
--- a/xmake/core/ui/view.lua
+++ b/xmake/core/ui/view.lua
@@ -68,6 +68,7 @@ function view:init(name, bounds)
-- init options
local options = object()
options.selectable = false -- true if window can be selected
+ options.mouseable = false -- false by default
self._OPTIONS = options
-- init attributes