# HG changeset patch
# User Darren Salt <[EMAIL PROTECTED]>
# Date 1170716606 0
# Node ID 6c337d2f29ef69b9c8fab491ebe8c1d5cb602455
# Parent 90b992be48a01f70d5e5a4911190d4a37b32ce1d
Allow slider widgets to be presented as buttons with pop-up windows.
The volume slider in the default windowed-mode toolbar is now a pop-up, and
the default full-screen toolbar gains a volume icon.
Update the documentation accordingly.
diff -r 6c337d2f29ef69b9c8fab491ebe8c1d5cb602455 -r
90b992be48a01f70d5e5a4911190d4a37b32ce1d ChangeLog
--- a/ChangeLog Mon Feb 05 23:03:26 2007 +0000
+++ b/ChangeLog Mon Feb 05 22:51:19 2007 +0000
@@ -19,6 +19,8 @@ 0.5.900:2007/??/??
- separate toolbar;
- windowed-mode blanking prevention.
Existing configurations are unaffected.
+ * Allow slider widgets to be presented as buttons with pop-up windows.
+ The volume slider in the default windowed-mode toolbar is a pop-up.
* Obsoleted and disabled most of the deprecated JS functions, except
for set_fullscreen() and toolbar_show() which remain deprecated.
If you need the others, build with --enable-obsolete.
diff -r 6c337d2f29ef69b9c8fab491ebe8c1d5cb602455 -r
90b992be48a01f70d5e5a4911190d4a37b32ce1d doc/Skin-HOWTO
--- a/doc/Skin-HOWTO Mon Feb 05 23:03:26 2007 +0000
+++ b/doc/Skin-HOWTO Mon Feb 05 22:51:19 2007 +0000
@@ -95,6 +95,7 @@ Properties common to all widgets:
vertical=BOOL whether the slider is horizontal or vertical
show-value=BOOL whether the slider's value is shown
inverted=BOOL whether the slider's "increment" direction is reversed
+ popup=BOOL whether the slider is presented in a pop-up
Widget types:
Buttons:
@@ -120,6 +121,19 @@ Properties common to all widgets:
vslider render as a vertical slider
spin render as a spin button
+ If the 'popup' property is set, then the slider is presented as a
+ button with a pop-up window. As such, the slider acts as a <button>,
+ except that you cannot use the 'onclick' property. In addition, the
+ following properties are available:
+
+ window-width=INT the width of the window (default auto)
+ window-height=INT the height of the window (default auto)
+
+ A vertical slider will normally be presented below the button and a
+ horizontal slider to one side (according to the normal text direction);
+ if it wouldn't be fully on-screen there, it'll be shown on the
+ opposite side.
+
<flipbutton>
THIS UI ITEM IS NOT CURRENTLY IMPLEMENTED.
Clickable button, requiring two child widgets for the "off" and "on"
diff -r 6c337d2f29ef69b9c8fab491ebe8c1d5cb602455 -r
90b992be48a01f70d5e5a4911190d4a37b32ce1d misc/toolbar-fullscreen.xml
--- a/misc/toolbar-fullscreen.xml Mon Feb 05 23:03:26 2007 +0000
+++ b/misc/toolbar-fullscreen.xml Mon Feb 05 22:51:19 2007 +0000
@@ -35,6 +35,7 @@
<end />
<control type="audio channel" />
<control type="volume" width="105" box-expand="1" box-fill="1" />
+ <image stock="gxine-settings-volume" />
<control type="mute" />
</hbox>
</vbox>
diff -r 6c337d2f29ef69b9c8fab491ebe8c1d5cb602455 -r
90b992be48a01f70d5e5a4911190d4a37b32ce1d misc/toolbar-window.xml
--- a/misc/toolbar-window.xml Mon Feb 05 23:03:26 2007 +0000
+++ b/misc/toolbar-window.xml Mon Feb 05 22:51:19 2007 +0000
@@ -33,7 +33,8 @@
<label text="" box-expand="1"/>
<end />
<control type="audio channel" />
- <control type="volume" width="105" box-expand="1" box-fill="1" />
+ <control type="volume" vertical="1" popup="1" window-height="120"
+ inverse="1" image="gxine-settings-volume" relief="none" />
<control type="mute" />
</hbox>
</vbox>
diff -r 6c337d2f29ef69b9c8fab491ebe8c1d5cb602455 -r
90b992be48a01f70d5e5a4911190d4a37b32ce1d src/xml_widgets.c
--- a/src/xml_widgets.c Mon Feb 05 23:03:26 2007 +0000
+++ b/src/xml_widgets.c Mon Feb 05 22:51:19 2007 +0000
@@ -362,7 +362,15 @@ static GtkWidget *create_box (xml_node_t
*/
static GtkWidget *
-create_button (xml_node_t *node)
+gxine_toggle_button_new_from_stock (const char *stock)
+{
+ GtkWidget *btn = gtk_toggle_button_new_with_label (stock);
+ gtk_button_set_use_stock (GTK_BUTTON (btn), TRUE);
+ return btn;
+}
+
+static GtkWidget *
+create_button (xml_node_t *node, gboolean click)
/* Properties:
* stock string none stock item
* label string none text if stock is not set
[translatable]
@@ -380,6 +388,18 @@ create_button (xml_node_t *node)
#ifndef MAKE_TRANSLATION_SOURCE
GtkWidget *button;
static const char *relief[] = { "none", "half", NULL };
+
+ typedef GtkWidget *(*button_new_t) (const char *);
+ typedef GtkWidget *(*plain_new_t) (void);
+ static const struct {
+ button_new_t stock[2], mnemonic[2], label[2];
+ plain_new_t plain[2];
+ } newbtn = {
+ { gxine_toggle_button_new_from_stock, gtk_button_new_from_stock },
+ { gtk_toggle_button_new_with_mnemonic, gtk_button_new_with_mnemonic },
+ { gtk_toggle_button_new_with_label, gtk_button_new_with_label },
+ { gtk_toggle_button_new, gtk_button_new },
+ };
#endif
alt = xml_parser_get_property (node, "alt");
@@ -395,14 +415,14 @@ create_button (xml_node_t *node)
return NULL;
#else
if (check_stock (image))
- button = gtk_button_new_from_stock (image);
+ button = newbtn.stock[click] (image);
else if (alt)
button = xml_parser_get_bool (node, "mnemonic")
- ? gtk_button_new_with_mnemonic (TRANSLATE (alt))
- : gtk_button_new_with_label (TRANSLATE (alt));
+ ? newbtn.mnemonic[click] (TRANSLATE (alt))
+ : newbtn.label[click] (TRANSLATE (alt));
else
{
- button = gtk_button_new ();
+ button = newbtn.plain[click] ();
if (image)
g_object_set (G_OBJECT (button), "image",
check_stock (image)
@@ -441,12 +461,12 @@ create_button (xml_node_t *node)
if (label && !image)
{
button = xml_parser_get_bool (node, "mnemonic")
- ? gtk_button_new_with_mnemonic (TRANSLATE (label))
- : gtk_button_new_with_label (TRANSLATE (label));
+ ? newbtn.mnemonic[click] (TRANSLATE (label))
+ : newbtn.label[click] (TRANSLATE (label));
goto created;
}
- button = gtk_button_new ();
+ button = newbtn.plain[click] ();
if (label || image)
{
g_object_set (G_OBJECT (button),
@@ -487,11 +507,14 @@ create_button (xml_node_t *node)
created:
gtk_button_set_relief (GTK_BUTTON (button),
2 - lookup_type (node, "relief", relief));
- /* set the command which is executed when the button is clicked */
- label = xml_parser_get_property (node, "onclick");
- if (label)
- command_attach (button, "clicked", "js-onclick", label,
- _("XML button click"));
+ if (click)
+ {
+ /* set the command which is executed when the button is clicked */
+ label = xml_parser_get_property (node, "onclick");
+ if (label)
+ command_attach (button, "clicked", "js-onclick", label,
+ _("XML button click"));
+ }
return button;
#endif /* ! MAKE_TRANSLATION_SOURCE */
}
@@ -557,6 +580,106 @@ set_tip (GtkWidget *w, const stock_t *st
TRANSLATE (*stock->tip ? stock->tip : stock->name),
NULL);
}
+
+static gboolean
+slider_button_cb (GtkWidget *widget, GdkEventButton *ev, gpointer data)
+{
+ gtk_grab_remove (widget);
+ gdk_keyboard_ungrab (ev->time);
+ gdk_pointer_ungrab (ev->time);
+ gtk_widget_hide (widget);
+ gtk_toggle_button_set_active (data, FALSE);
+ return FALSE;
+}
+
+static gboolean
+slider_widget_button_cb (GtkWidget *widget, GdkEventButton *ev, gpointer data)
+{
+ return slider_button_cb (gtk_widget_get_toplevel (widget), ev, data);
+}
+
+#include <gdk/gdkkeysyms.h>
+static gboolean
+slider_key_cb (GtkWidget *window, GdkEventKey *ev, gpointer data)
+{
+ switch (ev->keyval)
+ {
+ case GDK_Escape:
+ case GDK_KP_Enter:
+ case GDK_Return:
+ case GDK_space:
+ return slider_button_cb (window, (GdkEventButton *) ev, data);
+ default:
[... 3 lines omitted ...]
+
+static gboolean
+slider_window_cb (GtkWidget *button, gpointer window)
+{
+ if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)))
+ return FALSE;
+
+ gtk_window_set_transient_for (window,
+ GTK_WINDOW (gtk_widget_get_toplevel (button)));
+
+ GdkWindow *parent = gtk_widget_get_parent_window (button);
+ GtkAllocation ppos;
+ gdk_window_get_position (parent, &ppos.x, &ppos.y);
+ gdk_drawable_get_size (GDK_DRAWABLE (parent), &ppos.width, &ppos.height);
+
+ GdkScreen *screen = gtk_widget_get_screen (button);
+ gint monitor = gdk_screen_get_monitor_at_window (screen, parent);
+ GdkRectangle geom;
+ gdk_screen_get_monitor_geometry (screen, monitor, &geom);
+
+ gint wx, wy;
+ GtkRequisition req;
+ gtk_widget_size_request (window, &req);
+ gtk_window_get_default_size (window, &wx, &wy);
+ if (wx > req.width)
+ req.width = wx;
+ if (wy > req.height)
+ req.height = wy;
+
+ wx = button->allocation.x + ppos.x; /* button left */
+ wy = button->allocation.y + ppos.y; /* button top */
+
+ if (GTK_IS_VSCALE (((GtkBin *) window)->child))
+ {
+ /* arrange vertically, preferably below */
+ wx += (button->allocation.width - req.width) / 2; /* centre-aligned */
+ wy += (wy + req.height + button->allocation.height > geom.y + geom.height)
+ ? -req.height /* below (if enough space) */
+ : button->allocation.height; /* above */
+ }
+ else if (gtk_widget_get_default_direction () == GTK_TEXT_DIR_RTL)
+ {
+ /* arrange vertically, preferably to the left (RTL) */
+ wx -= (wx - req.width < geom.x)
+ ? -button->allocation.width /* left (if enough space) */
+ : req.width; /* right */
+ wy += (button->allocation.height - req.height) / 2; /* centre-aligned */
+ }
+ else
+ {
+ /* arrange vertically, preferably to the right (LTR) */
+ wx += (wx + req.width + button->allocation.width > geom.x + geom.width)
+ ? -req.width /* right (if enough space) */
+ : button->allocation.width; /* left */
+ wy += (button->allocation.height - req.height) / 2; /* centre-aligned */
+ }
+
+ gtk_window_move (GTK_WINDOW (window), wx, wy);
+ gtk_widget_show_all (window);
+
+ gdk_keyboard_grab (((GtkWidget *)window)->window, TRUE, GDK_CURRENT_TIME);
+ gdk_pointer_grab (((GtkWidget *)window)->window, TRUE,
+ GDK_BUTTON_RELEASE_MASK, NULL, NULL, GDK_CURRENT_TIME);
+ gtk_grab_add (window);
+
+ return TRUE;
+}
#endif
static GtkWidget *
@@ -564,7 +687,12 @@ create_stock_gxine (xml_node_t *node)
/* Properties:
* type string none widget identifer (see stock[].name)
* vertical bool FALSE slider orientation
+ * inverted bool FALSE slider direction reversal
* show-value bool FALSE show slider value numerically
+ * popup bool FALSE slider is a popup
+ * (use button properties except onclick)
+ * window-width int -1 popup window width
+ * window-height int -1 popup window height
*/
{
#ifndef MAKE_TRANSLATION_SOURCE
@@ -685,10 +813,35 @@ create_stock_gxine (xml_node_t *node)
if (GTK_IS_SCALE (w))
{
+ gtk_scale_set_digits (GTK_SCALE (w), 0);
gtk_scale_set_draw_value
(GTK_SCALE (w), xml_parser_get_bool (node, "show-value"));
gtk_range_set_inverted
(GTK_RANGE (w), xml_parser_get_bool (node, "inverted"));
+ if (xml_parser_get_bool (node, "popup"))
+ {
+ GtkWindow *window = GTK_WINDOW (gtk_window_new (GTK_WINDOW_POPUP));
+ gtk_window_set_default_size (window,
+ xml_parser_get_property_int (node, "window-width", -1),
+ xml_parser_get_property_int (node, "window-height", -1));
+ gtk_window_set_decorated (window, FALSE);
+ gtk_window_set_skip_pager_hint (window, TRUE);
+ gtk_window_set_skip_taskbar_hint (window, TRUE);
+ gtk_container_add (GTK_CONTAINER (window), w);
+ gtk_widget_add_events ((GtkWidget *)window, GDK_BUTTON_RELEASE_MASK);
+ gtk_widget_show (w);
+ GtkWidget *btn = create_button (node, FALSE);
+ g_object_connect (G_OBJECT (window),
+ "signal::destroy-event", gtk_widget_hide_on_delete, btn,
+ "signal::button-release-event", G_CALLBACK (slider_button_cb), btn,
+ "signal::key-press-event", G_CALLBACK (slider_key_cb), btn,
+ NULL);
+ g_signal_connect (G_OBJECT (w), "button-release-event",
+ G_CALLBACK (slider_widget_button_cb), btn);
+ g_signal_connect (G_OBJECT (btn), "toggled",
+ G_CALLBACK (slider_window_cb), window);
+ w = btn; /* for popups, we return the button, not the slider */
+ }
}
else
gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (w), TRUE);
@@ -990,7 +1143,7 @@ widget_parse (xml_node_t *node)
case 'b':
if (!strcasecmp (node->name + 1, "utton"))
- widget = create_button (node);
+ widget = create_button (node, TRUE);
break;
case 'c':
-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier.
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
Xine-cvslog mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/xine-cvslog