Implement Label buddies

This commit is contained in:
Christian Kaiser 2025-08-14 22:14:31 -03:00
parent 7e4f9ad078
commit f494b8f343
63 changed files with 321 additions and 219 deletions

View File

@ -4,27 +4,27 @@
<vbox id="brush_slot_params">
<grid columns="2">
<label text="@.brush" />
<label text="@.brush" for="brush_params" />
<buttonset id="brush_params" columns="3" multiple="true">
<item id="brush_type" text="@.brush_type" />
<item id="brush_size" text="@.brush_size" />
<item id="brush_angle" text="@.brush_angle" />
</buttonset>
<label text="@.color" />
<label text="@.color" for="color_params" />
<buttonset id="color_params" columns="2" multiple="true">
<item id="fg_color" text="@.foreground" />
<item id="bg_color" text="@.background" />
<item id="image_color" text="@.image_color" hspan="2" />
</buttonset>
<label text="@.ink" />
<label text="@.ink" for="ink_params" />
<buttonset id="ink_params" columns="2" multiple="true">
<item id="ink_type" text="@.ink_type" />
<item id="ink_opacity" text="@.ink_opacity" />
</buttonset>
<label text="@.extras" />
<label text="@.extras" for="extra_params" />
<buttonset id="extra_params" columns="2" multiple="true">
<item id="shade" text="@.shade" />
<item id="pixel_perfect" text="@.pixel_perfect" />

View File

@ -7,9 +7,9 @@
<separator text="@.size" left="true" horizontal="true" />
<hbox>
<grid columns="2">
<label text="@.width" />
<label text="@.width" for="width" />
<expr text="0" id="width" suffix="px" magnet="true" />
<label text="@.height" />
<label text="@.height" for="height" />
<expr text="0" id="height" suffix="px" />
<hbox filler="true" cell_hspan="2" />
</grid>
@ -28,16 +28,16 @@
<separator text="@.borders" left="true" horizontal="true" />
<grid columns="4">
<label text="@.left" />
<label text="@.left" for="left" />
<expr text="0" id="left" suffix="px" tooltip="@.left_tooltip" />
<label text="@.top" />
<label text="@.top" for="top" />
<expr text="0" id="top" suffix="px" tooltip="@.top_tooltip" />
<label text="@.right" />
<label text="@.right" for="right" />
<expr text="0" id="right" suffix="px" tooltip="@.right_tooltip" />
<label text="@.bottom" />
<label text="@.bottom" for="bottom" />
<expr text="0" id="bottom" suffix="px" tooltip="@.bottom_tooltip" />
</grid>

View File

@ -4,11 +4,11 @@
<gui>
<window id="cel_properties" text="@.title">
<grid id="properties_grid" columns="4">
<label text="@.opacity" />
<label text="@.opacity" for="opacity" />
<opacityslider id="opacity" cell_align="horizontal" width="128" cell_hspan="2" />
<button id="user_data" icon="icon_user_data" tooltip="@.user_data_tooltip" />
<label text="@.zindex" />
<label text="@.zindex" for="zindex" />
<expr id="zindex" cell_align="horizontal" width="128" />
<buttonset id="zindex_spin" columns="1">
<item icon="spin_up" />

View File

@ -5,10 +5,10 @@
<vbox>
<hbox expansive="true">
<grid columns="2">
<label text="@.x" />
<label text="@.x" for="x" />
<expr id="x" magnet="true" />
<label text="@.y" />
<label text="@.y" for="y" />
<expr id="y" />
</grid>
</hbox>

View File

@ -9,9 +9,9 @@
</view>
<hbox id="dithering_placeholder" />
<hbox id="amount">
<label text="@.amount" />
<label text="@.amount" for="factor" />
<slider min="0" max="100" id="factor" minwidth="100" />
<label text="%" />
<label text="%" for="factor" />
</hbox>
<combobox id="to_gray_combobox">
@ -24,10 +24,10 @@
<check id="advanced_check" text="@general.advanced_options" />
<grid id="advanced" columns="2">
<label text="@rgbmap_algorithm_selector.label" />
<label text="@rgbmap_algorithm_selector.label" for="rgbmap_algorithm_selector" />
<hbox id="rgbmap_algorithm_placeholder" cell_align="horizontal" />
<label text="@best_fit_criteria_selector.label" />
<label text="@best_fit_criteria_selector.label" for="best_fit_criteria_selector" />
<hbox id="best_fit_criteria_placeholder" cell_align="horizontal" />
</grid>

View File

@ -3,7 +3,7 @@
<gui>
<window id="css_options" text="@.title">
<grid columns="2">
<label text="@.pixel_scale" />
<label text="@.pixel_scale" for="pixel_scale" />
<expr id="pixel_scale" magnet="true" cell_align="horizontal"/>
<check text="@.with_vars" id="with_vars" cell_hspan="2" />

View File

@ -3,9 +3,9 @@
<gui>
<hbox id="despeckle">
<grid columns="2">
<label text="@.width" />
<label text="@.width" for="width" />
<expr id="width" cell_align="horizontal" />
<label text="@.height" />
<label text="@.height" for="height" />
<expr id="height" cell_align="horizontal" />
</grid>
</hbox>

View File

@ -3,16 +3,13 @@
<gui>
<window id="duplicate_sprite" text="@.title">
<box vertical="true">
<box horizontal="true" expansive="true">
<box vertical="true" homogeneous="true">
<grid columns="2">
<label text="@.duplicate" />
<label text="@.as" />
</box>
<box vertical="true" homogeneous="true" expansive="true">
<label text="" id="src_name" />
<entry maxsize="256" id="dst_name" magnet="true" />
</box>
</box>
<label text="" id="src_name" cell_align="horizontal" />
<label text="@.as" for="dst_name" />
<entry maxsize="256" id="dst_name" magnet="true" cell_align="horizontal" />
</grid>
<check text="@.merged_layers" id="flatten" />
<box horizontal="true" homogeneous="true">
<button text="@general.ok" closewindow="true" id="ok" magnet="true" />

View File

@ -32,29 +32,29 @@
<grid id="options" columns="2" childspacing="0" expansive="true">
<separator id="separator" text="@.max_point_value" horizontal="true" cell_hspan="2" />
<label id="size_label" text="@.size" style="mini_label" />
<label id="size_label" text="@.size" style="mini_label" for="min_size" />
<slider id="min_size" value="1" min="1" max="64" cell_align="horizontal" style="mini_slider"
tooltip="@.min_size_tooltip" tooltip_dir="left" />
<boxfiller />
<slider id="max_size" value="64" min="1" max="64" cell_align="horizontal" style="mini_slider"
tooltip="@.max_size_tooltip" tooltip_dir="left" />
<label id="angle_label" text="@.angle" style="mini_label" />
<label id="angle_label" text="@.angle" style="mini_label" for="min_angle" />
<slider id="min_angle" value="0" min="-180" max="+180" cell_align="horizontal" style="mini_slider"
tooltip="@.min_angle_tooltip" tooltip_dir="left" />
<boxfiller />
<slider id="max_angle" value="0" min="-180" max="+180" cell_align="horizontal" style="mini_slider"
tooltip="@.max_angle_tooltip" tooltip_dir="left" />
<label id="gradient_label" text="@.gradient" style="mini_label" />
<label id="gradient_label" text="@.gradient" style="mini_label" for="dithering_selector" />
<hbox id="gradient_placeholder" cell_vspan="2" />
<link id="gradient_from_to" style="mini_label" />
<separator id="separator2" text="@.sensors_tweaks" horizontal="true" cell_hspan="2" />
<label id="pressure_label" text="@.pressure" style="mini_label" />
<label id="pressure_label" text="@.pressure" style="mini_label" for="pressure_slider" />
<hbox id="pressure_placeholder" cell_align="horizontal" />
<label id="velocity_label" text="@.velocity" style="mini_label" />
<label id="velocity_label" text="@.velocity" style="mini_label" for="velocity_slider" />
<hbox id="velocity_placeholder" cell_align="horizontal" />
</grid>
<separator horizontal="true" cell_hspan="2" />

