~indicator-multiload/indicator-multiload/trunk

« back to all changes in this revision

Viewing changes to src/multiloadindicator.vala

  • Committer: Michael Hofmann
  • Date: 2011-05-02 06:49:06 UTC
  • Revision ID: mh21@piware.de-20110502064906-as0r6s80dtg2swdv
Initial public version.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/******************************************************************************
 
2
 * Copyright (C) 2011  Michael Hofmann <mh21@piware.de>                       *
 
3
 *                                                                            *
 
4
 * This program is free software; you can redistribute it and/or modify       *
 
5
 * it under the terms of the GNU General Public License as published by       *
 
6
 * the Free Software Foundation; either version 3 of the License, or          *
 
7
 * (at your option) any later version.                                        *
 
8
 *                                                                            *
 
9
 * This program is distributed in the hope that it will be useful,            *
 
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of             *
 
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the              *
 
12
 * GNU General Public License for more details.                               *
 
13
 *                                                                            *
 
14
 * You should have received a copy of the GNU General Public License along    *
 
15
 * with this program; if not, write to the Free Software Foundation, Inc.,    *
 
16
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.                *
 
17
 ******************************************************************************/
 
18
 
 
19
public class MultiLoadIndicator : Object {
 
20
    private uint index;
 
21
    private uint count;
 
22
    private uint height;
 
23
    private string directory;
 
24
    private TimeoutSource timeout;
 
25
    private FixedAppIndicator.Indicator indicator;
 
26
 
 
27
    private uint _size;
 
28
    private uint _speed;
 
29
    private IconData[] _icon_datas;
 
30
    private Gtk.Menu _menu;
 
31
 
 
32
    public uint size {
 
33
        get {
 
34
            return this._size;
 
35
        }
 
36
        set {
 
37
            this._size = value;
 
38
            foreach (unowned IconData icon_data in this._icon_datas)
 
39
                icon_data.trace_length = value;
 
40
        }
 
41
    }
 
42
 
 
43
    public uint speed {
 
44
        get {
 
45
            return this._speed;
 
46
        }
 
47
        set {
 
48
            this._speed = value;
 
49
            if (this.timeout != null)
 
50
                this.timeout.destroy();
 
51
            if (this.speed % 1000 == 0)
 
52
                this.timeout = new TimeoutSource.seconds(this.speed / 1000);
 
53
            else
 
54
                this.timeout = new TimeoutSource(this.speed);
 
55
            this.timeout.attach(null);
 
56
            this.timeout.set_callback(() => {
 
57
                    foreach (unowned IconData icon_data in this._icon_datas) {
 
58
                        icon_data.update_traces();
 
59
                        icon_data.update_factor();
 
60
                    }
 
61
                    if (indicator != null)
 
62
                        indicator.set_icon(this.write());
 
63
                    return true;
 
64
                });
 
65
        }
 
66
    }
 
67
 
 
68
    public IconData[] icon_datas {
 
69
        get {
 
70
            return this._icon_datas;
 
71
        }
 
72
    }
 
73
 
 
74
    public Gtk.Menu menu {
 
75
        get {
 
76
            return this._menu;
 
77
        }
 
78
        set {
 
79
            this._menu = value;
 
80
            if (value == null)
 
81
                this.indicator = null;
 
82
            if (value != null && this.indicator == null) {
 
83
                this.indicator = new FixedAppIndicator.Indicator.with_path("multiload", this.write(),
 
84
                        AppIndicator.IndicatorCategory.SYSTEM_SERVICES, this.directory);
 
85
                this.indicator.set_status(AppIndicator.IndicatorStatus.ACTIVE);
 
86
            }
 
87
            if (value != null)
 
88
                this.indicator.set_menu(value);
 
89
        }
 
90
    }
 
91
 
 
92
    // Needs to be called before destruction to break the reference cycle from the timeout source
 
93
    public void destroy() {
 
94
        if (this.timeout == null)
 
95
            return;
 
96
        this.timeout.destroy();
 
97
        this.timeout = null;
 
98
    }
 
99
 
 
100
    ~MultiLoadIndicator() {
 
101
        for (uint i = 0, icount = this.count; i < icount; ++i)
 
102
            FileUtils.remove(this.filename(i));
 
103
        DirUtils.remove(this.directory);
 
104
    }
 
105
 
 
106
    public MultiLoadIndicator() {
 
107
        var template = "/var/lock/multiload-icons-XXXXXX".dup();
 
108
        this.directory = DirUtils.mkdtemp(template);
 
109
        this.index = 0;
 
110
        this.count = 2;
 
111
        this.height = 22;
 
112
 
 
113
        this.size = 40;
 
114
        this.speed = 1000;
 
115
    }
 
116
 
 
117
    public void add_icon_data(IconData data) {
 
118
        data.trace_length = this._size;
 
119
        this._icon_datas += data;
 
120
    }
 
121
 
 
122
    private string filename(uint index) {
 
123
        return @"$(this.directory)/$index.png";
 
124
    }
 
125
 
 
126
    private string write() {
 
127
        uint count = 0;
 
128
        foreach (unowned IconData icon_data in this._icon_datas)
 
129
            if (icon_data.enabled)
 
130
                ++count;
 
131
        var surface = new Cairo.ImageSurface(Cairo.Format.ARGB32,
 
132
                (int)(count * (this._size + 2)) - 2, (int)this.height);
 
133
        var ctx = new Cairo.Context(surface);
 
134
        ctx.set_antialias(Cairo.Antialias.NONE);
 
135
        ctx.set_line_width(1);
 
136
        uint offset = 0;
 
137
        foreach (unowned IconData icon_data in this._icon_datas) {
 
138
            if (!icon_data.enabled)
 
139
                continue;
 
140
            icon_data.set_source_color(ctx);
 
141
            ctx.rectangle(offset, 0, this._size, this.height);
 
142
            ctx.fill();
 
143
            var values = new double[icon_data.length, this._size];
 
144
            var scale = icon_data.factor;
 
145
            for (uint j = 0, jsize = values.length[0]; j < jsize; ++j) {
 
146
                unowned double[] trace_data = icon_data.trace(j).values;
 
147
                for (uint i = 0, isize = values.length[1]; i < isize; ++i)
 
148
                    values[j, i] = (j > 0 ? values[j - 1, i] : 0) + trace_data[i] / scale;
 
149
            }
 
150
 
 
151
            for (int j = values.length[0] - 1; j >= 0; --j) {
 
152
                Gdk.cairo_set_source_color(ctx, icon_data.trace(j).color);
 
153
                for (uint i = 0, isize = values.length[1]; i < isize; ++i) {
 
154
                    // the baseline is outside the canvas
 
155
                    ctx.move_to(0.5 + offset + i, this.height + 0.5);
 
156
                    ctx.line_to(0.5 + offset + i,
 
157
                            this.height + 0.5 - this.height * values[j, i]);
 
158
                }
 
159
                ctx.stroke();
 
160
            }
 
161
            offset += this._size + 2;
 
162
        }
 
163
        string name = this.filename(this.index);
 
164
        surface.write_to_png(name);
 
165
        this.index = (this.index + 1) % this.count;
 
166
        return name;
 
167
    }
 
168
}