Class: SettingsDialog

Inherits:
Object
  • Object
show all
Defined in:
lib/vimamsa/gui_settings.rb

Instance Method Summary collapse

Constructor Details

#initializeSettingsDialog

Returns a new instance of SettingsDialog.



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# File 'lib/vimamsa/gui_settings.rb', line 73

def initialize
  @widgets = {}
  @window = Gtk::Window.new
  @window.set_transient_for($vmag.window) if $vmag&.window
  @window.modal = true
  @window.title = "Preferences"
  @window.default_width = 500

  outer = Gtk::Box.new(:vertical, 12)
  # outer.margin = 16
  @window.set_child(outer)

  notebook = Gtk::Notebook.new
  outer.append(notebook)

  all_settings_defs.each do |section|
    grid = Gtk::Grid.new
    grid.row_spacing = 10
    grid.column_spacing = 16
    grid.margin_top = 12
    grid.margin_bottom = 12
    grid.margin_start = 12
    grid.margin_end = 12

    grid_row = 0
    section[:settings].each do |s|
      label = Gtk::Label.new(s[:label])
      label.halign = :start
      label.hexpand = true

      if s[:type] == :string_list
        # Label spans both columns; editor on the next row spanning both columns
        grid.attach(label, 0, grid_row, 2, 1)
        grid_row += 1
        cur = get(s[:key])
        container, get_value = build_string_list_editor(cur.is_a?(Array) ? cur : [])
        @widgets[s[:key]] = { :widget => container, :type => s[:type], :get_value => get_value }
        grid.attach(container, 0, grid_row, 2, 1)
      else
        widget = make_widget(s)
        # Store prev_value so save_and_close can detect newly-enabled modules.
        @widgets[s[:key]] = { :widget => widget, :type => s[:type], :no_restart => s[:no_restart], :prev_value => cnf_get(s[:key]) }
        grid.attach(label, 0, grid_row, 1, 1)
        grid.attach(widget, 1, grid_row, 1, 1)
      end
      grid_row += 1
    end

    notebook.append_page(grid, Gtk::Label.new(section[:label]))
  end

  hbox = Gtk::Box.new(:horizontal, 8)
  hbox.halign = :end

  cancel_btn = Gtk::Button.new(:label => "Cancel")
  save_btn = Gtk::Button.new(:label => "Save")
  cancel_btn.signal_connect("clicked") { @window.destroy }
  save_btn.signal_connect("clicked") { save_and_close }

  hbox.append(cancel_btn)
  hbox.append(save_btn)
  outer.append(hbox)

  press = Gtk::EventControllerKey.new
  press.set_propagation_phase(Gtk::PropagationPhase::CAPTURE)
  @window.add_controller(press)
  press.signal_connect("key-pressed") do |_g, keyval, _kc, _y|
    if keyval == Gdk::Keyval::KEY_Escape
      @window.destroy
      true
    else
      false
    end
  end
end

Instance Method Details

#activate_no_restart_modulesObject

For modules that support live activation (no_restart: true), apply enable and disable transitions immediately without requiring a restart. Modules that were already in the target state when the dialog opened are skipped (prev_value matches new value), so we never double-init or double-disable.



263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
# File 'lib/vimamsa/gui_settings.rb', line 263

def activate_no_restart_modules
  @widgets.each do |key, info|
    next unless key.is_a?(Array) && key[0] == :modules && key[2] == :enabled
    next unless info[:no_restart]  # module requires restart — skip
    mod_name = key[1].to_s
    was_enabled = info[:prev_value]
    now_enabled = cnf_get(key)
    if !was_enabled && now_enabled
      # Toggled on: load the module file and call <name>_init.
      main_file = ppath("modules/#{mod_name}/#{mod_name}.rb")
      next unless File.exist?(main_file)
      load main_file
      init_fn = "#{mod_name}_init"
      send(init_fn) if respond_to?(init_fn, true)
    elsif was_enabled && !now_enabled
      # Toggled off: call <name>_disable to unregister actions and bindings.
      disable_fn = "#{mod_name}_disable"
      send(disable_fn) if respond_to?(disable_fn, true)
    end
  end