View File

@ -4,9 +4,9 @@
<gui>
<window id="export_file" text="@.title" help="exporting">
<grid columns="3">
<label text="@.output_file" />
<label text="@.output_file" for="output_field" />
<filename id="output_field" cell_align="horizontal" cell_hspan="2" />
<label id="resize_label" text="@.resize" />
<label id="resize_label" text="@.resize" for="resize" />
<hbox cell_hspan="2" cell_align="horizontal">
<combobox id="resize" editable="true" suffix="%" expansive="true">
<listitem text="25" />
@ -22,17 +22,17 @@
<listitem text="900" />
<listitem text="1000" />
</combobox>
<label id="area_label" text="@.area" />
<label id="area_label" text="@.area" for="area" />
<combobox id="area" text="" cell_align="horizontal" cell_hspan="2" expansive="true" />
</hbox>
<label id="layers_label" text="@.layers" />
<label id="layers_label" text="@.layers" for="layers" />
<combobox id="layers" text="" cell_align="horizontal" cell_hspan="2" />
<label id="frames_label" text="@.frames" />
<label id="frames_label" text="@.frames" for="frames" />
<combobox id="frames" text="" cell_align="horizontal" cell_hspan="2" />
<label id="anidir_label" text="@.anidir" />
<label id="anidir_label" text="@.anidir" for="anidir" />
<combobox id="anidir" text="" cell_align="horizontal" cell_hspan="2" />
<check id="play_subtags" text="@.play_subtags" cell_hspan="3" />

View File

@ -25,11 +25,11 @@
<!-- Layout -->
<grid id="section_layout" columns="4" expansive="true">
<label text="@.sheet_type" />
<label text="@.sheet_type" for="sheet_type" />
<combobox id="sheet_type" expansive="true" cell_hspan="3" cell_align="horizontal"
tooltip="@.sheet_type_tooltip" tooltip_dir="bottom" />
<label text="@.constraints" />
<label text="@.constraints" for="constraint_type" />
<hbox cell_hspan="3">
<combobox id="constraint_type" tooltip="@.constraints_tooltip" />
<expr id="width_constraint" />
@ -50,15 +50,15 @@
<button id="close_sprite_section" icon="window_close_icon" />
</hbox>
<grid id="section_sprite" columns="4" expansive="true">
<label text="@.source" />
<label text="@.source" for="source" />
<combobox id="source" text="" cell_hspan="2" cell_align="horizontal" />
<boxfiller />
<label text="@.layers" />
<label text="@.layers" for="layers" />
<combobox id="layers" text="" cell_hspan="2" cell_align="horizontal" />
<check id="split_layers" text="@.split_layers" tooltip="@.split_layers_tooltip" tooltip_dir="bottom" />
<label text="@.frames" />
<label text="@.frames" for="frames" />
<combobox id="frames" text="" cell_hspan="2" cell_align="horizontal" />
<check id="split_tags" text="@.split_tags" tooltip="@.split_tags_tooltip" tooltip_dir="top" />
</grid>
@ -75,11 +75,11 @@
<hbox cell_hspan="3">
<vbox>
<grid columns="2">
<label text="@.border" />
<label text="@.border" for="border_padding" />
<expr id="border_padding" text="0" tooltip="@.border_tooltip" />
<label text="@.shape" />
<label text="@.shape" for="shape_padding" />
<expr id="shape_padding" text="0" tooltip="@.shape_tooltip" />
<label text="@.inner" />
<label text="@.inner" for="inner_padding" />
<expr id="inner_padding" text="0" tooltip="@.inner_tooltip" />
</grid>
</vbox>
@ -130,12 +130,12 @@
<hbox />
<grid id="data_formats_placeholder" columns="3" cell_hspan="3" cell_align="horizontal">
<label text="@.data_filename_format" />
<label text="@.data_filename_format" for="data_filename_format" />
<entry id="data_filename_format" maxsize="1024" maxwidth="256" cell_align="horizontal"
tooltip="@.data_filename_format_tooltip" />
<link text="(?)" url="https://www.aseprite.org/docs/cli/#filename-format" />
<label text="@.data_tagname_format" />
<label text="@.data_tagname_format" for="data_tagname_format" />
<entry id="data_tagname_format" maxsize="1024" maxwidth="256" cell_align="horizontal"
tooltip="@.data_tagname_format_tooltip" />
<link text="(?)" url="https://www.aseprite.org/docs/cli/#tagname-format" />

View File

@ -27,10 +27,10 @@
</box>
<vbox id="file_view_placeholder" expansive="true" />
<grid columns="2">
<label text="@.file_name" />
<label text="@.file_name" for="file_name" />
<box id="file_name_placeholder" cell_align="horizontal" />
<label text="@.file_type" />
<label text="@.file_type" for="file_type" />
<hbox cell_align="horizontal">
<combobox id="file_type" minwidth="70" />
<boxfiller />

View File

@ -8,7 +8,7 @@
<label text="" id="frame" />
<box cell_align="horizontal" />
<label text="@.duration" />
<label text="@.duration" for="frlen" />
<expr id="frlen" magnet="true" />
<box cell_align="horizontal" />

View File

@ -3,7 +3,7 @@
<gui>
<window id="goto_frame" text="@.title">
<vbox>
<label text="@.frame_or_tags" />
<label text="@.frame_or_tags" for="frame" />
<vbox id="frame_placeholder" />
<separator horizontal="true" />

View File

@ -4,16 +4,16 @@
<window id="grid_settings" text="@.title">
<grid columns="4">
<label text="@.x" />
<label text="@.x" for="grid_x" />
<expr id="grid_x" text="" magnet="true" />
<label text="@.y" />
<label text="@.y" for="grid_y" />
<expr id="grid_y" text="" />
<label text="@.width" />
<label text="@.width" for="grid_w" />
<expr id="grid_w" text="" />
<label text="@.height" />
<label text="@.height" for="grid_h" />
<expr id="grid_h" text="" />
<separator horizontal="true" cell_hspan="4" />

View File

