File: gtk_message_picker.rb

package info (click to toggle)
mikutter 3.0.7%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 9,396 kB
  • ctags: 1,916
  • sloc: ruby: 16,619; sh: 117; makefile: 27
file content (136 lines) | stat: -rw-r--r-- 4,332 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
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
# -*- coding: utf-8 -*-
require 'gtk2'
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'utils'))
miquire :core, 'message', 'skin'
miquire :mui, 'mtk'
miquire :mui, 'extension'
miquire :mui, 'webicon'
miquire :miku, 'miku'

class Gtk::MessagePicker < Gtk::EventBox

  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))
    p "#{self}: #{to_a}"
  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 = [:==, :user, ''])
    pack = Gtk::HBox.new
    close = Gtk::Button.new.add(Gtk::WebIcon.new(Skin.get('close.png'), 16, 16)).set_relief(Gtk::RELIEF_NONE)
    close.signal_connect(:clicked){
      @container.remove(pack)
      pack.destroy
      call
      false }
    pack.closeup(close.top)
    if(expr.first == :and or expr.first == :or or expr.first == :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}].freeze
    if(@not)
      result = [:not, result].freeze end
    result 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, [:==, :user, '']]).show_all }
    container.closeup(btn).closeup(btn2) end

  class PickCondition < Gtk::HBox
    def initialize(conditions = [:==, :user, ''], *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
      closeup(Mtk::chooseone(lambda{ |new|
                               unless new === nil
                                 @subject = new.to_sym
                                 call end
                               @subject.to_s },
                             nil,
                             'user' => 'ユーザ名',
                             'body' => '本文',
                             'source' => 'Twitterクライアント'))
      closeup(Mtk::chooseone(lambda{ |new|
                               unless new === nil
                                 @condition = new.to_sym
                                 call end
                               @condition.to_s },
                             nil,
                             '==' => '=',
                             '!=' => '≠',
                             'include?' => '含む',
                             'match_regexp' => '正規表現'))
      add(Mtk::input(lambda{ |new|
                       unless new === nil
                         @expr = new.freeze
                         call end
                       @expr },
                             nil))
    end
  end

end