end

#build_string_list_editor(paths) ⇒ Object



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
206
207
208
209
210
211
212
213
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
# File 'lib/vimamsa/gui_settings.rb', line 179

def build_string_list_editor(paths)
  store = Gtk::ListStore.new(String)
  paths.each { |p| store.append[0] = p }

  tv = Gtk::TreeView.new(store)
  tv.headers_visible = false
  renderer = Gtk::CellRendererText.new
  renderer.ellipsize = Pango::EllipsizeMode::START
  col = Gtk::TreeViewColumn.new("", renderer, text: 0)
  col.expand = true
  tv.append_column(col)

  sw = Gtk::ScrolledWindow.new
  sw.set_policy(:automatic, :automatic)
  sw.set_child(tv)
  sw.set_size_request(-1, 120)
  sw.vexpand = true

  add_btn = Gtk::Button.new(label: "Add…")
  add_btn.signal_connect("clicked") do
    chooser = Gtk::FileChooserDialog.new(
      :title => "Select directory",
      :action => :select_folder,
      :buttons => [["Select", :accept], ["Cancel", :cancel]],
    )
    chooser.set_transient_for(@window)
    chooser.modal = true
    chooser.signal_connect("response") do |dlg, resp|
      if resp == Gtk::ResponseType::ACCEPT
        iter = store.append
        iter[0] = dlg.file.path
      end
      dlg.destroy
    end
    chooser.show
  end

  remove_btn = Gtk::Button.new(label: "Remove")
  remove_btn.signal_connect("clicked") do
    sel = tv.selection.selected
    store.remove(sel) if sel
  end

  btn_box = Gtk::Box.new(:horizontal, 6)
  btn_box.append(add_btn)
  btn_box.append(remove_btn)

  container = Gtk::Box.new(:vertical, 4)
  container.vexpand = true
  container.append(sw)
  container.append(btn_box)

  get_value = proc {
    result = []
    store.each { |_m, _path, iter| result << iter[0] }
    result
  }

  [container, get_value]
end

#make_widget(s) ⇒ Object



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
# File 'lib/vimamsa/gui_settings.rb', line 149

def make_widget(s)
  cur = cnf_get(s[:key])
  case s[:type]
  when :bool
    w = Gtk::Switch.new
    w.active = cur == true
    w.valign = :center
    w
  when :int
    adj = Gtk::Adjustment.new(cur.to_f, s[:min].to_f, s[:max].to_f, s[:step].to_f, s[:step].to_f * 5, 0.0)
    Gtk::SpinButton.new(adj, s[:step].to_f, 0)
  when :float
    adj = Gtk::Adjustment.new(cur.to_f, s[:min].to_f, s[:max].to_f, s[:step].to_f, s[:step].to_f * 5, 0.0)
    digits = s[:step].to_s.split(".").last.to_s.length
    digits = 2 if digits < 2
    Gtk::SpinButton.new(adj, s[:step].to_f, digits)
  when :string
    w = Gtk::Entry.new
    w.text = cur.to_s
    w
  when :select
    options = s[:options].is_a?(Proc) ? s[:options].call : s[:options]
    cur = cnf_get(s[:key]).to_s
    string_list = Gtk::StringList.new(options)
    w = Gtk::DropDown.new(string_list, nil)
    w.selected = [options.index(cur) || 0, 0].max
    w
  end
end

#runObject



285
286
287
# File 'lib/vimamsa/gui_settings.rb', line 285

def run
  @window.show
end

#save_and_closeObject



240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
# File 'lib/vimamsa/gui_settings.rb', line 240

def save_and_close
  @widgets.each do |key, info|
    val = case info[:type]
          when :bool        then info[:widget].active?
          when :int         then info[:widget].value.to_i
          when :float       then info[:widget].value.to_f
          when :string      then info[:widget].text
          when :string_list then info[:get_value].call
          when :select      then info[:widget].selected_item&.string
          end
    cnf_set(key, val) unless val.nil?
  end
  save_settings_to_file
  gui_refresh_font
  gui_refresh_style_scheme
  activate_no_restart_modules
  @window.destroy
end