@ -7,36 +7,36 @@
<grid columns="4">
<button id="select_file" text="@select_file.text" cell_hspan="4" />
<label text="@.type" />
<label text="@.type" for="sheet_type" />
<combobox id="sheet_type" cell_hspan="3" />
<separator text="@.tiles" horizontal="true" cell_hspan="4" />
<label text="@.x" />
<label text="@.x" for="x" />
<expr id="x" text="0" />
<label text="@.y" />
<label text="@.y" for="y" />
<expr id="y" text="0" />
<label text="@.width" />
<label text="@.width" for="width" />
<expr id="width" text="16" />
<label text="@.height" />
<label text="@.height" for="height" />
<expr id="height" text="16" />
<separator horizontal="true" cell_hspan="4" />
<label text="@.columns" />
<label text="@.columns" for="columns" />
<expr id="columns" />
<label text="@.rows" />
<label text="@.rows" for="rows" />
<expr id="rows" />
<check id="padding_enabled" text="@.padding" cell_hspan="4" />
<label text="@.horizontal_padding" id="horizontal_padding_label" />
<label text="@.horizontal_padding" id="horizontal_padding_label" for="horizontal_padding" />
<expr id="horizontal_padding" text="0" />
<label text="@.vertical_padding" id="vertical_padding_label" />
<label text="@.vertical_padding" id="vertical_padding_label" for="vertical_padding" />
<expr id="vertical_padding" text="0" />
<check id="partial_tiles" text="@.partial_tiles" cell_hspan="4" />

View File

@ -3,7 +3,7 @@
<gui>
<window id="jpeg_options" text="@.title">
<grid columns="2">
<label text="@.quality" />
<label text="@.quality" for="quality" />
<slider min="0" max="10" id="quality" cell_align="horizontal" width="128" />
<separator horizontal="true" cell_hspan="2" />

View File

@ -61,10 +61,8 @@
<listbox id="drag_actions" />
</view>
<separator horizontal="true" />
<hbox>
<vbox>
<label text="@.drag_angle" />
</vbox>
<grid columns="4">
<label text="@.drag_angle" for="drag_angle" cell_align="top" />
<buttonset columns="3" id="drag_angle">
<item icon="canvas_nw"
style="dir_item"
@ -100,15 +98,11 @@
tooltip="@.drag_angle_tooltip"
tooltip_dir="top" />
</buttonset>
<vbox>
<label text="@.drag_distance" />
</vbox>
<vbox>
<slider min="1" max="100" id="drag_distance" cell_align="horizontal" width="128"
tooltip="@.drag_distance_tooltip"
tooltip_dir="bottom" />
</vbox>
</hbox>
<label text="@.drag_distance" for="drag_distance" cell_align="top" />
<box>
<slider min="1" max="100" id="drag_distance" width="128" tooltip="@.drag_distance_tooltip" tooltip_dir="bottom" />
</box>
</grid>
</vbox>
</vbox>
</splitter>

View File

@ -5,18 +5,18 @@
<window id="layer_properties" text="@.title">
<vbox>
<grid id="properties_grid" columns="3">
<label text="@.name" />
<label text="@.name" for="name" />
<entry text="" id="name" magnet="true" maxsize="256" minwidth="64" cell_align="horizontal" />
<button id="user_data" icon="icon_user_data" tooltip="@general.user_data" />
<label text="@.mode" />
<label text="@.mode" for="mode" />
<combobox id="mode" />
<button id="tileset" icon="tiles" tooltip="@.tileset_tooltip" />
<label text="@.opacity" />
<label text="@.opacity" for="opacity" />
<opacityslider id="opacity" width="128" cell_align="horizontal" cell_hspan="2" />
<label id="uuid_label" text="@.uuid" visible="false" />
<label id="uuid_label" text="@.uuid" visible="false" for="uuid" />
<entry id="uuid" readonly="true" maxsize="36" cell_hspan="2" visible="false"/>
</grid>
</vbox>

View File

@ -5,7 +5,7 @@
<vbox>
<grid columns="2">
<label id="by_label" text="" />
<label id="by_label" text="" for="quantity" />
<expr id="quantity" expansive="true" magnet="true" suffix="px" />
<hbox />

View File

@ -4,7 +4,7 @@
<window id="new_folder_window" text="@new_folder.title">
<vbox>
<hbox>
<label text="@new_folder.folder_name" />
<label text="@new_folder.folder_name" for="name" />
<entry text="@new_folder.default_new_folder_name" id="name" maxsize="256" magnet="true" expansive="true" minwidth="128" />
</hbox>
<hbox>

View File

@ -5,7 +5,7 @@
<window id="new_layer" text="@.title" help="new-layer">
<vbox>
<grid columns="2">
<label text="@.name" />
<label text="@.name" for="name" />
<entry maxsize="256" text="@.default_new_layer_name" id="name" magnet="true" />
<vbox>

View File

@ -4,7 +4,7 @@
<window id="new_layout" text="@.title">
<vbox>
<hbox>
<label text="@.name" />
<label text="@.name" for="name" />
<entry maxsize="128" id="name" magnet="true" expansive="true" />
</hbox>

View File

@ -7,9 +7,9 @@
<separator text="@.size" left="true" horizontal="true" />
<grid columns="2">
<label text="@.width" />
<label text="@.width" for="width" />
<expr id="width" magnet="true" cell_align="horizontal" suffix="px" />
<label text="@.height" />
<label text="@.height" for="height" />
<expr id="height" cell_align="horizontal" suffix="px" />
</grid>
@ -29,7 +29,7 @@
<check id="advanced_check" text="@general.advanced_options" />
<vbox id="advanced">
<label text="@.pixel_ratio" />
<label text="@.pixel_ratio" for="pixel_ratio" />
<combobox id="pixel_ratio" cell_align="horizontal">
<listitem text="@.square_pixels" value="1:1" />
<listitem text="@.double_wide" value="2:1" />

View File

@ -4,12 +4,12 @@
<gui>
<window id="open_sequence" text="@.title">
<vbox>
<label text="@.description" />
<label text="@.description" for="files" />
<view expansive="true" id="view" minwidth="128" minheight="64">
<listbox id="files" multiselect="true" />
</view>
<hbox>
<label text="@.duration" />
<label text="@.duration" for="duration" />
<expr text="0" id="duration" suffix="ms" />
</hbox>
<separator horizontal="true" />

View File

