File: gtk_contextmenu.rb

package info (click to toggle)
mikutter 5.0.4%2Bdfsg1-2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 9,700 kB
  • sloc: ruby: 21,307; sh: 181; makefile: 19
file content (90 lines) | stat: -rw-r--r-- 2,395 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
# -*- coding: utf-8 -*-

module Gtk
  class ContextMenu
    extend Gem::Deprecate
    def initialize(*context)
      reset(context) end

    def reset(context)
      @contextmenu = context
    end

    def register(label, condition=:itself, &callback)
      @contextmenu = @contextmenu.push([label, condition.to_proc, callback])
    end
    alias :registmenu :register
    deprecate :registmenu, "register", 2018, 04

    def line(&proc)
      register(nil, proc || :itself)
    end
    alias :registline :line
    deprecate :registline, "line", 2018, 04


    # メニューが閉じられた時、自身を自動的に破棄する Gtk::Menu を作成して返す
    def temporary_menu
      menu = Gtk::Menu.new
      menu.ssc(:selection_done) do
        menu.destroy
        false end
      menu.ssc(:cancel) do
        menu.destroy
        false end
      menu end

    def build!(widget, optional, menu = temporary_menu)
      @contextmenu.each do |param|
        label, cond, proc, icon = param
        if cond.call(*[optional, widget][0, (cond.arity < 0 ? 1 : cond.arity)])
          if label
            item = gen_menu_item(label_text(label, optional, widget), icon, optional, widget)
            if proc
              item.ssc(:activate) do |w|
                proc.call(*[optional, widget][0...proc.arity])
                false
              end
            end
            menu.append(item)
          else
            menu.append(Gtk::MenuItem.new)
          end
        end
      end
      menu
    end

    def popup(widget, optional)
      menu = build!(widget, optional)

      if not menu.children.empty?
        menu.show_all.popup(nil, nil, 0, 0)
      end
    end

    private

    def label_text(label, optional, widget)
      if defined?(label.call)
        label.call(*[optional, widget][0, (label.arity == -1 ? 1 : label.arity)])
      else
        label
      end
    end

    def gen_menu_item(label_text, icon, optional, widget)
      if icon.is_a?(Proc)
        icon = icon.call(*[optional, widget][0, (icon.arity == -1 ? 1 : icon.arity)])
      end
      if icon
        Gtk::ImageMenuItem.new(label: label_text, use_underline: false).tap do |item|
          item.set_image(Gtk::WebIcon.new(icon, 16, 16))
          item.always_show_image = true
        end
      else
        Gtk::MenuItem.new(label: label_text, use_underline: false)
      end
    end
  end
end