/* * app - zavai main window * * Copyright (C) 2009 Enrico Zini * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ using GLib; namespace zavai { public class Zavai : Gtk.Window, zavai.Resource { public bool visibility = true; public signal void visibility_changed(bool visible); zavai.Applet current; string current_name; public Zavai() { title = "Zavai"; current = null; current_name = null; destroy += Gtk.main_quit; set_events(get_events() | Gdk.EventMask.VISIBILITY_NOTIFY_MASK); visibility_notify_event += on_visibility; set_skip_pager_hint(true); set_skip_taskbar_hint(true); //set_type_hint(Gdk.WindowTypeHint.DESKTOP); } private bool on_visibility(Gdk.Event event) { visibility = (event.visibility.state == Gdk.VisibilityState.UNOBSCURED); //visible = visibility; visibility_changed(visibility); return true; } public void toggle_visibility() { if (visibility) { visible = false; visibility = false; visibility_changed(visibility); //zavai.app.iconify(); } else { visible = true; present(); set_skip_pager_hint(true); set_skip_taskbar_hint(true); } } public void ensure_visible() { if (!visibility) { visible = true; present(); set_skip_pager_hint(true); set_skip_taskbar_hint(true); } } public void ensure_hidden() { if (visibility) { visible = false; visibility = false; visibility_changed(visibility); } } public void show_applet(string name) { zavai.Applet applet = zavai.registry.geta(name); // Remove the current applet if (current != null) { current.stop(); remove(current); current = null; current_name = null; } // Add the new applet current = applet; current_name = name; add(current); current.start(); current.show_all(); } public void push_applet(string name) { // Make the function idempotent if (current_name == name) return; //stderr.printf("push applet %s -> %s\n", current_name, name); zavai.Applet applet = zavai.registry.geta(name); // Remove the current applet if (current != null) { //stderr.printf("push applet remove %s\n", current_name); applet.back_link = current_name; current.stop(); remove(current); current = null; current_name = null; } //stderr.printf("push applet add %s\n", name); // Add the new applet current = applet; current_name = name; add(current); current.start(); current.show_all(); } public void back() { if (current != null) current.back(); } public void back_to_main() { show_applet("zavai.status"); } public void shutdown() { } public void run() { set_size_request(300, 500); //fullscreen(); show_all(); } public void run_script(string command) { zavai.log.info("Run program: " + command); string[] args = command.split(" "); Pid pid; try { Process.spawn_async( Environment.get_home_dir(), args, null, SpawnFlags.SEARCH_PATH, null, out pid); } catch (SpawnError e) { zavai.log.error("Running " + command + ": " + e.message); } } } public abstract class Applet : Gtk.VBox, Resource { // 'label' property: label to show in window title or button names protected string _label; public string label { get { return this._label; } set { if (_label != value) { _label = value; label_changed(); } } } public signal void label_changed(); protected Gtk.HBox button_box; // 'back_link' property: link to use to "go back". If null, do not show // a way to go back. protected AppletLink _back_link = null; public string back_link { get { return _back_link.target; } set { //stderr.printf("Set back link of %s to %s\n", _label, value); if (value == null && _back_link != null) { _back_link.target = value; button_box.remove(_back_link); } else if (value != null) { if (_back_link.target == null) { _back_link.target = value; button_box.pack_end(_back_link, true, true, 0); _back_link.show(); } else _back_link.target = value; } } } public Applet() { button_box = new Gtk.HBox(true, 0); this.homogeneous = false; this.spacing = 0; pack_end(button_box, false, true, 0); _back_link = new AppletStraightLink(); } public virtual void back() { _back_link.activate_applet(); } public virtual void back_to_main() { zavai.app.back_to_main(); } public void shutdown() { stop(); } public virtual void start() {} public virtual void stop() {} } public class Menu : Applet { public Menu(string label) { _label = label; } public void add_applet(string target) { pack_start(new AppletPushLink(target), false, false, 0); } public void add_service_toggle(string service_name, string label_start, string label_stop) { pack_start(new ServiceRequestLink(service_name, label_start, label_stop), false, false, 0); } public void add_widget(Gtk.Widget w) { pack_start(w, false, false, 0); } } public class BigButton : Gtk.Button { public BigButton() { set_size_request(0, zavai.config.min_button_height); } } public abstract class AppletLink : BigButton { protected string _target; public string target { get { return _target; } set { if (_target != null) { Applet a = zavai.registry.geta(_target); a.label_changed -= on_label_changed; } bool was_shown = _target != null; _target = value; if (_target != null) { Applet a = zavai.registry.geta(_target); set_label(a.label); a.label_changed += on_label_changed; if (!was_shown) show(); } else { if (was_shown) hide(); } } } private void on_label_changed(Applet a) { set_label(a.label); } private abstract void on_clicked(Gtk.Button src); public AppletLink(string? name = null) { _target = null; target = name; clicked += on_clicked; } public virtual void activate_applet() { on_clicked(this); } } public class AppletStraightLink : AppletLink { private override void on_clicked(Gtk.Button src) { //stderr.printf("straight link: %s\n", _target); if (_target != null) zavai.app.show_applet(_target); } public AppletStraightLink(string? name = null) { base(name); } } public class AppletPushLink : AppletLink { private override void on_clicked(Gtk.Button src) { //stderr.printf("push link: %s\n", _target); if (_target != null) zavai.app.push_applet(_target); } public AppletPushLink(string? name = null) { base(name); } } public class ServiceRequestLink : Gtk.ToggleButton { protected string service_name; protected string label_start; protected string label_stop; private void on_toggled(Gtk.Button src) { Service s = zavai.registry.gets(service_name); if (get_active()) s.request("servicerequestlink"); else s.release("servicerequestlink"); set_label(get_active() ? label_stop : label_start); } public ServiceRequestLink(string service_name, string label_start, string label_stop) { this.service_name = service_name; this.label_start = label_start; this.label_stop = label_stop; set_size_request(0, zavai.config.min_button_height); toggled += on_toggled; set_label(get_active() ? label_stop : label_start); } } public class StatusIcon : Gtk.Button { private Gtk.Image image_widget; public StatusIcon() { relief = Gtk.ReliefStyle.NONE; image_widget = new Gtk.Image(); image = image_widget; } public void set_from_file(string file) { image_widget.set_from_file(file); } public void install() { zavai.ui.main.status.status_icons.pack_start(this, false, false, 0); } } zavai.Zavai app; }