@ -36,18 +36,18 @@
<vbox id="section_general">
<separator text="@.section_general" horizontal="true" />
<grid columns="2">
<label text="@.ui_windows" />
<label text="@.ui_windows" for="ui_windows" />
<hbox>
<buttonset columns="2" id="ui_windows">
<item icon="one_win_icon" tooltip="@.one_win" tooltip_dir="bottom" style="multi_window_item" />
<item icon="multi_win_icon" tooltip="@.multi_win" tooltip_dir="bottom" style="multi_window_item" />
</buttonset>
<hbox id="theme_variants">
<label text="@.theme_mode" />
<label id="theme_mode_label" text="@.theme_mode" /> <!-- TODO: Get future dynamic ID, if any -->
</hbox>
</hbox>
<label text="@.screen_scaling" />
<label text="@.screen_scaling" for="screen_scale" />
<combobox id="screen_scale">
<listitem text="100%" value="1" />
<listitem text="200%" value="2" />
@ -55,7 +55,7 @@
<listitem text="400%" value="4" />
</combobox>
<label text="@.ui_scaling" />
<label text="@.ui_scaling" for="ui_scale" />
<combobox id="ui_scale">
<listitem text="100%" value="1" />
<listitem text="200%" value="2" />
@ -125,21 +125,21 @@
<separator text="@.section_files" horizontal="true" />
<label text="@.default_extension_for" />
<grid columns="2">
<label text="@.save_default_extension" />
<label text="@.save_default_extension" for="default_extension" />
<combobox id="default_extension" />
<label text="@.export_image_default_extension" />
<label text="@.export_image_default_extension" for="export_image_default_extension" />
<combobox id="export_image_default_extension" />
<label text="@.export_animation_default_extension" />
<label text="@.export_animation_default_extension" for="export_animation_default_extension" />
<combobox id="export_animation_default_extension" />
<label text="@.export_sprite_sheet_default_extension" />
<label text="@.export_sprite_sheet_default_extension" for="export_sprite_sheet_default_extension" />
<combobox id="export_sprite_sheet_default_extension" />
</grid>
<grid columns="2">
<label text="@.recent_files" />
<label text="@.recent_files" for="recent_files" />
<hbox>
<slider min="0" max="100" id="recent_files" width="128" tooltip="@.recent_files_tooltip" />
<button id="clear_recent_files" text="@.clear_recent_files" tooltip="@.clear_recent_files_tooltip" minwidth="60" />
@ -203,7 +203,7 @@
<check text="@.color_management" id="color_management" pref="color.manage" />
<grid columns="2">
<label text="@.window_cs" id="window_cs_label" />
<label text="@.window_cs" id="window_cs_label" for="window_cs" />
<combobox id="window_cs">
<listitem text="@.use_monitor_cs" />
<listitem text="@.use_srgb_cs" />
@ -213,10 +213,10 @@
<boxfiller />
<separator horizontal="true" />
<label text="@.working_rgb_cs" id="working_rgb_cs_label" />
<label text="@.working_rgb_cs" id="working_rgb_cs_label" for="working_rgb_cs" />
<combobox id="working_rgb_cs" />
<label text="@.files_with_cs" id="files_with_cs_label" />
<label text="@.files_with_cs" id="files_with_cs_label" for="files_with_cs" />
<combobox id="files_with_cs">
<listitem text="@.disable_cs" />
<listitem text="@.use_embedded_cs" />
@ -225,7 +225,7 @@
<listitem text="@.ask_cs" />
</combobox>
<label text="@.missing_cs" id="missing_cs_label" />
<label text="@.missing_cs" id="missing_cs_label" for="missing_cs" />
<combobox id="missing_cs">
<listitem text="@.disable_cs" />
<listitem text="@.assign_cs" />
@ -240,12 +240,12 @@
<separator text="@.alpha_and_opacity" horizontal="true" />
<grid columns="2">
<label text="@.alpha_range" id="alpha_range_label" />
<label text="@.alpha_range" id="alpha_range_label" for="alpha" />
<combobox id="alpha">
<listitem text="@.8bit_value" />
<listitem text="@.percentage" />
</combobox>
<label text="@.opacity_range" id="opacity_range_label" />
<label text="@.opacity_range" id="opacity_range_label" for="opacity" />
<combobox id="opacity">
<listitem text="@.8bit_value" />
<listitem text="@.percentage" />
@ -270,7 +270,7 @@
<check text="@.discard_brush" id="discard_brush" />
<hbox id="sampling_placeholder" />
<hbox>
<label text="@.right_click" />
<label text="@.right_click" for="right_click_behavior" />
<combobox id="right_click_behavior" expansive="true" />
</hbox>
</vbox>
@ -303,7 +303,7 @@
<check text="@.rewind_on_stop" id="rewind_on_stop" tooltip="@.rewind_on_stop_tooltip"
pref="general.rewind_on_stop" />
<hbox>
<label text="@.default_first_frame" />
<label text="@.default_first_frame" for="first_frame" />
<expr id="first_frame" />
</hbox>
<separator text="@.timeline_selection" horizontal="true" />
@ -337,7 +337,7 @@
<separator text="@.ui_mouse_cursor" horizontal="true" />
<check id="native_cursor" text="@.native_cursor" />
<hbox>
<label id="cursor_scale_label" text="@.cursor_scale_label" />
<label id="cursor_scale_label" text="@.cursor_scale_label" for="cursor_scale" />
<combobox id="cursor_scale">
<listitem text="100%" value="1" />
<listitem text="200%" value="2" />
@ -349,13 +349,13 @@
<separator text="@.painting_cursors" horizontal="true" />
<grid columns="2">
<label text="@.crosshair_type" />
<label text="@.crosshair_type" for="painting_cursor_type" />
<combobox id="painting_cursor_type">
<listitem text="@.simple_crosshair" value="0" />
<listitem text="@.crosshair_on_sprite" value="1" />
</combobox>
<label text="@.brush_preview" />
<label text="@.brush_preview" for="brush_preview" />
<combobox id="brush_preview">
<listitem text="@.brush_preview_none" value="0" />
<listitem text="@.brush_preview_edges" value="1" />
@ -364,7 +364,7 @@
<listitem text="@.brush_preview_fullnedges" value="4" />
</combobox>
<label text="@.cursor_color_type" />
<label text="@.cursor_color_type" for="cursor_color_type" />
<combobox id="cursor_color_type">
<listitem text="@.cursor_neg_bw" value="0" />
<listitem text="@.cursor_specific_color" value="1" />
@ -384,7 +384,7 @@
<separator text="@.bg_checkered" horizontal="true" />
<grid columns="2">
<label text="@.bg_size" />
<label text="@.bg_size" for="checkered_bg_size" />
<hbox>
<combobox id="checkered_bg_size" />
<expr id="checkered_bg_custom_w" />
@ -414,23 +414,23 @@
</hbox>
<grid columns="5">
<label text="@.grid_x" />
<label text="@.grid_x" for="grid_x" />
<expr id="grid_x" text="" />
<label text="@.grid_y" />
<label text="@.grid_y" for="grid_y" />
<expr id="grid_y" text="" />
<hbox />
<label text="@.grid_width" />
<label text="@.grid_width" for="grid_w" />
<expr id="grid_w" text="" />
<label text="@.grid_height" />
<label text="@.grid_height" for="grid_h" />
<expr id="grid_h" text="" />
<hbox />
<label text="@.grid_color" />
<label text="@.grid_color" for="grid_color" />
<colorpicker id="grid_color" rgba="true" cell_hspan="3" />
<hbox />
<label text="@.grid_opacity" />
<label text="@.grid_opacity" for="grid_opacity" />
<slider id="grid_opacity" cell_hspan="3" min="1" max="255" width="128" />
<check id="grid_auto_opacity" text="@.grid_auto" />
</grid>
@ -440,11 +440,11 @@
<separator horizontal="true" expansive="true" />
</hbox>
<grid columns="3">
<label text="@.grid_color" />
<label text="@.grid_color" for="pixel_grid_color" />
<colorpicker id="pixel_grid_color" rgba="true" />
<hbox />
<label text="@.grid_opacity" />
<label text="@.grid_opacity" for="pixel_grid_opacity" />
<slider id="pixel_grid_opacity" min="1" max="255" width="128" />
<check id="pixel_grid_auto_opacity" text="@.grid_auto" />
</grid>
@ -459,15 +459,15 @@
<vbox id="section_guides_and_slices">
<separator text="@.guides" horizontal="true" />
<grid columns="2">
<label text="@.layer_edges_color" />
<label text="@.layer_edges_color" for="layer_edges_color" />
<colorpicker id="layer_edges_color" rgba="true" />
<label text="@.auto_guides_color" />
<label text="@.auto_guides_color" for="auto_guides_color" />
<colorpicker id="auto_guides_color" rgba="true" />
</grid>
<separator text="@.slices" horizontal="true" />
<hbox>
<label text="@.default_slice_color" />
<label text="@.default_slice_color" for="default_slice_color" />
<colorpicker id="default_slice_color" rgba="true" />
</hbox>
</vbox>
@ -478,7 +478,7 @@
<hbox>
<check id="limit_undo" text="@.undo_size_limit" />
<expr id="undo_size_limit" tooltip="@.undo_size_limit_tooltip" />
<label text="@.undo_mb" />
<label text="@.undo_mb" for="undo_size_limit" />
</hbox>
<vbox>
@ -496,7 +496,7 @@
<vbox id="section_alerts">
<separator text="@.section_alerts" horizontal="true" />
<hbox>
<label text="@.open_sequence_alert" />
<label text="@.open_sequence_alert" for="open_sequence" />
<combobox id="open_sequence">
<listitem text="@.open_sequence_alert_ask" value="0" />
<listitem text="@.open_sequence_alert_yes" value="1" />
@ -582,7 +582,7 @@
<vbox id="section_aseprite_format">
<separator text="@.section_aseprite_format" horizontal="true" />
<grid columns="2">
<label text="@.cel_content_format" />
<label text="@.cel_content_format" for="cel_format" />
<combobox id="cel_format">
<listitem text="@.cel_format_compressed" />
<listitem text="@.cel_format_keep" />
@ -626,14 +626,14 @@
<check id="flash_layer" text="@.flash_selected_layer" />
<check id="use_selection_tool_loop" text="@.use_selection_tool_loop" />
<hbox>
<label text="@.non_active_layer_opacity" />
<label text="@.non_active_layer_opacity" for="nonactive_layers_opacity" />
<slider id="nonactive_layers_opacity" min="0" max="255" width="128" />
</hbox>
<separator text="@.color_quantization" horizontal="true" />
<grid columns="2">
<label text="@rgbmap_algorithm_selector.label" />
<label text="@rgbmap_algorithm_selector.label" for="rgbmap_algorithm_selector" />
<hbox id="rgbmap_algorithm_placeholder" />
<label text="@best_fit_criteria_selector.label" />
<label text="@best_fit_criteria_selector.label" for="best_fit_criteria_selector" />
<hbox id="best_fit_criteria_placeholder" />
</grid>
<separator text="@.performance" horizontal="true" />

