File: gtk_selectbox.rb

package info (click to toggle)
mikutter 5.0.4%2Bdfsg1-2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 9,700 kB
  • sloc: ruby: 21,307; sh: 181; makefile: 19
file content (74 lines) | stat: -rw-r--r-- 2,269 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# -*- coding: utf-8 -*-

require_relative '../utils'
require 'mui/gtk_crud'
require 'mui/gtk_tree_view_pretty_scroll'

=begin rdoc
  複数選択ウィジェットを作成する。
  これで作成されたウィジェットは、チェックボックスで複数の項目が選択できる。
  各項目は文字列でしか指定できない。
=end

class Gtk::SelectBox < Gtk::CRUD
  ITER_CHECK = 0
  ITER_STRING = 1
  ITER_ID = 2

  include Gtk::TreeViewPrettyScroll

  # _values_ は、{結果に含む値 => 表示される文字列}のHashか、
  # [[結果に含む値, 表示される文字列]]のような配列。
  # 結果に含む値が none の場合、その項目は選択できなくなる
  # _selected_ は、選択されている項目のリスト。<<とdeleteとinclude?を実装している必要がある
  def initialize(values, selected, none=nil, &changed_hook)
    type_strict values => :each
    @selected = ((selected.dup or []) rescue [])
    @none = none
    @changed_hook = changed_hook
    super()
    self.creatable = self.updatable = self.deletable = false
    setting_values values, selected end

  def selected
    @selected.freeze.lazy.select{|_|_ != @none}
  end

  private

  # 初期設定。コンストラクタに渡された項目をListViewに登録する
  def setting_values(values, selected)
    values.each{ |pair|
      id, string = *pair
      iter = model.append
      iter[ITER_ID] = id
      iter[ITER_STRING] = string
      iter[ITER_CHECK] = (selected and @selected.include?(id)) } end

  def column_schemer
    [ { :kind => :active, :widget => :boolean, :type => TrueClass, :label => '選択' },
      { :kind => :text, :widget => :input, :type => String, :label => '項目' },
      { :type => Object }
    ].freeze
  end

  def add_selected(id)
    @selected = @selected.melt
    @selected << id
  end

  def delete_selected(id)
    @selected = @selected.melt
    @selected.delete(id)
  end

  def on_updated(iter)
    if(iter[ITER_CHECK])
      if iter[ITER_ID] == @none
        iter[ITER_CHECK] = false
      else
        add_selected(iter[ITER_ID]) end
    else
      delete_selected(iter[ITER_ID]) end
    if @changed_hook
      @changed_hook.call(*[selected][0, @changed_hook.arity]) end end end