Module: Lich::Common::GUI::Accessibility
- Defined in:
- documented/common/gui/accessibility.rb
Class Method Summary collapse
-
.add_keyboard_navigation(widget, can_focus = true, tab_order = nil) ⇒ void
Adds keyboard navigation capabilities to a widget.
-
.add_keyboard_shortcut(widget, key, modifiers = []) ⇒ void
Adds a keyboard shortcut to a widget.
-
.announce(widget, message, _priority = :medium) ⇒ void
Announces a message through a widget for assistive technologies.
-
.create_accessible_label(container, input, text, position = :left) ⇒ Gtk::Label
Creates an accessible label for an input widget.
-
.get_atk_role(role_symbol) ⇒ Atk::Role?
Retrieves the ATK role corresponding to a given symbol.
-
.initialize_accessibility ⇒ Object
Initializes accessibility features for the GUI.
-
.make_accessible(widget, label, description = nil, role = nil) ⇒ void
Makes a widget accessible for assistive technologies.
-
.make_button_accessible(button, label, description = nil) ⇒ void
Makes a button accessible for assistive technologies.
-
.make_combo_accessible(combo, label, description = nil) ⇒ void
Makes a combo box accessible for assistive technologies.
-
.make_entry_accessible(entry, label, description = nil) ⇒ void
Makes an entry widget accessible for assistive technologies.
-
.make_tab_accessible(notebook, page, tab_label, description = nil) ⇒ void
Makes a tab in a notebook accessible for assistive technologies.
-
.make_window_accessible(window, title, description = nil) ⇒ void
Makes a window accessible for assistive technologies.
Class Method Details
.add_keyboard_navigation(widget, can_focus = true, tab_order = nil) ⇒ void
This method returns an undefined value.
Adds keyboard navigation capabilities to a widget.
145 146 147 148 149 150 151 152 153 154 155 156 |
# File 'documented/common/gui/accessibility.rb', line 145 def self.(, can_focus = true, tab_order = nil) begin .can_focus = can_focus # In GTK3, we need to check if the property exists before setting it if tab_order && .class.property?('tab-position') .set_property('tab-position', tab_order) end rescue StandardError => e Lich.log "warning: Could not set keyboard navigation: #{e.}" end end |
.add_keyboard_shortcut(widget, key, modifiers = []) ⇒ void
This method returns an undefined value.
Adds a keyboard shortcut to a widget.
165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 |
# File 'documented/common/gui/accessibility.rb', line 165 def self.add_keyboard_shortcut(, key, modifiers = []) return unless .respond_to?(:add_accelerator) begin # Convert modifiers to Gdk::ModifierType modifier_mask = 0 modifiers.each do |mod| case mod when :control, :ctrl modifier_mask |= Gdk::ModifierType::CONTROL_MASK when :shift modifier_mask |= Gdk::ModifierType::SHIFT_MASK when :alt modifier_mask |= Gdk::ModifierType::MOD1_MASK end end # Find or create accelerator group if .parent.is_a?(Gtk::Window) # Get the first accel group (replacing the unreachable loop) accel_group = .parent.accel_groups.first # Create new accel group if none found if accel_group.nil? accel_group = Gtk::AccelGroup.new .parent.add_accel_group(accel_group) end # Add accelerator .add_accelerator( "activate", accel_group, Gdk::Keyval.from_name(key), modifier_mask, Gtk::AccelFlags::VISIBLE ) end rescue StandardError => e Lich.log "warning: Could not add keyboard shortcut: #{e.}" end end |
.announce(widget, message, _priority = :medium) ⇒ void
This method returns an undefined value.
Announces a message through a widget for assistive technologies.
214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 |
# File 'documented/common/gui/accessibility.rb', line 214 def self.announce(, , _priority = :medium) return unless .respond_to?(:get_accessible) begin accessible = .get_accessible return unless accessible # In GTK3/ATK, we can use state changes to trigger screen reader announcements if accessible.respond_to?(:notify_state_change) # Toggle state to trigger announcement accessible.notify_state_change(Atk::StateType::SHOWING, true) # Set name to message temporarily original_name = nil if accessible.respond_to?(:get_name) && accessible.respond_to?(:set_name) original_name = accessible.get_name accessible.set_name() end # Restore original name after a short delay if original_name # Using one-shot timeout (returns false to prevent repetition) GLib::Timeout.add(1000) do accessible.set_name(original_name) false # Intentionally return false to run only once end end end rescue StandardError => e Lich.log "warning: Could not announce message: #{e.}" end end |
.create_accessible_label(container, input, text, position = :left) ⇒ Gtk::Label
Creates an accessible label for an input widget.
255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 |
# File 'documented/common/gui/accessibility.rb', line 255 def self.create_accessible_label(container, input, text, position = :left) label = Gtk::Label.new(text) label.set_alignment(position == :left ? 1 : 0, 0.5) # Connect label to input for screen readers if input.respond_to?(:get_accessible) && label.respond_to?(:get_accessible) input_accessible = input.get_accessible label_accessible = label.get_accessible if input_accessible && label_accessible && input_accessible.respond_to?(:add_relationship) && defined?(Atk::RelationType::LABEL_FOR) label_accessible.add_relationship(Atk::RelationType::LABEL_FOR, input_accessible) end end # Add to container based on position case container when Gtk::Box case position when :left container.pack_start(label, expand: false, fill: false, padding: 5) container.pack_start(input, expand: true, fill: true, padding: 5) when :right container.pack_start(input, expand: true, fill: true, padding: 5) container.pack_start(label, expand: false, fill: false, padding: 5) when :top, :bottom # For top/bottom, we need to change the box orientation or create a vertical box vbox = if container.orientation == :vertical container else vbox = Gtk::Box.new(:vertical, 5) container.add(vbox) vbox end if position == :top vbox.pack_start(label, expand: false, fill: false, padding: 2) vbox.pack_start(input, expand: true, fill: true, padding: 2) else vbox.pack_start(input, expand: true, fill: true, padding: 2) vbox.pack_start(label, expand: false, fill: false, padding: 2) end end when Gtk::Grid # For Grid, we need row and column information which isn't provided # This is a simplified version container.add(label) container.add(input) else # For other containers, just add both container.add(label) container.add(input) end label end |
.get_atk_role(role_symbol) ⇒ Atk::Role?
Retrieves the ATK role corresponding to a given symbol.
318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 |
# File 'documented/common/gui/accessibility.rb', line 318 def self.get_atk_role(role_symbol) return nil unless defined?(Atk::Role) begin case role_symbol when :button then Atk::Role::PUSH_BUTTON when :text then Atk::Role::TEXT when :combo_box then Atk::Role::COMBO_BOX when :page_tab then Atk::Role::PAGE_TAB when :panel then Atk::Role::PANEL when :window then Atk::Role::FRAME when :label then Atk::Role::LABEL when :list then Atk::Role::LIST when :list_item then Atk::Role::LIST_ITEM when :menu then Atk::Role::MENU when :menu_item then Atk::Role::MENU_ITEM when :check_box then Atk::Role::CHECK_BOX when :radio_button then Atk::Role::RADIO_BUTTON when :dialog then Atk::Role::DIALOG when :separator then Atk::Role::SEPARATOR when :scroll_bar then Atk::Role::SCROLL_BAR when :slider then Atk::Role::SLIDER when :spin_button then Atk::Role::SPIN_BUTTON when :table then Atk::Role::TABLE when :tree then Atk::Role::TREE when :tree_item then Atk::Role::TREE_ITEM else nil end rescue StandardError => e Lich.log "warning: Could not get ATK role: #{e.}" nil end end |
.initialize_accessibility ⇒ Object
Accessibility is not available on any non-linux platform.
Initializes accessibility features for the GUI. In GTK3, accessibility is enabled by default through ATK.
11 12 13 14 15 16 17 18 19 20 |
# File 'documented/common/gui/accessibility.rb', line 11 def self.initialize_accessibility # In GTK3, accessibility is enabled by default through ATK # Ensure ATK is loaded by referencing a Gail widget type # accessibility is not available on any non-linux platform begin GLib::Object.type_from_name('GailWidget') rescue NoMethodError => e Lich.log "warning: Could not initialize accessibility: #{e.}" if OS.linux? end end |
.make_accessible(widget, label, description = nil, role = nil) ⇒ void
This method returns an undefined value.
Makes a widget accessible for assistive technologies.
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
# File 'documented/common/gui/accessibility.rb', line 30 def self.make_accessible(, label, description = nil, role = nil) return unless .respond_to?(:get_accessible) begin accessible = .get_accessible return unless accessible # Set accessible name accessible.set_name(label) if accessible.respond_to?(:set_name) # Set accessible description accessible.set_description(description) if description && accessible.respond_to?(:set_description) # Set accessible role if role && accessible.respond_to?(:set_role) role_value = get_atk_role(role) accessible.set_role(role_value) if role_value end rescue StandardError => e Lich.log "warning: Could not make widget accessible: #{e.}" end end |
.make_button_accessible(button, label, description = nil) ⇒ void
This method returns an undefined value.
Makes a button accessible for assistive technologies.
60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'documented/common/gui/accessibility.rb', line 60 def self.(, label, description = nil) make_accessible(, label, description, :button) # Ensure button has a visible label for screen readers begin if .child.is_a?(Gtk::Label) .child.set_text(label) if .child.text.empty? elsif !.label.nil? && .label.empty? .label = label end rescue StandardError => e Lich.log "warning: Could not set button label: #{e.}" end end |
.make_combo_accessible(combo, label, description = nil) ⇒ void
This method returns an undefined value.
Makes a combo box accessible for assistive technologies.
93 94 95 |
# File 'documented/common/gui/accessibility.rb', line 93 def self.make_combo_accessible(combo, label, description = nil) make_accessible(combo, label, description, :combo_box) end |
.make_entry_accessible(entry, label, description = nil) ⇒ void
This method returns an undefined value.
Makes an entry widget accessible for assistive technologies.
82 83 84 |
# File 'documented/common/gui/accessibility.rb', line 82 def self.make_entry_accessible(entry, label, description = nil) make_accessible(entry, label, description, :text) end |
.make_tab_accessible(notebook, page, tab_label, description = nil) ⇒ void
This method returns an undefined value.
Makes a tab in a notebook accessible for assistive technologies.
105 106 107 108 109 110 111 112 113 114 115 116 117 118 |
# File 'documented/common/gui/accessibility.rb', line 105 def self.make_tab_accessible(notebook, page, tab_label, description = nil) begin page_num = notebook.page_num(page) return if page_num == -1 tab = notebook.get_tab_label(page) make_accessible(tab, tab_label, description, :page_tab) # Also make the page itself accessible make_accessible(page, tab_label, description, :panel) rescue StandardError => e Lich.log "warning: Could not make tab accessible: #{e.}" end end |
.make_window_accessible(window, title, description = nil) ⇒ void
This method returns an undefined value.
Makes a window accessible for assistive technologies.
127 128 129 130 131 132 133 134 135 136 |
# File 'documented/common/gui/accessibility.rb', line 127 def self.make_window_accessible(window, title, description = nil) make_accessible(window, title, description, :window) # Ensure window has a title for screen readers begin window.title = title if window.title.nil? || window.title.empty? rescue StandardError => e Lich.log "warning: Could not set window title: #{e.}" end end |