View File

@ -3,9 +3,9 @@
<gui>
<vbox id="outline" expansive="true">
<grid columns="2">
<label text="@.color" />
<label text="@.color" for="color" />
<colorpicker id="color" cell_align="horizontal" />
<label text="@.bg_color" />
<label text="@.bg_color" for="bg_color" />
<colorpicker id="bg_color" cell_align="horizontal" />
</grid>
<hbox>

View File

@ -14,7 +14,7 @@
<check id="alpha_channel" text="@.alpha_channel" cell_hspan="2" />
<check id="advanced_check" text="@general.advanced_options" cell_hspan="2" />
<hbox id="advanced" cell_hspan="2">
<label text="@rgbmap_algorithm_selector.label" />
<label text="@rgbmap_algorithm_selector.label" for="rgbmap_algorithm_selector" />
<hbox id="rgbmap_algorithm_placeholder" />
</hbox>

View File

@ -3,7 +3,7 @@
<gui>
<window id="palette_size" text="@.title">
<grid columns="3">
<label text="@.number_of_colors" />
<label text="@.number_of_colors" for="colors" />
<expr expansive="true" id="colors" magnet="true" />
<box cell_align="horizontal" />

View File

@ -4,13 +4,13 @@
<gui>
<window id="paste_text" text="@.title">
<grid columns="2">
<label text="@.text" />
<label text="@.text" for="user_text" />
<entry expansive="true" maxsize="256" minwidth="256" id="user_text" magnet="true" cell_align="horizontal" />
<label text="@.font" />
<label text="@.font" for="font_face" />
<font id="font_face" cell_align="horizontal" />
<label text="@.color" />
<label text="@.color" for="font_color" />
<hbox>
<colorpicker id="font_color" />
</hbox>

View File

@ -5,13 +5,13 @@
<vbox expansive="true" id="controls">
<hbox expansive="true">
<grid columns="2" id="controls">
<label text="@replace_color.from" />
<label text="@replace_color.from" for="from" />
<colorpicker id="from" cell_align="horizontal" />
<label text="@replace_color.to" />
<label text="@replace_color.to" for="to" />
<colorpicker id="to" cell_align="horizontal" />
</grid>
</hbox>
<label text="@replace_color.tolerance" />
<label text="@replace_color.tolerance" for="tolerance" />
<slider min="0" max="255" id="tolerance" />
</vbox>
</gui>

View File

@ -5,7 +5,7 @@
<window id="select_shortcut" text="@.title">
<vbox expansive="true">
<grid columns="3">
<label text="@.key" />
<label text="@.key" for="key_field" />
<hbox id="key_placeholder" cell_align="horizontal" />
<button text="@.clear" id="clear_button" minwidth="60" />

View File

@ -6,7 +6,7 @@
<window id="slice_properties" text="@.title" help="slices#slice-properties">
<vbox expansive="true">
<grid id="properties_grid" columns="3">
<label id="label1" text="@.name" />
<label text="@.name" for="name" />
<entry id="name" maxsize="256" magnet="true" cell_align="horizontal" expansive="true" />
<button id="user_data" icon="icon_user_data" maxsize="32" tooltip="@.user_data_tooltip" />
</grid>

View File

@ -22,19 +22,19 @@
<grid columns="2">
<separator text="@.advanced" horizontal="true" cell_hspan="2" />
<label text="@.transparent_color" />
<label text="@.transparent_color" for="transparent_color" />
<hbox>
<hbox id="transparent_color_placeholder" />
</hbox>
<label text="@.pixel_ratio" />
<label text="@.pixel_ratio" for="pixel_ratio" />
<combobox id="pixel_ratio" cell_align="horizontal">
<listitem text="@.square_pixels" value="1:1" />
<listitem text="@.double_wide" value="2:1" />
<listitem text="@.double_high" value="1:2" />
</combobox>
<label text="@.color_profile" />
<label text="@.color_profile" for="color_profile" />
<hbox>
<combobox id="color_profile" cell_align="horizontal" expansive="true" />
<hbox homogeneous="true">

View File

