~gotwig/gazette/global-service-states

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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
public class Service : Clutter.Actor, Granite.Services.SettingsSerializable {
    uint timeout = 0;
    float start_x;
    float start_y;
    float factor = 1;
    bool held = false;

    Settings settings;
    int title_size;
    int content_size;
    string title_face;
    string content_face;
    string text_color;
    string shadow_color;

    ShadowedLabel _title;
    ShadowedLabel reload;
    Clutter.Actor contents;
    unowned Gazette.Plugin.Base parent;

    const int MARGIN = 30;
    public double scale { get { return this.scale_x; } set { this.scale_x = this.scale_y = value; } }
    public string title {
        get { return _title.label; }
        set { _title.label = @"<span face='$title_face' font='$title_size'>" + value + "</span>"; contents.y = reload.y = _title.y + _title.height;}
    }

    public Service (Gazette.Plugin.Base parent) {
        debug("Creating service");
        settings = new Settings("org.pantheon.gazette.appearance");
        title_size = 20;
        content_size = 12;
        title_face = settings.get_string("title-font");
        content_face = settings.get_string("content-font");
        text_color = settings.get_string("text-color");
        shadow_color = settings.get_string("shadow-color");
        opacity = 0;
        reactive = true;
        scale_gravity = Clutter.Gravity.NORTH_WEST;
        this.parent = parent;
        this.parent.destroy.connect(() => { this.destroy(); });
        reload = get_reload_label(parent.name);
        reload.hide ();
        contents = new Clutter.Actor ();
        var layout_manager = new Clutter.FlowLayout(Clutter.FlowOrientation.VERTICAL);
        layout_manager.set_row_spacing(-8);
        contents.set_layout_manager(layout_manager);
        _title = new ShadowedLabel("", text_color, shadow_color);
        add_child (_title);
        add_child (contents);
        add_child (reload);
        display ();
    }
    public void add_content (string content) {
        this.contents.add_child(new ShadowedLabel(@"<span face='$content_face' font='$content_size'>" + content + "</span>", text_color, shadow_color));
    }
    public void add_content_with_link(string content, string uri) {
        this.contents.add_child(new ShadowedLink(@"<span face='$content_face' font='$content_size'>" + content + "</span>", uri, text_color, shadow_color));
    }
    public void add_content_marked_up(string content) {
        this.contents.add_child(new ShadowedLabel(content, text_color, shadow_color));
    }
    public void clear_contents () {
        contents.remove_all_children ();
    }
    public void add_clutter_actor (Clutter.Actor actor) {
        this.contents.add_child(actor);
    }
    public override bool button_press_event (Clutter.ButtonEvent event) {
        timeout = Timeout.add (Clutter.Settings.get_default ().long_press_duration, long_held);
        start_x = event.x - x;
        start_y = event.y - y;

        get_stage ().captured_event.connect (intercept);

        return false;
    }
    public void show_reload_label () {
        reload.show ();
    }
    public void hide_reload_label () {
        reload.hide ();
    }
    bool long_held () {
        held = true;
        animate (Clutter.AnimationMode.EASE_IN_OUT_BACK, 300, scale_x : 0.8f * factor, scale_y : 0.8f * factor);

        return false;
    }

    bool intercept (Clutter.Event event) {
        switch (event.get_type ()) {

            case Clutter.EventType.SCROLL:
                double scale_x_value = 0.0;
                double scale_y_value = 0.0;
                get_scale(out scale_x_value, out scale_y_value );
                switch (event.get_scroll_direction ()) {
                    case Clutter.ScrollDirection.UP:
                            animate (Clutter.AnimationMode.EASE_IN_OUT_BACK, 100, scale_x : scale_x_value * 1.01, scale_y : scale_y_value * 1.01);
                            factor *= 1.01f;
                            break;
                    case Clutter.ScrollDirection.DOWN:
                            animate (Clutter.AnimationMode.EASE_IN_OUT_BACK, 100, scale_x : scale_x_value * 0.99, scale_y : scale_y_value * 0.99);
                            factor *= 0.99f;
                            break;
                }
                return true;

            case Clutter.EventType.BUTTON_RELEASE:
                get_stage ().captured_event.disconnect (intercept);
                if (!held) {
                    clear_timeout ();
                    return false;
                }
                debug(@"The scaling factor is: $factor");
                animate (Clutter.AnimationMode.EASE_IN_OUT_BACK, 300, scale_x : 1.0f * factor, scale_y : 1.0f * factor);
                clear_timeout ();
                return true;

            case Clutter.EventType.MOTION:
                if (!held)
                    return false;
                float ex, ey;
                event.get_coords (out ex, out ey);
                x = Math.floorf (ex - start_x);
                y = Math.floorf (ey - start_y);
                return true;
        }
        return false;
    }
    ShadowedLabel get_reload_label (string name) {
        var reload = new ShadowedLabel("<span face='Open Sans Light' font='16'>" +_("Could not load ") + name + _(",\nclick here to try again.") + "</span>", text_color, shadow_color);
        reload.reactive = true;
        reload.button_release_event.connect (parent.update);
        return reload;
    }
    void clear_timeout () {
        if (timeout > 0) {
            Source.remove (timeout);
            timeout = 0;
        }
        held = false;
    }

    internal void display () {
        animate (Clutter.AnimationMode.LINEAR, 400, opacity : 255);
    }

    public string settings_serialize () {
        return @"$x,$y,$scale"; //TODO add rotation settings
    }
    public void settings_deserialize (string s) {
        debug(@"deserialize called with $s");
        var arr = s.split(",");
        this.x = (float) double.parse(arr[0]);
        this.y = (float) double.parse(arr[1]);
        this.scale = double.parse(arr[2]);
        this.factor = (float) this.scale;
    }
}