Class: MittensUi::Core

Inherits:
Object
  • Object
show all
Includes:
Helpers
Defined in:
lib/mittens_ui/core.rb

Overview

Base class for all MittensUi widgets. All components inherit from Core, which handles rendering into the application layout automatically on instantiation.

Widgets are rendered into the LayoutManager grid using a 12-unit column system. The width of a widget can be controlled via the :width option.

Examples:

Creating a custom widget that inherits from Core

class MyWidget < MittensUi::Core
  def initialize(options = {})
    @gtk_widget = Gtk::Label.new('Hello')
    super(@gtk_widget, options)
  end
end

Controlling widget width

MittensUi::Label.new('Half width', width: :half)
MittensUi::Label.new('Full width', width: :full)

Deferring render for container widgets like HeaderBar

MittensUi::Button.new(title: 'Click', defer_render: true)

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Helpers

#icon_map, #list_system_icons, #set_margin_from_opts_for

Constructor Details

#initialize(widget, options = {}) ⇒ Core

Initializes the widget, sets its width and margins, and renders it into the application layout unless :defer_render is true.

Parameters:

  • widget (Gtk::Widget)

    the underlying GTK widget to wrap

  • options (Hash) (defaults to: {})

    configuration options

Options Hash (options):

  • :width (Symbol) — default: :full

    the column width of the widget. Accepted values are :full, :half, :third, :quarter

  • :defer_render (Boolean) — default: false

    when true, the widget will not be automatically added to the layout on initialization. Use this when passing a widget as a child to a container like HBox or HeaderBar

  • :top (Integer)

    top margin in pixels

  • :left (Integer)

    left margin in pixels

  • :bottom (Integer)

    bottom margin in pixels

  • :right (Integer)

    right margin in pixels



51
52
53
54
55
56
57
58
59
# File 'lib/mittens_ui/core.rb', line 51

def initialize(widget, options = {})
  @core_widget  = widget # This represents the GTK widget.
  @core_widget.focusable = true
  @width        = options[:width]        || :full
  @defer_render = options[:defer_render] || false
  set_margin_from_opts_for(@core_widget, options)
  render unless @defer_render
  enable_hover_focus
end

Instance Attribute Details

#core_widgetGtk::Widget (readonly)

The underlying GTK widget instance. Use this to access raw GTK functionality not exposed by MittensUi.

Returns:

  • (Gtk::Widget)

    the underlying GTK widget



35
36
37
# File 'lib/mittens_ui/core.rb', line 35

def core_widget
  @core_widget
end

Instance Method Details

#hidden?Boolean

Returns whether the widget is currently hidden.

Examples:

btn.hidden?  # => false
btn.hide
btn.hidden?  # => true

Returns:

  • (Boolean)

    true if the widget is visible, false if hidden



80
81
82
# File 'lib/mittens_ui/core.rb', line 80

def hidden?
  !@core_widget.visible?
end

#hidevoid

This method returns an undefined value.

Hides the widget from view without removing it from the layout. The widget can be shown again by calling #show.

Examples:

btn = MittensUi::Button.new(title: 'Click')
btn.hide


91
92
93
94
95
# File 'lib/mittens_ui/core.rb', line 91

def hide
  return if @core_widget.nil?

  @core_widget.hide
end

#keyboard_shortcut(modifier, key, timer: 0, &block) ⇒ void

This method returns an undefined value.

Registers a simple keyboard shortcut on @core_wiget using a modifier + key combination.

Attaches a Gtk::EventControllerKey to the widget that listens for the given key combination. The widget must have focus for the shortcut to fire. If a timer is provided, the block is executed after the specified delay via GLib::Timeout.

Examples:

Instant shortcut

btn.keyboard_shortcut("ctrl", "d") { puts "Ctrl+D fired" }

Delayed shortcut

btn.keyboard_shortcut("ctrl", "s", timer: 2) { puts "fired after 2s" }

