~frandelhoyo/wingpanel/wingpanel

« back to all changes in this revision

Viewing changes to src/Widgets/BasePanel.vala

  • Committer: Cody Garver
  • Author(s): Victor
  • Date: 2013-04-16 18:13:05 UTC
  • mfrom: (124.1.44 wingpanel)
  • Revision ID: cody@elementaryos.org-20130416181305-mjb3in0e3fo06jb2
- [CMake] Use new ValaPrecompile module to fix double-compilation bug.
- Cleaner object dependencies. Abstract the Indicator.Object API away from UI code.
- Better indicator reference management.
- Proper handling of indicator entries.
- Indicator Sorting.
- Consistent Theming for the Panel. This doesn't apply to the popovers since their theming is still partially hardcoded.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// -*- Mode: vala; indent-tabs-mode: nil; tab-width: 4 -*-
 
2
//  
 
3
//  Copyright (C) 2011-2013 Wingpanel Developers
 
4
// 
 
5
//  This program is free software: you can redistribute it and/or modify
 
6
//  it under the terms of the GNU General Public License as published by
 
7
//  the Free Software Foundation, either version 3 of the License, or
 
8
//  (at your option) any later version.
 
9
// 
 
10
//  This program is distributed in the hope that it will be useful,
 
11
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
//  GNU General Public License for more details.
 
14
// 
 
15
//  You should have received a copy of the GNU General Public License
 
16
//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
17
 
 
18
public abstract class Wingpanel.Widgets.BasePanel : Gtk.Window {
 
19
    private enum Struts {
 
20
        LEFT,
 
21
        RIGHT,
 
22
        TOP,
 
23
        BOTTOM,
 
24
        LEFT_START,
 
25
        LEFT_END,
 
26
        RIGHT_START,
 
27
        RIGHT_END,
 
28
        TOP_START,
 
29
        TOP_END,
 
30
        BOTTOM_START,
 
31
        BOTTOM_END,
 
32
        N_VALUES
 
33
    }
 
34
 
 
35
    private const int SHADOW_SIZE = 4;
 
36
 
 
37
    private int panel_height = 0;
 
38
    private int panel_x;
 
39
    private int panel_y;
 
40
    private int panel_width;
 
41
    private int panel_displacement = -40;
 
42
    private uint animation_timer = 0;
 
43
 
 
44
    private PanelShadow shadow = new PanelShadow ();
 
45
 
 
46
    public BasePanel () {
 
47
        decorated = false;
 
48
        resizable = false;
 
49
        skip_taskbar_hint = true;
 
50
        app_paintable = true;
 
51
        set_visual (get_screen ().get_rgba_visual ());
 
52
        set_type_hint (Gdk.WindowTypeHint.DOCK);
 
53
 
 
54
        panel_resize (false);
 
55
 
 
56
        // Update the panel size on screen size or monitor changes
 
57
        screen.size_changed.connect (on_monitors_changed);
 
58
        screen.monitors_changed.connect (on_monitors_changed);
 
59
 
 
60
        destroy.connect (Gtk.main_quit);
 
61
    }
 
62
 
 
63
    protected abstract Gtk.StyleContext get_draw_style_context ();
 
64
 
 
65
    public override void realize () {
 
66
        base.realize ();
 
67
        panel_resize (false);
 
68
    }
 
69
 
 
70
    public override bool draw (Cairo.Context cr) {
 
71
        Gtk.Allocation size;
 
72
        get_allocation (out size);
 
73
 
 
74
        if (panel_height != size.height) {
 
75
            panel_height = size.height;
 
76
            message ("New Panel Height: %i", size.height);
 
77
            shadow.move (panel_x, panel_y + panel_height + panel_displacement);
 
78
            set_struts ();
 
79
        }
 
80
 
 
81
        var ctx = get_draw_style_context ();
 
82
        ctx.render_background (cr, size.x, size.y, size.width, size.height);
 
83
 
 
84
        // Slide in
 
85
        if (animation_timer == 0) {
 
86
            panel_displacement = -panel_height;
 
87
            animation_timer = Timeout.add (300 / panel_height, animation_callback);
 
88
        }
 
89
 
 
90
        var child = get_child ();
 
91
 
 
92
        if (child != null)
 
93
            propagate_draw (child, cr);
 
94
 
 
95
        if (!shadow.visible)
 
96
            shadow.show_all ();
 
97
 
 
98
        return true;
 
99
    }
 
100
 
 
101
    private bool animation_callback () {
 
102
        if (panel_displacement >= 0 ) {
 
103
            return false;
 
104
        } else {
 
105
            panel_displacement += 1;
 
106
            move (panel_x, panel_y + panel_displacement);
 
107
            shadow.move (panel_x, panel_y + panel_height + panel_displacement);
 
108
            return true;
 
109
        }
 
110
    }
 
111
 
 
112
    private void on_monitors_changed () {
 
113
        panel_resize (true);
 
114
    }
 
115
 
 
116
    private void set_struts () {
 
117
        if (!get_realized ())
 
118
            return;
 
119
 
 
120
        // Since uchar is 8 bits in vala but the struts are 32 bits
 
121
        // we have to allocate 4 times as much and do bit-masking
 
122
        var struts = new ulong[Struts.N_VALUES];
 
123
 
 
124
        struts[Struts.TOP] = panel_height + panel_y;
 
125
        struts[Struts.TOP_START] = panel_x;
 
126
        struts[Struts.TOP_END] = panel_x + panel_width;
 
127
 
 
128
        var first_struts = new ulong[Struts.BOTTOM + 1];
 
129
        for (var i = 0; i < first_struts.length; i++)
 
130
            first_struts[i] = struts[i];
 
131
 
 
132
        unowned X.Display display = Gdk.X11Display.get_xdisplay (get_display ());
 
133
        var xid = Gdk.X11Window.get_xid (get_window ());
 
134
 
 
135
        display.change_property (xid, display.intern_atom ("_NET_WM_STRUT_PARTIAL", false), X.XA_CARDINAL,
 
136
                                 32, X.PropMode.Replace, (uchar[]) struts, struts.length);
 
137
        display.change_property (xid, display.intern_atom ("_NET_WM_STRUT", false), X.XA_CARDINAL,
 
138
                                 32, X.PropMode.Replace, (uchar[]) first_struts, first_struts.length);
 
139
    }
 
140
 
 
141
    private void panel_resize (bool redraw) {
 
142
        Gdk.Rectangle monitor_dimensions;
 
143
 
 
144
        screen.get_monitor_geometry (screen.get_primary_monitor(), out monitor_dimensions);
 
145
 
 
146
        panel_x = monitor_dimensions.x;
 
147
        panel_y = monitor_dimensions.y;
 
148
        panel_width = monitor_dimensions.width;
 
149
 
 
150
        move (panel_x, panel_y + panel_displacement);
 
151
        shadow.move (panel_x, panel_y + panel_height + panel_displacement);
 
152
 
 
153
        this.set_size_request (panel_width, -1);
 
154
        shadow.set_size_request (panel_width, SHADOW_SIZE);
 
155
 
 
156
        set_struts ();
 
157
 
 
158
        if (redraw)
 
159
            queue_draw ();
 
160
    }
 
161
}