// -*- 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;
}
}
}