~and471/slickpanel/trunk

« back to all changes in this revision

Viewing changes to panel/items/indicator/indicatorlist.vala

  • Committer: Andrew Higginson
  • Date: 2014-12-29 17:48:31 UTC
  • Revision ID: at.higginson@gmail.com-20141229174831-bukedaw8kny4aq8t
updating

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright 2010 Andrew Higginson
 
2
 *
 
3
 * This program is free software; you can redistribute it and/or modify
 
4
 * it under the terms of the GNU General Public License as published by
 
5
 * the Free Software Foundation; either version 2 of the License, or
 
6
 * (at your option) any later version.
 
7
*/
 
8
 
 
9
namespace SlickPanel {
 
10
 
 
11
public class IndicatorItem : Gtk.MenuItem {
 
12
 
 
13
    public Indicator.Object object;
 
14
    public unowned Indicator.ObjectEntry entry;
 
15
 
 
16
    public IndicatorItem(Indicator.Object object, Indicator.ObjectEntry entry) {
 
17
        this.object = object;
 
18
        this.entry = entry;
 
19
        
 
20
        var hbox = new Gtk.HBox (false, 6);
 
21
        if (entry.image != null && entry.image is Gtk.Image) {
 
22
            hbox.pack_start(entry.image, false, false);
 
23
        }
 
24
        if (entry.label != null && entry.label is Gtk.Label) {
 
25
            hbox.pack_end(entry.label, true, true);
 
26
        }
 
27
        if (entry.menu != null && entry.menu is Gtk.Menu) {
 
28
            this.set_submenu(entry.menu);
 
29
        }
 
30
        this.add(hbox);
 
31
        
 
32
        this.scroll_event.connect(this.on_scroll_event);
 
33
    }
 
34
    
 
35
    private bool on_scroll_event(Gdk.EventScroll event) {
 
36
            this.object.entry_scrolled(this.entry, 1, (Indicator.ScrollDirection) event.direction);
 
37
        return false;
 
38
    }
 
39
}
 
40
 
 
41
public class IndicatorList : Item {
 
42
 
 
43
    private Gee.TreeMap<string, Object> indicator_objects;
 
44
    public signal void loaded();
 
45
 
 
46
    public IndicatorList() {
 
47
        this.type_ = Settings.ItemType.INDICATOR_BAR;
 
48
        this.widget = new Gtk.MenuBar();
 
49
        (this.widget as Gtk.MenuBar).set_child_pack_direction(Gtk.PackDirection.RTL);
 
50
        
 
51
        this.indicator_objects = new Gee.TreeMap<string, Object>(
 
52
            (a, b) => {
 
53
                var order_a = IndicatorOrder.from_name((string) a);
 
54
                var order_b = IndicatorOrder.from_name((string) b);
 
55
                
 
56
                if (order_a > order_b) {
 
57
                    return -1;
 
58
                }
 
59
                if (order_a == order_b) {
 
60
                    return 0;
 
61
                }
 
62
                if (order_a < order_b) {
 
63
                    return 1;
 
64
                }
 
65
                assert_not_reached();
 
66
            });
 
67
        Thread.create<void*>(create_indicators, false);
 
68
    }
 
69
    
 
70
    public override void set_orientation(Gtk.Orientation orientation) {
 
71
        if (orientation == Gtk.Orientation.HORIZONTAL) {
 
72
            (this.widget as Gtk.MenuBar).set_pack_direction(Gtk.PackDirection.LTR);
 
73
        } else {
 
74
            (this.widget as Gtk.MenuBar).set_pack_direction(Gtk.PackDirection.TTB);
 
75
        }
 
76
    }
 
77
    
 
78
    public override void set_settings(Settings.Item item_settings) {
 
79
        //do something
 
80
    }
 
81
 
 
82
    /* Private Functions */
 
83
    
 
84
    private void* create_indicators() {
 
85
        create_indicator_menus(get_indicator_modules(Config.INDICATORS_DIR, true), true);
 
86
        create_indicator_menus(get_indicator_modules("/usr/share/unity/indicators", false), false);
 
87
 
 
88
        this.loaded();
 
89
        return null;
 
90
    }
 
91
 
 
92
    private File[] get_indicator_modules(string directory, bool legacy) {
 
93
        return Paths.enumerate_directory(File.new_for_path(directory), 
 
94
            (file_name) => {
 
95
                var is_library_file = !legacy || file_name.has_suffix(Module.SUFFIX);
 
96
                var is_not_appmenu = file_name != "libappmenu.so";
 
97
                return (is_library_file && is_not_appmenu);
 
98
            }
 
99
        );
 
100
    }
 
101
    
 
102
    private void create_indicator_menus(File[] indicator_files, bool legacy) {
 
103
        foreach (var indicator_file in indicator_files) {
 
104
            Indicator.Object indicator_object;
 
105
            
 
106
            if (legacy) {
 
107
                indicator_object = new Indicator.Object.from_file(indicator_file.get_path());
 
108
            } else {
 
109
                indicator_object = new Indicator.Ng.for_profile(indicator_file.get_path(), "desktop");
 
110
            }
 
111
            indicator_object.set_data("file-name", indicator_file.get_basename());
 
112
            indicator_object.entry_added.connect(this.on_indicator_object_entry_added);
 
113
            indicator_object.entry_removed.connect(this.on_indicator_object_entry_removed);
 
114
            indicator_object.ref();
 
115
            this.indicator_objects.set(indicator_file.get_basename(), indicator_object);
 
116
        }
 
117
        
 
118
        foreach (var indicator_object in this.indicator_objects.values) {
 
119
            GLib.List<weak Indicator.ObjectEntry> entries = 
 
120
                ((Indicator.Object) indicator_object).get_entries();
 
121
            
 
122
            foreach (var entry in entries) {
 
123
                this.create_indicator_menuitem(indicator_object as Indicator.Object, entry);
 
124
            }
 
125
        }
 
126
    }
 
127
    
 
128
    private void create_indicator_menuitem(Indicator.Object object, 
 
129
        Indicator.ObjectEntry entry, int? position = null) 
 
130
    {
 
131
        var item = new IndicatorItem(object, entry);
 
132
        
 
133
        if (position != null) {
 
134
            (this.widget as Gtk.MenuBar).insert(item, position);
 
135
        } else {
 
136
            (this.widget as Gtk.MenuBar).prepend(item);
 
137
        }
 
138
        item.show_all();
 
139
    }
 
140
    
 
141
    private IndicatorItem? get_item_for_entry(Indicator.ObjectEntry entry) {
 
142
        foreach (var widget in (this.widget as Gtk.MenuBar).get_children()) {
 
143
            var item = widget as IndicatorItem;
 
144
            if (item.entry == entry) {
 
145
                return item;
 
146
            }
 
147
        }
 
148
        return null;
 
149
    }
 
150
    
 
151
    /* Callbacks */
 
152
    
 
153
    private void on_indicator_object_entry_added(Indicator.Object object, 
 
154
        Indicator.ObjectEntry entry) {
 
155
        
 
156
        var order = IndicatorOrder.from_name(object.get_data("file-name"));
 
157
        IndicatorOrder closest_order = IndicatorOrder.NO_ORDER;
 
158
        int? position = null;
 
159
        
 
160
        foreach (var widget in (this.widget as Gtk.MenuBar).get_children()) {
 
161
            var item = widget as IndicatorItem;
 
162
            var item_order = IndicatorOrder.from_name(item.object.get_data("file-name"));
 
163
            
 
164
            bool distance_is_less = Utils.Math.mod(item_order - order)
 
165
                < Utils.Math.mod(closest_order - order);
 
166
            bool distance_is_not_zero = item_order - order != 0;
 
167
            
 
168
            if (distance_is_less && distance_is_not_zero) {
 
169
                closest_order = item_order;
 
170
                position = (this.widget as Gtk.MenuBar).get_children().index(widget) + 1;
 
171
            }
 
172
 
 
173
        }
 
174
        
 
175
        this.create_indicator_menuitem(object, entry, position);
 
176
    }
 
177
    
 
178
    private void on_indicator_object_entry_removed(Indicator.Object object, 
 
179
        Indicator.ObjectEntry entry)
 
180
    {
 
181
        var item = this.get_item_for_entry(entry);
 
182
        if (item != null) {
 
183
            (this.widget as Gtk.MenuBar).remove(item);
 
184
        }
 
185
    }
 
186
 
 
187
    /* Public Functions */
 
188
    public override bool set_xml_property(string name, string value) {
 
189
        bool handled = base.set_xml_property(name, value);
 
190
        if (handled) {
 
191
            return true;
 
192
        }
 
193
        switch (name) {
 
194
            case "ellipsis":
 
195
                return true;
 
196
            default:
 
197
                return false;
 
198
        }
 
199
    }
 
200
}
 
201
}