// -*- Mode: vala; indent-tabs-mode: nil; tab-width: 4 -*- /*** BEGIN LICENSE Copyright (C) 2011-2013 Wingpanel Developers This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License version 3, as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, SATISFACTORY QUALITY, 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, see END LICENSE ***/ using Gdk; namespace SuperWingpanel.Widgets { // reference needed for unmaximize call [DBus (name = "org.pantheon.gala")] interface Gala : Object { public abstract void perform_action (int type) throws IOError; } public class PrimaryWindow : WindowIface { private Gtk.Box left_wrapper; private Gtk.Box right_wrapper; private Gtk.SizeGroup size_group; private bool clock_is_centered = false; private IndicatorMenubar indicator_menubar; private MenuBar clock_menubar; private MenuBar apps_menubar; private Gtk.EventBox unmaximize_event; private Gtk.EventBox close_event; private Gtk.Label window_name; public PrimaryWindow (WingpanelApp app) { base (app); left_wrapper = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 0); right_wrapper = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 0); container.set_homogeneous (false); left_wrapper.set_homogeneous (false); right_wrapper.set_homogeneous (false); add (container); var style_context = get_style_context (); style_context.add_class (StyleClass.PANEL); style_context.add_class (Gtk.STYLE_CLASS_MENUBAR); // Watch for mouse add_events (EventMask.ENTER_NOTIFY_MASK | EventMask.LEAVE_NOTIFY_MASK | EventMask.POINTER_MOTION_MASK); destroy.connect (Gtk.main_quit); } public override void set_window_manager(WindowManager window_manager) { manager = window_manager; add_default_widgets (manager.settings); } public override Gtk.StyleContext get_draw_style_context () { return indicator_menubar.get_style_context (); } private void add_default_widgets (Services.Settings settings) { // window buttons var screen = Wnck.Screen.get_default (); window_name = new Gtk.Label(" "); var close_box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 0); var close_icon = new Gtk.Image.from_file ("/usr/share/super-wingpanel/icons/window-close.svg"); close_event = new Gtk.EventBox (); close_box.pack_start (close_icon, false, false, 2); close_event.add (close_box); close_event.set_visible_window (false); close_event.button_press_event.connect (() => { screen.force_update(); var active_window = screen.get_active_window(); if (active_window.get_window_type() == Wnck.WindowType.NORMAL) { active_window.close(Gtk.get_current_event_time()); } return true; }); left_wrapper.pack_start (close_event, false, true, 0); var unmaximize_box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 0); var unmaximize_icon = new Gtk.Image.from_file ("/usr/share/super-wingpanel/icons/window-unmaximize.svg"); unmaximize_event = new Gtk.EventBox (); unmaximize_box.pack_start (unmaximize_icon, false, false, 4); unmaximize_event.add (unmaximize_box); unmaximize_event.set_visible_window (false); unmaximize_event.button_press_event.connect (() => { screen.force_update(); try { Gala gala = Bus.get_proxy_sync (BusType.SESSION, "org.pantheon.gala", "/org/pantheon/gala"); gala.perform_action (2); // action 2 = maximize/unmaximize } catch (IOError e) { // TODO: something... } return true; }); right_wrapper.pack_end (unmaximize_event, false, true, 0); // Add Apps button apps_menubar = new MenuBar (); var apps_button = new Widgets.AppsButton (settings); apps_menubar.append (apps_button); left_wrapper.pack_start (apps_menubar, false, true, 0); left_wrapper.pack_start (window_name, false, true, 0); container.pack_start (left_wrapper); clock_menubar = new MenuBar (); container.pack_start (clock_menubar, false, false, 0); // Menubar for storing indicators indicator_menubar = new IndicatorMenubar (); right_wrapper.pack_end (indicator_menubar, false, false, 0); container.pack_end (right_wrapper); size_group = new Gtk.SizeGroup (Gtk.SizeGroupMode.HORIZONTAL); set_clock_centered (!manager.settings.enable_slim_mode); } public void set_clock_centered (bool enable) { if (enable != clock_is_centered) { clock_is_centered = enable; if (enable) { size_group.add_widget (left_wrapper); size_group.add_widget (right_wrapper); } else { size_group.remove_widget (left_wrapper); size_group.remove_widget (right_wrapper); } } } public void show_app_button (bool enable) { if (enable) apps_menubar.show (); else apps_menubar.hide (); } public void show_window_controls (bool enable) { close_event.set_visible (enable); unmaximize_event.set_visible (enable); window_name.set_visible (enable); } public void set_window_text (string window_text) { if (window_text.length > 75) window_name.set_markup("" + window_text.slice (0, 72) + "..."); else window_name.set_markup("" + window_text + ""); } public override void load_indicators (IndicatorLoader indicator_loader) { var indicators = indicator_loader.get_indicators (); foreach (var indicator in indicators) load_indicator (indicator); } private void load_indicator (IndicatorIface indicator) { var entries = indicator.get_entries (); foreach (var entry in entries) create_entry (entry); indicator.entry_added.connect (create_entry); indicator.entry_removed.connect (delete_entry); } private void create_entry (IndicatorWidget entry) { if (entry.get_indicator ().get_name () == "libdatetime.so") { clock_menubar.prepend (entry); } else if (entry.get_indicator ().get_name () == "libappmenu.so") { apps_menubar.append (entry); } else { indicator_menubar.insert_sorted (entry); } } private void delete_entry (IndicatorWidget entry) { var parent = entry.parent; parent.remove (entry); } public override void update_size_and_position () { update_clock_alignment (); unowned PositionManager position_manager = manager.position_manager; position_manager.update_size_and_position (); move (position_manager.X, position_manager.Y); set_size_request (position_manager.W, position_manager.H); manager.shadow.update_size_and_position (position_manager.shadow_X, position_manager.shadow_Y, position_manager.shadow_W, position_manager.shadow_H); } public void update_clock_alignment () { if (manager.settings.enable_slim_mode) set_clock_centered (false); else if (manager.settings.hide_mode == HideType.INTELLISLIM && manager.renderer.hide_progress >= 0.5) set_clock_centered (false); else set_clock_centered (true); } public override bool draw (Cairo.Context cr) { manager.renderer.draw_panel (cr); return true; } } }