mirror of
https://gitlab.uni-freiburg.de/opensourcevdi/virt-viewer
synced 2026-01-07 11:24:16 +00:00
window: Replace autoDrawer with native Gtk widgets
GtkRevealer was intrudced in Gtk+ 3.10 and, combined with Gtk Overlay
(intoduced in Gtk+ 3.2), can provide a more sustainably implementation
of the AutoDrawer functionality.
This approach is completely based on the approach taken by virt-manager:
dc05600324
Resolves: https://bugs.freedesktop.org/show_bug.cgi?id=94495
Signed-off-by: Fabiano Fidêncio <fidencio@redhat.com>
Acked-by: Eduardo Lima (Etrunko) <etrunko@redhat.com>
This commit is contained in:
parent
3ab81d7617
commit
cc455b7f91
@ -68,12 +68,8 @@ libvirt_viewer_la_SOURCES = \
|
||||
virt-viewer-window.c \
|
||||
virt-viewer-vm-connection.h \
|
||||
virt-viewer-vm-connection.c \
|
||||
view/autoDrawer.c \
|
||||
view/autoDrawer.h \
|
||||
view/drawer.c \
|
||||
view/drawer.h \
|
||||
view/ovBox.c \
|
||||
view/ovBox.h \
|
||||
virt-viewer-timed-revealer.c \
|
||||
virt-viewer-timed-revealer.h \
|
||||
$(NULL)
|
||||
|
||||
if HAVE_GTK_VNC
|
||||
|
||||
@ -8,246 +8,255 @@
|
||||
<property name="default_height">768</property>
|
||||
<signal name="delete-event" handler="virt_viewer_window_delete" swapped="no"/>
|
||||
<child>
|
||||
<object class="GtkVBox" id="viewer-box">
|
||||
<object class="GtkOverlay" id="viewer-overlay">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkMenuBar" id="top-menu">
|
||||
<object class="GtkVBox" id="viewer-box">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="menu-file">
|
||||
<object class="GtkMenuBar" id="top-menu">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="label" translatable="yes">_File</property>
|
||||
<property name="use_underline">True</property>
|
||||
<child type="submenu">
|
||||
<object class="GtkMenu" id="menu1">
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="menu-file">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="accel_group">accelgroup</property>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="menu-file-screenshot">
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="label" translatable="yes">_File</property>
|
||||
<property name="use_underline">True</property>
|
||||
<child type="submenu">
|
||||
<object class="GtkMenu" id="menu1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="label" translatable="yes">_Screenshot</property>
|
||||
<property name="use_underline">True</property>
|
||||
<signal name="activate" handler="virt_viewer_window_menu_file_screenshot" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="menu-file-usb-device-selection">
|
||||
<property name="visible">True</property>
|
||||
<property name="sensitive">False</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="label" translatable="yes">_USB device selection</property>
|
||||
<property name="use_underline">True</property>
|
||||
<signal name="activate" handler="virt_viewer_window_menu_file_usb_device_selection" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="menu-file-smartcard-insert">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="accel_path"><virt-viewer>/file/smartcard-insert</property>
|
||||
<property name="label" translatable="yes">Smartcard insertion</property>
|
||||
<property name="use_underline">True</property>
|
||||
<signal name="activate" handler="virt_viewer_window_menu_file_smartcard_insert" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="menu-file-smartcard-remove">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="accel_path"><virt-viewer>/file/smartcard-remove</property>
|
||||
<property name="label" translatable="yes">Smartcard removal</property>
|
||||
<property name="use_underline">True</property>
|
||||
<signal name="activate" handler="virt_viewer_window_menu_file_smartcard_remove" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="menu-preferences">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">_Preferences</property>
|
||||
<property name="use_underline">True</property>
|
||||
<signal name="activate" handler="virt_viewer_window_menu_preferences_cb" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparatorMenuItem" id="separatormenuitem1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="imagemenuitem5">
|
||||
<property name="label" translatable="yes">_Quit</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="use_underline">True</property>
|
||||
<accelerator key="q" signal="activate" modifiers="GDK_SHIFT_MASK | GDK_CONTROL_MASK"/>
|
||||
<signal name="activate" handler="virt_viewer_window_menu_file_quit" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="menu-view">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="label" translatable="yes">_View</property>
|
||||
<property name="use_underline">True</property>
|
||||
<child type="submenu">
|
||||
<object class="GtkMenu" id="menu2">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="accel_group">accelgroup</property>
|
||||
<child>
|
||||
<object class="GtkCheckMenuItem" id="menu-view-fullscreen">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="accel_path"><virt-viewer>/view/toggle-fullscreen</property>
|
||||
<property name="label" translatable="yes">_Full screen</property>
|
||||
<property name="use_underline">True</property>
|
||||
<signal name="toggled" handler="virt_viewer_window_menu_view_fullscreen" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="menu-view-zoom">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="label" translatable="yes">_Zoom</property>
|
||||
<property name="use_underline">True</property>
|
||||
<child type="submenu">
|
||||
<object class="GtkMenu" id="menu4">
|
||||
<property name="accel_group">accelgroup</property>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="menu-file-screenshot">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="accel_group">accelgroup</property>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="menu-view-zoom-in">
|
||||
<property name="accel_path"><virt-viewer>/view/zoom-in</property>
|
||||
<property name="label" translatable="yes">Zoom _In</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="use_underline">True</property>
|
||||
<signal name="activate" handler="virt_viewer_window_menu_view_zoom_in" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="menu-view-zoom-out">
|
||||
<property name="accel_path"><virt-viewer>/view/zoom-out</property>
|
||||
<property name="label" translatable="yes">Zoom _Out</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="use_underline">True</property>
|
||||
<signal name="activate" handler="virt_viewer_window_menu_view_zoom_out" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparatorMenuItem" id="separatormenuitem4">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="menu-view-zoom-reset">
|
||||
<property name="accel_path"><virt-viewer>/view/zoom-reset</property>
|
||||
<property name="label" translatable="yes">_Normal Size</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="use_underline">True</property>
|
||||
<signal name="activate" handler="virt_viewer_window_menu_view_zoom_reset" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="label" translatable="yes">_Screenshot</property>
|
||||
<property name="use_underline">True</property>
|
||||
<signal name="activate" handler="virt_viewer_window_menu_file_screenshot" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="menu-file-usb-device-selection">
|
||||
<property name="visible">True</property>
|
||||
<property name="sensitive">False</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="label" translatable="yes">_USB device selection</property>
|
||||
<property name="use_underline">True</property>
|
||||
<signal name="activate" handler="virt_viewer_window_menu_file_usb_device_selection" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="menu-file-smartcard-insert">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="accel_path"><virt-viewer>/file/smartcard-insert</property>
|
||||
<property name="label" translatable="yes">Smartcard insertion</property>
|
||||
<property name="use_underline">True</property>
|
||||
<signal name="activate" handler="virt_viewer_window_menu_file_smartcard_insert" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="menu-file-smartcard-remove">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="accel_path"><virt-viewer>/file/smartcard-remove</property>
|
||||
<property name="label" translatable="yes">Smartcard removal</property>
|
||||
<property name="use_underline">True</property>
|
||||
<signal name="activate" handler="virt_viewer_window_menu_file_smartcard_remove" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="menu-preferences">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">_Preferences</property>
|
||||
<property name="use_underline">True</property>
|
||||
<signal name="activate" handler="virt_viewer_window_menu_preferences_cb" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparatorMenuItem" id="separatormenuitem1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="imagemenuitem5">
|
||||
<property name="label" translatable="yes">_Quit</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="use_underline">True</property>
|
||||
<accelerator key="q" signal="activate" modifiers="GDK_SHIFT_MASK | GDK_CONTROL_MASK"/>
|
||||
<signal name="activate" handler="virt_viewer_window_menu_file_quit" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="menu-displays">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="label" translatable="yes">_Displays</property>
|
||||
<property name="use_underline">True</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="menu-view-release-cursor">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="accel_path"><virt-viewer>/view/release-cursor</property>
|
||||
<property name="label" translatable="yes">Release cursor</property>
|
||||
<property name="use_underline">True</property>
|
||||
<signal name="activate" handler="virt_viewer_window_menu_view_release_cursor" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="menu-send">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="label" translatable="yes">_Send key</property>
|
||||
<property name="use_underline">True</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="menu-help">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="label" translatable="yes">_Help</property>
|
||||
<property name="use_underline">True</property>
|
||||
<child type="submenu">
|
||||
<object class="GtkMenu" id="menu3">
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="menu-view">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="menu-help-guest-details">
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="label" translatable="yes">_View</property>
|
||||
<property name="use_underline">True</property>
|
||||
<child type="submenu">
|
||||
<object class="GtkMenu" id="menu2">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="label" translatable="yes">_Guest Details</property>
|
||||
<property name="use_underline">True</property>
|
||||
<signal name="activate" handler="virt_viewer_window_menu_help_guest_details" swapped="no"/>
|
||||
<property name="accel_group">accelgroup</property>
|
||||
<child>
|
||||
<object class="GtkCheckMenuItem" id="menu-view-fullscreen">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="accel_path"><virt-viewer>/view/toggle-fullscreen</property>
|
||||
<property name="label" translatable="yes">_Full screen</property>
|
||||
<property name="use_underline">True</property>
|
||||
<signal name="toggled" handler="virt_viewer_window_menu_view_fullscreen" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="menu-view-zoom">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="label" translatable="yes">_Zoom</property>
|
||||
<property name="use_underline">True</property>
|
||||
<child type="submenu">
|
||||
<object class="GtkMenu" id="menu4">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="accel_group">accelgroup</property>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="menu-view-zoom-in">
|
||||
<property name="accel_path"><virt-viewer>/view/zoom-in</property>
|
||||
<property name="label" translatable="yes">Zoom _In</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="use_underline">True</property>
|
||||
<signal name="activate" handler="virt_viewer_window_menu_view_zoom_in" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="menu-view-zoom-out">
|
||||
<property name="accel_path"><virt-viewer>/view/zoom-out</property>
|
||||
<property name="label" translatable="yes">Zoom _Out</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="use_underline">True</property>
|
||||
<signal name="activate" handler="virt_viewer_window_menu_view_zoom_out" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparatorMenuItem" id="separatormenuitem4">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="menu-view-zoom-reset">
|
||||
<property name="accel_path"><virt-viewer>/view/zoom-reset</property>
|
||||
<property name="label" translatable="yes">_Normal Size</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="use_underline">True</property>
|
||||
<signal name="activate" handler="virt_viewer_window_menu_view_zoom_reset" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="menu-displays">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="label" translatable="yes">_Displays</property>
|
||||
<property name="use_underline">True</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="menu-view-release-cursor">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="accel_path"><virt-viewer>/view/release-cursor</property>
|
||||
<property name="label" translatable="yes">Release cursor</property>
|
||||
<property name="use_underline">True</property>
|
||||
<signal name="activate" handler="virt_viewer_window_menu_view_release_cursor" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="imagemenuitem10">
|
||||
<property name="label" translatable="yes">_About</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="menu-send">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="label" translatable="yes">_Send key</property>
|
||||
<property name="use_underline">True</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="menu-help">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="label" translatable="yes">_Help</property>
|
||||
<property name="use_underline">True</property>
|
||||
<child type="submenu">
|
||||
<object class="GtkMenu" id="menu3">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="use_underline">True</property>
|
||||
<signal name="activate" handler="virt_viewer_window_menu_help_about" swapped="no"/>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="menu-help-guest-details">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="label" translatable="yes">_Guest Details</property>
|
||||
<property name="use_underline">True</property>
|
||||
<signal name="activate" handler="virt_viewer_window_menu_help_guest_details" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="imagemenuitem10">
|
||||
<property name="label" translatable="yes">_About</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="use_underline">True</property>
|
||||
<signal name="activate" handler="virt_viewer_window_menu_help_about" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
<property name="index">-1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
|
||||
@ -1,991 +0,0 @@
|
||||
/* *************************************************************************
|
||||
* Copyright (c) 2005 VMware Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
* *************************************************************************/
|
||||
|
||||
/*
|
||||
* autoDrawer.c -
|
||||
*
|
||||
* Subclass of ViewDrawer that encapsulates the behaviour typically required
|
||||
* when using the drawer to implement a menu/toolbar that auto-opens when
|
||||
* moused-over and auto-closes when the mouse leaves.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "autoDrawer.h"
|
||||
|
||||
|
||||
struct _ViewAutoDrawerPrivate
|
||||
{
|
||||
gboolean active;
|
||||
gboolean pinned;
|
||||
gboolean inputUngrabbed;
|
||||
|
||||
gboolean opened;
|
||||
gboolean forceClosing;
|
||||
|
||||
gboolean fill;
|
||||
gint offset;
|
||||
|
||||
guint closeConnection;
|
||||
guint delayConnection;
|
||||
guint delayValue;
|
||||
guint overlapPixels;
|
||||
guint noOverlapPixels;
|
||||
|
||||
GtkWidget *over;
|
||||
GtkWidget *evBox;
|
||||
};
|
||||
|
||||
#define VIEW_AUTODRAWER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), VIEW_TYPE_AUTODRAWER, ViewAutoDrawerPrivate))
|
||||
|
||||
/* The unaltered parent class. */
|
||||
static ViewDrawerClass *parentClass;
|
||||
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* ViewAutoDrawerEnforce --
|
||||
*
|
||||
* Enforce an AutoDrawer's goal now.
|
||||
*
|
||||
* Results:
|
||||
* None
|
||||
*
|
||||
* Side effects:
|
||||
* None
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static void
|
||||
ViewAutoDrawerEnforce(ViewAutoDrawer *that, // IN
|
||||
gboolean animate) // IN
|
||||
{
|
||||
double fraction;
|
||||
GtkAllocation allocation;
|
||||
ViewAutoDrawerPrivate *priv = that->priv;
|
||||
|
||||
if (!priv->active) {
|
||||
ViewOvBox_SetMin(VIEW_OV_BOX(that), -1);
|
||||
ViewOvBox_SetFraction(VIEW_OV_BOX(that), 0);
|
||||
return;
|
||||
}
|
||||
|
||||
g_assert(priv->over != NULL);
|
||||
g_assert(GTK_IS_WIDGET(priv->over));
|
||||
|
||||
ViewOvBox_SetMin(VIEW_OV_BOX(that), priv->noOverlapPixels);
|
||||
|
||||
// The forceClosing flag overrides the opened flag.
|
||||
if (priv->opened && !priv->forceClosing) {
|
||||
fraction = 1;
|
||||
} else {
|
||||
gtk_widget_get_allocation (priv->over, &allocation);
|
||||
fraction = ((double)priv->overlapPixels / allocation.height);
|
||||
}
|
||||
|
||||
if (!animate) {
|
||||
ViewOvBox_SetFraction(VIEW_OV_BOX(that), fraction);
|
||||
}
|
||||
ViewDrawer_SetGoal(VIEW_DRAWER(that), fraction);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* ViewAutoDrawerOnEnforceDelay --
|
||||
*
|
||||
* Callback fired when a delayed update happens to update the drawer state.
|
||||
*
|
||||
* Results:
|
||||
* FALSE to indicate timer should not repeat.
|
||||
*
|
||||
* Side effects:
|
||||
* None
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static gboolean
|
||||
ViewAutoDrawerOnEnforceDelay(ViewAutoDrawer *that) // IN
|
||||
{
|
||||
that->priv->delayConnection = 0;
|
||||
ViewAutoDrawerEnforce(that, TRUE);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* ViewAutoDrawerOnCloseDelay --
|
||||
*
|
||||
* Callback fired when the drawer is closed manually. This prevents the
|
||||
* drawer from reopening right away.
|
||||
*
|
||||
* Results:
|
||||
* FALSE to indicate timer should not repeat.
|
||||
*
|
||||
* Side effects:
|
||||
* None
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static gboolean
|
||||
ViewAutoDrawerOnCloseDelay(ViewAutoDrawer *that) // IN
|
||||
{
|
||||
that->priv->closeConnection = 0;
|
||||
that->priv->forceClosing = FALSE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* ViewAutoDrawerUpdate --
|
||||
*
|
||||
* Decide whether an AutoDrawer should be opened or closed, and enforce
|
||||
* that decision now or later.
|
||||
*
|
||||
* Results:
|
||||
* None
|
||||
*
|
||||
* Side effects:
|
||||
* None
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static void
|
||||
ViewAutoDrawerUpdate(ViewAutoDrawer *that, // IN
|
||||
gboolean immediate) // IN
|
||||
{
|
||||
ViewAutoDrawerPrivate *priv = that->priv;
|
||||
GtkWidget *toplevel = gtk_widget_get_toplevel(GTK_WIDGET(that));
|
||||
GtkWindow *window;
|
||||
GtkAllocation allocation;
|
||||
|
||||
if (!toplevel || !gtk_widget_is_toplevel(toplevel)) {
|
||||
// The autoDrawer cannot function properly without a toplevel.
|
||||
return;
|
||||
}
|
||||
window = GTK_WINDOW(toplevel);
|
||||
|
||||
/*
|
||||
* We decide to open the drawer by OR'ing several conditions. Evaluating a
|
||||
* condition can have the side-effect of setting 'immediate' to TRUE, so we
|
||||
* cannot stop evaluating the conditions after we have found one to be TRUE.
|
||||
*/
|
||||
|
||||
priv->opened = FALSE;
|
||||
|
||||
/* Is the AutoDrawer pinned? */
|
||||
|
||||
if (priv->pinned) {
|
||||
immediate = TRUE;
|
||||
|
||||
priv->opened = TRUE;
|
||||
}
|
||||
|
||||
/* Is the mouse cursor inside the event box? */
|
||||
|
||||
if (gtk_widget_get_window(priv->evBox)) {
|
||||
int x;
|
||||
int y;
|
||||
GdkDevice *dev;
|
||||
GdkDeviceManager *devmgr;
|
||||
|
||||
devmgr = gdk_display_get_device_manager(gtk_widget_get_display(priv->evBox));
|
||||
dev = gdk_device_manager_get_client_pointer(devmgr);
|
||||
|
||||
gdk_window_get_device_position(gtk_widget_get_window(priv->evBox),
|
||||
dev, &x, &y, NULL);
|
||||
|
||||
gtk_widget_get_allocation(priv->evBox, &allocation);
|
||||
g_assert(gtk_container_get_border_width( GTK_CONTAINER(priv->evBox))
|
||||
== 0);
|
||||
if ( (guint)x < (guint)allocation.width
|
||||
&& (guint)y < (guint)allocation.height) {
|
||||
priv->opened = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* If there is a focused widget, is it inside the event box? */
|
||||
|
||||
{
|
||||
GtkWidget *focus;
|
||||
|
||||
focus = gtk_window_get_focus(window);
|
||||
if (focus && gtk_widget_is_ancestor(focus, priv->evBox)) {
|
||||
/*
|
||||
* Override the default 'immediate' to make sure the 'over' widget
|
||||
* immediately appears along with the widget the focused widget.
|
||||
*/
|
||||
immediate = TRUE;
|
||||
|
||||
priv->opened = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* If input is grabbed, is it on behalf of a widget inside the event box? */
|
||||
|
||||
if (!priv->inputUngrabbed) {
|
||||
GtkWidget *grabbed = NULL;
|
||||
|
||||
if (gtk_window_has_group (window)) {
|
||||
GtkWindowGroup *group = gtk_window_get_group (window);
|
||||
grabbed = gtk_window_group_get_current_grab (group);
|
||||
}
|
||||
if (!grabbed) {
|
||||
grabbed = gtk_grab_get_current();
|
||||
}
|
||||
|
||||
if (grabbed && GTK_IS_MENU(grabbed)) {
|
||||
/*
|
||||
* With cascading menus, the deepest menu owns the grab. Traverse the
|
||||
* menu hierarchy up until we reach the attach widget for the whole
|
||||
* hierarchy.
|
||||
*/
|
||||
|
||||
for (;;) {
|
||||
GtkWidget *menuAttach;
|
||||
GtkWidget *menuItemParent;
|
||||
|
||||
menuAttach = gtk_menu_get_attach_widget(GTK_MENU(grabbed));
|
||||
if (!menuAttach) {
|
||||
/*
|
||||
* It is unfortunately not mandatory for a menu to have a proper
|
||||
* attach widget set.
|
||||
*/
|
||||
break;
|
||||
}
|
||||
|
||||
grabbed = menuAttach;
|
||||
if (!GTK_IS_MENU_ITEM(grabbed)) {
|
||||
break;
|
||||
}
|
||||
|
||||
menuItemParent = gtk_widget_get_parent(grabbed);
|
||||
g_return_if_fail(menuItemParent);
|
||||
if (!GTK_IS_MENU(menuItemParent)) {
|
||||
break;
|
||||
}
|
||||
|
||||
grabbed = menuItemParent;
|
||||
}
|
||||
}
|
||||
|
||||
if (grabbed && gtk_widget_is_ancestor(grabbed, priv->evBox)) {
|
||||
/*
|
||||
* Override the default 'immediate' to make sure the 'over' widget
|
||||
* immediately appears along with the widget the grab happens on
|
||||
* behalf of.
|
||||
*/
|
||||
immediate = TRUE;
|
||||
|
||||
priv->opened = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (priv->delayConnection) {
|
||||
g_source_remove(priv->delayConnection);
|
||||
priv->delayConnection = 0;
|
||||
}
|
||||
|
||||
if (priv->forceClosing) {
|
||||
ViewAutoDrawerEnforce(that, TRUE);
|
||||
} else if (immediate) {
|
||||
ViewAutoDrawerEnforce(that, FALSE);
|
||||
} else {
|
||||
priv->delayConnection = g_timeout_add(priv->delayValue,
|
||||
(GSourceFunc)ViewAutoDrawerOnEnforceDelay, that);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* ViewAutoDrawerOnOverEnterLeave --
|
||||
*
|
||||
* Respond to enter/leave events by doing a delayed update of the drawer
|
||||
* state.
|
||||
*
|
||||
* Results:
|
||||
* FALSE to indicate event was not handled.
|
||||
*
|
||||
* Side effects:
|
||||
* Will queue delayed update.
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static gboolean
|
||||
ViewAutoDrawerOnOverEnterLeave(GtkWidget *evBox G_GNUC_UNUSED, // IN: Unused
|
||||
GdkEventCrossing *event G_GNUC_UNUSED, // IN
|
||||
ViewAutoDrawer *that) // IN
|
||||
{
|
||||
/*
|
||||
* This change happens in response to user input. By default, give the user
|
||||
* some time to correct his input before reacting to the change.
|
||||
*/
|
||||
ViewAutoDrawerUpdate(that, FALSE);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* ViewAutoDrawerOnGrabNotify --
|
||||
*
|
||||
* Respond to grab notifications by updating the drawer state.
|
||||
*
|
||||
* Results:
|
||||
* None
|
||||
*
|
||||
* Side effects:
|
||||
* Might queue delayed update.
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static void
|
||||
ViewAutoDrawerOnGrabNotify(GtkWidget *evBox G_GNUC_UNUSED, // IN: Unused
|
||||
gboolean ungrabbed, // IN
|
||||
ViewAutoDrawer *that) // IN
|
||||
{
|
||||
ViewAutoDrawerPrivate *priv = that->priv;
|
||||
|
||||
priv->inputUngrabbed = ungrabbed;
|
||||
|
||||
/*
|
||||
* This change happens in response to user input. By default, give the user
|
||||
* some time to correct his input before reacting to the change.
|
||||
*/
|
||||
ViewAutoDrawerUpdate(that, FALSE);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* ViewAutoDrawerOnSetFocus --
|
||||
*
|
||||
* Respond to changes in the focus widget of the autoDrawer's toplevel
|
||||
* by recalculating the state.
|
||||
*
|
||||
* Results:
|
||||
* None
|
||||
*
|
||||
* Side effects:
|
||||
* Drawer state is updated.
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static void
|
||||
ViewAutoDrawerOnSetFocus(GtkWindow *window G_GNUC_UNUSED, // IN
|
||||
GtkWidget *widget G_GNUC_UNUSED, // IN
|
||||
ViewAutoDrawer *that) // IN
|
||||
{
|
||||
/*
|
||||
* This change happens in response to user input. By default, give the user
|
||||
* some time to correct his input before reacting to the change.
|
||||
*/
|
||||
ViewAutoDrawerUpdate(that, FALSE);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* ViewAutoDrawerOnHierarchyChanged --
|
||||
*
|
||||
* Respond to changes in the toplevel for the AutoDrawer. A toplevel is
|
||||
* required for the AutoDrawer to calculate its state.
|
||||
*
|
||||
* Results:
|
||||
* None
|
||||
*
|
||||
* Side effects:
|
||||
* Drawer state is updated.
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static void
|
||||
ViewAutoDrawerOnHierarchyChanged(ViewAutoDrawer *that, // IN
|
||||
GtkWidget *oldToplevel) // IN
|
||||
{
|
||||
GtkWidget *newToplevel = gtk_widget_get_toplevel(GTK_WIDGET(that));
|
||||
|
||||
if (oldToplevel && gtk_widget_is_toplevel(oldToplevel)) {
|
||||
g_signal_handlers_disconnect_by_func(oldToplevel,
|
||||
G_CALLBACK(ViewAutoDrawerOnSetFocus),
|
||||
that);
|
||||
}
|
||||
|
||||
if (newToplevel && gtk_widget_is_toplevel(newToplevel)) {
|
||||
g_signal_connect_after(newToplevel, "set-focus",
|
||||
G_CALLBACK(ViewAutoDrawerOnSetFocus), that);
|
||||
}
|
||||
|
||||
/* This change happens programmatically. Always react to it immediately. */
|
||||
ViewAutoDrawerUpdate(that, TRUE);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* ViewAutoDrawerSetOver --
|
||||
*
|
||||
* Virtual method override so that the user's over widget is placed
|
||||
* inside the AutoDrawer's event box.
|
||||
*
|
||||
* Results:
|
||||
* None
|
||||
*
|
||||
* Side effects:
|
||||
* None
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static void
|
||||
ViewAutoDrawerSetOver(ViewOvBox *ovBox, // IN
|
||||
GtkWidget *widget) // IN
|
||||
{
|
||||
ViewAutoDrawer *that = VIEW_AUTODRAWER(ovBox);
|
||||
ViewAutoDrawerPrivate *priv = that->priv;
|
||||
GtkWidget *oldChild = gtk_bin_get_child(GTK_BIN(priv->evBox));
|
||||
|
||||
if (oldChild) {
|
||||
g_object_ref(oldChild);
|
||||
gtk_container_remove(GTK_CONTAINER(priv->evBox), oldChild);
|
||||
}
|
||||
|
||||
if (widget) {
|
||||
gtk_container_add(GTK_CONTAINER(priv->evBox), widget);
|
||||
}
|
||||
|
||||
if (oldChild) {
|
||||
g_object_unref(oldChild);
|
||||
}
|
||||
|
||||
priv->over = widget;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* ViewAutoDrawerRefreshPacking --
|
||||
*
|
||||
* Sets the actual packing values for fill, expand, and packing
|
||||
* given internal settings.
|
||||
*
|
||||
* Results:
|
||||
* None
|
||||
*
|
||||
* Side effects:
|
||||
* Drawer state is updated.
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static void
|
||||
ViewAutoDrawerRefreshPacking(ViewAutoDrawer *that) // IN
|
||||
{
|
||||
gboolean expand;
|
||||
gboolean fill;
|
||||
guint padding;
|
||||
|
||||
expand = (that->priv->fill || (that->priv->offset < 0));
|
||||
fill = that->priv->fill;
|
||||
padding = (expand || fill) ? 0 : that->priv->offset;
|
||||
|
||||
gtk_box_set_child_packing(GTK_BOX(that), that->priv->evBox,
|
||||
expand, fill, padding, GTK_PACK_START);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* ViewAutoDrawerInit --
|
||||
*
|
||||
* Initialize a ViewAutoDrawer.
|
||||
*
|
||||
* Results:
|
||||
* None
|
||||
*
|
||||
* Side effects:
|
||||
* None
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static void
|
||||
ViewAutoDrawerInit(GTypeInstance *instance, // IN
|
||||
gpointer klass G_GNUC_UNUSED) // Unused
|
||||
{
|
||||
ViewAutoDrawer *that;
|
||||
ViewAutoDrawerPrivate *priv;
|
||||
|
||||
that = VIEW_AUTODRAWER(instance);
|
||||
that->priv = VIEW_AUTODRAWER_GET_PRIVATE(that);
|
||||
priv = that->priv;
|
||||
|
||||
priv->active = TRUE;
|
||||
priv->pinned = FALSE;
|
||||
priv->forceClosing = FALSE;
|
||||
priv->inputUngrabbed = TRUE;
|
||||
priv->delayConnection = 0;
|
||||
priv->delayValue = 250;
|
||||
priv->overlapPixels = 0;
|
||||
priv->noOverlapPixels = 1;
|
||||
|
||||
priv->fill = TRUE;
|
||||
priv->offset = -1;
|
||||
|
||||
priv->evBox = gtk_event_box_new();
|
||||
gtk_widget_show(priv->evBox);
|
||||
VIEW_OV_BOX_CLASS(parentClass)->set_over(VIEW_OV_BOX(that), priv->evBox);
|
||||
|
||||
g_signal_connect(priv->evBox, "enter-notify-event",
|
||||
G_CALLBACK(ViewAutoDrawerOnOverEnterLeave), that);
|
||||
g_signal_connect(priv->evBox, "leave-notify-event",
|
||||
G_CALLBACK(ViewAutoDrawerOnOverEnterLeave), that);
|
||||
g_signal_connect(priv->evBox, "grab-notify",
|
||||
G_CALLBACK(ViewAutoDrawerOnGrabNotify), that);
|
||||
|
||||
g_signal_connect(that, "hierarchy-changed",
|
||||
G_CALLBACK(ViewAutoDrawerOnHierarchyChanged), NULL);
|
||||
|
||||
/* This change happens programmatically. Always react to it immediately. */
|
||||
ViewAutoDrawerUpdate(that, TRUE);
|
||||
|
||||
ViewAutoDrawerRefreshPacking(that);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* ViewAutoDrawerFinalize --
|
||||
*
|
||||
* "finalize" method of a ViewAutoDrawer.
|
||||
*
|
||||
* Results:
|
||||
* None
|
||||
*
|
||||
* Side effects:
|
||||
* None
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static void
|
||||
ViewAutoDrawerFinalize(GObject *object) // IN
|
||||
{
|
||||
ViewAutoDrawer *that;
|
||||
|
||||
that = VIEW_AUTODRAWER(object);
|
||||
if (that->priv->delayConnection) {
|
||||
g_source_remove(that->priv->delayConnection);
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS(parentClass)->finalize(object);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* ViewAutoDrawerClassInit --
|
||||
*
|
||||
* Initialize the ViewAutoDrawerClass.
|
||||
*
|
||||
* Results:
|
||||
* None
|
||||
*
|
||||
* Side effects:
|
||||
* None
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static void
|
||||
ViewAutoDrawerClassInit(gpointer klass) // IN
|
||||
{
|
||||
GObjectClass *objectClass = G_OBJECT_CLASS(klass);
|
||||
ViewOvBoxClass *ovBoxClass = VIEW_OV_BOX_CLASS(klass);
|
||||
|
||||
parentClass = g_type_class_peek_parent(klass);
|
||||
|
||||
objectClass->finalize = ViewAutoDrawerFinalize;
|
||||
|
||||
ovBoxClass->set_over = ViewAutoDrawerSetOver;
|
||||
|
||||
g_type_class_add_private(klass, sizeof(ViewAutoDrawerPrivate));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* ViewAutoDrawer_GetType --
|
||||
*
|
||||
* Get the (memoized) GType of the ViewAutoDrawer GTK+ object.
|
||||
*
|
||||
* Results:
|
||||
* The GType
|
||||
*
|
||||
* Side effects:
|
||||
* None
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
GType
|
||||
ViewAutoDrawer_GetType(void)
|
||||
{
|
||||
static GType type = 0;
|
||||
|
||||
if (type == 0) {
|
||||
static const GTypeInfo info = {
|
||||
sizeof (ViewAutoDrawerClass),
|
||||
NULL, /* BaseInit */
|
||||
NULL, /* BaseFinalize */
|
||||
(GClassInitFunc)ViewAutoDrawerClassInit,
|
||||
NULL,
|
||||
NULL, /* Class Data */
|
||||
sizeof (ViewAutoDrawer),
|
||||
0, /* n_preallocs */
|
||||
(GInstanceInitFunc)ViewAutoDrawerInit,
|
||||
NULL,
|
||||
};
|
||||
|
||||
type = g_type_register_static(VIEW_TYPE_DRAWER, "ViewAutoDrawer", &info, 0);
|
||||
}
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* ViewAutoDrawer_New --
|
||||
*
|
||||
* Create a new ViewAutoDrawer GTK+ widget.
|
||||
*
|
||||
* Results:
|
||||
* The widget
|
||||
*
|
||||
* Side effects:
|
||||
* None
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
GtkWidget *
|
||||
ViewAutoDrawer_New(void)
|
||||
{
|
||||
return GTK_WIDGET(g_object_new(VIEW_TYPE_AUTODRAWER, NULL));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* ViewAutoDrawer_SetSlideDelay --
|
||||
*
|
||||
* Set the response time of an AutoDrawer in ms., i.e. the time that
|
||||
* elapses between:
|
||||
* - when the AutoDrawer notices a change that can impact the outcome of
|
||||
* the decision to open or close the drawer,
|
||||
* and
|
||||
* - when the AutoDrawer makes such decision.
|
||||
*
|
||||
* Users move the mouse inaccurately. If they temporarily move the mouse in
|
||||
* or out of the AutoDrawer for less than the reponse time, their move will
|
||||
* be ignored.
|
||||
*
|
||||
* Results:
|
||||
* None
|
||||
*
|
||||
* Side effects:
|
||||
* None
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void
|
||||
ViewAutoDrawer_SetSlideDelay(ViewAutoDrawer *that, // IN
|
||||
guint delay) // IN
|
||||
{
|
||||
g_return_if_fail(VIEW_IS_AUTODRAWER(that));
|
||||
|
||||
that->priv->delayValue = delay;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* ViewAutoDrawer_SetOverlapPixels --
|
||||
*
|
||||
* Set the number of pixels that the over widget overlaps the under widget
|
||||
* when not open.
|
||||
*
|
||||
* Results:
|
||||
* None
|
||||
*
|
||||
* Side effects:
|
||||
* Drawer state is updated.
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void
|
||||
ViewAutoDrawer_SetOverlapPixels(ViewAutoDrawer *that, // IN
|
||||
guint overlapPixels) // IN
|
||||
{
|
||||
g_return_if_fail(VIEW_IS_AUTODRAWER(that));
|
||||
|
||||
that->priv->overlapPixels = overlapPixels;
|
||||
|
||||
/* This change happens programmatically. Always react to it immediately. */
|
||||
ViewAutoDrawerUpdate(that, TRUE);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* ViewAutoDrawer_SetNoOverlapPixels --
|
||||
*
|
||||
* Set the number of pixels that the drawer reserves when not open. The
|
||||
* over widget does not overlap the under widget over these pixels.
|
||||
*
|
||||
* Results:
|
||||
* None
|
||||
*
|
||||
* Side effects:
|
||||
* Drawer state is updated.
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void
|
||||
ViewAutoDrawer_SetNoOverlapPixels(ViewAutoDrawer *that, // IN
|
||||
guint noOverlapPixels) // IN
|
||||
{
|
||||
g_return_if_fail(VIEW_IS_AUTODRAWER(that));
|
||||
|
||||
that->priv->noOverlapPixels = noOverlapPixels;
|
||||
|
||||
/* This change happens programmatically. Always react to it immediately. */
|
||||
ViewAutoDrawerUpdate(that, TRUE);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* ViewAutoDrawer_SetActive --
|
||||
*
|
||||
* Set whether the AutoDrawer is active or not. That is to say, whether
|
||||
* it is acting as a drawer or not. When inactive, the over and under
|
||||
* widget do not overlap and the net result is very much like a vbox.
|
||||
*
|
||||
* Results:
|
||||
* None
|
||||
*
|
||||
* Side effects:
|
||||
* Drawer state is updated.
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void
|
||||
ViewAutoDrawer_SetActive(ViewAutoDrawer *that, // IN
|
||||
gboolean active) // IN
|
||||
{
|
||||
g_return_if_fail(VIEW_IS_AUTODRAWER(that));
|
||||
|
||||
that->priv->active = active;
|
||||
|
||||
/* This change happens programmatically. Always react to it immediately. */
|
||||
ViewAutoDrawerUpdate(that, TRUE);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* ViewAutoDrawer_SetPinned --
|
||||
*
|
||||
* Set whether the AutoDrawer is pinned or not. When pinned, the
|
||||
* AutoDrawer will stay open regardless of the state of any other inputs.
|
||||
*
|
||||
* Results:
|
||||
* None
|
||||
*
|
||||
* Side effects:
|
||||
* Drawer state is updated.
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void
|
||||
ViewAutoDrawer_SetPinned(ViewAutoDrawer *that, // IN
|
||||
gboolean pinned) // IN
|
||||
{
|
||||
g_return_if_fail(VIEW_IS_AUTODRAWER(that));
|
||||
|
||||
that->priv->pinned = pinned;
|
||||
|
||||
/*
|
||||
* This change happens in response to user input. By default, give the user
|
||||
* some time to correct his input before reacting to the change.
|
||||
*/
|
||||
ViewAutoDrawerUpdate(that, FALSE);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* ViewAutoDrawer_SetFill --
|
||||
*
|
||||
* Set whether the Over widget of the AutoDrawer should fill the full
|
||||
* width of the AutoDrawer or just occupy the minimum space it needs.
|
||||
* A value of TRUE overrides offset settings.
|
||||
*
|
||||
* Results:
|
||||
* None
|
||||
*
|
||||
* Side effects:
|
||||
* Drawer state is updated.
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void
|
||||
ViewAutoDrawer_SetFill(ViewAutoDrawer *that, // IN
|
||||
gboolean fill) // IN
|
||||
{
|
||||
g_return_if_fail(VIEW_IS_AUTODRAWER(that));
|
||||
|
||||
that->priv->fill = fill;
|
||||
ViewAutoDrawerRefreshPacking(that);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* ViewAutoDrawer_SetOffset --
|
||||
*
|
||||
* Set the drawer's X offset, or distance in pixels from the left side.
|
||||
* If offset is -1, the drawer will be centered. If fill has been set
|
||||
* TRUE by SetFill, these settings will have no effect.
|
||||
*
|
||||
* Results:
|
||||
* None
|
||||
*
|
||||
* Side effects:
|
||||
* Drawer state is updated.
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void
|
||||
ViewAutoDrawer_SetOffset(ViewAutoDrawer *that, // IN
|
||||
gint offset) // IN
|
||||
{
|
||||
g_return_if_fail(VIEW_IS_AUTODRAWER(that));
|
||||
|
||||
that->priv->offset = offset;
|
||||
ViewAutoDrawerRefreshPacking(that);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* ViewAutoDrawer_Close --
|
||||
*
|
||||
* Closes the drawer. This will not unset the pinned state.
|
||||
*
|
||||
* Results:
|
||||
* None
|
||||
*
|
||||
* Side effects:
|
||||
* Drawer state is updated. If there is a focused widget inside the
|
||||
* drawer, unfocus it.
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void
|
||||
ViewAutoDrawer_Close(ViewAutoDrawer *that) // IN
|
||||
{
|
||||
GtkWindow *window;
|
||||
GtkWidget *focus;
|
||||
GtkWidget *toplevel;
|
||||
|
||||
g_return_if_fail(VIEW_IS_AUTODRAWER(that));
|
||||
toplevel = gtk_widget_get_toplevel(GTK_WIDGET(that));
|
||||
|
||||
if (!toplevel || !gtk_widget_is_toplevel(toplevel)) {
|
||||
// The autoDrawer cannot function properly without a toplevel.
|
||||
return;
|
||||
}
|
||||
window = GTK_WINDOW(toplevel);
|
||||
|
||||
focus = gtk_window_get_focus(window);
|
||||
if (focus && gtk_widget_is_ancestor(focus, that->priv->evBox)) {
|
||||
gtk_window_set_focus(window, NULL);
|
||||
}
|
||||
|
||||
that->priv->forceClosing = TRUE;
|
||||
that->priv->closeConnection =
|
||||
g_timeout_add(ViewDrawer_GetCloseTime(&that->parent) +
|
||||
that->priv->delayValue,
|
||||
(GSourceFunc)ViewAutoDrawerOnCloseDelay, that);
|
||||
|
||||
/* This change happens programmatically. Always react to it immediately. */
|
||||
ViewAutoDrawerUpdate(that, TRUE);
|
||||
}
|
||||
@ -1,91 +0,0 @@
|
||||
/* *************************************************************************
|
||||
* Copyright (c) 2005 VMware Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
* *************************************************************************/
|
||||
|
||||
/*
|
||||
* autoDrawer.h --
|
||||
*
|
||||
* Declarations for the ViewAutoDrawer GTK+ widget.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef LIBVIEW_AUTODRAWER_H
|
||||
#define LIBVIEW_AUTODRAWER_H
|
||||
|
||||
|
||||
#include "drawer.h"
|
||||
|
||||
|
||||
#define VIEW_TYPE_AUTODRAWER (ViewAutoDrawer_GetType())
|
||||
#define VIEW_AUTODRAWER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), VIEW_TYPE_AUTODRAWER, ViewAutoDrawer))
|
||||
#define VIEW_AUTODRAWER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), VIEW_TYPE_AUTODRAWER, ViewAutoDrawerClass))
|
||||
#define VIEW_IS_AUTODRAWER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), VIEW_TYPE_AUTODRAWER))
|
||||
#define VIEW_IS_AUTODRAWER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), VIEW_TYPE_AUTODRAWER))
|
||||
#define VIEW_AUTODRAWER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), VIEW_TYPE_AUTODRAWER, ViewAutoDrawerClass))
|
||||
|
||||
typedef struct _ViewAutoDrawerPrivate ViewAutoDrawerPrivate;
|
||||
|
||||
typedef struct _ViewAutoDrawer {
|
||||
/* Must come first. */
|
||||
ViewDrawer parent;
|
||||
|
||||
/* Private. */
|
||||
ViewAutoDrawerPrivate *priv;
|
||||
} ViewAutoDrawer;
|
||||
|
||||
typedef struct _ViewAutoDrawerClass {
|
||||
/* Must come first. */
|
||||
ViewDrawerClass parent;
|
||||
|
||||
/* Padding for future expansion */
|
||||
void (*_view_reserved0)(void);
|
||||
void (*_view_reserved1)(void);
|
||||
void (*_view_reserved2)(void);
|
||||
void (*_view_reserved3)(void);
|
||||
} ViewAutoDrawerClass;
|
||||
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
|
||||
GType ViewAutoDrawer_GetType(void);
|
||||
|
||||
GtkWidget *ViewAutoDrawer_New(void);
|
||||
|
||||
void ViewAutoDrawer_SetSlideDelay(ViewAutoDrawer *that, guint delay);
|
||||
void ViewAutoDrawer_SetOverlapPixels(ViewAutoDrawer *that, guint overlapPixels);
|
||||
void ViewAutoDrawer_SetNoOverlapPixels(ViewAutoDrawer *that, guint noOverlapPixels);
|
||||
|
||||
void ViewAutoDrawer_SetActive(ViewAutoDrawer *that, gboolean active);
|
||||
|
||||
void ViewAutoDrawer_SetPinned(ViewAutoDrawer *that, gboolean pinned);
|
||||
|
||||
void ViewAutoDrawer_SetFill(ViewAutoDrawer *that, gboolean fill);
|
||||
|
||||
void ViewAutoDrawer_SetOffset(ViewAutoDrawer *that, gint offset);
|
||||
|
||||
void ViewAutoDrawer_Close(ViewAutoDrawer *that);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
#endif /* LIBVIEW_AUTODRAWER_H */
|
||||
@ -1,366 +0,0 @@
|
||||
/* *************************************************************************
|
||||
* Copyright (c) 2005 VMware, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
* *************************************************************************/
|
||||
|
||||
/*
|
||||
* drawer.c -
|
||||
*
|
||||
* Implementation of a GTK+ drawer, i.e. a widget that opens and closes by
|
||||
* sliding smoothly, at constant speed, over another one.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "drawer.h"
|
||||
|
||||
|
||||
struct _ViewDrawerPrivate
|
||||
{
|
||||
unsigned int period;
|
||||
double step;
|
||||
double goal;
|
||||
struct {
|
||||
gboolean pending;
|
||||
guint id;
|
||||
} timer;
|
||||
};
|
||||
|
||||
#define VIEW_DRAWER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), VIEW_TYPE_DRAWER, ViewDrawerPrivate))
|
||||
|
||||
/* The unaltered parent class. */
|
||||
static ViewOvBoxClass *parentClass;
|
||||
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* ViewDrawerInit --
|
||||
*
|
||||
* Initialize a ViewDrawer.
|
||||
*
|
||||
* Results:
|
||||
* None
|
||||
*
|
||||
* Side effects:
|
||||
* None
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static void
|
||||
ViewDrawerInit(GTypeInstance *instance, // IN
|
||||
gpointer klass G_GNUC_UNUSED) // Unused
|
||||
{
|
||||
ViewDrawer *that;
|
||||
|
||||
that = VIEW_DRAWER(instance);
|
||||
that->priv = VIEW_DRAWER_GET_PRIVATE(that);
|
||||
|
||||
that->priv->period = 10;
|
||||
that->priv->step = 0.2;
|
||||
that->priv->timer.pending = FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* ViewDrawerFinalize --
|
||||
*
|
||||
* "finalize" method of a ViewOvBox.
|
||||
*
|
||||
* Results:
|
||||
* None
|
||||
*
|
||||
* Side effects:
|
||||
* None
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static void
|
||||
ViewDrawerFinalize(GObject *object) // IN
|
||||
{
|
||||
ViewDrawer *that;
|
||||
ViewDrawerPrivate *priv;
|
||||
|
||||
that = VIEW_DRAWER(object);
|
||||
priv = that->priv;
|
||||
|
||||
if (priv->timer.pending) {
|
||||
g_source_remove(priv->timer.id);
|
||||
priv->timer.pending = FALSE;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS(parentClass)->finalize(object);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* ViewDrawerClassInit --
|
||||
*
|
||||
* Initialize the ViewDrawerClass.
|
||||
*
|
||||
* Results:
|
||||
* None
|
||||
*
|
||||
* Side effects:
|
||||
* None
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static void
|
||||
ViewDrawerClassInit(gpointer klass) // IN
|
||||
{
|
||||
GObjectClass *objectClass = G_OBJECT_CLASS(klass);
|
||||
|
||||
parentClass = g_type_class_peek_parent(klass);
|
||||
|
||||
objectClass->finalize = ViewDrawerFinalize;
|
||||
|
||||
g_type_class_add_private(klass, sizeof(ViewDrawerPrivate));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* ViewDrawer_GetType --
|
||||
*
|
||||
* Get the (memoized) GType of the ViewDrawer GTK+ object.
|
||||
*
|
||||
* Results:
|
||||
* The GType
|
||||
*
|
||||
* Side effects:
|
||||
* None
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
GType
|
||||
ViewDrawer_GetType(void)
|
||||
{
|
||||
static GType type = 0;
|
||||
|
||||
if (type == 0) {
|
||||
static const GTypeInfo info = {
|
||||
sizeof (ViewDrawerClass),
|
||||
NULL, /* BaseInit */
|
||||
NULL, /* BaseFinalize */
|
||||
(GClassInitFunc)ViewDrawerClassInit,
|
||||
NULL,
|
||||
NULL, /* Class Data */
|
||||
sizeof (ViewDrawer),
|
||||
0, /* n_preallocs */
|
||||
(GInstanceInitFunc)ViewDrawerInit,
|
||||
NULL
|
||||
};
|
||||
|
||||
type = g_type_register_static(VIEW_TYPE_OV_BOX, "ViewDrawer", &info, 0);
|
||||
}
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* ViewDrawer_New --
|
||||
*
|
||||
* Create a new ViewDrawer GTK+ widget.
|
||||
*
|
||||
* Results:
|
||||
* The widget
|
||||
*
|
||||
* Side effects:
|
||||
* None
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
GtkWidget *
|
||||
ViewDrawer_New(void)
|
||||
{
|
||||
ViewDrawer *that;
|
||||
|
||||
that = VIEW_DRAWER(g_object_new(VIEW_TYPE_DRAWER, NULL));
|
||||
|
||||
return GTK_WIDGET(that);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* ViewDrawerOnTimer --
|
||||
*
|
||||
* Timer callback of a ViewDrawer. If we have reached the goal, deschedule
|
||||
* the timer. Otherwise make progress towards the goal, and keep the timer
|
||||
* scheduled.
|
||||
*
|
||||
* Results:
|
||||
* TRUE if the timer must be rescheduled.
|
||||
* FALSE if the timer must not be rescheduled.
|
||||
*
|
||||
* Side effects:
|
||||
* None
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static gint
|
||||
ViewDrawerOnTimer(gpointer data) // IN
|
||||
{
|
||||
ViewDrawer *that;
|
||||
ViewDrawerPrivate *priv;
|
||||
double fraction;
|
||||
|
||||
that = VIEW_DRAWER(data);
|
||||
priv = that->priv;
|
||||
|
||||
fraction = ViewOvBox_GetFraction(VIEW_OV_BOX(that));
|
||||
/*
|
||||
* Comparing double values with '==' is most of the time a bad idea, due to
|
||||
* the inexact representation of values in binary (see
|
||||
* http://www2.hursley.ibm.com/decimal/decifaq1.html and http://boost.org/libs/test/doc/components/test_tools/floating_point_comparison.html).
|
||||
* But in this particular case it is legitimate. --hpreg
|
||||
*/
|
||||
if (priv->goal == fraction) {
|
||||
return priv->timer.pending = FALSE;
|
||||
}
|
||||
|
||||
ViewOvBox_SetFraction(VIEW_OV_BOX(that),
|
||||
priv->goal > fraction
|
||||
? MIN(fraction + priv->step, priv->goal)
|
||||
: MAX(fraction - priv->step, priv->goal));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* ViewDrawer_SetSpeed --
|
||||
*
|
||||
* Set the 'period' (in ms.) and 'step' properties of a ViewDrawer, which
|
||||
* determine the speed and smoothness of the drawer's motion.
|
||||
*
|
||||
* Results:
|
||||
* None
|
||||
*
|
||||
* Side effects:
|
||||
* None
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void
|
||||
ViewDrawer_SetSpeed(ViewDrawer *that, // IN
|
||||
unsigned int period, // IN
|
||||
double step) // IN
|
||||
{
|
||||
ViewDrawerPrivate *priv;
|
||||
|
||||
g_return_if_fail(that != NULL);
|
||||
|
||||
priv = that->priv;
|
||||
|
||||
priv->period = period;
|
||||
if (priv->timer.pending) {
|
||||
g_source_remove(priv->timer.id);
|
||||
priv->timer.id = g_timeout_add(priv->period, ViewDrawerOnTimer, that);
|
||||
}
|
||||
priv->step = step;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* ViewDrawer_SetGoal --
|
||||
*
|
||||
* Set the 'goal' property of a ViewDrawer, i.e. how much the drawer should
|
||||
* be opened when it is done sliding.
|
||||
*
|
||||
* Results:
|
||||
* None
|
||||
*
|
||||
* Side effects:
|
||||
* None
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void
|
||||
ViewDrawer_SetGoal(ViewDrawer *that, // IN
|
||||
double goal) // IN
|
||||
{
|
||||
ViewDrawerPrivate *priv;
|
||||
|
||||
g_return_if_fail(that != NULL);
|
||||
g_return_if_fail(goal >= 0 && goal <= 1);
|
||||
|
||||
priv = that->priv;
|
||||
|
||||
priv->goal = goal;
|
||||
if (priv->timer.pending == FALSE) {
|
||||
priv->timer.id = g_timeout_add(priv->period, ViewDrawerOnTimer, that);
|
||||
priv->timer.pending = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* ViewDrawer_GetCloseTime --
|
||||
*
|
||||
* Get the approximate amount of time it will take for this drawer to
|
||||
* open and close, in ms.
|
||||
*
|
||||
* Results:
|
||||
* The time it takes to open or close the drawer.
|
||||
*
|
||||
* Side effects:
|
||||
* None
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
ViewDrawer_GetCloseTime(ViewDrawer *that)
|
||||
{
|
||||
ViewDrawerPrivate *priv;
|
||||
|
||||
if (that == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
priv = that->priv;
|
||||
|
||||
return priv->period * ((int)(1/priv->step) + 1);
|
||||
}
|
||||
@ -1,83 +0,0 @@
|
||||
/* *************************************************************************
|
||||
* Copyright (c) 2005 VMware, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
* *************************************************************************/
|
||||
|
||||
/*
|
||||
* drawer.h --
|
||||
*
|
||||
* Declarations for the ViewDrawer GTK+ widget.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef LIBVIEW_DRAWER_H
|
||||
#define LIBVIEW_DRAWER_H
|
||||
|
||||
|
||||
#include "ovBox.h"
|
||||
|
||||
|
||||
#define VIEW_TYPE_DRAWER (ViewDrawer_GetType())
|
||||
#define VIEW_DRAWER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), VIEW_TYPE_DRAWER, ViewDrawer))
|
||||
#define VIEW_DRAWER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), VIEW_TYPE_DRAWER, ViewDrawerClass))
|
||||
#define VIEW_IS_DRAWER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), VIEW_TYPE_DRAWER))
|
||||
#define VIEW_IS_DRAWER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), VIEW_TYPE_DRAWER))
|
||||
#define VIEW_DRAWER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), VIEW_TYPE_DRAWER, ViewDrawerClass))
|
||||
|
||||
typedef struct _ViewDrawerPrivate ViewDrawerPrivate;
|
||||
|
||||
typedef struct _ViewDrawer {
|
||||
/* Must come first. */
|
||||
ViewOvBox parent;
|
||||
|
||||
/* Private. */
|
||||
ViewDrawerPrivate *priv;
|
||||
} ViewDrawer;
|
||||
|
||||
|
||||
typedef struct _ViewDrawerClass {
|
||||
/* Must come first. */
|
||||
ViewOvBoxClass parent;
|
||||
|
||||
/* Padding for future expansion */
|
||||
void (*_view_reserved0)(void);
|
||||
void (*_view_reserved1)(void);
|
||||
void (*_view_reserved2)(void);
|
||||
void (*_view_reserved3)(void);
|
||||
} ViewDrawerClass;
|
||||
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
|
||||
GType ViewDrawer_GetType(void);
|
||||
|
||||
GtkWidget *ViewDrawer_New(void);
|
||||
|
||||
void ViewDrawer_SetSpeed(ViewDrawer *that, unsigned int period, double step);
|
||||
void ViewDrawer_SetGoal(ViewDrawer *that, double fraction);
|
||||
int ViewDrawer_GetCloseTime(ViewDrawer *that);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
#endif /* LIBVIEW_DRAWER_H */
|
||||
946
src/view/ovBox.c
946
src/view/ovBox.c
@ -1,946 +0,0 @@
|
||||
/* *************************************************************************
|
||||
* Copyright (c) 2005 VMware, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
* *************************************************************************/
|
||||
|
||||
/*
|
||||
* ovBox.c --
|
||||
*
|
||||
* Implementation of a GTK+ overlapping box. Allows you to display and
|
||||
* quickly move a child that overlaps another child.
|
||||
*
|
||||
* Implementation notes
|
||||
* --------------------
|
||||
*
|
||||
* Changing 'fraction' is fast (we just move the 'overWin' X window, which
|
||||
* ultimately copies a rectangle on the X server side), and does not
|
||||
* flicker (the 'under' and 'over' GTK children are not re-drawn, except
|
||||
* for parts of them that become exposed).
|
||||
*
|
||||
* o Initially, we thought it could be done with only 2 X windows
|
||||
*
|
||||
* Layout Hierarchy
|
||||
* ------ ---------
|
||||
*
|
||||
* /- overWin --\ underWin
|
||||
* | | overWin
|
||||
* /-+- underWin -+-\
|
||||
* | | | |
|
||||
* | \------------/ |
|
||||
* | |
|
||||
* \----------------/
|
||||
*
|
||||
* But the 'under' GTK child could create other X windows inside
|
||||
* 'underWin', which makes it impossible to guarantee that 'overWin'
|
||||
* will stay stacked on top.
|
||||
*
|
||||
* o So we are forced to use 3 X windows
|
||||
*
|
||||
* Layout Hierarchy
|
||||
* ------ ---------
|
||||
*
|
||||
* /- overWin --\ window
|
||||
* | | overWin
|
||||
* /---+- window ---+---\ underWin
|
||||
* | | | |
|
||||
* | /-+- underWin -+-\ |
|
||||
* | | | | | |
|
||||
* | | \------------/ | |
|
||||
* | | | |
|
||||
* | \----------------/ |
|
||||
* | |
|
||||
* \--------------------/
|
||||
*
|
||||
* --hpreg
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "ovBox.h"
|
||||
|
||||
struct _ViewOvBoxPrivate
|
||||
{
|
||||
GdkWindow *underWin;
|
||||
GtkWidget *under;
|
||||
GdkWindow *overWin;
|
||||
GtkWidget *over;
|
||||
GtkRequisition overR;
|
||||
unsigned int min;
|
||||
double fraction;
|
||||
gint verticalOffset;
|
||||
};
|
||||
|
||||
#define VIEW_OV_BOX_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), VIEW_TYPE_OV_BOX, ViewOvBoxPrivate))
|
||||
|
||||
/* The unaltered parent class. */
|
||||
static GtkBoxClass *parentClass;
|
||||
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* ViewOvBoxInit --
|
||||
*
|
||||
* Initialize a ViewOvBox.
|
||||
*
|
||||
* Results:
|
||||
* None
|
||||
*
|
||||
* Side effects:
|
||||
* None
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static void
|
||||
ViewOvBoxInit(GTypeInstance *instance, // IN
|
||||
gpointer klass G_GNUC_UNUSED) // Unused
|
||||
{
|
||||
ViewOvBox *that;
|
||||
ViewOvBoxPrivate *priv;
|
||||
|
||||
that = VIEW_OV_BOX(instance);
|
||||
that->priv = VIEW_OV_BOX_GET_PRIVATE(that);
|
||||
priv = that->priv;
|
||||
|
||||
gtk_widget_set_has_window (GTK_WIDGET (that), TRUE);
|
||||
|
||||
priv->underWin = NULL;
|
||||
priv->under = NULL;
|
||||
priv->overWin = NULL;
|
||||
priv->over = NULL;
|
||||
priv->overR.height = -1;
|
||||
priv->overR.width = -1;
|
||||
priv->min = 0;
|
||||
priv->fraction = 0;
|
||||
priv->verticalOffset = 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* ViewOvBoxMap --
|
||||
*
|
||||
* "map" method of a ViewOvBox.
|
||||
*
|
||||
* Results:
|
||||
* None
|
||||
*
|
||||
* Side effects:
|
||||
* None
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static void
|
||||
ViewOvBoxMap(GtkWidget *widget) // IN
|
||||
{
|
||||
gdk_window_show(gtk_widget_get_window (widget));
|
||||
GTK_WIDGET_CLASS(parentClass)->map(widget);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* ViewOvBoxUnmap --
|
||||
*
|
||||
* "unmap" method of a ViewOvBox.
|
||||
*
|
||||
* Results:
|
||||
* None
|
||||
*
|
||||
* Side effects:
|
||||
* None
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static void
|
||||
ViewOvBoxUnmap(GtkWidget *widget) // IN
|
||||
{
|
||||
gdk_window_hide(gtk_widget_get_window (widget));
|
||||
GTK_WIDGET_CLASS(parentClass)->unmap(widget);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* ViewOvBoxGetActualMin --
|
||||
*
|
||||
* Retrieve the actual 'min' value, i.e. a value that is guaranteed not to
|
||||
* exceed the height of the 'over' child.
|
||||
*
|
||||
* Results:
|
||||
* The actual 'min' value.
|
||||
*
|
||||
* Side effects:
|
||||
* None
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static inline unsigned int
|
||||
ViewOvBoxGetActualMin(ViewOvBox *that) // IN
|
||||
{
|
||||
return MIN(that->priv->min, that->priv->overR.height);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* ViewOvBoxGetUnderGeometry --
|
||||
*
|
||||
* Retrieve the geometry to apply to 'that->underWin'.
|
||||
*
|
||||
* Results:
|
||||
* The geometry
|
||||
*
|
||||
* Side effects:
|
||||
* None
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static void
|
||||
ViewOvBoxGetUnderGeometry(ViewOvBox *that, // IN
|
||||
int *x, // OUT
|
||||
int *y, // OUT
|
||||
int *width, // OUT
|
||||
int *height) // OUT
|
||||
{
|
||||
unsigned int min;
|
||||
GtkAllocation allocation;
|
||||
|
||||
min = ViewOvBoxGetActualMin(that);
|
||||
gtk_widget_get_allocation (GTK_WIDGET(that), &allocation);
|
||||
|
||||
*x = 0;
|
||||
*y = min;
|
||||
*width = allocation.width;
|
||||
*height = allocation.height - min;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* ViewOvBoxGetOverGeometry --
|
||||
*
|
||||
* Retrieve the geometry to apply to 'that->overWin'.
|
||||
*
|
||||
* Results:
|
||||
* The geometry
|
||||
*
|
||||
* Side effects:
|
||||
* None
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static void
|
||||
ViewOvBoxGetOverGeometry(ViewOvBox *that, // IN
|
||||
int *x, // OUT
|
||||
int *y, // OUT
|
||||
int *width, // OUT
|
||||
int *height) // OUT
|
||||
{
|
||||
ViewOvBoxPrivate *priv;
|
||||
gboolean expand;
|
||||
gboolean fill;
|
||||
guint padding;
|
||||
unsigned int boxWidth;
|
||||
GtkAllocation allocation;
|
||||
|
||||
priv = that->priv;
|
||||
|
||||
if (priv->over) {
|
||||
/*
|
||||
* When a child's expand or fill property changes, GtkBox queues
|
||||
* a resize for the child.
|
||||
*/
|
||||
gtk_container_child_get(GTK_CONTAINER(that), priv->over,
|
||||
"expand", &expand,
|
||||
"fill", &fill,
|
||||
"padding", &padding,
|
||||
NULL);
|
||||
} else {
|
||||
/* Default values used by GtkBox. */
|
||||
expand = TRUE;
|
||||
fill = TRUE;
|
||||
padding = 0;
|
||||
}
|
||||
|
||||
gtk_widget_get_allocation(GTK_WIDGET(that), &allocation);
|
||||
boxWidth = allocation.width;
|
||||
if (!expand) {
|
||||
*width = MIN(priv->overR.width, boxWidth - padding);
|
||||
*x = padding;
|
||||
} else if (!fill) {
|
||||
*width = MIN(priv->overR.width, boxWidth);
|
||||
*x = (boxWidth - *width) / 2;
|
||||
} else {
|
||||
*width = boxWidth;
|
||||
*x = 0;
|
||||
}
|
||||
|
||||
*y = (priv->overR.height - ViewOvBoxGetActualMin(that))
|
||||
* (priv->fraction - 1) + priv->verticalOffset;
|
||||
*height = priv->overR.height;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* ViewOvBoxSetBackground --
|
||||
*
|
||||
* Set the background color of the 'underWin' and 'overWin' X windows.
|
||||
*
|
||||
* Results:
|
||||
* None
|
||||
*
|
||||
* Side effects:
|
||||
* None
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static void
|
||||
ViewOvBoxSetBackground(ViewOvBox *that) // IN
|
||||
{
|
||||
GtkWidget *widget = GTK_WIDGET(that);
|
||||
GtkStyleContext *stylecontext;
|
||||
|
||||
stylecontext = gtk_widget_get_style_context(widget);
|
||||
gtk_style_context_set_background(stylecontext, gtk_widget_get_window(widget));
|
||||
gtk_style_context_set_background(stylecontext, that->priv->underWin);
|
||||
gtk_style_context_set_background(stylecontext, that->priv->overWin);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* ViewOvBoxRealize --
|
||||
*
|
||||
* "realize" method of a ViewOvBox.
|
||||
*
|
||||
* Results:
|
||||
* None
|
||||
*
|
||||
* Side effects:
|
||||
* None
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static void
|
||||
ViewOvBoxRealize(GtkWidget *widget) // IN
|
||||
{
|
||||
ViewOvBox *that;
|
||||
ViewOvBoxPrivate *priv;
|
||||
GdkWindowAttr attributes;
|
||||
gint mask;
|
||||
GtkAllocation allocation;
|
||||
GdkWindow *window;
|
||||
|
||||
gtk_widget_set_realized (widget, TRUE);
|
||||
|
||||
that = VIEW_OV_BOX(widget);
|
||||
priv = that->priv;
|
||||
|
||||
attributes.window_type = GDK_WINDOW_CHILD;
|
||||
attributes.wclass = GDK_INPUT_OUTPUT;
|
||||
attributes.visual = gtk_widget_get_visual(widget);
|
||||
attributes.event_mask = gtk_widget_get_events(widget) | GDK_EXPOSURE_MASK;
|
||||
mask = GDK_WA_VISUAL | GDK_WA_X | GDK_WA_Y;
|
||||
|
||||
gtk_widget_get_allocation(widget, &allocation);
|
||||
attributes.x = allocation.x;
|
||||
attributes.y = allocation.y;
|
||||
attributes.width = allocation.width;
|
||||
attributes.height = allocation.height;
|
||||
window = gdk_window_new(gtk_widget_get_parent_window(widget),
|
||||
&attributes, mask);
|
||||
gtk_widget_set_window(widget, window);
|
||||
gdk_window_set_user_data(window, that);
|
||||
|
||||
/*
|
||||
* The order in which we create the children X window matters: the child
|
||||
* created last is stacked on top. --hpreg
|
||||
*/
|
||||
|
||||
ViewOvBoxGetUnderGeometry(that, &attributes.x, &attributes.y,
|
||||
&attributes.width, &attributes.height);
|
||||
priv->underWin = gdk_window_new(window, &attributes, mask);
|
||||
gdk_window_set_user_data(priv->underWin, that);
|
||||
if (priv->under) {
|
||||
gtk_widget_set_parent_window(priv->under, priv->underWin);
|
||||
}
|
||||
gdk_window_show(priv->underWin);
|
||||
|
||||
ViewOvBoxGetOverGeometry(that, &attributes.x, &attributes.y,
|
||||
&attributes.width, &attributes.height);
|
||||
priv->overWin = gdk_window_new(window, &attributes, mask);
|
||||
gdk_window_set_user_data(priv->overWin, that);
|
||||
if (priv->over) {
|
||||
gtk_widget_set_parent_window(priv->over, priv->overWin);
|
||||
}
|
||||
gdk_window_show(priv->overWin);
|
||||
|
||||
ViewOvBoxSetBackground(that);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* ViewOvBoxUnrealize --
|
||||
*
|
||||
* "unrealize" method of a ViewOvBox.
|
||||
*
|
||||
* Results:
|
||||
* None
|
||||
*
|
||||
* Side effects:
|
||||
* None
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static void
|
||||
ViewOvBoxUnrealize(GtkWidget *widget) // IN
|
||||
{
|
||||
ViewOvBox *that;
|
||||
ViewOvBoxPrivate *priv;
|
||||
|
||||
that = VIEW_OV_BOX(widget);
|
||||
priv = that->priv;
|
||||
|
||||
/*
|
||||
* Unrealize the parent before destroying the windows so that we end up
|
||||
* unrealizing all the child widgets before destroying the child windows,
|
||||
* giving them a chance to reparent their windows before we clobber them.
|
||||
*/
|
||||
GTK_WIDGET_CLASS(parentClass)->unrealize(widget);
|
||||
|
||||
|
||||
gdk_window_set_user_data(priv->underWin, NULL);
|
||||
gdk_window_destroy(priv->underWin);
|
||||
priv->underWin = NULL;
|
||||
|
||||
gdk_window_set_user_data(priv->overWin, NULL);
|
||||
gdk_window_destroy(priv->overWin);
|
||||
priv->overWin = NULL;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* ViewOvBoxRealSizeRequest --
|
||||
*
|
||||
* "size_request" method, generalized to work with both gtk-2 and 3.
|
||||
*
|
||||
* Results:
|
||||
* None
|
||||
*
|
||||
* Side effects:
|
||||
* None
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
static void
|
||||
ViewOvBoxRealSizeRequest(GtkWidget *widget, // IN
|
||||
GtkRequisition *min_in, GtkRequisition *nat_in, // IN
|
||||
GtkRequisition *min_out, GtkRequisition *nat_out) // OUT
|
||||
{
|
||||
ViewOvBox *that;
|
||||
ViewOvBoxPrivate *priv;
|
||||
gboolean expand;
|
||||
gboolean fill;
|
||||
guint padding;
|
||||
unsigned int min;
|
||||
|
||||
that = VIEW_OV_BOX(widget);
|
||||
priv = that->priv;
|
||||
|
||||
gtk_widget_get_preferred_size(priv->over, NULL, &priv->overR);
|
||||
|
||||
gtk_container_child_get(GTK_CONTAINER(that), priv->over,
|
||||
"expand", &expand,
|
||||
"fill", &fill,
|
||||
"padding", &padding,
|
||||
NULL);
|
||||
|
||||
min = ViewOvBoxGetActualMin(that);
|
||||
|
||||
if (min_out) {
|
||||
min_out->width = MAX(min_in->width, priv->overR.width +
|
||||
((expand || fill) ? 0 : padding));
|
||||
min_out->height = MAX(min_in->height + min, priv->overR.height);
|
||||
}
|
||||
if (nat_out) {
|
||||
nat_out->width = MAX(nat_in->width, priv->overR.width +
|
||||
((expand || fill) ? 0 : padding));
|
||||
nat_out->height = MAX(nat_in->height + min, priv->overR.height);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ViewOvBox_get_preferred_width (GtkWidget *widget,
|
||||
gint *minimal_width,
|
||||
gint *natural_width)
|
||||
{
|
||||
ViewOvBoxPrivate *priv = VIEW_OV_BOX(widget)->priv;
|
||||
GtkRequisition min_in, nat_in, min_out, nat_out;
|
||||
|
||||
gtk_widget_get_preferred_size(priv->under, &min_in, &nat_in);
|
||||
|
||||
ViewOvBoxRealSizeRequest(widget, &min_in, &nat_in, &min_out, &nat_out);
|
||||
|
||||
*minimal_width = min_out.width;
|
||||
*natural_width = nat_out.width;
|
||||
}
|
||||
|
||||
static void
|
||||
ViewOvBox_get_preferred_height (GtkWidget *widget,
|
||||
gint *minimal_height,
|
||||
gint *natural_height)
|
||||
{
|
||||
ViewOvBoxPrivate *priv = VIEW_OV_BOX(widget)->priv;
|
||||
GtkRequisition min_in, nat_in, min_out, nat_out;
|
||||
|
||||
gtk_widget_get_preferred_size(priv->under, &min_in, &nat_in);
|
||||
|
||||
ViewOvBoxRealSizeRequest(widget, &min_in, &nat_in, &min_out, &nat_out);
|
||||
|
||||
*minimal_height = min_out.height;
|
||||
*natural_height = nat_out.height;
|
||||
}
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* ViewOvBoxSizeAllocate --
|
||||
*
|
||||
* "size_allocate" method of a ViewOvBox.
|
||||
*
|
||||
* Results:
|
||||
* None
|
||||
*
|
||||
* Side effects:
|
||||
* None
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static void
|
||||
ViewOvBoxSizeAllocate(GtkWidget *widget, // IN
|
||||
GtkAllocation *allocation) // IN
|
||||
{
|
||||
ViewOvBox *that;
|
||||
ViewOvBoxPrivate *priv;
|
||||
GtkAllocation under;
|
||||
GtkAllocation over;
|
||||
|
||||
gtk_widget_set_allocation (widget, allocation);
|
||||
|
||||
that = VIEW_OV_BOX(widget);
|
||||
priv = that->priv;
|
||||
|
||||
ViewOvBoxGetUnderGeometry(that, &under.x, &under.y, &under.width,
|
||||
&under.height);
|
||||
ViewOvBoxGetOverGeometry(that, &over.x, &over.y, &over.width, &over.height);
|
||||
|
||||
if (gtk_widget_get_realized(widget)) {
|
||||
gdk_window_move_resize(gtk_widget_get_window(widget),
|
||||
allocation->x, allocation->y,
|
||||
allocation->width, allocation->height);
|
||||
gdk_window_move_resize(priv->underWin, under.x, under.y, under.width,
|
||||
under.height);
|
||||
gdk_window_move_resize(priv->overWin, over.x, over.y, over.width,
|
||||
over.height);
|
||||
}
|
||||
|
||||
under.x = 0;
|
||||
under.y = 0;
|
||||
gtk_widget_size_allocate(priv->under, &under);
|
||||
over.x = 0;
|
||||
over.y = 0;
|
||||
gtk_widget_size_allocate(priv->over, &over);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* ViewOvBoxStyleSet --
|
||||
*
|
||||
* "style_set" method of a ViewOvBox.
|
||||
*
|
||||
* Results:
|
||||
* None
|
||||
*
|
||||
* Side effects:
|
||||
* None
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static void
|
||||
ViewOvBoxStyleSet(GtkWidget *widget, // IN
|
||||
GtkStyle *previousStyle) // IN: Unused
|
||||
{
|
||||
ViewOvBox *that;
|
||||
|
||||
that = VIEW_OV_BOX(widget);
|
||||
|
||||
if (gtk_widget_get_realized(widget)) {
|
||||
ViewOvBoxSetBackground(that);
|
||||
}
|
||||
|
||||
GTK_WIDGET_CLASS(parentClass)->style_set(widget, previousStyle);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* ViewOvBoxSetChild --
|
||||
*
|
||||
* Set a child of a ViewOvBox.
|
||||
*
|
||||
* Results:
|
||||
* None
|
||||
*
|
||||
* Side effects:
|
||||
* None
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static void
|
||||
ViewOvBoxSetChild(ViewOvBox *that, // IN
|
||||
GtkWidget **child, // IN
|
||||
GdkWindow *childWin, // IN
|
||||
GtkWidget *widget) // IN
|
||||
{
|
||||
GtkWidget *oldChild = *child;
|
||||
|
||||
if (oldChild) {
|
||||
g_object_ref(oldChild);
|
||||
gtk_container_remove(GTK_CONTAINER(that), oldChild);
|
||||
}
|
||||
|
||||
*child = widget;
|
||||
if (*child) {
|
||||
gtk_widget_set_parent_window(widget, childWin);
|
||||
gtk_container_add(GTK_CONTAINER(that), *child);
|
||||
}
|
||||
|
||||
if (oldChild) {
|
||||
g_object_unref(oldChild);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* ViewOvBoxSetOver --
|
||||
*
|
||||
* Base implementation of ViewOvBox_SetOver.
|
||||
*
|
||||
* Results:
|
||||
* None
|
||||
*
|
||||
* Side effects:
|
||||
* None
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static void
|
||||
ViewOvBoxSetOver(ViewOvBox *that, // IN
|
||||
GtkWidget *widget) // IN
|
||||
{
|
||||
ViewOvBoxSetChild(that, &that->priv->over, that->priv->overWin, widget);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* ViewOvBoxClassInit --
|
||||
*
|
||||
* Initialize the ViewOvBoxClass.
|
||||
*
|
||||
* Results:
|
||||
* None
|
||||
*
|
||||
* Side effects:
|
||||
* None
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static void
|
||||
ViewOvBoxClassInit(ViewOvBoxClass *klass) // IN
|
||||
{
|
||||
GtkWidgetClass *widgetClass;
|
||||
|
||||
widgetClass = GTK_WIDGET_CLASS(klass);
|
||||
|
||||
widgetClass->map = ViewOvBoxMap;
|
||||
widgetClass->unmap = ViewOvBoxUnmap;
|
||||
widgetClass->realize = ViewOvBoxRealize;
|
||||
widgetClass->unrealize = ViewOvBoxUnrealize;
|
||||
widgetClass->get_preferred_width = ViewOvBox_get_preferred_width;
|
||||
widgetClass->get_preferred_height = ViewOvBox_get_preferred_height;
|
||||
widgetClass->size_allocate = ViewOvBoxSizeAllocate;
|
||||
widgetClass->style_set = ViewOvBoxStyleSet;
|
||||
|
||||
klass->set_over = ViewOvBoxSetOver;
|
||||
|
||||
parentClass = g_type_class_peek_parent(klass);
|
||||
|
||||
g_type_class_add_private(klass, sizeof(ViewOvBoxPrivate));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* ViewOvBox_GetType --
|
||||
*
|
||||
* Get the (memoized) GType of the ViewOvBox GTK+ object.
|
||||
*
|
||||
* Results:
|
||||
* The GType
|
||||
*
|
||||
* Side effects:
|
||||
* None
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
GType
|
||||
ViewOvBox_GetType(void)
|
||||
{
|
||||
static GType type = 0;
|
||||
|
||||
if (type == 0) {
|
||||
static const GTypeInfo info = {
|
||||
sizeof (ViewOvBoxClass),
|
||||
NULL, /* BaseInit */
|
||||
NULL, /* BaseFinalize */
|
||||
(GClassInitFunc)ViewOvBoxClassInit,
|
||||
NULL,
|
||||
NULL, /* Class Data */
|
||||
sizeof (ViewOvBox),
|
||||
0, /* n_preallocs */
|
||||
(GInstanceInitFunc)ViewOvBoxInit,
|
||||
NULL,
|
||||
};
|
||||
|
||||
type = g_type_register_static(GTK_TYPE_BOX, "ViewOvBox", &info, 0);
|
||||
}
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* ViewOvBox_New --
|
||||
*
|
||||
* Create a new ViewOvBox GTK+ widget.
|
||||
*
|
||||
* Results:
|
||||
* The widget
|
||||
*
|
||||
* Side effects:
|
||||
* None
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
GtkWidget *
|
||||
ViewOvBox_New(void)
|
||||
{
|
||||
ViewOvBox *that;
|
||||
|
||||
that = VIEW_OV_BOX(g_object_new(VIEW_TYPE_OV_BOX, NULL));
|
||||
|
||||
return GTK_WIDGET(that);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* ViewOvBox_SetUnder --
|
||||
*
|
||||
* Set the under widget of a ViewOvBox.
|
||||
*
|
||||
* Results:
|
||||
* None
|
||||
*
|
||||
* Side effects:
|
||||
* None
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void
|
||||
ViewOvBox_SetUnder(ViewOvBox *that, // IN
|
||||
GtkWidget *widget) // IN
|
||||
{
|
||||
g_return_if_fail(that != NULL);
|
||||
|
||||
ViewOvBoxSetChild(that, &that->priv->under, that->priv->underWin, widget);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* ViewOvBox_SetOver --
|
||||
*
|
||||
* Set the over widget of a ViewOvBox.
|
||||
*
|
||||
* Results:
|
||||
* None
|
||||
*
|
||||
* Side effects:
|
||||
* None
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void
|
||||
ViewOvBox_SetOver(ViewOvBox *that, // IN
|
||||
GtkWidget *widget) // IN
|
||||
{
|
||||
g_return_if_fail(that != NULL);
|
||||
|
||||
VIEW_OV_BOX_GET_CLASS(that)->set_over(that, widget);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* ViewOvBox_SetMin --
|
||||
*
|
||||
* Set the 'min' property of a ViewOvBox, i.e. the number of pixel of the
|
||||
* 'over' child that should always be displayed without overlapping on the
|
||||
* 'under' child.
|
||||
*
|
||||
* Using a value of -1 displays the 'over' child entirely.
|
||||
*
|
||||
* Results:
|
||||
* None
|
||||
*
|
||||
* Side effects:
|
||||
* None
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void
|
||||
ViewOvBox_SetMin(ViewOvBox *that, // IN
|
||||
unsigned int min) // IN
|
||||
{
|
||||
g_return_if_fail(that != NULL);
|
||||
|
||||
that->priv->min = min;
|
||||
gtk_widget_queue_resize(GTK_WIDGET(that));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* ViewOvBox_SetFraction --
|
||||
*
|
||||
* Set the 'fraction' property of a ViewOvBox, i.e. how much of the 'over'
|
||||
* child should overlap on the 'under' child.
|
||||
*
|
||||
* Results:
|
||||
* None
|
||||
*
|
||||
* Side effects:
|
||||
* None
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void
|
||||
ViewOvBox_SetFraction(ViewOvBox *that, // IN
|
||||
double fraction) // IN
|
||||
{
|
||||
g_return_if_fail(that != NULL);
|
||||
g_return_if_fail(fraction >=0 && fraction <= 1);
|
||||
|
||||
that->priv->fraction = fraction;
|
||||
if (gtk_widget_get_realized(GTK_WIDGET (that))) {
|
||||
int x;
|
||||
int y;
|
||||
int width;
|
||||
int height;
|
||||
|
||||
ViewOvBoxGetOverGeometry(that, &x, &y, &width, &height);
|
||||
gdk_window_move(that->priv->overWin, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* ViewOvBox_GetFraction --
|
||||
*
|
||||
* Retrieve the 'fraction' property of a ViewOvBox.
|
||||
*
|
||||
* Results:
|
||||
* The value
|
||||
*
|
||||
* Side effects:
|
||||
* None
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
double
|
||||
ViewOvBox_GetFraction(ViewOvBox *that)
|
||||
{
|
||||
g_return_val_if_fail(that != NULL, 0);
|
||||
|
||||
return that->priv->fraction;
|
||||
}
|
||||
103
src/view/ovBox.h
103
src/view/ovBox.h
@ -1,103 +0,0 @@
|
||||
/* *************************************************************************
|
||||
* Copyright (c) 2005 VMware, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
* *************************************************************************/
|
||||
|
||||
/*
|
||||
* ovBox.h --
|
||||
*
|
||||
* Declarations for the ViewOvBox GTK+ widget.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef LIBVIEW_OVBOX_H
|
||||
#define LIBVIEW_OVBOX_H
|
||||
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
|
||||
#define VIEW_TYPE_OV_BOX (ViewOvBox_GetType())
|
||||
#define VIEW_OV_BOX(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), VIEW_TYPE_OV_BOX, ViewOvBox))
|
||||
#define VIEW_OV_BOX_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), VIEW_TYPE_OV_BOX, ViewOvBoxClass))
|
||||
#define VIEW_IS_OV_BOX(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), VIEW_TYPE_OV_BOX))
|
||||
#define VIEW_IS_OV_BOX_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), VIEW_TYPE_OV_BOX))
|
||||
#define VIEW_OV_BOX_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), VIEW_TYPE_OV_BOX, ViewOvBoxClass))
|
||||
|
||||
typedef struct _ViewOvBoxPrivate ViewOvBoxPrivate;
|
||||
|
||||
typedef struct _ViewOvBox {
|
||||
/* Must come first. */
|
||||
GtkBox parent;
|
||||
|
||||
/* Private. */
|
||||
ViewOvBoxPrivate *priv;
|
||||
} ViewOvBox;
|
||||
|
||||
|
||||
typedef struct _ViewOvBoxClass {
|
||||
/* Must come first. */
|
||||
GtkBoxClass parent;
|
||||
|
||||
/* Virtual methods. */
|
||||
void (* set_over)(ViewOvBox *ovBox, GtkWidget *widget);
|
||||
|
||||
/* Padding for future expansion */
|
||||
void (*_view_reserved0)(void);
|
||||
void (*_view_reserved1)(void);
|
||||
void (*_view_reserved2)(void);
|
||||
void (*_view_reserved3)(void);
|
||||
} ViewOvBoxClass;
|
||||
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
|
||||
GType
|
||||
ViewOvBox_GetType(void);
|
||||
|
||||
GtkWidget *
|
||||
ViewOvBox_New(void);
|
||||
|
||||
void
|
||||
ViewOvBox_SetUnder(ViewOvBox *that,
|
||||
GtkWidget *widget);
|
||||
|
||||
void
|
||||
ViewOvBox_SetOver(ViewOvBox *that,
|
||||
GtkWidget *widget);
|
||||
|
||||
void
|
||||
ViewOvBox_SetMin(ViewOvBox *that,
|
||||
unsigned int min);
|
||||
|
||||
void
|
||||
ViewOvBox_SetFraction(ViewOvBox *that,
|
||||
double fraction);
|
||||
|
||||
double
|
||||
ViewOvBox_GetFraction(ViewOvBox *that);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
#endif /* LIBVIEW_OVBOX_H */
|
||||
213
src/virt-viewer-timed-revealer.c
Normal file
213
src/virt-viewer-timed-revealer.c
Normal file
@ -0,0 +1,213 @@
|
||||
/*
|
||||
* Virt Viewer: A virtual machine console viewer
|
||||
*
|
||||
* Copyright (c) 2016 Red Hat, Inc.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* Author: Cole Robinson <crobinso@redhat.com>
|
||||
* Author: Fabiano Fidêncio <fidencio@redhat.com>
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "virt-viewer-timed-revealer.h"
|
||||
|
||||
G_DEFINE_TYPE (VirtViewerTimedRevealer, virt_viewer_timed_revealer, G_TYPE_OBJECT)
|
||||
|
||||
#define VIRT_VIEWER_TIMED_REVEALER_GET_PRIVATE(obj) \
|
||||
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), VIRT_VIEWER_TYPE_TIMED_REVEALER, VirtViewerTimedRevealerPrivate))
|
||||
|
||||
struct _VirtViewerTimedRevealerPrivate
|
||||
{
|
||||
gboolean fullscreen;
|
||||
guint timeout_id;
|
||||
|
||||
GtkWidget *revealer;
|
||||
GtkWidget *evBox;
|
||||
};
|
||||
|
||||
static void
|
||||
virt_viewer_timed_revealer_unregister_timeout(VirtViewerTimedRevealer *self)
|
||||
{
|
||||
VirtViewerTimedRevealerPrivate *priv = self->priv;
|
||||
|
||||
if (priv->timeout_id) {
|
||||
g_source_remove(priv->timeout_id);
|
||||
priv->timeout_id = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
schedule_unreveal_timeout_cb(VirtViewerTimedRevealer *self)
|
||||
{
|
||||
VirtViewerTimedRevealerPrivate *priv = self->priv;
|
||||
|
||||
gtk_revealer_set_reveal_child(GTK_REVEALER(priv->revealer), FALSE);
|
||||
priv->timeout_id = 0;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
virt_viewer_timed_revealer_schedule_unreveal_timeout(VirtViewerTimedRevealer *self,
|
||||
guint timeout)
|
||||
{
|
||||
VirtViewerTimedRevealerPrivate *priv = self->priv;
|
||||
|
||||
if (priv->timeout_id != 0)
|
||||
return;
|
||||
|
||||
priv->timeout_id = g_timeout_add(timeout,
|
||||
(GSourceFunc)schedule_unreveal_timeout_cb,
|
||||
self);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
virt_viewer_timed_revealer_enter_leave_notify(GtkWidget *evBox,
|
||||
GdkEventCrossing *event,
|
||||
VirtViewerTimedRevealer *self)
|
||||
{
|
||||
VirtViewerTimedRevealerPrivate *priv = self->priv;
|
||||
GdkDevice *device;
|
||||
GtkAllocation allocation;
|
||||
gint x, y;
|
||||
gboolean entered;
|
||||
|
||||
if (!priv->fullscreen)
|
||||
return FALSE;
|
||||
|
||||
device = gdk_event_get_device((GdkEvent *)event);
|
||||
|
||||
gdk_window_get_device_position(event->window, device, &x, &y, 0);
|
||||
gtk_widget_get_allocation(evBox, &allocation);
|
||||
|
||||
entered = !!(x >= 0 && y >= 0 && x < allocation.width && y < allocation.height);
|
||||
|
||||
/*
|
||||
* Pointer exited the toolbar, and toolbar is revealed. Schedule
|
||||
* a timeout to close it, if one isn't already scheduled.
|
||||
*/
|
||||
if (!entered && gtk_revealer_get_reveal_child(GTK_REVEALER(priv->revealer))) {
|
||||
virt_viewer_timed_revealer_schedule_unreveal_timeout(self, 1000);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
virt_viewer_timed_revealer_unregister_timeout(self);
|
||||
if (entered && !gtk_revealer_get_reveal_child(GTK_REVEALER(priv->revealer))) {
|
||||
gtk_revealer_set_reveal_child(GTK_REVEALER(priv->revealer), TRUE);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
virt_viewer_timed_revealer_init(VirtViewerTimedRevealer *self)
|
||||
{
|
||||
self->priv = VIRT_VIEWER_TIMED_REVEALER_GET_PRIVATE(self);
|
||||
}
|
||||
|
||||
static void
|
||||
virt_viewer_timed_revealer_dispose(GObject *object)
|
||||
{
|
||||
VirtViewerTimedRevealer *self = VIRT_VIEWER_TIMED_REVEALER(object);
|
||||
VirtViewerTimedRevealerPrivate *priv = self->priv;
|
||||
|
||||
g_clear_object(&priv->evBox);
|
||||
g_clear_object(&priv->revealer);
|
||||
|
||||
if (priv->timeout_id) {
|
||||
g_source_remove(priv->timeout_id);
|
||||
priv->timeout_id = 0;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS(virt_viewer_timed_revealer_parent_class)->dispose(object);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
virt_viewer_timed_revealer_class_init(VirtViewerTimedRevealerClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS(klass);
|
||||
|
||||
g_type_class_add_private (klass, sizeof (VirtViewerTimedRevealerPrivate));
|
||||
|
||||
object_class->dispose = virt_viewer_timed_revealer_dispose;
|
||||
}
|
||||
|
||||
VirtViewerTimedRevealer *
|
||||
virt_viewer_timed_revealer_new(GtkWidget *toolbar)
|
||||
{
|
||||
VirtViewerTimedRevealer *self;
|
||||
VirtViewerTimedRevealerPrivate *priv;
|
||||
|
||||
self = g_object_new(VIRT_VIEWER_TYPE_TIMED_REVEALER, NULL);
|
||||
|
||||
priv = self->priv;
|
||||
|
||||
priv->fullscreen = FALSE;
|
||||
priv->timeout_id = 0;
|
||||
|
||||
priv->revealer = gtk_revealer_new();
|
||||
gtk_container_add(GTK_CONTAINER(priv->revealer), toolbar);
|
||||
|
||||
/*
|
||||
* Adding the revealer to the eventbox seems to ensure the
|
||||
* GtkEventBox always has 1 invisible pixel showing at the top of the
|
||||
* screen, which we can use to grab the pointer event to show
|
||||
* the hidden toolbar.
|
||||
*/
|
||||
|
||||
priv->evBox = gtk_event_box_new();
|
||||
gtk_container_add(GTK_CONTAINER(priv->evBox), priv->revealer);
|
||||
gtk_widget_set_halign(priv->evBox, GTK_ALIGN_CENTER);
|
||||
gtk_widget_set_valign(priv->evBox, GTK_ALIGN_START);
|
||||
gtk_widget_show_all(priv->evBox);
|
||||
|
||||
g_signal_connect(priv->evBox,
|
||||
"enter-notify-event",
|
||||
G_CALLBACK(virt_viewer_timed_revealer_enter_leave_notify),
|
||||
self);
|
||||
g_signal_connect(priv->evBox,
|
||||
"leave-notify-event",
|
||||
G_CALLBACK(virt_viewer_timed_revealer_enter_leave_notify),
|
||||
self);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
void
|
||||
virt_viewer_timed_revealer_force_reveal(VirtViewerTimedRevealer *self,
|
||||
gboolean fullscreen)
|
||||
{
|
||||
VirtViewerTimedRevealerPrivate *priv;
|
||||
|
||||
g_return_if_fail(VIRT_VIEWER_IS_TIMED_REVEALER(self));
|
||||
|
||||
priv = self->priv;
|
||||
|
||||
virt_viewer_timed_revealer_unregister_timeout(self);
|
||||
priv->fullscreen = fullscreen;
|
||||
gtk_revealer_set_reveal_child(GTK_REVEALER(priv->revealer), fullscreen);
|
||||
virt_viewer_timed_revealer_schedule_unreveal_timeout(self, 2000);
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
virt_viewer_timed_revealer_get_overlay_widget(VirtViewerTimedRevealer *self)
|
||||
{
|
||||
g_return_val_if_fail(VIRT_VIEWER_IS_TIMED_REVEALER(self), NULL);
|
||||
|
||||
return self->priv->evBox;
|
||||
}
|
||||
74
src/virt-viewer-timed-revealer.h
Normal file
74
src/virt-viewer-timed-revealer.h
Normal file
@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Virt Viewer: A virtual machine console viewer
|
||||
*
|
||||
* Copyright (c) 2016 Red Hat, Inc.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* Author: Cole Robinson <crobinso@redhat.com>
|
||||
* Author: Fabiano Fidêncio <fidencio@redhat.com>
|
||||
*/
|
||||
|
||||
#ifndef _VIRT_VIEWER_TIMED_REVEALER_H
|
||||
#define _VIRT_VIEWER_TIMED_REVEALER_H
|
||||
|
||||
#include <glib-object.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define VIRT_VIEWER_TYPE_TIMED_REVEALER virt_viewer_timed_revealer_get_type()
|
||||
|
||||
#define VIRT_VIEWER_TIMED_REVEALER(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST ((obj), VIRT_VIEWER_TYPE_TIMED_REVEALER, VirtViewerTimedRevealer))
|
||||
|
||||
#define VIRT_VIEWER_TIMED_REVEALER_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST ((klass), VIRT_VIEWER_TYPE_TIMED_REVEALER, VirtViewerTimedRevealerClass))
|
||||
|
||||
#define VIRT_VIEWER_IS_TIMED_REVEALER(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), VIRT_VIEWER_TYPE_TIMED_REVEALER))
|
||||
|
||||
#define VIRT_VIEWER_IS_TIMED_REVEALER_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE ((klass), VIRT_VIEWER_TYPE_TIMED_REVEALER))
|
||||
|
||||
#define VIRT_VIEWER_TIMED_REVEALER_GET_CLASS(obj) \
|
||||
(G_TYPE_INSTANCE_GET_CLASS ((obj), VIRT_VIEWER_TYPE_TIMED_REVEALER, VirtViewerTimedRevealerClass))
|
||||
|
||||
typedef struct _VirtViewerTimedRevealerPrivate VirtViewerTimedRevealerPrivate;
|
||||
|
||||
typedef struct {
|
||||
GObject parent;
|
||||
VirtViewerTimedRevealerPrivate *priv;
|
||||
} VirtViewerTimedRevealer;
|
||||
|
||||
typedef struct {
|
||||
GObjectClass parent_class;
|
||||
} VirtViewerTimedRevealerClass;
|
||||
|
||||
GType virt_viewer_timed_revealer_get_type (void);
|
||||
|
||||
VirtViewerTimedRevealer *
|
||||
virt_viewer_timed_revealer_new(GtkWidget *toolbar);
|
||||
|
||||
void
|
||||
virt_viewer_timed_revealer_force_reveal(VirtViewerTimedRevealer *self,
|
||||
gboolean fullscreen);
|
||||
|
||||
GtkWidget *
|
||||
virt_viewer_timed_revealer_get_overlay_widget(VirtViewerTimedRevealer *self);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* _VIRT_VIEWER_TIMED_REVEALER_H */
|
||||
@ -41,7 +41,7 @@
|
||||
#include "virt-viewer-session.h"
|
||||
#include "virt-viewer-app.h"
|
||||
#include "virt-viewer-util.h"
|
||||
#include "view/autoDrawer.h"
|
||||
#include "virt-viewer-timed-revealer.h"
|
||||
|
||||
#define ZOOM_STEP 10
|
||||
|
||||
@ -91,13 +91,13 @@ struct _VirtViewerWindowPrivate {
|
||||
|
||||
GtkBuilder *builder;
|
||||
GtkWidget *window;
|
||||
GtkWidget *layout;
|
||||
GtkWidget *toolbar;
|
||||
GtkWidget *toolbar_usb_device_selection;
|
||||
GtkWidget *toolbar_send_key;
|
||||
GtkAccelGroup *accel_group;
|
||||
VirtViewerNotebook *notebook;
|
||||
VirtViewerDisplay *display;
|
||||
VirtViewerTimedRevealer *revealer;
|
||||
|
||||
gboolean accel_enabled;
|
||||
GValue accel_setting;
|
||||
@ -188,6 +188,8 @@ virt_viewer_window_dispose (GObject *object)
|
||||
priv->builder = NULL;
|
||||
}
|
||||
|
||||
g_clear_object(&priv->revealer);
|
||||
|
||||
for (it = priv->accel_list ; it != NULL ; it = it->next) {
|
||||
g_object_unref(G_OBJECT(it->data));
|
||||
}
|
||||
@ -305,6 +307,8 @@ virt_viewer_window_init (VirtViewerWindow *self)
|
||||
g_value_init(&priv->accel_setting, G_TYPE_STRING);
|
||||
|
||||
priv->notebook = virt_viewer_notebook_new();
|
||||
gtk_widget_show(GTK_WIDGET(priv->notebook));
|
||||
|
||||
priv->builder = virt_viewer_util_load_ui("virt-viewer.ui");
|
||||
|
||||
gtk_widget_set_sensitive(GTK_WIDGET(gtk_builder_get_object(self->priv->builder, "menu-send")), FALSE);
|
||||
@ -335,7 +339,7 @@ virt_viewer_window_init (VirtViewerWindow *self)
|
||||
vbox = GTK_WIDGET(gtk_builder_get_object(priv->builder, "viewer-box"));
|
||||
virt_viewer_window_toolbar_setup(self);
|
||||
|
||||
gtk_box_pack_end(GTK_BOX(vbox), priv->layout, TRUE, TRUE, 0);
|
||||
gtk_box_pack_end(GTK_BOX(vbox), GTK_WIDGET(priv->notebook), TRUE, TRUE, 0);
|
||||
gdk_rgba_parse(&color, "black");
|
||||
/* FIXME:
|
||||
* This method has been deprecated in 3.16.
|
||||
@ -344,7 +348,7 @@ virt_viewer_window_init (VirtViewerWindow *self)
|
||||
* For the bug report about this deprecated function, please, see:
|
||||
* https://bugs.freedesktop.org/show_bug.cgi?id=94276
|
||||
*/
|
||||
gtk_widget_override_background_color(priv->layout, GTK_STATE_FLAG_NORMAL, &color);
|
||||
gtk_widget_override_background_color(GTK_WIDGET(priv->notebook), GTK_STATE_FLAG_NORMAL, &color);
|
||||
|
||||
priv->window = GTK_WIDGET(gtk_builder_get_object(priv->builder, "viewer"));
|
||||
gtk_window_add_accel_group(GTK_WINDOW(priv->window), priv->accel_group);
|
||||
@ -481,7 +485,7 @@ virt_viewer_window_leave_fullscreen(VirtViewerWindow *self)
|
||||
virt_viewer_display_set_monitor(priv->display, -1);
|
||||
virt_viewer_display_set_fullscreen(priv->display, FALSE);
|
||||
}
|
||||
ViewAutoDrawer_SetActive(VIEW_AUTODRAWER(priv->layout), FALSE);
|
||||
virt_viewer_timed_revealer_force_reveal(priv->revealer, FALSE);
|
||||
gtk_widget_show(menu);
|
||||
gtk_widget_hide(priv->toolbar);
|
||||
gtk_widget_set_size_request(priv->window, -1, -1);
|
||||
@ -518,8 +522,7 @@ virt_viewer_window_enter_fullscreen(VirtViewerWindow *self, gint monitor)
|
||||
virt_viewer_window_menu_fullscreen_set_active(self, TRUE);
|
||||
gtk_widget_hide(menu);
|
||||
gtk_widget_show(priv->toolbar);
|
||||
ViewAutoDrawer_SetActive(VIEW_AUTODRAWER(priv->layout), TRUE);
|
||||
ViewAutoDrawer_Close(VIEW_AUTODRAWER(priv->layout));
|
||||
virt_viewer_timed_revealer_force_reveal(priv->revealer, TRUE);
|
||||
|
||||
if (priv->display) {
|
||||
virt_viewer_display_set_monitor(priv->display, monitor);
|
||||
@ -1064,6 +1067,7 @@ static void
|
||||
virt_viewer_window_toolbar_setup(VirtViewerWindow *self)
|
||||
{
|
||||
GtkWidget *button;
|
||||
GtkWidget *overlay;
|
||||
VirtViewerWindowPrivate *priv = self->priv;
|
||||
|
||||
priv->toolbar = g_object_ref(gtk_toolbar_new());
|
||||
@ -1109,16 +1113,10 @@ virt_viewer_window_toolbar_setup(VirtViewerWindow *self)
|
||||
gtk_toolbar_insert(GTK_TOOLBAR(priv->toolbar), GTK_TOOL_ITEM(button), 0);
|
||||
g_signal_connect(button, "clicked", G_CALLBACK(virt_viewer_window_toolbar_leave_fullscreen), self);
|
||||
|
||||
priv->layout = ViewAutoDrawer_New();
|
||||
|
||||
ViewAutoDrawer_SetActive(VIEW_AUTODRAWER(priv->layout), FALSE);
|
||||
ViewOvBox_SetOver(VIEW_OV_BOX(priv->layout), priv->toolbar);
|
||||
ViewOvBox_SetUnder(VIEW_OV_BOX(priv->layout), GTK_WIDGET(priv->notebook));
|
||||
ViewAutoDrawer_SetOffset(VIEW_AUTODRAWER(priv->layout), -1);
|
||||
ViewAutoDrawer_SetFill(VIEW_AUTODRAWER(priv->layout), FALSE);
|
||||
ViewAutoDrawer_SetOverlapPixels(VIEW_AUTODRAWER(priv->layout), 1);
|
||||
ViewAutoDrawer_SetNoOverlapPixels(VIEW_AUTODRAWER(priv->layout), 0);
|
||||
gtk_widget_show(priv->layout);
|
||||
priv->revealer = virt_viewer_timed_revealer_new(priv->toolbar);
|
||||
overlay = GTK_WIDGET(gtk_builder_get_object(priv->builder, "viewer-overlay"));
|
||||
gtk_overlay_add_overlay(GTK_OVERLAY(overlay),
|
||||
virt_viewer_timed_revealer_get_overlay_widget(priv->revealer));
|
||||
}
|
||||
|
||||
VirtViewerNotebook*
|
||||
@ -1356,9 +1354,7 @@ virt_viewer_window_enable_kiosk(VirtViewerWindow *self)
|
||||
g_return_if_fail(VIRT_VIEWER_IS_WINDOW(self));
|
||||
priv = self->priv;
|
||||
|
||||
ViewOvBox_SetOver(VIEW_OV_BOX(priv->layout), gtk_drawing_area_new());
|
||||
ViewAutoDrawer_SetActive(VIEW_AUTODRAWER(priv->layout), FALSE);
|
||||
ViewAutoDrawer_SetOverlapPixels(VIEW_AUTODRAWER(priv->layout), 0);
|
||||
virt_viewer_timed_revealer_force_reveal(priv->revealer, FALSE);
|
||||
|
||||
/* You probably also want X11 Option "DontVTSwitch" "true" */
|
||||
/* and perhaps more distro/desktop-specific options */
|
||||
|
||||
Loading…
Reference in New Issue
Block a user