@ -1,45 +1,36 @@
<!-- Aseprite -->
<!-- Copyright (C) 2024 by Igara Studio S.A. -->
<!-- Copyright (C) 2025 by Igara Studio S.A. -->
<!-- Copyright (C) 2001-2018 by David Capello -->
<gui>
<window id="sprite_size" text="@.title" help="resize">
<box vertical="true">
<box vertical="true">
<separator text="@.pixels" left="true" horizontal="true" />
<box vertical="true" expansive="true">
<box horizontal="true">
<box vertical="true" homogeneous="true">
<label text="@.width" />
<label text="@.height" />
</box>
<box vertical="true" homogeneous="true" expansive="true">
<grid columns="3">
<label text="@.width" for="width_px" />
<expr expansive="true" id="width_px" suffix="px" magnet="true" tooltip="@.width_px_tooltip" />
<check text="@.lock_ratio" id="lock_ratio" selected="true" expansive="false" cell_vspan="2" />
<label text="@.height" for="height_px" />
<expr expansive="true" id="height_px" suffix="px" tooltip="@.height_px_tooltip" />
</box>
<check text="@.lock_ratio" id="lock_ratio" selected="true" />
</box>
</box>
</grid>
<separator text="@.percentage" left="true" horizontal="true" />
<box vertical="true" expansive="true">
<box horizontal="true">
<box vertical="true" homogeneous="true">
<label text="@.width" />
<label text="@.height" />
</box>
<box vertical="true" homogeneous="true" expansive="true">
<expr expansive="true" text="100" suffix="%" id="width_perc" magnet="true" tooltip="@.width_perc_tooltip"
decimals="4" />
<expr expansive="true" text="100" suffix="%" id="height_perc" tooltip="@.height_perc_tooltip"
decimals="4" />
</box>
<box horizontal="true" width="64" />
</box>
</box>
<grid columns="3">
<label text="@.width" for="width_perc" />
<expr expansive="true" text="100" suffix="%" id="width_perc" magnet="true" tooltip="@.width_perc_tooltip" decimals="4" />
<boxfiller cell_vspan="2" />
<label text="@.height" for="height_perc" />
<expr expansive="true" text="100" suffix="%" id="height_perc" tooltip="@.height_perc_tooltip" decimals="4" />
</grid>
</box>
<separator text="@.interpolation" left="true" horizontal="true" />
<box vertical="true" expansive="true">
<box horizontal="true">
<label text="@.method" />
<label text="@.method" for="method" />
<combobox id="method" expansive="true" />
</box>
</box>

View File

@ -3,7 +3,7 @@
<gui>
<window id="svg_options" text="@.title">
<grid columns="2">
<label text="@.pixel_scale" />
<label text="@.pixel_scale" for="pxsc" />
<expr id="pxsc" magnet="true" cell_align="horizontal"/>
<separator horizontal="true" cell_hspan="2" />

View File

@ -7,17 +7,17 @@
<vbox>
<grid id="properties_grid" columns="3">
<label text="@.name" />
<label text="@.name" for="name" />
<entry maxsize="256" id="name" magnet="true" cell_align="horizontal" expansive="true" />
<button id="user_data" icon="icon_user_data" maxsize="32" tooltip="@general.user_data" />
<label text="@.from" />
<label text="@.from" for="from" />
<expr id="from" cell_hspan="2" />
<label text="@.to" />
<label text="@.to" for="to" />
<expr id="to" cell_hspan="2" />
<label text="@.ani_dir" />
<label text="@.ani_dir" for="anidir" />
<combobox id="anidir" cell_hspan="2" />
<check text="@.repeat" id="limit_repeat" />

View File

@ -3,7 +3,7 @@
<gui>
<window id="tga_options" text="@.title">
<grid columns="2">
<label text="@.bits_per_pixel" id="bits_per_pixel_label" />
<label text="@.bits_per_pixel" id="bits_per_pixel_label" for="bits_per_pixel" />
<combobox id="bits_per_pixel" cell_align="horizontal" />
<check text="@.compress" id="compress" cell_hspan="2" />

View File

@ -7,19 +7,19 @@
</combobox>
<grid columns="4" expansive="true">
<label text="@.name" />
<label text="@.name" for="name" />
<entry maxsize="256" id="name" text="" cell_hspan="3" />
<label text="@.grid_width" />
<label text="@.grid_width" for="grid_width" />
<expr id="grid_width" text="" />
<label text="@.grid_height" />
<label text="@.grid_height" for="grid_height" />
<expr id="grid_height" text="" />
<label id="base_index_label" text="@.base_index" />
<label id="base_index_label" text="@.base_index" for="base_index" />
<expr id="base_index" text="1" tooltip="@.base_tooltip" />
<boxfiller id="base_index_filler" cell_hspan="2" />
<label id="flips_label" text="@.allowed_flips" />
<label id="flips_label" text="@.allowed_flips" for="flips" />
<buttonset id="flips" columns="3" multiple="true">
<item id="xflip" text="X" minwidth="20" tooltip="@.allowed_flips_tooltip" tooltip_dir="bottom" />
<item id="yflip" text="Y" minwidth="20" tooltip="@.allowed_flips_tooltip" tooltip_dir="bottom" />

View File

@ -11,7 +11,7 @@
<vbox>
<separator text="@.frame_header" left="true" horizontal="true" />
<hbox>
<label text="@.first_frame" />
<label text="@.first_frame" for="first_frame" />
<expr id="first_frame" />
</hbox>
@ -20,7 +20,7 @@
<separator id="thumb_h_separator" horizontal="true" expansive="true" />
</hbox>
<grid columns="2" id="thumb_box">
<label text="@.thumbnail_size" />
<label text="@.thumbnail_size" for="zoom" />
<slider min="1" max="10" id="zoom" cell_align="horizontal" width="128" />
<check id="thumb_overlay_enabled" text="@.overlay_size"/>
@ -38,10 +38,10 @@
<button id="reset_onionskin" text="@.reset" minwidth="60" />
</hbox>
<label text="@.opacity" />
<label text="@.opacity" for="opacity" />
<opacityslider id="opacity" cell_align="horizontal" width="128" />
<label text="@.opacity_step" />
<label text="@.opacity_step" for="opacity_step" />
<opacityslider id="opacity_step" cell_align="horizontal" width="128" />
<check id="loop_tag" text="@.loop_tags" cell_hspan="2" />

View File

@ -3,8 +3,8 @@
<!-- Copyright (C) 2001-2017 by David Capello -->
<gui>
<hbox id="user_data">
<label id="color_label" text="@.color" />
<label id="entry_label" text="@.user_data" />
<label id="color_label" text="@.color" for="color" />
<label id="entry_label" text="@.user_data" for="entry" />
<colorpicker id="color" simple="true" expansive="true" />
<entry id="entry" maxsize="65535" minwidth="128" expansive="true" />
</hbox>

View File

@ -7,7 +7,7 @@
<label text="@.save_as" />
<check text="@.animation_loop" id="loop" />
<hbox>
<label text="@.type" />
<label text="@.type" for="type" />
<combobox id="type" cell_align="horizontal" cell_hspan="2">
<listitem text="@.simple_webp" value="0" />
<listitem text="@.lossless_webp" value="1" />
@ -16,11 +16,11 @@
</hbox>
<vbox id="lossless_options">
<hbox>
<label width="55" text="@.compression" />
<label width="55" text="@.compression" for="compression" />
<slider min="0" max="9" id="compression" cell_align="horizontal" width="128" />
</hbox>
<hbox>
<label width="55" text="@.image_hint" />
<label width="55" text="@.image_hint" for="image_hint" />
<combobox width="128" id="image_hint">
<listitem text="@.image_hint_default" value="0" />
<listitem text="@.image_hint_picture" value="1" />
@ -31,11 +31,11 @@
</vbox>
<vbox id="lossy_options">
<hbox>
<label width="55" text="@.quality" />
<label width="55" text="@.quality" for="quality" />
<slider min="0" max="100" id="quality" cell_align="horizontal" width="128" />
</hbox>
<hbox>
<label width="55" text="@.image_preset" />
<label width="55" text="@.image_preset" for="image_preset" />
<combobox width="128" id="image_preset">
<listitem text="@.image_preset_default" value="0" />
<listitem text="@.image_preset_picture" value="1" />

