|
|
@ -76,24 +76,35 @@ Panel.ATTRS {
|
|
|
|
drag_bound = 'frame', -- or 'body'
|
|
|
|
drag_bound = 'frame', -- or 'body'
|
|
|
|
on_drag_begin = DEFAULT_NIL,
|
|
|
|
on_drag_begin = DEFAULT_NIL,
|
|
|
|
on_drag_end = DEFAULT_NIL,
|
|
|
|
on_drag_end = DEFAULT_NIL,
|
|
|
|
|
|
|
|
resizable = false,
|
|
|
|
|
|
|
|
resize_anchors = {t=false, l=true, r=true, b=true},
|
|
|
|
|
|
|
|
resize_min = DEFAULT_NIL,
|
|
|
|
|
|
|
|
on_resize_begin = DEFAULT_NIL,
|
|
|
|
|
|
|
|
on_resize_end = DEFAULT_NIL,
|
|
|
|
autoarrange_subviews = false, -- whether to automatically lay out subviews
|
|
|
|
autoarrange_subviews = false, -- whether to automatically lay out subviews
|
|
|
|
autoarrange_gap = 0, -- how many blank lines to insert between widgets
|
|
|
|
autoarrange_gap = 0, -- how many blank lines to insert between widgets
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function Panel:init(args)
|
|
|
|
function Panel:init(args)
|
|
|
|
self.keyboard_drag = nil -- true when we are in keyboard dragging mode
|
|
|
|
self.resize_min = self.resize_min or {}
|
|
|
|
|
|
|
|
self.resize_min.w = self.resize_min.w or (self.frame or {}).w or 5
|
|
|
|
|
|
|
|
self.resize_min.h = self.resize_min.h or (self.frame or {}).h or 5
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self.kbd_get_pos = nil -- fn when we are in keyboard dragging mode
|
|
|
|
self.saved_frame = nil -- copy of frame when dragging started
|
|
|
|
self.saved_frame = nil -- copy of frame when dragging started
|
|
|
|
self.saved_frame_rect = nil -- copy of frame_rect when dragging started
|
|
|
|
self.saved_frame_rect = nil -- copy of frame_rect when dragging started
|
|
|
|
self.drag_offset = nil -- relative pos of held panel tile
|
|
|
|
self.drag_offset = nil -- relative pos of held panel tile
|
|
|
|
|
|
|
|
self.resize_edge = nil -- which dimension is being resized?
|
|
|
|
self:addviews(args.subviews)
|
|
|
|
self:addviews(args.subviews)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
local function Panel_update_frame(self, frame, clear_state)
|
|
|
|
local function Panel_update_frame(self, frame, clear_state)
|
|
|
|
if clear_state then
|
|
|
|
if clear_state then
|
|
|
|
self.keyboard_drag = nil
|
|
|
|
self.kbd_get_pos = nil
|
|
|
|
self.saved_frame = nil
|
|
|
|
self.saved_frame = nil
|
|
|
|
self.saved_frame_rect = nil
|
|
|
|
self.saved_frame_rect = nil
|
|
|
|
self.drag_offset = nil
|
|
|
|
self.drag_offset = nil
|
|
|
|
|
|
|
|
self.resize_edge = nil
|
|
|
|
end
|
|
|
|
end
|
|
|
|
if not frame then return end
|
|
|
|
if not frame then return end
|
|
|
|
if self.frame.l == frame.l and self.frame.r == frame.r
|
|
|
|
if self.frame.l == frame.l and self.frame.r == frame.r
|
|
|
@ -105,6 +116,57 @@ local function Panel_update_frame(self, frame, clear_state)
|
|
|
|
self:updateLayout()
|
|
|
|
self:updateLayout()
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-- dim: the name of the dimension var (i.e. 'h' or 'w')
|
|
|
|
|
|
|
|
-- anchor: the name of the anchor var (i.e. 't', 'b', 'l', or 'r')
|
|
|
|
|
|
|
|
-- opposite_anchor: the name of the anchor var for the opposite edge
|
|
|
|
|
|
|
|
-- max_dim: how big this panel can get from its current pos and fit in parent
|
|
|
|
|
|
|
|
-- wanted_dim: how big the player is trying to make the panel
|
|
|
|
|
|
|
|
-- max_anchor: max value of the frame anchor for the edge that is being resized
|
|
|
|
|
|
|
|
-- wanted_anchor: how small the player is trying to make the anchor value
|
|
|
|
|
|
|
|
local function Panel_resize_edge_base(frame, resize_min, dim, anchor,
|
|
|
|
|
|
|
|
opposite_anchor, max_dim, wanted_dim,
|
|
|
|
|
|
|
|
max_anchor, wanted_anchor)
|
|
|
|
|
|
|
|
frame[dim] = math.max(resize_min[dim], math.min(max_dim, wanted_dim))
|
|
|
|
|
|
|
|
if frame[anchor] or not frame[opposite_anchor] then
|
|
|
|
|
|
|
|
frame[anchor] = math.max(0, math.min(max_anchor, wanted_anchor))
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
local function Panel_resize_edge(frame, resize_min, dim, anchor,
|
|
|
|
|
|
|
|
opposite_anchor, dim_base, dim_ref, anchor_ref,
|
|
|
|
|
|
|
|
dim_far, mouse_ref)
|
|
|
|
|
|
|
|
local dim_sign = (anchor == 't' or anchor == 'l') and 1 or -1
|
|
|
|
|
|
|
|
local max_dim = dim_base - dim_ref + 1
|
|
|
|
|
|
|
|
local wanted_dim = dim_sign * (dim_far - mouse_ref) + 1
|
|
|
|
|
|
|
|
local max_anchor = dim_base - resize_min[dim] - dim_ref + 1
|
|
|
|
|
|
|
|
local wanted_anchor = dim_sign * (mouse_ref - anchor_ref)
|
|
|
|
|
|
|
|
Panel_resize_edge_base(frame, resize_min, dim, anchor, opposite_anchor,
|
|
|
|
|
|
|
|
max_dim, wanted_dim, max_anchor, wanted_anchor)
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
local function Panel_resize_frame(self, mouse_pos)
|
|
|
|
|
|
|
|
local frame, resize_min = copyall(self.frame), self.resize_min
|
|
|
|
|
|
|
|
local parent_rect = self.frame_parent_rect
|
|
|
|
|
|
|
|
local ref_rect = self.saved_frame_rect
|
|
|
|
|
|
|
|
if self.resize_edge:find('t') then
|
|
|
|
|
|
|
|
Panel_resize_edge(frame, resize_min, 'h', 't', 'b', ref_rect.y2,
|
|
|
|
|
|
|
|
parent_rect.y1, parent_rect.y1, ref_rect.y2, mouse_pos.y)
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
if self.resize_edge:find('b') then
|
|
|
|
|
|
|
|
Panel_resize_edge(frame, resize_min, 'h', 'b', 't', parent_rect.y2,
|
|
|
|
|
|
|
|
ref_rect.y1, parent_rect.y2, ref_rect.y1, mouse_pos.y)
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
if self.resize_edge:find('l') then
|
|
|
|
|
|
|
|
Panel_resize_edge(frame, resize_min, 'w', 'l', 'r', ref_rect.x2,
|
|
|
|
|
|
|
|
parent_rect.x1, parent_rect.x1, ref_rect.x2, mouse_pos.x)
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
if self.resize_edge:find('r') then
|
|
|
|
|
|
|
|
Panel_resize_edge(frame, resize_min, 'w', 'r', 'l', parent_rect.x2,
|
|
|
|
|
|
|
|
ref_rect.x1, parent_rect.x2, ref_rect.x1, mouse_pos.x)
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
return frame
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
local function Panel_drag_frame(self, mouse_pos)
|
|
|
|
local function Panel_drag_frame(self, mouse_pos)
|
|
|
|
local frame = copyall(self.frame)
|
|
|
|
local frame = copyall(self.frame)
|
|
|
|
local parent_rect, frame_rect = self.frame_parent_rect, self.frame_rect
|
|
|
|
local parent_rect, frame_rect = self.frame_parent_rect, self.frame_rect
|
|
|
@ -140,31 +202,42 @@ end
|
|
|
|
|
|
|
|
|
|
|
|
local function Panel_make_frame(self, mouse_pos)
|
|
|
|
local function Panel_make_frame(self, mouse_pos)
|
|
|
|
mouse_pos = mouse_pos or xy2pos(dfhack.screen.getMousePos())
|
|
|
|
mouse_pos = mouse_pos or xy2pos(dfhack.screen.getMousePos())
|
|
|
|
return Panel_drag_frame(self, mouse_pos)
|
|
|
|
return self.resize_edge and Panel_resize_frame(self, mouse_pos)
|
|
|
|
|
|
|
|
or Panel_drag_frame(self, mouse_pos)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
local function Panel_begin_drag(self, drag_offset)
|
|
|
|
local function Panel_begin_drag(self, drag_offset, resize_edge)
|
|
|
|
Panel_update_frame(self, nil, true)
|
|
|
|
Panel_update_frame(self, nil, true)
|
|
|
|
self.drag_offset = drag_offset or {x=0, y=0}
|
|
|
|
self.drag_offset = drag_offset or {x=0, y=0}
|
|
|
|
|
|
|
|
self.resize_edge = resize_edge
|
|
|
|
self.saved_frame = copyall(self.frame)
|
|
|
|
self.saved_frame = copyall(self.frame)
|
|
|
|
self.saved_frame_rect = copyall(self.frame_rect)
|
|
|
|
self.saved_frame_rect = copyall(self.frame_rect)
|
|
|
|
self.prev_focus_owner = self.focus_group.cur
|
|
|
|
self.prev_focus_owner = self.focus_group.cur
|
|
|
|
self:setFocus(true)
|
|
|
|
self:setFocus(true)
|
|
|
|
if self.on_drag_begin then self.on_drag_begin() end
|
|
|
|
if self.resize_edge then
|
|
|
|
|
|
|
|
if self.on_resize_begin then self.on_resize_begin(success) end
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
if self.on_drag_begin then self.on_drag_begin(success) end
|
|
|
|
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
local function Panel_end_drag(self, frame, success)
|
|
|
|
local function Panel_end_drag(self, frame, success)
|
|
|
|
|
|
|
|
success = not not success
|
|
|
|
if self.prev_focus_owner then
|
|
|
|
if self.prev_focus_owner then
|
|
|
|
self.prev_focus_owner:setFocus(true)
|
|
|
|
self.prev_focus_owner:setFocus(true)
|
|
|
|
else
|
|
|
|
else
|
|
|
|
self:setFocus(false)
|
|
|
|
self:setFocus(false)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
Panel_update_frame(self, frame, true)
|
|
|
|
Panel_update_frame(self, frame, true)
|
|
|
|
|
|
|
|
if self.resize_edge then
|
|
|
|
|
|
|
|
if self.on_resize_end then self.on_resize_end(success) end
|
|
|
|
|
|
|
|
else
|
|
|
|
if self.on_drag_end then self.on_drag_end(success) end
|
|
|
|
if self.on_drag_end then self.on_drag_end(success) end
|
|
|
|
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
function Panel:onInput(keys)
|
|
|
|
function Panel:onInput(keys)
|
|
|
|
if self.keyboard_drag then
|
|
|
|
if self.kbd_get_pos then
|
|
|
|
if keys.SELECT or keys.LEAVESCREEN then
|
|
|
|
if keys.SELECT or keys.LEAVESCREEN then
|
|
|
|
Panel_end_drag(self, keys.LEAVESCREEN and self.saved_frame or nil,
|
|
|
|
Panel_end_drag(self, keys.LEAVESCREEN and self.saved_frame or nil,
|
|
|
|
not not keys.SELECT)
|
|
|
|
not not keys.SELECT)
|
|
|
@ -173,8 +246,10 @@ function Panel:onInput(keys)
|
|
|
|
for code in pairs(keys) do
|
|
|
|
for code in pairs(keys) do
|
|
|
|
local dx, dy = guidm.get_movement_delta(code, 1, 10)
|
|
|
|
local dx, dy = guidm.get_movement_delta(code, 1, 10)
|
|
|
|
if dx then
|
|
|
|
if dx then
|
|
|
|
local kbd_pos = {x=self.frame_rect.x1+dx,
|
|
|
|
local frame_rect = self.frame_rect
|
|
|
|
y=self.frame_rect.y1+dy}
|
|
|
|
local kbd_pos = self.kbd_get_pos()
|
|
|
|
|
|
|
|
kbd_pos.x = kbd_pos.x + dx
|
|
|
|
|
|
|
|
kbd_pos.y = kbd_pos.y + dy
|
|
|
|
Panel_update_frame(self, Panel_make_frame(self, kbd_pos))
|
|
|
|
Panel_update_frame(self, Panel_make_frame(self, kbd_pos))
|
|
|
|
return true
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
end
|
|
|
@ -197,31 +272,74 @@ function Panel:onInput(keys)
|
|
|
|
local x,y = self:getMousePos(gui.ViewRect{rect=rect})
|
|
|
|
local x,y = self:getMousePos(gui.ViewRect{rect=rect})
|
|
|
|
if not x then return end
|
|
|
|
if not x then return end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if self.resizable then
|
|
|
|
|
|
|
|
local rect = self.frame_rect
|
|
|
|
|
|
|
|
if self.resize_anchors.r and self.resize_anchors.b
|
|
|
|
|
|
|
|
and x == rect.x2 - rect.x1 and y == rect.y2 - rect.y1 then
|
|
|
|
|
|
|
|
self.resize_edge = 'rb'
|
|
|
|
|
|
|
|
elseif self.resize_anchors.l and self.resize_anchors.b
|
|
|
|
|
|
|
|
and x == 0 and y == rect.y2 - rect.y1 then
|
|
|
|
|
|
|
|
self.resize_edge = 'lb'
|
|
|
|
|
|
|
|
elseif self.resize_anchors.r and self.resize_anchors.t
|
|
|
|
|
|
|
|
and x == rect.x2 - rect.x1 and y == 0 then
|
|
|
|
|
|
|
|
self.resize_edge = 'rt'
|
|
|
|
|
|
|
|
elseif self.resize_anchors.r and self.resize_anchors.t
|
|
|
|
|
|
|
|
and x == 0 and y == 0 then
|
|
|
|
|
|
|
|
self.resize_edge = 'lt'
|
|
|
|
|
|
|
|
elseif self.resize_anchors.r and x == rect.x2 - rect.x1 then
|
|
|
|
|
|
|
|
self.resize_edge = 'r'
|
|
|
|
|
|
|
|
elseif self.resize_anchors.l and x == 0 then
|
|
|
|
|
|
|
|
self.resize_edge = 'l'
|
|
|
|
|
|
|
|
elseif self.resize_anchors.b and y == rect.y2 - rect.y1 then
|
|
|
|
|
|
|
|
self.resize_edge = 'b'
|
|
|
|
|
|
|
|
elseif self.resize_anchors.t and y == 0 then
|
|
|
|
|
|
|
|
self.resize_edge = 't'
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
local is_dragging = false
|
|
|
|
local is_dragging = false
|
|
|
|
if self.draggable then
|
|
|
|
if not self.resize_edge and self.draggable then
|
|
|
|
local on_body = self:getMousePos()
|
|
|
|
local on_body = self:getMousePos()
|
|
|
|
is_dragging = (self.drag_anchors.title and self.frame_style and y == 0)
|
|
|
|
is_dragging = (self.drag_anchors.title and self.frame_style and y == 0)
|
|
|
|
or (self.drag_anchors.frame and not on_body) -- includes inset
|
|
|
|
or (self.drag_anchors.frame and not on_body) -- includes inset
|
|
|
|
or (self.drag_anchors.body and on_body)
|
|
|
|
or (self.drag_anchors.body and on_body)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
if is_dragging then
|
|
|
|
if self.resize_edge or is_dragging then
|
|
|
|
Panel_begin_drag(self, {x=x, y=y})
|
|
|
|
Panel_begin_drag(self, {x=x, y=y}, self.resize_edge)
|
|
|
|
return true
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
function Panel:setKeyboardDragEnabled(enabled)
|
|
|
|
function Panel:setKeyboardDragEnabled(enabled)
|
|
|
|
if (enabled and self.keyboard_drag)
|
|
|
|
if (enabled and self.kbd_get_pos)
|
|
|
|
or (not enabled and not self.keyboard_drag) then
|
|
|
|
or (not enabled and not self.kbd_get_pos) then
|
|
|
|
return
|
|
|
|
return
|
|
|
|
end
|
|
|
|
end
|
|
|
|
if enabled then
|
|
|
|
if enabled then
|
|
|
|
Panel_begin_drag(self)
|
|
|
|
local kbd_get_pos = function() return {x=0, y=0} end
|
|
|
|
|
|
|
|
Panel_begin_drag(self, kbd_get_pos())
|
|
|
|
|
|
|
|
self.kbd_get_pos = kbd_get_pos
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
Panel_end_drag(self)
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function Panel:setKeyboardResizeEnabled(enabled)
|
|
|
|
|
|
|
|
if (enabled and self.kbd_get_pos)
|
|
|
|
|
|
|
|
or (not enabled and not self.kbd_get_pos) then
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
if enabled then
|
|
|
|
|
|
|
|
local resize_edge = 'rb'
|
|
|
|
|
|
|
|
local kbd_get_pos = function()
|
|
|
|
|
|
|
|
return {x=self.frame_rect.x2, y=self.frame_rect.y2}
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
Panel_begin_drag(self, kbd_get_pos(), resize_edge)
|
|
|
|
|
|
|
|
self.kbd_get_pos = kbd_get_pos
|
|
|
|
else
|
|
|
|
else
|
|
|
|
Panel_end_drag(self)
|
|
|
|
Panel_end_drag(self)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
self.keyboard_drag = enabled
|
|
|
|
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
function Panel:onRenderBody(dc)
|
|
|
|
function Panel:onRenderBody(dc)
|
|
|
@ -264,7 +382,7 @@ function Panel:onRenderFrame(dc, rect)
|
|
|
|
if not self.frame_style then return end
|
|
|
|
if not self.frame_style then return end
|
|
|
|
local x1,y1,x2,y2 = rect.x1, rect.y1, rect.x2, rect.y2
|
|
|
|
local x1,y1,x2,y2 = rect.x1, rect.y1, rect.x2, rect.y2
|
|
|
|
gui.paint_frame(x1, y1, x2, y2, self.frame_style, self.frame_title)
|
|
|
|
gui.paint_frame(x1, y1, x2, y2, self.frame_style, self.frame_title)
|
|
|
|
if self.drag_offset and not self.keyboard_drag
|
|
|
|
if self.drag_offset and not self.kbd_get_pos
|
|
|
|
and df.global.enabler.mouse_lbut == 0 then
|
|
|
|
and df.global.enabler.mouse_lbut == 0 then
|
|
|
|
Panel_end_drag(self, nil, true)
|
|
|
|
Panel_end_drag(self, nil, true)
|
|
|
|
end
|
|
|
|
end
|
|
|
|