Parameters:

  • modifier (String)

    The modifier key. Accepts “ctrl”, “shift”, “alt”, or “super”.

  • key (String)

    The key name as a GTK key string (“d”, “s”, “Return”, “Escape”).

  • timer (Integer) (defaults to: 0)

    Seconds to wait before invoking the block. Defaults to 0 (immediate).

  • block (Proc)

    The block to execute when the shortcut is triggered.



145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
# File 'lib/mittens_ui/core.rb', line 145

def keyboard_shortcut(modifier, key, timer: 0, &block)
  @shortcut_controllers ||= []

  controller = Gtk::EventControllerKey.new

  controller.signal_connect("key-pressed") do |_ctrl, keyval, _keycode, state|
    mod_match = case modifier.to_s.downcase
                when "ctrl"  then (state & Gdk::ModifierType::CONTROL_MASK).nonzero?
                when "shift" then (state & Gdk::ModifierType::SHIFT_MASK).nonzero?
                when "alt"   then (state & Gdk::ModifierType::ALT_MASK).nonzero?
                when "super" then (state & Gdk::ModifierType::SUPER_MASK).nonzero?
                else false
                end

    key_match = (keyval == Gdk::Keyval.from_name(key))

    if mod_match && key_match
      if timer > 0
        GLib::Timeout.add(timer * 1000) do
          block.call
          GLib::Source::REMOVE
        end
      else
        block.call
      end
      true  # consume the event
    else
      false
    end
  end

  @shortcut_controllers << { modifier: modifier, key: key, controller: controller }
  @core_widget.add_controller(controller)
end

#removevoid

This method returns an undefined value.

Removes the widget from the application layout permanently. Unlike #hide, this cannot be undone.

Examples:

btn = MittensUi::Button.new(title: 'Click')
btn.remove


104
105
106
107
108
# File 'lib/mittens_ui/core.rb', line 104

def remove
  return if @defer_render

  MittensUi::Application.layout.remove(@core_widget)
end

#remove_keyboard_shortcut(modifier, key) ⇒ void

This method returns an undefined value.

Removes a previously registered keyboard shortcut from @core_widget.

Finds the shortcut matching the given modifier and key combination, detaches its Gtk::EventControllerKey from the underlying GTK widget.

If no matching shortcut is found, this is a no-op.

Examples:

btn.remove_shortcut("ctrl", "d")

Parameters:

  • modifier (String)

    The modifier key used when registering the shortcut (“ctrl”).

  • key (String)

    The key name used when registering the shortcut (“d”).



194
195
196
197
198
199
200
201
# File 'lib/mittens_ui/core.rb', line 194

def remove_keyboard_shortcut(modifier, key)
  @shortcut_controllers&.reject! do |entry|
    if entry[:modifier] == modifier && entry[:key] == key
      @gtk_widget.remove_controller(entry[:controller])
      true
    end
  end
end

#rendervoid

This method returns an undefined value.

Adds the widget to the application layout grid. Called automatically during initialization unless :defer_render is true. Can be overridden in subclasses that require special placement (HeaderBar, Notify).



116
117
118
119
120
121
122
123
# File 'lib/mittens_ui/core.rb', line 116

def render
  container = MittensUi::Application.current_container
  if container
    container.attach_widget(@core_widget)
  else
    MittensUi::Application.layout.add(@core_widget, width: @width)
  end
end

#shortcutsArray<String>

Returns a list of all keyboard shortcuts registered on @core_wiget.

Each shortcut is represented as a human-readable string in the format “modifier+key” (“ctrl+d”, “alt+r”).

Examples:

btn.shortcuts # => ["ctrl+d", "ctrl+s"]

Returns:

  • (Array<String>)

    Registered shortcuts, or an empty array if none.



212
213
214
# File 'lib/mittens_ui/core.rb', line 212

def shortcuts
  @shortcut_controllers&.map { |e| "#{e[:modifier]}+#{e[:key]}" } || []
end

#showvoid

This method returns an undefined value.

Shows the widget if it is hidden.

Examples:

btn = MittensUi::Button.new(title: 'Click')
btn.hide
btn.show


68
69
70
71
# File 'lib/mittens_ui/core.rb', line 68

def show
  # GTK4: show_all removed — use show instead
  @core_widget.show
end