View File

@ -212,7 +212,7 @@ private:
if (m_showUI) {
app::gen::GotoFrame window;
TagsEntry combobox(editor->sprite()->tags());
combobox.setId("frame");
window.framePlaceholder()->addChild(&combobox);
combobox.setFocusMagnet(true);

View File

@ -227,6 +227,7 @@ void NewLayerCommand::onExecute(Context* context)
if (isTilemap) {
tilesetSelector = new TilesetSelector(sprite, tilesetInfo);
window.tilesetOptions()->addChild(tilesetSelector);
window.tilesetLabel()->setBuddy(tilesetSelector->tilesets());
}
window.openWindowInForeground();

View File

@ -1096,6 +1096,7 @@ private:
m_themeVars->deferDelete();
}
m_themeVars = list;
themeModeLabel()->setBuddy(m_themeVars);
themeVariants()->setVisible(list ? true : false);
themeVariants()->initTheme();
}

View File

@ -303,7 +303,7 @@ void SpritePropertiesCommand::onExecute(Context* context)
color_button = new ColorButton(app::Color::fromIndex(sprite->transparentColor()),
IMAGE_INDEXED,
ColorButtonOptions());
color_button->setId("transparent_color");
window.transparentColorPlaceholder()->addChild(color_button);
// TODO add a way to get or create an existent TooltipManager

View File

@ -658,6 +658,8 @@ int Dialog_add_widget(lua_State* L, Widget* widget)
if (label || !dlg->hbox) {
if (label) {
auto labelWidget = new ui::Label(label);
labelWidget->setBuddy(widget);
if (!visible)
labelWidget->setVisible(false);

View File

@ -22,6 +22,8 @@ BestFitCriteriaSelector::BestFitCriteriaSelector()
int(doc::FitCriteria::CIELAB) == 4,
"Unexpected doc::FitCriteria values");
setId("best_fit_criteria_selector");
addItem(Strings::best_fit_criteria_selector_default());
addItem(Strings::best_fit_criteria_selector_rgb());
addItem(Strings::best_fit_criteria_selector_linearized_rgb());

View File

@ -264,7 +264,7 @@ void ColorButton::onPaint(PaintEvent& ev)
}
}
draw_color_button(g, rc, color, (doc::ColorMode)m_pixelFormat, hasMouse(), false);
draw_color_button(g, rc, color, (doc::ColorMode)m_pixelFormat, hasMouse() || hasFocus(), false);
// Draw text
std::string str = m_color.toHumanReadableString(m_pixelFormat,

View File

@ -173,6 +173,8 @@ private:
DitheringSelector::DitheringSelector(Type type) : m_type(type)
{
setId("dithering_selector"); // Used for label buddies.
Extensions& extensions = App::instance()->extensions();
// If an extension with "ditheringMatrices" is disable/enable, we

View File

@ -54,8 +54,10 @@ enum {
// Special slider to set the min/max threshold values of a sensor
class DynamicsPopup::ThresholdSlider : public Widget {
public:
ThresholdSlider()
ThresholdSlider(const char* id)
{
setId(id);
setFocusStop(true);
setExpansive(true);
initTheme();
}
@ -186,6 +188,7 @@ private:
}
break;
}
case kFocusEnterMessage: invalidate(); break;
}
return Widget::onProcessMessage(msg);
}
@ -278,8 +281,10 @@ DynamicsPopup::DynamicsPopup(Delegate* delegate)
Preferences::instance().shared.shareDynamics(sameInAllTools);
});
m_dynamics->gradientPlaceholder()->addChild(m_ditheringSel);
m_dynamics->pressurePlaceholder()->addChild(m_pressureThreshold = new ThresholdSlider);
m_dynamics->velocityPlaceholder()->addChild(m_velocityThreshold = new ThresholdSlider);
m_dynamics->pressurePlaceholder()->addChild(
m_pressureThreshold = new ThresholdSlider("pressure_slider"));
m_dynamics->velocityPlaceholder()->addChild(
m_velocityThreshold = new ThresholdSlider("velocity_slider"));
addChild(m_dynamics);
}

View File

@ -305,6 +305,7 @@ FileSelector::FileSelector(FileSelectorType type) : m_type(type), m_navigationLo
m_fileName = new CustomFileNameEntry;
m_fileName->setFocusMagnet(true);
m_fileName->setId("file_name");
fileNamePlaceholder()->addChild(m_fileName);
goBackButton()->setFocusStop(false);

View File

@ -21,6 +21,8 @@ RgbMapAlgorithmSelector::RgbMapAlgorithmSelector()
int(doc::RgbMapAlgorithm::OCTREE) == 2,
"Unexpected doc::RgbMapAlgorithm values");
setId("rgbmap_algorithm_selector");
addItem(Strings::rgbmap_algorithm_selector_default());
addItem(Strings::rgbmap_algorithm_selector_rgb5a3());
addItem(Strings::rgbmap_algorithm_selector_octree());

View File

@ -24,6 +24,8 @@ SamplingSelector::SamplingSelector(Behavior behavior)
addChild(&m_downsamplingLabel);
addChild(&m_downsampling);
m_downsamplingLabel.setBuddy(&m_downsampling);
m_downsampling.addItem(new ListItem(Strings::downsampling_nearest()));
m_downsampling.addItem(new ListItem(Strings::downsampling_bilinear()));
m_downsampling.addItem(new ListItem(Strings::downsampling_bilinear_mipmap()));

View File

