@ -151,6 +151,8 @@ local MenuItem = InputContainer:new{
multilines_show_more_text = false ,
-- Align text & mandatory baselines (only when single_line=true)
align_baselines = false ,
-- Show a line of dots (also called tab or dot leaders) between text and mandatory
with_dots = false ,
}
function MenuItem : init ( )
@ -265,6 +267,9 @@ function MenuItem:init()
text = self.bidi_wrap_func ( text )
end
local dots_widget
local dots_left_padding = Size.padding . small
local dots_right_padding = Size.padding . small
if self.single_line then -- items only in single line
-- No font size change: text will be truncated if it overflows
item_name = TextWidget : new {
@ -279,21 +284,54 @@ function MenuItem:init()
-- feeling (which might make it no more truncated, but well...)
local text_max_width_if_ellipsis = available_width + text_mandatory_padding - text_ellipsis_mandatory_padding
item_name : setMaxWidth ( text_max_width_if_ellipsis )
else
if self.with_dots then
local dots_width = available_width + text_mandatory_padding - w - dots_left_padding - dots_right_padding
if dots_width > 0 then
local dots_text , dots_min_width = self : getDotsText ( self.info_face )
-- Don't show any dots if there would be less than 3
if dots_width >= dots_min_width then
dots_widget = TextWidget : new {
text = dots_text ,
face = self.info_face , -- same as mandatory widget, to keep their baseline adjusted
max_width = dots_width ,
truncate_with_ellipsis = false ,
}
end
end
end
end
if self.align_baselines then -- Align baselines of text and mandatory
-- The container widgets would additionally center these widgets,
-- so make sure they all get a height=self.dimen.h so they don't
-- risk being shifted later and becoming misaligned
local name_baseline = item_name : getBaseline ( )
local mandatory_baseline = mandatory_widget : getBaseline ( )
local baselines_diff = Math.round ( name_baseline - mandatory_baseline )
local mdtr_baseline = mandatory_widget : getBaseline ( )
local name_height = item_name : getSize ( ) . h
local mdtr_height = mandatory_widget : getSize ( ) . h
-- Make all the TextWidgets be self.dimen.h
item_name.forced_height = self.dimen . h
mandatory_widget.forced_height = self.dimen . h
if dots_widget then
dots_widget.forced_height = self.dimen . h
end
-- And adjust their baselines for proper centering and alignment
-- (We made sure the font sizes wouldn't exceed self.dimen.h, so we
-- get only non-negative pad_top here, and we're moving them down.)
local name_missing_pad_top = math.floor ( ( self.dimen . h - name_height ) / 2 )
local mdtr_missing_pad_top = math.floor ( ( self.dimen . h - mdtr_height ) / 2 )
name_baseline = name_baseline + name_missing_pad_top
mdtr_baseline = mdtr_baseline + mdtr_missing_pad_top
local baselines_diff = Math.round ( name_baseline - mdtr_baseline )
if baselines_diff > 0 then
mandatory_widget = VerticalGroup : new {
VerticalSpan : new { width = baselines_diff } ,
mandatory_widget ,
}
elseif baselines_diff < 0 then
item_name = VerticalGroup : new {
VerticalSpan : new { width = - baselines_diff } ,
item_name ,
}
mdtr_baseline = mdtr_baseline + baselines_diff
else
name_baseline = name_baseline - baselines_diff
end
item_name.forced_baseline = name_baseline
mandatory_widget.forced_baseline = mdtr_baseline
if dots_widget then
dots_widget.forced_baseline = mdtr_baseline
end
end
@ -381,6 +419,13 @@ function MenuItem:init()
}
}
if dots_widget then
mandatory_widget = HorizontalGroup : new {
dots_widget ,
HorizontalSpan : new { width = dots_right_padding } ,
mandatory_widget ,
}
end
local mandatory_container = RightContainer : new {
dimen = Geom : new { w = self.content_width , h = self.dimen . h } ,
mandatory_widget ,
@ -427,6 +472,34 @@ function MenuItem:init()
}
end
local _dots_cached_info
function MenuItem : getDotsText ( face )
local screen_w = Screen : getWidth ( )
if not _dots_cached_info or _dots_cached_info.screen_width ~= screen_w
or _dots_cached_info.face ~= face then
local unit = " . "
local tmp = TextWidget : new {
text = unit ,
face = face ,
}
local unit_w = tmp : getSize ( ) . w
tmp : free ( )
-- (We assume/expect no kerning will happen between consecutive units)
local nb_units = math.ceil ( screen_w / unit_w )
local min_width = unit_w * 3 -- have it not shown if smaller than this
local text = unit : rep ( nb_units )
_dots_cached_info = {
text = text ,
min_width = min_width ,
screen_width = screen_w ,
face = face ,
}
end
return _dots_cached_info.text , _dots_cached_info.min_width
end
function MenuItem : onFocus ( initial_focus )
if Device : isTouchDevice ( ) then
-- Devices which are Keys capable will get this onFocus called by
@ -1079,6 +1152,7 @@ function Menu:updateItems(select_number)
single_line = self.single_line ,
multilines_show_more_text = multilines_show_more_text ,
align_baselines = self.align_baselines ,
with_dots = self.with_dots ,
line_color = self.line_color ,
items_padding = self.items_padding ,
}