aboutsummaryrefslogtreecommitdiffstats
path: root/core/plugin/gui/gui.rb
blob: 1049b38f87ba2c6d198317eb11ce57b7295bc388 (plain)
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
141
# -*- coding: utf-8 -*-
# mikutterにGUIをつけるプラグイン

require File.expand_path File.join(File.dirname(__FILE__), 'dsl')
require File.expand_path File.join(File.dirname(__FILE__), 'window')
require File.expand_path File.join(File.dirname(__FILE__), 'pane')
require File.expand_path File.join(File.dirname(__FILE__), 'tab')
require File.expand_path File.join(File.dirname(__FILE__), 'cluster')
require File.expand_path File.join(File.dirname(__FILE__), 'fragment')
require File.expand_path File.join(File.dirname(__FILE__), 'timeline')
require File.expand_path File.join(File.dirname(__FILE__), 'tab_child_widget')
require File.expand_path File.join(File.dirname(__FILE__), 'postbox')
require File.expand_path File.join(File.dirname(__FILE__), 'command')

Plugin.create :gui do

  # タブを作成する
  # ==== Args
  # [slug] ユニークな識別名。
  # [name] タブ名。チップヘルプや、無ければアイコンに使われる。
  # [&proc] メインの定義部分
  # ==== Return
  # procの戻り値
  defdsl :tab do |slug, name=nil, &proc|
    if proc
      i_tab = Plugin::GUI::Tab.instance(slug, name, self.name)
      result = i_tab.instance_eval(&proc)
      Plugin.call :gui_tab_change_icon, i_tab
      i_tab.tab_toolbar.rewind
      result
    else
      Plugin::GUI::Tab.instance(slug, name, self.name) end end

  # _slug_ に対応するタイムラインを返す
  # ==== Args
  # [slug] タイムラインのスラッグ
  # ==== Return
  # Plugin::GUI::Timeline
  defdsl :timeline do |slug, &proc|
    tl = Plugin::GUI::Timeline.instance(slug)
    tl.instance_eval(&proc) if proc
    tl end

  # プロフィールタブを定義する
  # ==== Args
  # [slug] タブスラッグ
  # [title] タブのタイトル
  defdsl :user_fragment do |slug, title, &proc|
    filter_user_detail_view_fragments do |tabs, i_cluster, user|
      tabs.insert(where_should_insert_it(slug, tabs.map(&:first), UserConfig[:profile_tab_order]),
                  [slug,
                   -> {
                     fragment_slug = "#{slug}_#{user.uri}_#{Process.pid}_#{Time.now.to_i.to_s(16)}_#{rand(2 ** 32).to_s(16)}".to_sym
                     i_fragment = Plugin::GUI::Fragment.instance(fragment_slug, title)
                     i_cluster << i_fragment
                     i_fragment.instance_eval{ @model = user }
                     handler_tag(fragment_slug) do |tag|
                       on_gui_destroy do |w|
                         detach(tag) if w == i_fragment end
                       i_fragment.instance_eval_with_delegate(self, &proc) end } ])
      [tabs, i_cluster, user] end end

  # 投稿詳細タブを定義する
  # ==== Args
  # [slug] タブスラッグ
  # [title] タブのタイトル
  defdsl :message_fragment do |slug, title, &proc|
    filter_message_detail_view_fragments do |tabs, i_cluster, message|
      tabs.insert(where_should_insert_it(slug, tabs.map(&:first), UserConfig[:profile_tab_order]),
                  [slug,
                   -> {
                     fragment_slug = "#{slug}_#{message.uri}_#{Process.pid}_#{Time.now.to_i.to_s(16)}_#{rand(2 ** 32).to_s(16)}".to_sym
                     i_fragment = Plugin::GUI::Fragment.instance(fragment_slug, title)
                     i_cluster << i_fragment
                     i_fragment.instance_eval{ @model = message }
                     handler_tag(fragment_slug) do |tag|
                       on_gui_destroy do |w|
                         detach(tag) if w == i_fragment end
                       i_fragment.instance_eval_with_delegate(self, &proc) end } ])
      [tabs, i_cluster, message] end end

  # ダイアログボックスを作成し表示する。
  # ダイアログボックスの内容は _proc_ によって生成される。
  # _proc_ からは、 _Gtk::FormDSL_ のメソッドを利用して内容を作成できる。
  # ==== Args
  # [title] ダイアログボックスタイトルバー等に表示されるテキスト(String)
  # [default] エレメントのデフォルト値。{キー: デフォルト値}のようなHash
  # ==== Return
  # 入力の完了・中断を通知する _Delayer::Deferred_ 。
  # OKボタンが押された場合は _next_ が、キャンセルが押されたり、ボタンを押さずにダイアログを閉じた場合は _trap_ が呼ばれる。
  # ブロックに渡されるオブジェクトは:
  # ===== OKボタンが押された場合
  #     obj.ok? # => true
  #     obj.state # => :ok
  #     obj[:'フォームエレメントのキー(Symbol)'] # => フォームに入力されている値
  #     obj.to_h # => {フォームエレメントのキー: フォームに入力されている値} のHash
  # ===== キャンセルボタンが押された場合
  #     obj.ok? # => false
  #     obj.state # => :cancel
  # ===== ボタンを押さずにダイアログを閉じられた場合
  #     obj.ok? # => false
  #     obj.state # => :close
  defdsl :dialog do |title, default={}, &proc|
    promise = Delayer::Deferred.new(true)
    Plugin.call(:gui_dialog, self, title, default, proc, promise)
    promise
  end

  # obsolete
  defdsl :profiletab do |slug, title, &proc|
    warn 'Plugin#profiletab is obsolete. use Plugin#user_fragment'
    user_fragment slug, title, &proc
  end

  # window,pane,tab設置
  Plugin::GUI.ui_setting.each { |window_slug, panes|
    window = Plugin::GUI::Window.instance(window_slug,  Environment::NAME)
    window.set_icon Skin['icon.png']
    window << Plugin::GUI::Postbox.instance
    if panes.empty?
      panes = { default: [] } end
    panes.each { |pane_slug, tabs|
      pane = Plugin::GUI::Pane.instance(pane_slug)
      tabs.each { |tab_slug|
        pane << Plugin::GUI::Tab.instance(tab_slug) }
      window << pane } }

  # 互換性のため。ステータスバーの更新。ツールキットプラグインで定義されているgui_window_rewindstatusを呼ぶこと
  on_rewindstatus do |text|
    Plugin.call(:gui_window_rewindstatus, Plugin::GUI::Window.instance(:default), text, 10)
  end

  on_gui_destroy do |widget|
    widget.parent.remove(widget) if widget.respond_to?(:parent)
    widget.children.each(&:destroy) if widget.respond_to?(:children) end

  filter_tabs do |set|
    [(set || {}).merge(Plugin::GUI::Tab.cuscaded)]
  end

end