mirror of
https://github.com/koreader/koreader.git
synced 2025-08-10 00:52:38 +00:00
Normalize some widgets appearance (those using ButtonTable)
This makes button heights similar in all uses of ButtonTable. It depended on how the ButtonTable was used in each widget (previously, first and last row may have different sizes than the others). buttontable.lua: more even buttons height whether zero_sep or not framecontainer.lua: added padding_top/bottom/left/right (similar to what was done for iconbutton) The following widgets have been adapted for this, with some additional fixes: buttondialog.lua buttondialogtitle.lua: wider title with adequate padding confirmbox.lua + multiconfirmbox.lua: dismissable via tap outside inputdialog.lua + multiinputdialog.lua: more even vertical padding between elements imageviewer.lua textviewer.lua datewidget.lua timewidget.lua Additionaly: frontlightwidget.lua: fixed width of progress bar that was exceeding window width since the Size scaling adjustements
This commit is contained in:
@@ -384,7 +384,7 @@ function ReaderHighlight:onHoldRelease()
|
||||
},
|
||||
{
|
||||
{
|
||||
text = "_",
|
||||
text = "-",
|
||||
enabled = false,
|
||||
},
|
||||
{
|
||||
|
||||
@@ -46,6 +46,10 @@ function ButtonDialog:init()
|
||||
bordersize = Size.border.window,
|
||||
radius = Size.radius.window,
|
||||
padding = Size.padding.button,
|
||||
-- No padding at top or bottom to make all buttons
|
||||
-- look the same size
|
||||
padding_top = 0,
|
||||
padding_bottom = 0,
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
@@ -7,7 +7,6 @@ local FrameContainer = require("ui/widget/container/framecontainer")
|
||||
local Geom = require("ui/geometry")
|
||||
local GestureRange = require("ui/gesturerange")
|
||||
local InputContainer = require("ui/widget/container/inputcontainer")
|
||||
local LineWidget = require("ui/widget/linewidget")
|
||||
local Size = require("ui/size")
|
||||
local TextBoxWidget = require("ui/widget/textboxwidget")
|
||||
local VerticalGroup = require("ui/widget/verticalgroup")
|
||||
@@ -19,13 +18,14 @@ local Screen = Device.screen
|
||||
local ButtonDialogTitle = InputContainer:new{
|
||||
title = nil,
|
||||
title_align = nil,
|
||||
title_face = Font:getFace("x_smalltfont"),
|
||||
title_padding = Size.padding.large,
|
||||
title_margin = Size.margin.title,
|
||||
buttons = nil,
|
||||
tap_close_callback = nil,
|
||||
}
|
||||
|
||||
function ButtonDialogTitle:init()
|
||||
self.medium_font_face = Font:getFace("ffont")
|
||||
self.large_font_face = Font:getFace("largeffont")
|
||||
if Device:hasKeys() then
|
||||
self.key_events = {
|
||||
Close = { {"Back"}, doc = "close button dialog" }
|
||||
@@ -43,31 +43,27 @@ function ButtonDialogTitle:init()
|
||||
}
|
||||
}
|
||||
end
|
||||
local vertical_span = VerticalSpan:new{ width = Size.span.vertical_default }
|
||||
self[1] = CenterContainer:new{
|
||||
dimen = Screen:getSize(),
|
||||
FrameContainer:new{
|
||||
VerticalGroup:new{
|
||||
align = "center",
|
||||
vertical_span,
|
||||
TextBoxWidget:new{
|
||||
text = self.title,
|
||||
width = Screen:getWidth() * 0.8 ,
|
||||
face = self.medium_font_face,
|
||||
bold = true,
|
||||
alignment = self.title_align or "left",
|
||||
FrameContainer:new{
|
||||
padding = self.title_padding,
|
||||
margin = self.title_margin,
|
||||
bordersize = 0,
|
||||
TextBoxWidget:new{
|
||||
text = self.title,
|
||||
width = Screen:getWidth() * 0.8 ,
|
||||
face = self.title_face,
|
||||
alignment = self.title_align or "left",
|
||||
},
|
||||
},
|
||||
vertical_span,
|
||||
LineWidget:new{
|
||||
dimen = Geom:new{
|
||||
w = Screen:getWidth() * 0.9,
|
||||
h = Size.line.medium,
|
||||
}
|
||||
},
|
||||
vertical_span,
|
||||
VerticalSpan:new{ width = Size.span.vertical_default },
|
||||
ButtonTable:new{
|
||||
width = Screen:getWidth() * 0.9,
|
||||
buttons = self.buttons,
|
||||
zero_sep = true,
|
||||
show_parent = self,
|
||||
},
|
||||
},
|
||||
@@ -75,6 +71,7 @@ function ButtonDialogTitle:init()
|
||||
bordersize = Size.border.window,
|
||||
radius = Size.radius.window,
|
||||
padding = Size.padding.button,
|
||||
padding_bottom = 0, -- no padding below buttontable
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
@@ -32,7 +32,12 @@ function ButtonTable:init()
|
||||
self.container = VerticalGroup:new{ width = self.width }
|
||||
table.insert(self, self.container)
|
||||
if self.zero_sep then
|
||||
self:addHorizontalSep()
|
||||
-- If we're asked to add a first line, don't add a vspan before: caller
|
||||
-- must do its own padding before.
|
||||
-- Things look better when the first line is gray like the others.
|
||||
self:addHorizontalSep(false, true, true)
|
||||
else
|
||||
self:addHorizontalSep(false, false, true)
|
||||
end
|
||||
local row_cnt = #self.buttons
|
||||
for i = 1, row_cnt do
|
||||
@@ -72,9 +77,10 @@ function ButtonTable:init()
|
||||
end -- end for each button
|
||||
table.insert(self.container, horizontal_group)
|
||||
if i < row_cnt then
|
||||
self:addHorizontalSep()
|
||||
self:addHorizontalSep(true, true, true)
|
||||
end
|
||||
end -- end for each button line
|
||||
self:addHorizontalSep(true, false, false)
|
||||
if Device:hasDPad() or Device:hasKeyboard() then
|
||||
self.layout = self.buttons_layout
|
||||
self.layout[1][1]:onFocus()
|
||||
@@ -84,18 +90,24 @@ function ButtonTable:init()
|
||||
end
|
||||
end
|
||||
|
||||
function ButtonTable:addHorizontalSep()
|
||||
table.insert(self.container,
|
||||
VerticalSpan:new{ width = Size.span.vertical_default })
|
||||
table.insert(self.container, LineWidget:new{
|
||||
background = Blitbuffer.COLOR_GREY,
|
||||
dimen = Geom:new{
|
||||
w = self.width,
|
||||
h = self.sep_width,
|
||||
}
|
||||
})
|
||||
table.insert(self.container,
|
||||
VerticalSpan:new{ width = Size.span.vertical_default })
|
||||
function ButtonTable:addHorizontalSep(vspan_before, add_line, vspan_after, black_line)
|
||||
if vspan_before then
|
||||
table.insert(self.container,
|
||||
VerticalSpan:new{ width = Size.span.vertical_default })
|
||||
end
|
||||
if add_line then
|
||||
table.insert(self.container, LineWidget:new{
|
||||
background = black_line and Blitbuffer.COLOR_BLACK or Blitbuffer.COLOR_GREY,
|
||||
dimen = Geom:new{
|
||||
w = self.width,
|
||||
h = self.sep_width,
|
||||
}
|
||||
})
|
||||
end
|
||||
if vspan_after then
|
||||
table.insert(self.container,
|
||||
VerticalSpan:new{ width = Size.span.vertical_default })
|
||||
end
|
||||
end
|
||||
|
||||
function ButtonTable:onSelectByKeyPress()
|
||||
|
||||
@@ -33,6 +33,7 @@ local Size = require("ui/size")
|
||||
local TextBoxWidget = require("ui/widget/textboxwidget")
|
||||
local UIManager = require("ui/uimanager")
|
||||
local VerticalGroup = require("ui/widget/verticalgroup")
|
||||
local VerticalSpan = require("ui/widget/verticalspan")
|
||||
local logger = require("logger")
|
||||
local _ = require("gettext")
|
||||
local Screen = Device.screen
|
||||
@@ -48,25 +49,28 @@ local ConfirmBox = InputContainer:new{
|
||||
other_buttons = nil,
|
||||
margin = Size.margin.default,
|
||||
padding = Size.padding.default,
|
||||
dismissable = true, -- set to false if any button callback is required
|
||||
}
|
||||
|
||||
function ConfirmBox:init()
|
||||
if Device:isTouchDevice() then
|
||||
self.ges_events.TapClose = {
|
||||
GestureRange:new{
|
||||
ges = "tap",
|
||||
range = Geom:new{
|
||||
x = 0, y = 0,
|
||||
w = Screen:getWidth(),
|
||||
h = Screen:getHeight(),
|
||||
if self.dismissable then
|
||||
if Device:isTouchDevice() then
|
||||
self.ges_events.TapClose = {
|
||||
GestureRange:new{
|
||||
ges = "tap",
|
||||
range = Geom:new{
|
||||
x = 0, y = 0,
|
||||
w = Screen:getWidth(),
|
||||
h = Screen:getHeight(),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
end
|
||||
if Device:hasKeys() then
|
||||
self.key_events = {
|
||||
Close = { {"Back"}, doc = "cancel" }
|
||||
}
|
||||
end
|
||||
if Device:hasKeys() then
|
||||
self.key_events = {
|
||||
Close = { {"Back"}, doc = "cancel" }
|
||||
}
|
||||
end
|
||||
end
|
||||
local content = HorizontalGroup:new{
|
||||
align = "center",
|
||||
@@ -127,9 +131,12 @@ function ConfirmBox:init()
|
||||
background = Blitbuffer.COLOR_WHITE,
|
||||
margin = self.margin,
|
||||
padding = self.padding,
|
||||
padding_bottom = 0, -- no padding below buttontable
|
||||
VerticalGroup:new{
|
||||
align = "left",
|
||||
content,
|
||||
-- Add same vertical space after than before content
|
||||
VerticalSpan:new{ width = self.margin + self.padding },
|
||||
button_table,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,6 +30,10 @@ local FrameContainer = WidgetContainer:new{
|
||||
radius = 0,
|
||||
bordersize = Size.border.window,
|
||||
padding = Size.padding.default,
|
||||
padding_top = nil,
|
||||
padding_right = nil,
|
||||
padding_bottom = nil,
|
||||
padding_left = nil,
|
||||
width = nil,
|
||||
height = nil,
|
||||
invert = false,
|
||||
@@ -37,9 +41,13 @@ local FrameContainer = WidgetContainer:new{
|
||||
|
||||
function FrameContainer:getSize()
|
||||
local content_size = self[1]:getSize()
|
||||
self._padding_top = self.padding_top or self.padding
|
||||
self._padding_right = self.padding_right or self.padding
|
||||
self._padding_bottom = self.padding_bottom or self.padding
|
||||
self._padding_left = self.padding_left or self.padding
|
||||
return Geom:new{
|
||||
w = content_size.w + ( self.margin + self.bordersize + self.padding ) * 2,
|
||||
h = content_size.h + ( self.margin + self.bordersize + self.padding ) * 2
|
||||
w = content_size.w + ( self.margin + self.bordersize ) * 2 + self._padding_left + self._padding_right,
|
||||
h = content_size.h + ( self.margin + self.bordersize ) * 2 + self._padding_top + self._padding_bottom
|
||||
}
|
||||
end
|
||||
|
||||
@@ -67,8 +75,8 @@ function FrameContainer:paintTo(bb, x, y)
|
||||
end
|
||||
if self[1] then
|
||||
self[1]:paintTo(bb,
|
||||
x + self.margin + self.bordersize + self.padding,
|
||||
y + self.margin + self.bordersize + self.padding)
|
||||
x + self.margin + self.bordersize + self._padding_left,
|
||||
y + self.margin + self.bordersize + self._padding_top)
|
||||
end
|
||||
if self.invert then
|
||||
bb:invertRect(x + self.bordersize, y + self.bordersize,
|
||||
|
||||
@@ -154,8 +154,9 @@ function DateWidget:update()
|
||||
}
|
||||
|
||||
local ok_cancel_buttons = ButtonTable:new{
|
||||
width = Screen:getWidth()*0.9,
|
||||
width = self.width - 2*Size.padding.default,
|
||||
buttons = buttons,
|
||||
zero_sep = true,
|
||||
show_parent = self,
|
||||
}
|
||||
|
||||
@@ -176,8 +177,13 @@ function DateWidget:update()
|
||||
},
|
||||
date_group
|
||||
},
|
||||
date_line,
|
||||
ok_cancel_buttons
|
||||
CenterContainer:new{
|
||||
dimen = Geom:new{
|
||||
w = self.width,
|
||||
h = ok_cancel_buttons:getSize().h,
|
||||
},
|
||||
ok_cancel_buttons
|
||||
}
|
||||
}
|
||||
}
|
||||
self[1] = WidgetContainer:new{
|
||||
|
||||
@@ -47,13 +47,20 @@ function FrontLightWidget:init()
|
||||
self.steps = self.steps + 1
|
||||
end
|
||||
self.steps = math.min(self.steps , steps_fl)
|
||||
|
||||
-- button width to fit screen size
|
||||
self.button_width = math.floor(self.screen_width * 0.9 / self.steps) - 12
|
||||
local button_margin = Size.margin.tiny
|
||||
local button_padding = Size.padding.button
|
||||
local button_bordersize = Size.border.button
|
||||
self.button_width = math.floor(self.screen_width * 0.9 / self.steps) -
|
||||
2 * (button_margin + button_padding + button_bordersize)
|
||||
|
||||
self.fl_prog_button = Button:new{
|
||||
text = "",
|
||||
radius = 0,
|
||||
margin = Size.margin.tiny,
|
||||
margin = button_margin,
|
||||
padding = button_padding,
|
||||
bordersize = button_bordersize,
|
||||
enabled = true,
|
||||
width = self.button_width,
|
||||
show_parent = self,
|
||||
@@ -124,9 +131,7 @@ function FrontLightWidget:setProgress(num, step)
|
||||
for i = step_min, step_num do
|
||||
table.insert(fl_group, self.fl_prog_button:new{
|
||||
text= "",
|
||||
margin = Size.margin.tiny,
|
||||
preselect = true,
|
||||
width = self.button_width,
|
||||
callback = function()
|
||||
if i == step_min then
|
||||
self:setProgress(self.fl_min, step)
|
||||
@@ -215,12 +220,16 @@ function FrontLightWidget:setProgress(num, step)
|
||||
}
|
||||
table.insert(button_group_up, button_table_up)
|
||||
table.insert(button_group_down, button_table_down)
|
||||
table.insert(vertical_group,padding_span)
|
||||
table.insert(vertical_group,button_group_up)
|
||||
table.insert(vertical_group,padding_span)
|
||||
table.insert(vertical_group,fl_group)
|
||||
table.insert(vertical_group,padding_span)
|
||||
table.insert(vertical_group,button_group_down)
|
||||
table.insert(vertical_group,padding_span)
|
||||
table.insert(self.fl_container, vertical_group)
|
||||
-- Reset container height to what it actually contains
|
||||
self.fl_container.dimen.h = vertical_group:getSize().h
|
||||
|
||||
UIManager:setDirty("all", "ui")
|
||||
return true
|
||||
|
||||
@@ -47,7 +47,7 @@ local ImageViewer = InputContainer:new{
|
||||
title_padding = Size.padding.default,
|
||||
title_margin = Size.margin.title,
|
||||
image_padding = Size.margin.small,
|
||||
button_padding = Size.padding.large,
|
||||
button_padding = Size.padding.default,
|
||||
|
||||
-- sensitivity for hold (trigger full refresh) vs pan (move image)
|
||||
pan_threshold = Screen:scaleBySize(5),
|
||||
@@ -155,7 +155,7 @@ function ImageViewer:update()
|
||||
},
|
||||
}
|
||||
local button_table = ButtonTable:new{
|
||||
width = self.width,
|
||||
width = self.width - 2*self.button_padding,
|
||||
button_font_face = "cfont",
|
||||
button_font_size = 20,
|
||||
buttons = buttons,
|
||||
|
||||
@@ -60,9 +60,9 @@ local RenderText = require("ui/rendertext")
|
||||
local Size = require("ui/size")
|
||||
local TextBoxWidget = require("ui/widget/textboxwidget")
|
||||
local TextWidget = require("ui/widget/textwidget")
|
||||
local VerticalGroup = require("ui/widget/verticalgroup")
|
||||
local WidgetContainer = require("ui/widget/container/widgetcontainer")
|
||||
local UIManager = require("ui/uimanager")
|
||||
local VerticalGroup = require("ui/widget/verticalgroup")
|
||||
local VerticalSpan = require("ui/widget/verticalspan")
|
||||
local Screen = require("device").screen
|
||||
|
||||
local InputDialog = InputContainer:new{
|
||||
@@ -87,7 +87,7 @@ local InputDialog = InputContainer:new{
|
||||
title_margin = Size.margin.title,
|
||||
input_padding = Size.padding.large,
|
||||
input_margin = Size.margin.default,
|
||||
button_padding = Size.padding.large,
|
||||
button_padding = Size.padding.default,
|
||||
}
|
||||
|
||||
function InputDialog:init()
|
||||
@@ -120,11 +120,11 @@ function InputDialog:init()
|
||||
TextBoxWidget:new{
|
||||
text = self.description,
|
||||
face = self.description_face,
|
||||
width = self.width,
|
||||
width = self.width - 2*self.title_padding - 2*self.title_margin,
|
||||
}
|
||||
}
|
||||
else
|
||||
self.description = WidgetContainer:new()
|
||||
self.description = VerticalSpan:new{ width = self.title_margin + self.title_padding }
|
||||
end
|
||||
|
||||
self._input_widget = InputText:new{
|
||||
@@ -149,7 +149,7 @@ function InputDialog:init()
|
||||
parent = self,
|
||||
}
|
||||
self.button_table = ButtonTable:new{
|
||||
width = self.width,
|
||||
width = self.width - 2*self.button_padding,
|
||||
button_font_face = "cfont",
|
||||
button_font_size = 20,
|
||||
buttons = self.buttons,
|
||||
@@ -159,7 +159,7 @@ function InputDialog:init()
|
||||
|
||||
self.title_bar = LineWidget:new{
|
||||
dimen = Geom:new{
|
||||
w = self.button_table:getSize().w + 2*self.button_padding,
|
||||
w = self.width,
|
||||
h = Size.line.thick,
|
||||
}
|
||||
}
|
||||
@@ -182,6 +182,8 @@ function InputDialog:init()
|
||||
},
|
||||
self._input_widget,
|
||||
},
|
||||
-- Add same vertical space after than before InputText
|
||||
VerticalSpan:new{ width = self.title_margin + self.title_padding },
|
||||
-- buttons
|
||||
CenterContainer:new{
|
||||
dimen = Geom:new{
|
||||
|
||||
@@ -19,8 +19,11 @@ Example:
|
||||
local Blitbuffer = require("ffi/blitbuffer")
|
||||
local ButtonTable = require("ui/widget/buttontable")
|
||||
local CenterContainer = require("ui/widget/container/centercontainer")
|
||||
local Device = require("device")
|
||||
local Font = require("ui/font")
|
||||
local FrameContainer = require("ui/widget/container/framecontainer")
|
||||
local Geom = require("ui/geometry")
|
||||
local GestureRange = require("ui/gesturerange")
|
||||
local HorizontalGroup = require("ui/widget/horizontalgroup")
|
||||
local HorizontalSpan = require("ui/widget/horizontalspan")
|
||||
local ImageWidget = require("ui/widget/imagewidget")
|
||||
@@ -29,6 +32,7 @@ local Size = require("ui/size")
|
||||
local TextBoxWidget = require("ui/widget/textboxwidget")
|
||||
local UIManager = require("ui/uimanager")
|
||||
local VerticalGroup = require("ui/widget/verticalgroup")
|
||||
local VerticalSpan = require("ui/widget/verticalspan")
|
||||
local logger = require("logger")
|
||||
local _ = require("gettext")
|
||||
local Screen = require("device").screen
|
||||
@@ -45,9 +49,29 @@ local MultiConfirmBox = InputContainer:new{
|
||||
cancel_callback = function() end,
|
||||
margin = Size.margin.default,
|
||||
padding = Size.padding.default,
|
||||
dismissable = true, -- set to false if any button callback is required
|
||||
}
|
||||
|
||||
function MultiConfirmBox:init()
|
||||
if self.dismissable then
|
||||
if Device:isTouchDevice() then
|
||||
self.ges_events.TapClose = {
|
||||
GestureRange:new{
|
||||
ges = "tap",
|
||||
range = Geom:new{
|
||||
x = 0, y = 0,
|
||||
w = Screen:getWidth(),
|
||||
h = Screen:getHeight(),
|
||||
}
|
||||
}
|
||||
}
|
||||
end
|
||||
if Device:hasKeys() then
|
||||
self.key_events = {
|
||||
Close = { {"Back"}, doc = "cancel" }
|
||||
}
|
||||
end
|
||||
end
|
||||
local content = HorizontalGroup:new{
|
||||
align = "center",
|
||||
ImageWidget:new{
|
||||
@@ -100,9 +124,12 @@ function MultiConfirmBox:init()
|
||||
background = Blitbuffer.COLOR_WHITE,
|
||||
margin = self.margin,
|
||||
padding = self.padding,
|
||||
padding_bottom = 0, -- no padding below buttontable
|
||||
VerticalGroup:new{
|
||||
align = "left",
|
||||
content,
|
||||
-- Add same vertical space after than before content
|
||||
VerticalSpan:new{ width = self.margin + self.padding },
|
||||
button_table,
|
||||
}
|
||||
}
|
||||
@@ -126,6 +153,14 @@ function MultiConfirmBox:onClose()
|
||||
return true
|
||||
end
|
||||
|
||||
function MultiConfirmBox:onTapClose(arg, ges)
|
||||
if ges.pos:notIntersectWith(self[1][1].dimen) then
|
||||
self:onClose()
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function MultiConfirmBox:onSelect()
|
||||
logger.dbg("selected:", self.selected.x)
|
||||
if self.selected.x == 1 then
|
||||
|
||||
@@ -10,6 +10,7 @@ local Size = require("ui/size")
|
||||
local TextBoxWidget = require("ui/widget/textboxwidget")
|
||||
local UIManager = require("ui/uimanager")
|
||||
local VerticalGroup = require("ui/widget/verticalgroup")
|
||||
local VerticalSpan = require("ui/widget/verticalspan")
|
||||
local _ = require("gettext")
|
||||
local Screen = Device.screen
|
||||
|
||||
@@ -75,6 +76,14 @@ function MultiInputDialog:init()
|
||||
})
|
||||
end
|
||||
|
||||
-- Add same vertical space after than before InputText
|
||||
table.insert(VerticalGroupData,CenterContainer:new{
|
||||
dimen = Geom:new{
|
||||
w = self.title_bar:getSize().w,
|
||||
h = self.description_padding + self.description_margin,
|
||||
},
|
||||
VerticalSpan:new{ width = self.description_padding + self.description_margin },
|
||||
})
|
||||
-- buttons
|
||||
table.insert(VerticalGroupData,CenterContainer:new{
|
||||
dimen = Geom:new{
|
||||
|
||||
@@ -43,7 +43,7 @@ local TextViewer = InputContainer:new{
|
||||
title_margin = Size.margin.title,
|
||||
text_padding = Size.padding.large,
|
||||
text_margin = Size.margin.small,
|
||||
button_padding = Size.padding.large,
|
||||
button_padding = Size.padding.default,
|
||||
}
|
||||
|
||||
function TextViewer:init()
|
||||
|
||||
@@ -139,8 +139,9 @@ function TimeWidget:update()
|
||||
}
|
||||
|
||||
local ok_cancel_buttons = ButtonTable:new{
|
||||
width = Screen:getWidth()*0.9,
|
||||
width = self.width - 2*Size.padding.default,
|
||||
buttons = buttons,
|
||||
zero_sep = true,
|
||||
show_parent = self,
|
||||
}
|
||||
|
||||
@@ -160,8 +161,13 @@ function TimeWidget:update()
|
||||
},
|
||||
time_group
|
||||
},
|
||||
time_line,
|
||||
ok_cancel_buttons
|
||||
CenterContainer:new{
|
||||
dimen = Geom:new{
|
||||
w = self.width,
|
||||
h = ok_cancel_buttons:getSize().h,
|
||||
},
|
||||
ok_cancel_buttons
|
||||
}
|
||||
}
|
||||
}
|
||||
self[1] = WidgetContainer:new{
|
||||
|
||||
Reference in New Issue
Block a user