aboutsummaryrefslogtreecommitdiffstats
path: root/core/plugin/gtk/world_shifter.rb
blob: 3af51187116943aa596d605894c7368c2c1b3d71 (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
# -*- coding: utf-8 -*-

require "gtk2"

class Gtk::WorldShifter < Gtk::EventBox
  UserConfig[:gtk_accountbox_geometry] ||= 32

  def initialize
    super
    ssc(:button_press_event) do |this,event|
      open_menu event if 3 >= event.button
      false
    end
    ssc_atonce(:realize) do
      refresh
    end
    pluggaloid_event_listener
  end

  def refresh
    destroy_menu
    put_face
    modify_face
  end

  def open_menu(event)
    @menu ||= Gtk::Menu.new.tap do |menu|
      Enumerator.new{|y|
        Plugin.filtering(:worlds, y)
      }.each do |world|
        item = Gtk::ImageMenuItem.new(world.title, false)
        item.set_image Gtk::WebIcon.new(world.icon, UserConfig[:gtk_accountbox_geometry], UserConfig[:gtk_accountbox_geometry])
        item.ssc(:activate) { |w|
          Plugin.call(:world_change_current, world)
          false }
        menu.append item
      end
      menu.append Gtk::SeparatorMenuItem.new
      item = Gtk::ImageMenuItem.new(Plugin[:gtk]._('Worldを追加'), false)
      item.set_image Gtk::WebIcon.new(Skin['add.png'], UserConfig[:gtk_accountbox_geometry], UserConfig[:gtk_accountbox_geometry])
      item.ssc(:activate) { |w|
        Plugin.call(:request_world_add)
        false }
      menu.append item
      menu
    end
    @menu.show_all.popup(nil, nil, event.button, event.time)
  end

  def destroy_menu
    @menu&.destroy
    @menu = nil
  end

  def pluggaloid_event_listener
    tag = Plugin[:gtk].handler_tag(:world_shifter) do
      Plugin[:gtk].on_world_change_current{ refresh }
      Plugin[:gtk].on_userconfig_modify do |key, newval|
        refresh if key == :world_shifter_visibility
      end
      Plugin[:gtk].on_world_create do |world|
        refresh
      end
      Plugin[:gtk].on_world_destroy do |world|
        refresh
      end
    end
    ssc(:destroy) do
      Plugin[:gtk].detach(tag)
    end
  end

  def put_face
    if visible?
      add_face_widget_ifn
    else
      remove_face_widget_ifn
    end
  end

  def visible?
    case UserConfig[:world_shifter_visibility]
    when :always
      true
    when :auto
      1 < Enumerator.new{|y| Plugin.filtering(:worlds, y) }.take(2).to_a.size
    else
      false
    end
  end

  def modify_face
    if @face
      world, = Plugin.filtering(:world_current, nil)
      transaction = @world_transaction = SecureRandom.uuid
      rect = { width:  UserConfig[:gtk_accountbox_geometry],
               height: UserConfig[:gtk_accountbox_geometry] }
      @face.pixbuf = world&.icon&.load_pixbuf(**rect) do |pixbuf|
        if transaction == @world_transaction
          @face.pixbuf = pixbuf
        end
      end || Skin['add.png'].pixbuf(**rect)
    end
  end

  def add_face_widget_ifn
    if not @face
      @face = Gtk::Image.new(Skin['loading.png'].pixbuf(width: UserConfig[:gtk_accountbox_geometry], height: UserConfig[:gtk_accountbox_geometry]))
      self.add(@face).show_all
    end
  end

  def remove_face_widget_ifn
    if @face
      self.remove(@face)
      @face.destroy
      @face = nil
    end
  end
end