Module ui.widget.dictquicklookup
This module renders the dictionary widget.
Dictionary button extension API (for plugins)
Plugins can extend dictionary popup buttons via:
ReaderDictionary:addToDictButtons(spec)
Specs are consumed in two places: 1. ReaderDictionary customize menu generation. 2. DictQuickLookup runtime button pool + layout assembly.
There is one unified spec model for both persistent and transient actions.
Registration lifecycle
- Register once (typically in plugin init) when
self.ui.dictionaryexists. - Specs are stored by id; ids must be unique.
- Popup instances are created later; callbacks run per popup instance.
Spec fields
Required:
- id (string): unique key used in config/layout/button lookup.
Labels:
- menu_text (string): entry label in "Customize buttons" selector (non-conditional only).
- text (string): static runtime button label.
- text_func (function(dict_popup) -> string): dynamic runtime label.
Visibility and enabled state:
- show_func (function(dict_popup) -> bool): runtime visibility gate (default true).
- enabled (bool): static enabled state.
- enable_func (function(dict_popup) -> bool): dynamic enabled state (takes precedence over enabled).
Actions:
- callback (function(dict_popup)): tap action.
- hold_callback (function(dict_popup)): long-press action.
Layout and style:
- conditional (bool): runtime-only transient button/row if true.
- row_group (string): group conditional buttons into same transient row.
- pairs_with (string|string[]): pairing hint used alongside can_shrink to create compact rows.
- insert_first (bool): non-conditional auto insertion at top of default layout.
- can_shrink (bool): allow width shrink in 4-button rows when paired.
- auto_row_style_width_min_row_size (int): minimum number of buttons per row to apply auto styling.
- auto_row_style_width_ratio (float): width percentage being given to the button when auto styling is applied.
- vsync (bool): propagated to button entry.
Persistent vs transient behavior
Non-conditional (conditional ~= true):
- Can appear in Customize buttons menu when menu_text is provided.
- Can be toggled/sorted by users through dictionary button customization.
- On fresh installs (no dict_button_config), can be auto-added to default_layout.
Conditional or transient (conditional == true):
- Runtime-only, appended via extra_layout.
- Not user-toggleable in persistent customization.
- Usually used for context-dependent actions (review buttons, link-dependent actions, etc).
Conditional row grouping rules
- If
row_groupis shared, buttons join one transient row. - Else, each conditional button becomes its own transient row.
Runtime layout pipeline
At popup build time (buildButtonLayout):
1. Built-in buttons are created (_getButtonPool).
2. Base layout is selected (default/config/wiki variants).
3. ReaderDictionary injects plugin buttons into pool/layout.
4. Transient extra_layout rows are appended.
5. Row styling/shrink logic is applied.
Ordering
Registered specs are iterated with ffiUtil.orderedPairs (alphabetical by key).
This gives deterministic order for:
- default insertion,
- conditional row key discovery,
- and final row composition.
Usage:
function MyPlugin:registerDictButtons()
if self.ui and self.ui.dictionary then
self.ui.dictionary:addToDictButtons({
id = "my_custom_action",
menu_text = _("My custom action"),
text_func = function(dict_popup)
return dict_popup._my_custom_action_state and _("Disable action") or _("Enable action")
end,
insert_first = true,
show_func = function(dict_popup)
return true -- or some condition based on dict_popup
end,
callback = function(dict_popup)
local current = dict_popup._my_custom_action_state == true
dict_popup._my_custom_action_state = not current
end,
})
end
end