/* * 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; public Zavai() { title = "Zavai"; current = null; destroy += Gtk.main_quit; set_events(get_events() | Gdk.EventMask.VISIBILITY_NOTIFY_MASK); set_position(Gtk.WindowPosition.MOUSE); visibility_notify_event += on_visibility; set_skip_pager_hint(true); set_skip_taskbar_hint(true); //set_type_hint(Gdk.WindowTypeHint.DESKTOP); zavai.registry.register(this); } 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(Applet applet) { // Remove the current applet if (current != null) { current.stop(); remove(current); current = null; } // Add the new applet current = applet; add(current); current.start(); current.show_all(); } public void push_applet(Applet applet) { // Make the function idempotent if (current == applet) return; // Remove the current applet if (current != null) { //stderr.printf("push applet remove %s\n", current_name); applet.back_link = current; current.stop(); remove(current); current = null; } //stderr.printf("push applet add %s\n", name); // Add the new applet current = applet; add(current); current.start(); current.show_all(); } public void back() { if (current != null) current.back(); } public void back_to_main() { show_applet(zavai.ui.main.status); } public void shutdown() { } public void run() { set_size_request(300, 500); //fullscreen(); if (zavai.config.profile == "laptop") { visibility = false; zavai.app.ensure_hidden(); zavai.ui.wm.raise_icon.update_icon(); } else { 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 Applet 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(); zavai.registry.register(this); } 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(Applet target) { pack_start(new AppletPushLink(target), false, false, 0); } public void add_service_toggle(Service service, string label_start, string label_stop) { pack_start(new ServiceRequestLink(service, 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 Applet _target; public Applet target { get { return _target; } set { if (_target != null) { _target.label_changed -= on_label_changed; } bool was_shown = _target != null; _target = value; if (_target != null) { set_label(_target.label); _target.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(Applet? applet = null) { _target = null; target = applet; 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(Applet? applet = null) { base(applet); } } 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(Applet? applet = null) { base(applet); } } public class ServiceRequestLink : Gtk.ToggleButton { protected Service service; protected string label_start; protected string label_stop; private void on_toggled(Gtk.Button src) { if (get_active()) service.request("servicerequestlink"); else service.release("servicerequestlink"); set_label(get_active() ? label_stop : label_start); } public ServiceRequestLink(Service service, string label_start, string label_stop) { this.service = service; 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); } } public zavai.Zavai app; public zavai.Menu menu_main; public zavai.Menu menu_gps; public zavai.Menu menu_gsm; public zavai.Menu menu_misc; namespace main { public void init() { zavai.app = new zavai.Zavai(); menu_main = new zavai.Menu("Main menu"); // Create menus menu_gps = new zavai.Menu("GPS"); menu_main.add_applet(menu_gps); menu_gsm = new zavai.Menu("GSM"); menu_main.add_applet(menu_gsm); menu_misc = new zavai.Menu("Misc"); menu_main.add_applet(menu_misc); } } }