@ -27,6 +27,7 @@ class SelectShortcut::KeyField : public ui::Entry {
public:
KeyField(const Shortcut& shortcut) : ui::Entry(256, "")
{
setId("key_field");
setTranslateDeadKeys(false);
setExpansive(true);
setFocusMagnet(true);

View File

@ -285,6 +285,11 @@ Widget* WidgetLoader::convertXmlElementToWidget(const XMLElement* elem,
widget->setAlign((center ? CENTER : (right ? RIGHT : LEFT)) |
(top ? TOP : (bottom ? BOTTOM : MIDDLE)));
const char* buddy = elem->Attribute("for");
if (buddy != NULL) {
((Label*)widget)->setBuddy(buddy);
}
}
else if (elem_name == "link") {
const char* url = elem->Attribute("url");

View File

@ -73,6 +73,12 @@ bool ButtonBase::onProcessMessage(Message* msg)
if (isSelected())
setSelected(false);
}
else if (m_behaviorType == kCheckWidget) {
// Focus from a label buddy also toggles the checkbox
auto* focusMsg = static_cast<FocusMessage*>(msg);
if (focusMsg->source() == FocusMessage::Source::Buddy)
setSelected(!isSelected());
}
// TODO theme specific stuff
invalidate();
@ -100,7 +106,7 @@ bool ButtonBase::onProcessMessage(Message* msg)
mnemonicPressed ||
// Magnetic widget catches ENTERs
(isFocusMagnet() && ((scancode == kKeyEnter) || (scancode == kKeyEnterPad)))) {
manager()->setFocus(this);
manager()->setFocus(this, FocusMessage::Source::Keyboard);
// Dispatch focus movement messages (because the buttons
// process them)

View File

@ -393,6 +393,8 @@ bool ComboBox::onProcessMessage(Message* msg)
break;
case kFocusEnterMessage:
auto* focusMsg = static_cast<FocusMessage*>(msg);
// Here we focus the entry field only if the combobox is
// editable and receives the focus in a direct way (e.g. when
// the window was just opened and the combobox is the first
@ -400,6 +402,9 @@ bool ComboBox::onProcessMessage(Message* msg)
if ((isEditable()) && (manager()->getFocus() == this)) {
m_entry->requestFocus();
}
else if (isClickOpen() && focusMsg->source() == FocusMessage::Source::Buddy) {
switchListBox();
}
break;
}

View File

@ -9,14 +9,19 @@
#include "config.h"
#endif
#include "ui/box.h"
#include "ui/button.h"
#include "ui/combobox.h"
#include "ui/label.h"
#include "ui/manager.h"
#include "ui/message.h"
#include "ui/size_hint_event.h"
#include "ui/theme.h"
#include "ui/window.h"
namespace ui {
Label::Label(const std::string& text) : Widget(kLabelWidget)
Label::Label(const std::string& text) : Widget(kLabelWidget), m_buddy(nullptr)
{
enableFlags(IGNORE_MOUSE);
setAlign(LEFT | MIDDLE);
@ -24,4 +29,59 @@ Label::Label(const std::string& text) : Widget(kLabelWidget)
initTheme();
}
Widget* Label::buddy()
{
if (m_buddy || m_buddyId.empty())
return m_buddy;
if (parent()) {
// This can miss some cases where the hierarchy is not direct
setBuddy(parent()->findChild(m_buddyId.c_str()));
}
return m_buddy;
}
void Label::setBuddy(Widget* buddy)
{
m_buddy = buddy;
if (m_buddy)
disableFlags(IGNORE_MOUSE);
}
void Label::setBuddy(const std::string& buddyId)
{
m_buddy = nullptr;
m_buddyId = buddyId;
if (!m_buddyId.empty())
disableFlags(IGNORE_MOUSE);
}
bool Label::onProcessMessage(Message* msg)
{
switch (msg->type()) {
case kMouseDownMessage:
auto* bud = buddy();
if (bud && bud->isVisible() && !bud->hasFocus()) {
if (bud->isEnabled() && (bud->type() == kGridWidget || bud->type() == kBoxWidget)) {
// Iterate through containers until we find something worth focusing
for (auto* child : bud->children()) {
if (child->isVisible() && child->isEnabled() && !child->hasFlags(IGNORE_MOUSE)) {
manager()->setFocus(child, FocusMessage::Source::Buddy);
return true;
}
}
}
manager()->setFocus(bud, FocusMessage::Source::Buddy);
return true;
}
break;
}
return Widget::onProcessMessage(msg);
}
} // namespace ui

View File

@ -16,6 +16,17 @@ namespace ui {
class Label : public Widget {
public:
Label(const std::string& text);
Widget* buddy();
void setBuddy(Widget* buddy);
void setBuddy(const std::string& buddyId);
protected:
bool onProcessMessage(Message* msg) override;
private:
Widget* m_buddy;
std::string m_buddyId;
};
} // namespace ui

View File

@ -787,7 +787,7 @@ bool Manager::handleWindowZOrder()
}
// Put the focus
setFocus(mouse_widget);
setFocus(mouse_widget, FocusMessage::Source::Mouse);
return true;
}
@ -954,7 +954,7 @@ Widget* Manager::getCapture()
return capture_widget;
}
void Manager::setFocus(Widget* widget)
void Manager::setFocus(Widget* widget, FocusMessage::Source source)
{
if ((focus_widget != widget) &&
(!(widget) || (!(widget->hasFlags(DISABLED)) && !(widget->hasFlags(HIDDEN)) &&
@ -964,7 +964,7 @@ void Manager::setFocus(Widget* widget)
// Fetch the focus
if (focus_widget && focus_widget != commonAncestor) {
auto* msg = new FocusMessage(kFocusLeaveMessage, oldFocus, widget);
auto* msg = new FocusMessage(kFocusLeaveMessage, oldFocus, widget, source);
msg->setRecipient(focus_widget);
msg->setPropagateToParent(true);
msg->setCommonAncestor(commonAncestor);
@ -981,7 +981,7 @@ void Manager::setFocus(Widget* widget)
// Put the focus
focus_widget = widget;
if (widget) {
auto* msg = new FocusMessage(kFocusEnterMessage, oldFocus, widget);
auto* msg = new FocusMessage(kFocusEnterMessage, oldFocus, widget, source);
msg->setRecipient(widget);
msg->setPropagateToParent(true);
msg->setCommonAncestor(commonAncestor);
@ -1103,14 +1103,14 @@ void Manager::attractFocus(Widget* widget)
// If magnetic widget exists and it doesn't have the focus
if (magnet && !magnet->hasFocus())
setFocus(magnet);
setFocus(magnet, FocusMessage::Source::Window);
}
void Manager::focusFirstChild(Widget* widget)
{
for (Widget* it = widget->window(); it; it = next_widget(it)) {
if (does_accept_focus(it) && !(child_accept_focus(it, true))) {
setFocus(it);
setFocus(it, FocusMessage::Source::Window);
break;
}
}
@ -2438,7 +2438,7 @@ bool Manager::processFocusMovementMessage(Message* msg)
}
if ((focus) && (focus != focus_widget))
setFocus(focus);
setFocus(focus, FocusMessage::Source::Keyboard);
}
return ret;

View File

@ -14,6 +14,7 @@
#include "ui/display.h"
#include "ui/keys.h"
#include "ui/layer.h"
#include "ui/message.h"
#include "ui/message_type.h"
#include "ui/mouse_button.h"
#include "ui/pointer_type.h"
@ -85,7 +86,7 @@ public:
Widget* getMouse();
Widget* getCapture();
void setFocus(Widget* widget);
void setFocus(Widget* widget, FocusMessage::Source source = FocusMessage::Source::Other);
void setMouse(Widget* widget);
void setCapture(Widget* widget, bool force = false);
void attractFocus(Widget* widget);

View File

@ -98,18 +98,31 @@ private:
class FocusMessage : public Message {
public:
FocusMessage(MessageType type, Widget* oldFocus, Widget* newFocus)
enum class Source {
Keyboard,
Mouse,
// Focused by window opening, either from being the first child, or the focus magnet
Window,
// Focused by the label buddy
Buddy,
// Any other type of focus
Other
};
FocusMessage(MessageType type, Widget* oldFocus, Widget* newFocus, Source source = Source::Other)
: Message(type)
, m_oldFocus(oldFocus)
, m_newFocus(newFocus)
, m_source(source)
{
}
Widget* oldFocus() { return m_oldFocus; }
Widget* newFocus() { return m_newFocus; }
Source source() const { return m_source; }
private:
Widget* m_oldFocus;
Widget* m_newFocus;
Source m_source;
};
class KeyMessage : public Message {