提案 #1258 » 1258-1.patch
| core/plugin/extract/extract.rb | ||
|---|---|---|
|                                    true } }))) | ||
|     Plugin.create :extract do | ||
|       add_tab_observer = on_extract_tab_create(&tablist.method(:add_record)) | ||
|       update_tab_observer = on_extract_tab_update(&tablist.method(:update_record)) | ||
|       delete_tab_observer = on_extract_tab_delete(&tablist.method(:remove_record)) | ||
|       tablist.ssc(:destroy) do | ||
|         detach add_tab_observer | ||
|         detach update_tab_observer | ||
|         detach delete_tab_observer end end | ||
|   end | ||
| core/plugin/extract/extract_tab_list.rb | ||
|---|---|---|
| =end | ||
| class Plugin::Extract::ExtractTabList < ::Gtk::TreeView | ||
|   ITER_NAME = 0 | ||
|   ITER_ID   = 1 | ||
|   ICON_SIZE = 16 | ||
|   COL_ICON  = 0 | ||
|   COL_NAME  = 1 | ||
|   COL_ID    = 2 | ||
|   COL_SOUND = 3 | ||
|   COL_POPUP = 4 | ||
|   def initialize(plugin) | ||
|     type_strict plugin => Plugin | ||
|     @plugin = plugin | ||
|     super(Gtk::ListStore.new(String, Numeric)) | ||
|     append_column Gtk::TreeViewColumn.new(plugin._("名前"), Gtk::CellRendererText.new, text: ITER_NAME) | ||
|     extract_tabs.each(&method(:add_record)) end | ||
|     super(Gtk::ListStore.new( | ||
|       GdkPixbuf::Pixbuf, # icon | ||
|       String,            # name | ||
|       Numeric,           # id | ||
|       GdkPixbuf::Pixbuf, # sound | ||
|       GdkPixbuf::Pixbuf  # popup | ||
|     )) | ||
|     append_column Gtk::TreeViewColumn.new( | ||
|       '', | ||
|       Gtk::CellRendererPixbuf.new, | ||
|       pixbuf: COL_ICON | ||
|     ) | ||
|     append_column Gtk::TreeViewColumn.new( | ||
|       plugin._('名前'), | ||
|       Gtk::CellRendererText.new, | ||
|       text: COL_NAME | ||
|     ).tap { |col| col.expand = true } | ||
|     append_column Gtk::TreeViewColumn.new( | ||
|       '', | ||
|       Gtk::CellRendererPixbuf.new, | ||
|       pixbuf: COL_SOUND | ||
|     ) | ||
|     append_column Gtk::TreeViewColumn.new( | ||
|       '', | ||
|       Gtk::CellRendererPixbuf.new, | ||
|       pixbuf: COL_POPUP | ||
|     ) | ||
|     extract_tabs.each(&method(:add_record)) | ||
|     register_signal_handlers | ||
|   end | ||
|   # 現在選択されている抽出タブのIDを返す | ||
|   # ==== Return | ||
|   # 選択されている項目のID。何も選択されていない場合はnil | ||
|   def selected_id | ||
|     selected_iter = selection.selected | ||
|     selected_iter[ITER_ID] if selected_iter end | ||
|     selected_iter[COL_ID] if selected_iter end | ||
|   # レコードを追加する | ||
|   # ==== Args | ||
|   # [record] 追加するレコード(Hash) | ||
|   # ==== Return | ||
|   # self | ||
|   def add_record(record) | ||
|     iter = model.append | ||
|     iter[Plugin::Extract::ExtractTabList::ITER_NAME] = record[:name] | ||
|     iter[Plugin::Extract::ExtractTabList::ITER_ID] = record[:id] | ||
|     self end | ||
|     setup_iter iter, record | ||
|   end | ||
|   # レコードをもとにリストビューを更新する | ||
|   # ==== Args | ||
|   # [record] 更新されたレコード(Hash) | ||
|   def update_record(record) | ||
|     update_iter = model.to_enum | ||
|                        .map { |_, _, iter| iter } | ||
|                        .find { |iter| iter[COL_ID] == record[:id] } | ||
|     setup_iter update_iter, record if update_iter | ||
|   end | ||
|   # 抽出タブをリストから削除する | ||
|   # ==== Args | ||
| ... | ... | |
|   # ==== Return | ||
|   # self | ||
|   def remove_record(record_id) | ||
|     remove_iter = model.to_enum(:each).map{|_,_,iter|iter}.find{|iter| record_id == iter[ITER_ID] } | ||
|     remove_iter = model.to_enum(:each).map{|_,_,iter|iter}.find{|iter| record_id == iter[COL_ID] } | ||
|     model.remove(remove_iter) if remove_iter | ||
|     self end | ||
|   private | ||
|   def register_signal_handlers | ||
|     # 項目をダブルクリックして設定を開く | ||
|     ssc(:button_press_event) do |_, ev| | ||
|       next if ev.event_type != Gdk::Event::BUTTON2_PRESS | ||
|       id = selected_id | ||
|       if id | ||
|         Plugin.call(:extract_open_edit_dialog, id) | ||
|         true | ||
|       end | ||
|     end | ||
|   end | ||
| # ==== utility | ||
|   # レコードの配列を返す | ||
| ... | ... | |
|   def extract_tabs | ||
|     UserConfig[:extract_tabs] || [] end | ||
|   # イテレータにレコードの内容をコピーする | ||
|   # ==== Args | ||
|   # [iter] TreeIter | ||
|   # [record] 参照するレコード (Hash) | ||
|   def setup_iter(iter, record) | ||
|     size = { width: ICON_SIZE, height: ICON_SIZE } | ||
|     set_icon = lambda { |col, photo| | ||
|       iter[col] = photo.load_pixbuf(**size) do |pb| | ||
|         iter[col] = pb unless destroyed? | ||
|       end | ||
|     } | ||
|     iter[COL_NAME] = record[:name] | ||
|     iter[COL_ID] = record[:id] | ||
|     if record[:icon] | ||
|       photo = Enumerator.new do |y| | ||
|         Plugin.filtering :photo_filter, record[:icon], y | ||
|       end.first | ||
|       set_icon.call COL_ICON, photo | ||
|     end | ||
|     if record[:sound].to_s.empty? | ||
|       # FIXME: 適当なアイコンを標準スキンに入れる | ||
|       set_icon.call COL_SOUND, Skin['speaker-x.png'] | ||
|     else | ||
|       set_icon.call COL_SOUND, Skin['speaker-l.png'] | ||
|     end | ||
|     if record[:popup] | ||
|       # FIXME: 適当なアイコンを標準スキンに入れる | ||
|       set_icon.call COL_POPUP, Skin['popup.png'] | ||
|     else | ||
|       set_icon.call COL_POPUP, Skin['no-popup.png'] | ||
|     end | ||
|   end | ||
|   # def on_created(iter) | ||
|   #   Plugin.call(:extract_tab_create, | ||
|   #               name: iter[ITER_NAME], | ||
|   #               name: iter[COL_NAME], | ||
|   #               sexp: iter[ITER_SEXP], | ||
|   #               sources: iter[ITER_SOURCE], | ||
|   #               id: iter[ITER_ID] = gen_uniq_id) end | ||
|   #               id: iter[COL_ID] = gen_uniq_id) end | ||
|   # def on_updated(iter) | ||
|   #   Plugin.call(:extract_tab_update, | ||
|   #               name: iter[ITER_NAME], | ||
|   #               name: iter[COL_NAME], | ||
|   #               sexp: iter[ITER_SEXP], | ||
|   #               sources: iter[ITER_SOURCE], | ||
|   #               id: iter[ITER_ID]) end | ||
|   #               id: iter[COL_ID]) end | ||
|   def gen_uniq_id(uniq_id = Time.now.to_i) | ||
|     if extract_tabs.any?{ |x| x[:id] == uniq_id } | ||