File: gtk_message_picker.rb

package info (click to toggle)
mikutter 3.8.6%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 10,544 kB
  • sloc: ruby: 20,548; sh: 99; makefile: 19
file content (140 lines) | stat: -rw-r--r-- 4,763 bytes parent folder | download
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
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
# -*- coding: utf-8 -*-
require 'gtk2'
require_relative '../utils'
miquire :core, 'skin'
miquire :mui, 'mtk'
miquire :mui, 'extension'
miquire :mui, 'webicon'
miquire :miku, 'miku'

class Gtk::MessagePicker < Gtk::EventBox
  DEFAULT_CONDITION = [:==, :user, ''.freeze].freeze

  def initialize(conditions, &block)
    conditions = [] unless conditions.is_a? MIKU::List
    super()
    @not = (conditions.respond_to?(:car) and (conditions.car == :not))
    if(@not)
      conditions = (conditions[1] or []).freeze end
    @changed_hook = block
    shell = Gtk::VBox.new
    @container = Gtk::VBox.new
    @function, *exprs = *conditions.to_a
    @function ||= :and
    shell.add(@container)
    shell.closeup(add_button.center)
    exprs.each{|x| add_condition(x) }
    add(Gtk::Frame.new.set_border_width(8).set_label_widget(option_widgets).add(shell))
  end

  def function(new = @function)
    (new ? :or : :and) end

  def option_widgets
    @option_widgets ||= Gtk::HBox.new.
      closeup(Mtk::boolean(lambda{ |new|
                             unless new.nil?
                               @function = function(new)
                               call end
                             @function == :or },
                           'いずれかにマッチする')).
      closeup(Mtk::boolean(lambda{ |new|
                             unless new.nil?
                               @not = new
                               call end
                             @not },
                           '否定')) end

  def add_button
    @add_button ||= gen_add_button end

  def add_condition(expr = DEFAULT_CONDITION)
    pack = Gtk::HBox.new
    close = Gtk::Button.new.add(Gtk::WebIcon.new(Skin['close.png'], 16, 16)).set_relief(Gtk::RELIEF_NONE)
    close.signal_connect(:clicked){
      @container.remove(pack)
      pack.destroy
      call
      false }
    pack.closeup(close.top)
    case expr.first
    when :and, :or, :not
      pack.add(Gtk::MessagePicker.new(expr, &method(:call)))
    else
      pack.add(Gtk::MessagePicker::PickCondition.new(expr, &method(:call))) end
    @container.closeup(pack) end

  def to_a
    result = [@function, *@container.children.map{|x| x.children.last.to_a}.reject(&:empty?)].freeze
    if result.size == 1
      [].freeze
    else
      if @not
        result = [:not, result].freeze end
      result end end

  private

  def call
    if @changed_hook
      @changed_hook.call end end

  def gen_add_button
    container = Gtk::HBox.new
    btn = Gtk::Button.new('条件を追加')
    btn.signal_connect(:clicked){
      add_condition.show_all }
    btn2 = Gtk::Button.new('サブフィルタを追加')
    btn2.signal_connect(:clicked){
      add_condition([:and, DEFAULT_CONDITION]).show_all }
    container.closeup(btn).closeup(btn2) end

  class PickCondition < Gtk::HBox
    def initialize(conditions = DEFAULT_CONDITION, *args, &block)
      super(*args)
      @changed_hook = block
      @condition, @subject, @expr = *conditions.to_a
      build
    end

    def to_a
      [@condition, @subject, @expr].freeze end

    private

    def call
      if @changed_hook
        @changed_hook.call end end

    def build
      extract_condition = Hash[Plugin.filtering(:extract_condition, []).first.map{|ec| [ec.slug, ec]}]
      w_argument = Mtk::input(lambda{ |new|
                                unless new === nil
                                  @expr = new.freeze
                                  call end
                                @expr },
                              nil)
      w_operator = Mtk::chooseone(lambda{ |new|
                                    unless new === nil
                                      @condition = new.to_sym
                                      call end
                                    @condition.to_s },
                                  nil,
                                  Hash[Plugin.filtering(:extract_operator, []).first.map{ |eo| [eo.slug.to_s, eo.name] }])
      w_condition = Mtk::chooseone(lambda{ |new|
                                     unless new === nil
                                       @subject = new.to_sym
                                       call end
                                     sensitivity = extract_condition[@subject][:operator] && 0 != extract_condition[@subject][:args]
                                     w_argument.set_sensitive(sensitivity)
                                     w_operator.set_sensitive(sensitivity)
                                     @subject.to_s },
                                   nil,
                                   Hash[extract_condition.map{ |slug, ec| [slug.to_s, ec.name] }])
      closeup(w_condition)
      closeup(w_operator)
      add(w_argument)
    end
  end

end