Commit 7641c6f9 authored by Havoc Pennington's avatar Havoc Pennington Committed by Havoc Pennington
Browse files

Button-reordering patch. Has all the code except actually installing a

2002-10-03  Havoc Pennington  <hp@pobox.com>

        Button-reordering patch. Has all the code except actually
	installing a gconf schema and reading the gconf key in prefs.c.
	metacity-theme-viewer displays the button layouts for testing
	themes.

	* src/preview-widget.c (meta_preview_size_request): make up a
	width/height if no child widget

	* src/prefs.c (meta_prefs_get_button_layout): new function

	* src/frames.c: get the button layout from prefs and
	use it when drawing

	* src/theme.c (meta_frame_layout_calc_geometry): enhance to be
	able to lay out buttons in different arrangements
	(button_rect): draw the new button background rectangles
	(meta_theme_draw_frame): require a button layout argument
	(meta_theme_calc_geometry): pass in the button layout

	* src/preview-widget.h: mod to handle button layouts

	* src/theme-viewer.c: mod to handle button layouts
parent 261c9a74
2002-10-03 Havoc Pennington <hp@pobox.com>
Button-reordering patch. Has all the code except actually
installing a gconf schema and reading the gconf key in prefs.c.
metacity-theme-viewer displays the button layouts for testing
themes.
* src/preview-widget.c (meta_preview_size_request): make up a
width/height if no child widget
* src/prefs.c (meta_prefs_get_button_layout): new function
* src/frames.c: get the button layout from prefs and
use it when drawing
* src/theme.c (meta_frame_layout_calc_geometry): enhance to be
able to lay out buttons in different arrangements
(button_rect): draw the new button background rectangles
(meta_theme_draw_frame): require a button layout argument
(meta_theme_calc_geometry): pass in the button layout
* src/preview-widget.h: mod to handle button layouts
* src/theme-viewer.c: mod to handle button layouts
2002-10-03 Havoc Pennington <hp@redhat.com>
* configure.in: 2.4.2
......
......@@ -117,7 +117,6 @@ typedef enum
META_GRAB_OP_CLICKING_MENU
} MetaGrabOp;
typedef enum
{
META_CURSOR_DEFAULT,
......@@ -169,6 +168,32 @@ typedef enum
META_VIRTUAL_MOD5_MASK = 1 << 14
} MetaVirtualModifier;
/* Function a window button can have. Note, you can't add stuff here
* without extending the theme format to draw a new function and
* breaking all existing themes.
*/
typedef enum
{
META_BUTTON_FUNCTION_MENU,
META_BUTTON_FUNCTION_MINIMIZE,
META_BUTTON_FUNCTION_MAXIMIZE,
META_BUTTON_FUNCTION_CLOSE,
META_BUTTON_FUNCTION_LAST
} MetaButtonFunction;
#define MAX_BUTTONS_PER_CORNER META_BUTTON_FUNCTION_LAST
typedef struct _MetaButtonLayout MetaButtonLayout;
struct _MetaButtonLayout
{
/* buttons in the group on the left side */
MetaButtonFunction left_buttons[MAX_BUTTONS_PER_CORNER];
/* buttons in the group on the right side */
MetaButtonFunction right_buttons[MAX_BUTTONS_PER_CORNER];
};
/* should investigate changing these to whatever most apps use */
#define META_ICON_WIDTH 32
#define META_ICON_HEIGHT 32
......
......@@ -73,7 +73,9 @@ static void meta_frames_ensure_layout (MetaFrames *frames,
static MetaUIFrame* meta_frames_lookup_window (MetaFrames *frames,
Window xwindow);
static void meta_frames_font_changed (MetaFrames *frames);
static void meta_frames_font_changed (MetaFrames *frames);
static void meta_frames_button_layout_changed (MetaFrames *frames);
static GdkRectangle* control_rect (MetaFrameControl control,
MetaFrameGeometry *fgeom);
......@@ -161,12 +163,19 @@ unsigned_long_hash (gconstpointer v)
}
static void
font_changed_callback (MetaPreference pref,
void *data)
prefs_changed_callback (MetaPreference pref,
void *data)
{
if (pref == META_PREF_TITLEBAR_FONT)
switch (pref)
{
case META_PREF_TITLEBAR_FONT:
meta_frames_font_changed (META_FRAMES (data));
break;
case META_PREF_BUTTON_LAYOUT:
meta_frames_button_layout_changed (META_FRAMES (data));
break;
default:
break;
}
}
......@@ -185,7 +194,7 @@ meta_frames_init (MetaFrames *frames)
gtk_widget_set_double_buffered (GTK_WIDGET (frames), FALSE);
meta_prefs_add_listener (font_changed_callback, frames);
meta_prefs_add_listener (prefs_changed_callback, frames);
}
static void
......@@ -237,7 +246,7 @@ meta_frames_finalize (GObject *object)
frames = META_FRAMES (object);
meta_prefs_remove_listener (font_changed_callback, frames);
meta_prefs_remove_listener (prefs_changed_callback, frames);
g_hash_table_destroy (frames->text_heights);
......@@ -292,6 +301,31 @@ meta_frames_font_changed (MetaFrames *frames)
}
static void
queue_draw_func (gpointer key, gpointer value, gpointer data)
{
MetaUIFrame *frame;
MetaFrames *frames;
frames = META_FRAMES (data);
frame = value;
/* If a resize occurs it will cause a redraw, but the
* resize may not actually be needed so we always redraw
* in case of color change.
*/
gtk_style_set_background (GTK_WIDGET (frames)->style,
frame->window, GTK_STATE_NORMAL);
gdk_window_invalidate_rect (frame->window, NULL, FALSE);
}
static void
meta_frames_button_layout_changed (MetaFrames *frames)
{
g_hash_table_foreach (frames->frames,
queue_draw_func, frames);
}
static void
meta_frames_style_set (GtkWidget *widget,
GtkStyle *prev_style)
......@@ -394,6 +428,7 @@ meta_frames_calc_geometry (MetaFrames *frames,
int width, height;
MetaFrameFlags flags;
MetaFrameType type;
MetaButtonLayout button_layout;
meta_core_get_client_size (gdk_display, frame->xwindow,
&width, &height);
......@@ -402,12 +437,15 @@ meta_frames_calc_geometry (MetaFrames *frames,
type = meta_core_get_frame_type (gdk_display, frame->xwindow);
meta_frames_ensure_layout (frames, frame);
meta_prefs_get_button_layout (&button_layout);
meta_theme_calc_geometry (meta_theme_get_current (),
type,
frame->text_height,
flags,
width, height,
&button_layout,
fgeom);
}
......@@ -1524,6 +1562,7 @@ meta_frames_paint_to_drawable (MetaFrames *frames,
GdkRectangle *areas;
int n_areas;
int screen_width, screen_height;
MetaButtonLayout button_layout;
widget = GTK_WIDGET (frames);
......@@ -1656,10 +1695,12 @@ meta_frames_paint_to_drawable (MetaFrames *frames,
/* Now draw remaining portion of region */
gdk_region_get_rectangles (edges, &areas, &n_areas);
meta_prefs_get_button_layout (&button_layout);
i = 0;
while (i < n_areas)
{
{
if (GDK_IS_WINDOW (drawable))
gdk_window_begin_paint_rect (drawable, &areas[i]);
......@@ -1673,6 +1714,7 @@ meta_frames_paint_to_drawable (MetaFrames *frames,
w, h,
frame->layout,
frame->text_height,
&button_layout,
button_states,
mini_icon, icon);
......
......@@ -799,6 +799,10 @@ meta_preference_to_string (MetaPreference pref)
case META_PREF_COMMANDS:
return "COMMANDS";
case META_PREF_BUTTON_LAYOUT:
return "BUTTON_LAYOUT";
break;
}
return "(unknown)";
......@@ -1142,6 +1146,27 @@ meta_prefs_get_gconf_key_for_command (int i)
return key;
}
void
meta_prefs_get_button_layout (MetaButtonLayout *button_layout)
{
/* FIXME */
int i;
i = 0;
while (i < MAX_BUTTONS_PER_CORNER)
{
button_layout->left_buttons[i] = META_BUTTON_FUNCTION_LAST;
button_layout->right_buttons[i] = META_BUTTON_FUNCTION_LAST;
++i;
}
button_layout->left_buttons[0] = META_BUTTON_FUNCTION_MENU;
button_layout->right_buttons[0] = META_BUTTON_FUNCTION_MINIMIZE;
button_layout->right_buttons[1] = META_BUTTON_FUNCTION_MAXIMIZE;
button_layout->right_buttons[2] = META_BUTTON_FUNCTION_CLOSE;
}
void
meta_prefs_get_screen_bindings (const MetaKeyPref **bindings,
int *n_bindings)
......
......@@ -38,7 +38,8 @@ typedef enum
META_PREF_WINDOW_KEYBINDINGS,
META_PREF_SCREEN_KEYBINDINGS,
META_PREF_DISABLE_WORKAROUNDS,
META_PREF_COMMANDS
META_PREF_COMMANDS,
META_PREF_BUTTON_LAYOUT
} MetaPreference;
typedef void (* MetaPrefsChangedFunc) (MetaPreference pref,
......@@ -66,6 +67,8 @@ const char* meta_prefs_get_command (int i);
char* meta_prefs_get_gconf_key_for_command (int i);
void meta_prefs_get_button_layout (MetaButtonLayout *button_layout);
void meta_prefs_set_num_workspaces (int n_workspaces);
/* Screen bindings */
......
......@@ -79,8 +79,24 @@ meta_preview_class_init (MetaPreviewClass *class)
static void
meta_preview_init (MetaPreview *preview)
{
int i;
GTK_WIDGET_SET_FLAGS (preview, GTK_NO_WINDOW);
i = 0;
while (i < MAX_BUTTONS_PER_CORNER)
{
preview->button_layout.left_buttons[i] = META_BUTTON_FUNCTION_LAST;
preview->button_layout.right_buttons[i] = META_BUTTON_FUNCTION_LAST;
++i;
}
preview->button_layout.left_buttons[0] = META_BUTTON_FUNCTION_MENU;
preview->button_layout.right_buttons[0] = META_BUTTON_FUNCTION_MINIMIZE;
preview->button_layout.right_buttons[1] = META_BUTTON_FUNCTION_MAXIMIZE;
preview->button_layout.right_buttons[2] = META_BUTTON_FUNCTION_CLOSE;
preview->type = META_FRAME_TYPE_NORMAL;
preview->flags =
META_FRAME_ALLOWS_DELETE |
......@@ -218,7 +234,7 @@ meta_preview_expose (GtkWidget *widget,
if (client_width < 0)
client_width = 1;
if (client_height < 0)
client_height = 1;
client_height = 1;
if (preview->theme)
{
......@@ -235,6 +251,7 @@ meta_preview_expose (GtkWidget *widget,
client_width, client_height,
preview->layout,
preview->text_height,
&preview->button_layout,
button_states,
meta_preview_get_mini_icon (),
meta_preview_get_icon ());
......@@ -267,6 +284,13 @@ meta_preview_size_request (GtkWidget *widget,
req->width += child_requisition.width;
req->height += child_requisition.height;
}
else
{
#define NO_CHILD_WIDTH 80
#define NO_CHILD_HEIGHT 20
req->width += NO_CHILD_WIDTH;
req->height += NO_CHILD_HEIGHT;
}
req->width += GTK_CONTAINER (widget)->border_width * 2;
req->height += GTK_CONTAINER (widget)->border_width * 2;
......@@ -369,6 +393,17 @@ meta_preview_set_frame_flags (MetaPreview *preview,
gtk_widget_queue_resize (GTK_WIDGET (preview));
}
void
meta_preview_set_button_layout (MetaPreview *preview,
const MetaButtonLayout *button_layout)
{
g_return_if_fail (META_IS_PREVIEW (preview));
preview->button_layout = *button_layout;
gtk_widget_queue_draw (GTK_WIDGET (preview));
}
#include "inlinepixbufs.h"
GdkPixbuf*
......
......@@ -52,6 +52,7 @@ struct _MetaPreview
int top_height;
int bottom_height;
MetaButtonLayout button_layout;
};
struct _MetaPreviewClass
......@@ -63,14 +64,17 @@ struct _MetaPreviewClass
GtkType meta_preview_get_type (void) G_GNUC_CONST;
GtkWidget* meta_preview_new (void);
void meta_preview_set_theme (MetaPreview *preview,
MetaTheme *theme);
void meta_preview_set_title (MetaPreview *preview,
const char *title);
void meta_preview_set_frame_type (MetaPreview *preview,
MetaFrameType type);
void meta_preview_set_frame_flags (MetaPreview *preview,
MetaFrameFlags flags);
void meta_preview_set_theme (MetaPreview *preview,
MetaTheme *theme);
void meta_preview_set_title (MetaPreview *preview,
const char *title);
void meta_preview_set_frame_type (MetaPreview *preview,
MetaFrameType type);
void meta_preview_set_frame_flags (MetaPreview *preview,
MetaFrameFlags flags);
void meta_preview_set_button_layout (MetaPreview *preview,
const MetaButtonLayout *button_layout);
GdkPixbuf* meta_preview_get_icon (void);
GdkPixbuf* meta_preview_get_mini_icon (void);
......
......@@ -28,6 +28,22 @@
#include <time.h>
#include <stdlib.h>
/* We need to compute all different button arrangements
* in terms of button location. We don't care about
* different arrangements in terms of button function.
*
* So if dups are allowed, from 0-4 buttons on the left, from 0-4 on
* the right, 5x5=25 combinations.
*
* If no dups, 0-4 on left determines the number on the right plus
* we have a special case for the "no buttons on either side" case.
*/
#ifndef ALLOW_DUPLICATE_BUTTONS
#define BUTTON_LAYOUT_COMBINATIONS (MAX_BUTTONS_PER_CORNER + 1 + 1)
#else
#define BUTTON_LAYOUT_COMBINATIONS ((MAX_BUTTONS_PER_CORNER+1)*(MAX_BUTTONS_PER_CORNER+1))
#endif
#define CLIENT_WIDTH 200
#define CLIENT_HEIGHT 200
......@@ -40,7 +56,7 @@ enum
};
static MetaTheme *global_theme = NULL;
static GtkWidget *previews[META_FRAME_TYPE_LAST*FONT_SIZE_LAST] = { NULL, };
static GtkWidget *previews[META_FRAME_TYPE_LAST*FONT_SIZE_LAST + BUTTON_LAYOUT_COMBINATIONS] = { NULL, };
static void run_position_expression_tests (void);
static void run_position_expression_timings (void);
......@@ -547,6 +563,190 @@ preview_collection (int font_size,
return sw;
}
static MetaButtonLayout different_layouts[BUTTON_LAYOUT_COMBINATIONS];
static void
init_layouts (void)
{
int i;
/* Blank out all the layouts */
i = 0;
while (i < (int) G_N_ELEMENTS (different_layouts))
{
int j;
j = 0;
while (j < MAX_BUTTONS_PER_CORNER)
{
different_layouts[i].left_buttons[j] = META_BUTTON_FUNCTION_LAST;
different_layouts[i].right_buttons[j] = META_BUTTON_FUNCTION_LAST;
++j;
}
++i;
}
#ifndef ALLOW_DUPLICATE_BUTTONS
i = 0;
while (i <= MAX_BUTTONS_PER_CORNER)
{
int j;
j = 0;
while (j < i)
{
different_layouts[i].right_buttons[j] = (MetaButtonFunction) j;
++j;
}
while (j < MAX_BUTTONS_PER_CORNER)
{
different_layouts[i].left_buttons[j-i] = (MetaButtonFunction) j;
++j;
}
++i;
}
/* Special extra case for no buttons on either side */
different_layouts[i].left_buttons[0] = META_BUTTON_FUNCTION_LAST;
different_layouts[i].right_buttons[0] = META_BUTTON_FUNCTION_LAST;
#else
/* FIXME this code is if we allow duplicate buttons,
* which we currently do not
*/
int left;
int i;
left = 0;
i = 0;
while (left < MAX_BUTTONS_PER_CORNER)
{
int right;
right = 0;
while (right < MAX_BUTTONS_PER_CORNER)
{
int j;
static MetaButtonFunction left_functions[MAX_BUTTONS_PER_CORNER] = {
META_BUTTON_FUNCTION_MENU,
META_BUTTON_FUNCTION_MINIMIZE,
META_BUTTON_FUNCTION_MAXIMIZE,
META_BUTTON_FUNCTION_CLOSE
};
static MetaButtonFunction right_functions[MAX_BUTTONS_PER_CORNER] = {
META_BUTTON_FUNCTION_MINIMIZE,
META_BUTTON_FUNCTION_MAXIMIZE,
META_BUTTON_FUNCTION_CLOSE,
META_BUTTON_FUNCTION_MENU
};
g_assert (i < BUTTON_LAYOUT_COMBINATIONS);
j = 0;
while (j <= left)
{
different_layouts[i].left_buttons[j] = left_functions[j];
++j;
}
j = 0;
while (j <= right)
{
different_layouts[i].right_buttons[j] = right_functions[j];
++j;
}
++i;
++right;
}
++left;
}
#endif
}
static GtkWidget*
previews_of_button_layouts (void)
{
static gboolean initted = FALSE;
GtkWidget *box;
GtkWidget *sw;
GdkColor desktop_color;
int i;
GtkWidget *eventbox;
if (!initted)
{
init_layouts ();
initted = TRUE;
}
sw = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
GTK_POLICY_AUTOMATIC,
GTK_POLICY_AUTOMATIC);
box = gtk_vbox_new (FALSE, 0);
gtk_box_set_spacing (GTK_BOX (box), 20);
gtk_container_set_border_width (GTK_CONTAINER (box), 20);
eventbox = gtk_event_box_new ();
gtk_container_add (GTK_CONTAINER (eventbox), box);
gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (sw), eventbox);
desktop_color.red = 0x5144;
desktop_color.green = 0x75D6;
desktop_color.blue = 0xA699;
gtk_widget_modify_bg (eventbox, GTK_STATE_NORMAL, &desktop_color);
i = 0;
while (i < BUTTON_LAYOUT_COMBINATIONS)
{
GtkWidget *align;
double xalign, yalign;
GtkWidget *eventbox2;
GtkWidget *preview;
char *title;
eventbox2 = gtk_event_box_new ();
preview = meta_preview_new ();
gtk_container_add (GTK_CONTAINER (eventbox2), preview);
meta_preview_set_theme (META_PREVIEW (preview), global_theme);
title = g_strdup_printf ("Button layout test %d", i+1);
meta_preview_set_title (META_PREVIEW (preview), title);
g_free (title);
meta_preview_set_button_layout (META_PREVIEW (preview),
&different_layouts[i]);
xalign = 0.5;
yalign = 0.5;
align = gtk_alignment_new (0.0, 0.0, xalign, yalign);
gtk_container_add (GTK_CONTAINER (align), eventbox2);
gtk_box_pack_start (GTK_BOX (box), align, TRUE, TRUE, 0);
previews[META_FRAME_TYPE_LAST*FONT_SIZE_LAST + i] = preview;
++i;
}
return sw;
}
int
main (int argc, char **argv)
{
......@@ -630,6 +830,11 @@ main (int argc, char **argv)
collection,
gtk_label_new ("Large Title Font"));
collection = previews_of_button_layouts ();
gtk_notebook_append_page (GTK_NOTEBOOK (notebook),
collection,
gtk_label_new ("Button Layouts"));
i = 0;
while (i < (int) G_N_ELEMENTS (previews))
{
......@@ -698,6 +903,7 @@ run_theme_benchmark (int client_width,
clock_t start;
clock_t end;
int i;
MetaButtonLayout button_layout;
#define ITERATIONS 100
widget = gtk_window_new (GTK_WINDOW_TOPLEVEL);
......@@ -718,7 +924,21 @@ run_theme_benchmark (int client_width,
-1);
layout = create_title_layout (widget);
i = 0;
while (i < MAX_BUTTONS_PER_CORNER)
{
button_layout.left_buttons[i] = META_BUTTON_FUNCTION_LAST;
button_layout.right_buttons[i] = META_BUTTON_FUNCTION_LAST;
++i;
}
button_layout.left_buttons[0] = META_BUTTON_FUNCTION_MENU;
button_layout.right_buttons[0] = META_BUTTON_FUNCTION_MINIMIZE;
button_layout.right_buttons[1] = META_BUTTON_FUNCTION_MAXIMIZE;
button_layout.right_buttons[2] = META_BUTTON_FUNCTION_CLOSE;
start = clock ();