* Useful resources:
*
* http://lxr.mozilla.org/mozilla/source/gfx/src/windows/nsNativeThemeWin.cpp
+ * http://lxr.mozilla.org/seamonkey/source/widget/src/windows/nsLookAndFeel.cpp
* http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/commctls/userex/functions/drawthemebackground.asp
*/
#define PART_SIZE 13
-static const char check_aa_bits[] = {
+static const guint8 check_aa_bits[] = {
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
-static const char check_base_bits[] = {
+static const guint8 check_base_bits[] = {
0x00,0x00,0x00,0x00,0xfc,0x07,0xfc,0x07,0xfc,0x07,0xfc,0x07,0xfc,0x07,0xfc,
0x07,0xfc,0x07,0xfc,0x07,0xfc,0x07,0x00,0x00,0x00,0x00};
-static const char check_black_bits[] = {
+static const guint8 check_black_bits[] = {
0x00,0x00,0xfe,0x0f,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,
0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x00,0x00};
-static const char check_dark_bits[] = {
+static const guint8 check_dark_bits[] = {
0xff,0x1f,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,
0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00};
-static const char check_light_bits[] = {
+static const guint8 check_light_bits[] = {
0x00,0x00,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,
0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0xfe,0x1f};
-static const char check_mid_bits[] = {
+static const guint8 check_mid_bits[] = {
0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,
0x08,0x00,0x08,0x00,0x08,0x00,0x08,0xfc,0x0f,0x00,0x00};
-static const char check_text_bits[] = {
+static const guint8 check_text_bits[] = {
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x03,0x88,0x03,0xd8,0x01,0xf8,
0x00,0x70,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
-static const char radio_base_bits[] = {
+static const guint8 radio_base_bits[] = {
0x00,0x00,0x00,0x00,0xf0,0x01,0xf8,0x03,0xfc,0x07,0xfc,0x07,0xfc,0x07,0xfc,
0x07,0xfc,0x07,0xf8,0x03,0xf0,0x01,0x00,0x00,0x00,0x00};
-static const char radio_black_bits[] = {
+static const guint8 radio_black_bits[] = {
0x00,0x00,0xf0,0x01,0x0c,0x02,0x04,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,
0x00,0x02,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
-static const char radio_dark_bits[] = {
+static const guint8 radio_dark_bits[] = {
0xf0,0x01,0x0c,0x06,0x02,0x00,0x02,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,
0x00,0x01,0x00,0x02,0x00,0x02,0x00,0x00,0x00,0x00,0x00};
-static const char radio_light_bits[] = {
+static const guint8 radio_light_bits[] = {
0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x08,0x00,0x10,0x00,0x10,0x00,0x10,0x00,
0x10,0x00,0x10,0x00,0x08,0x00,0x08,0x0c,0x06,0xf0,0x01};
-static const char radio_mid_bits[] = {
+static const guint8 radio_mid_bits[] = {
0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x04,0x00,0x08,0x00,0x08,0x00,0x08,0x00,
0x08,0x00,0x08,0x00,0x04,0x0c,0x06,0xf0,0x01,0x00,0x00};
-static const char radio_text_bits[] = {
+static const guint8 radio_text_bits[] = {
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0xf0,0x01,0xf0,0x01,0xf0,
0x01,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
static struct {
- const char *bits;
+ const guint8 *bits;
GdkBitmap *bmap;
} parts[] = {
{ check_aa_bits, NULL },
get_system_font(XpThemeClass klazz, XpThemeFont type, LOGFONT *out_lf)
{
#if 0
- /* TODO: this crashes. need to figure out why and how to fix it */
+ /* TODO: this causes crashes later because the font name is in UCS2, and the pango fns don't deal with that gracefully */
if (xp_theme_get_system_font(klazz, type, out_lf))
return TRUE;
else
gchar *string = NULL;
gchar *name;
- gint i, l;
- gsize nbytes;
+ size_t i, l, nbytes;
/* If lfFaceName is ASCII, assume it is the common (English) name
* for the font. Is this valid? Do some TrueType fonts have
if ((hfont = CreateFontIndirect (lfp)) == NULL)
goto fail0;
- if ((oldhfont = SelectObject (pango_win32_hdc, hfont)) == NULL)
+ if ((oldhfont = (HFONT)SelectObject (pango_win32_hdc, hfont)) == NULL)
goto fail1;
if (!pango_win32_get_name_header (pango_win32_hdc, &header))
static void
setup_msw_rc_style(void)
{
- /* TODO: Owen says:
- "If your setup_system_styles() function called gtk_rc_parse_string(), then you are just piling a new set of strings on top each time the theme changes .. the old ones won't be removed" */
-
char buf[1024], font_buf[256], *font_ptr;
GdkColor menu_color;
GdkColor base_prelight;
GdkColor text_prelight;
+ gboolean xp_theme = xp_theme_is_active();
+
/* Prelight */
sys_color_to_gtk_color(XP_THEME_CLASS_TEXT, COLOR_HIGHLIGHTTEXT, &fg_prelight);
sys_color_to_gtk_color(XP_THEME_CLASS_TEXT, COLOR_HIGHLIGHT, &bg_prelight);
"style \"msw-menu-bar\" = \"msw-menu\"\n"
"{\n"
"bg[NORMAL] = { %d, %d, %d }\n"
- "GtkMenuBar::shadow-type = out\n"
+ "GtkMenuBar::shadow-type = %s\n"
"}widget_class \"*MenuBar*\" style \"msw-menu-bar\"\n",
btn_face.red,
btn_face.green,
- btn_face.blue);
+ btn_face.blue,
+ (xp_theme ? "etched-in" : "out"));
+ gtk_rc_parse_string(buf);
+
+ g_snprintf(buf, sizeof (buf),
+ "style \"msw-toolbar\" = \"msw-default\"\n"
+ "{\n"
+ "GtkHandleBox::shadow-type = %s\n"
+ "GtkToolbar::shadow-type = %s\n"
+ "}widget_class \"*HandleBox*\" style \"msw-toolbar\"\n",
+ (xp_theme ? "none" : "out"),
+ (xp_theme ? "none" : "out"));
gtk_rc_parse_string(buf);
/* enable tooltip fonts */
"GtkRange::stepper-size = %d\n"
"GtkRange::stepper-spacing = 0\n"
"GtkRange::trough_border = 0\n"
- "}widget_class \"*VScrollbar*\" style \"msw-vscrollbar\"\n",
+ "GtkScale::slider-length = %d\n"
+ "}widget_class \"*VScrollbar*\" style \"msw-vscrollbar\"\n"
+ "widget_class \"*VScale*\" style \"msw-vscrollbar\"\n",
GetSystemMetrics(SM_CYVTHUMB),
- get_system_metric(XP_THEME_CLASS_SCROLLBAR, SM_CXVSCROLL));
+ get_system_metric(XP_THEME_CLASS_SCROLLBAR, SM_CXVSCROLL),
+ 11);
gtk_rc_parse_string(buf);
g_snprintf(buf, sizeof (buf),
"GtkRange::stepper-size = %d\n"
"GtkRange::stepper-spacing = 0\n"
"GtkRange::trough_border = 0\n"
- "}widget_class \"*HScrollbar*\" style \"msw-hscrollbar\"\n",
+ "GtkScale::slider-length = %d\n"
+ "}widget_class \"*HScrollbar*\" style \"msw-hscrollbar\"\n"
+ "widget_class \"*HScale*\" style \"msw-hscrollbar\"\n",
GetSystemMetrics(SM_CXHTHUMB),
- get_system_metric(XP_THEME_CLASS_SCROLLBAR, SM_CYHSCROLL));
+ get_system_metric(XP_THEME_CLASS_SCROLLBAR, SM_CYHSCROLL),
+ 11);
gtk_rc_parse_string(buf);
/* radio/check button sizes */
return;
}
}
-
else if (detail && !strcmp (detail, "slider"))
{
if (GTK_IS_SCROLLBAR(widget))
{
GtkScrollbar * scrollbar = GTK_SCROLLBAR(widget);
gboolean is_v = GTK_IS_VSCROLLBAR(widget);
+
if (xp_theme_draw(window,
is_v
? XP_THEME_ELEMENT_SCROLLBAR_V
{
gboolean is_vertical = GTK_IS_VSCROLLBAR(widget);
- if (GTK_IS_RANGE(widget)
- && xp_theme_draw(window,
+ if (xp_theme_draw(window,
is_vertical
? XP_THEME_ELEMENT_TROUGH_V
: XP_THEME_ELEMENT_TROUGH_H,
{
gboolean is_vertical = GTK_IS_VSCALE(widget);
- parent_class->draw_box (style, window, state_type, GTK_SHADOW_NONE, area,
+ if(!xp_theme_is_active ()) {
+ parent_class->draw_box (style, window, state_type, GTK_SHADOW_NONE, area,
widget, detail, x, y, width, height);
+ }
- if(is_vertical)
- parent_class->draw_box(style, window, state_type, GTK_SHADOW_ETCHED_IN, area, NULL, NULL, (2 * x + width)/2, y, 1, height);
- else
- parent_class->draw_box(style, window, state_type, GTK_SHADOW_ETCHED_IN, area, NULL, NULL, x, (2 * y + height)/2, width, 1);
+ if(is_vertical) {
+ if(xp_theme_draw(window, XP_THEME_ELEMENT_SCALE_TROUGH_V, style, (2 * x + width)/2, y, 2, height, state_type, area))
+ return;
+
+ parent_class->draw_box(style, window, state_type, GTK_SHADOW_ETCHED_IN, area, NULL, NULL, (2 * x + width)/2, y, 1, height);
+ }
+ else {
+ if(xp_theme_draw(window, XP_THEME_ELEMENT_SCALE_TROUGH_H, style, x, (2 * y + height)/2, width, 2, state_type, area))
+ return;
+ parent_class->draw_box(style, window, state_type, GTK_SHADOW_ETCHED_IN, area, NULL, NULL, x, (2 * y + height)/2, width, 1);
+ }
return;
}
}
}
}
else if (detail && (strcmp (detail, "vscrollbar") == 0 || strcmp (detail, "hscrollbar") == 0))
- {
- GtkScrollbar * scrollbar = GTK_SCROLLBAR(widget);
- if (shadow_type == GTK_SHADOW_IN)
- shadow_type = GTK_SHADOW_ETCHED_IN;
- if (scrollbar->range.adjustment->page_size >= (scrollbar->range.adjustment->upper-scrollbar->range.adjustment->lower))
- shadow_type = GTK_SHADOW_OUT;
- }
- else if (detail && strcmp (detail, "handlebox_bin") == 0)
- {
+ {
+ GtkScrollbar * scrollbar = GTK_SCROLLBAR(widget);
+ if (shadow_type == GTK_SHADOW_IN)
+ shadow_type = GTK_SHADOW_ETCHED_IN;
+ if (scrollbar->range.adjustment->page_size >= (scrollbar->range.adjustment->upper-scrollbar->range.adjustment->lower))
+ shadow_type = GTK_SHADOW_OUT;
+ }
+ else if (detail && (strcmp (detail, "handlebox_bin") == 0 || strcmp (detail, "toolbar") == 0 ||
+ strcmp (detail, "menubar") == 0))
+ {
if (xp_theme_draw(window, XP_THEME_ELEMENT_REBAR,
style, x, y, width, height, state_type, area))
{
return;
}
- }
- else
+ }
+ else if (detail &&
+ (!strcmp(detail, "handlebox"))) /* grip */
{
- const gchar * name = gtk_widget_get_name (widget);
-
- if (name && !strcmp (name, "gtk-tooltips")) {
- if (xp_theme_draw (window, XP_THEME_ELEMENT_TOOLTIP, style, x, y, width, height, state_type, area))
- {
- return;
- }
- else {
- HBRUSH brush;
- gint xoff, yoff;
- GdkDrawable *drawable;
- RECT rect;
- HDC hdc;
-
- if (!GDK_IS_WINDOW(window))
- {
- xoff = 0;
- yoff = 0;
- drawable = window;
- }
- else
- {
- gdk_window_get_internal_paint_info(window, &drawable, &xoff, &yoff);
- }
-
- rect.left = x - xoff;
- rect.top = y - yoff;
- rect.right = rect.left + width;
- rect.bottom = rect.top + height;
-
- hdc = gdk_win32_hdc_get(window, style->dark_gc[state_type], 0);
- brush = GetSysColorBrush(COLOR_3DDKSHADOW);
- if (brush)
- FrameRect(hdc, &rect, brush);
- InflateRect(&rect, -1, -1);
- FillRect(hdc, &rect, (HBRUSH) (COLOR_INFOBK+1));
-
- return;
- }
- }
}
+ else
+ {
+ const gchar * name = gtk_widget_get_name (widget);
+
+ if (name && !strcmp (name, "gtk-tooltips")) {
+ if (xp_theme_draw (window, XP_THEME_ELEMENT_TOOLTIP, style, x, y, width, height, state_type, area))
+ {
+ return;
+ }
+ else {
+ HBRUSH brush;
+ gint xoff, yoff;
+ GdkDrawable *drawable;
+ RECT rect;
+ HDC hdc;
+
+ if (!GDK_IS_WINDOW(window))
+ {
+ xoff = 0;
+ yoff = 0;
+ drawable = window;
+ }
+ else
+ {
+ gdk_window_get_internal_paint_info(window, &drawable, &xoff, &yoff);
+ }
+
+ rect.left = x - xoff;
+ rect.top = y - yoff;
+ rect.right = rect.left + width;
+ rect.bottom = rect.top + height;
+
+ hdc = gdk_win32_hdc_get(window, style->dark_gc[state_type], 0);
+ brush = GetSysColorBrush(COLOR_3DDKSHADOW);
+ if (brush)
+ FrameRect(hdc, &rect, brush);
+ InflateRect(&rect, -1, -1);
+ FillRect(hdc, &rect, (HBRUSH) (COLOR_INFOBK+1));
+
+ return;
+ }
+
+ }
+ }
parent_class->draw_box (style, window, state_type, shadow_type, area,
widget, detail, x, y, width, height);
{
GtkNotebook *notebook = GTK_NOTEBOOK(widget);
GtkPositionType pos_type = gtk_notebook_get_tab_pos(notebook);
+ gint x2, y2, w2, h2;
- if (pos_type == GTK_POS_TOP && state_type == GTK_STATE_NORMAL)
- height += XP_EDGE_SIZE;
-
-#if 0
- /* FIXME: pos != TOP to be implemented */
- else if (pos_type == GTK_POS_BOTTOM)
- y -= XP_EDGE_SIZE;
- else if (pos_type == GTK_POS_RIGHT)
- width += XP_EDGE_SIZE;
- else if (pos_type == GTK_POS_LEFT)
- height -= XP_EDGE_SIZE;
-#endif
+ x2 = x; y2 = y; w2 = width; h2 = height;
+ if (pos_type == GTK_POS_TOP && state_type == GTK_STATE_NORMAL) {
+ /*h2 += XP_EDGE_SIZE;*/
+ }
+ else if (pos_type == GTK_POS_BOTTOM && state_type == GTK_STATE_NORMAL) {
+ /*h2 += XP_EDGE_SIZE;*/
+ }
+ else if (pos_type == GTK_POS_LEFT && state_type == GTK_STATE_NORMAL) {
+ x2 += 1;
+ w2 -= XP_EDGE_SIZE;
+ }
+ else if (pos_type == GTK_POS_RIGHT && state_type == GTK_STATE_NORMAL) {
+ w2 -= (XP_EDGE_SIZE + 1);
+ }
- if (pos_type == GTK_POS_TOP
- && xp_theme_draw
+ if (xp_theme_draw
(window, gtk_notebook_get_current_page(notebook)==0
? XP_THEME_ELEMENT_TAB_ITEM_LEFT_EDGE
: XP_THEME_ELEMENT_TAB_ITEM,
- style, x, y, width, height, state_type, area))
+ style, x2, y2, w2, h2, state_type, area))
{
return;
}
gint x2,
gint y)
{
-
+#if 0
if (detail && !strcmp(detail, "menuitem")) {
if (xp_theme_draw(window, XP_THEME_ELEMENT_MENU_SEPARATOR, style,
x1, y, x2, style->ythickness, state_type, area)) {
return;
}
+ } else if (detail && !strcmp(detail, "toolbar")) {
+ if (xp_theme_draw(window, XP_THEME_ELEMENT_TOOLBAR_SEPARATOR_H, style,
+ x1, y, x2, style->ythickness, state_type, area)) {
+ return;
+ }
}
+ if(xp_theme_draw(window, XP_THEME_ELEMENT_LINE_H, style, x1, y, x2, style->ythickness, state_type, area))
+ return;
+#endif
+
parent_class->draw_hline (style, window, state_type, area, widget,
detail, x1, x2, y);
}
gint y2,
gint x)
{
+#if 0
+ if (detail && !strcmp(detail, "toolbar")) {
+ if (xp_theme_draw(window, XP_THEME_ELEMENT_TOOLBAR_SEPARATOR_V, style,
+ x, y1, style->xthickness, y2, state_type, area)) {
+ return;
+ }
+ }
+
+ if(xp_theme_draw(window, XP_THEME_ELEMENT_LINE_V, style, x, y1, style->xthickness, y2, state_type, area))
+ return;
+#endif
+
parent_class->draw_vline (style, window, state_type, area, widget,
detail, y1, y2, x);
}
+static void
+draw_slider (GtkStyle *style,
+ GdkWindow *window,
+ GtkStateType state_type,
+ GtkShadowType shadow_type,
+ GdkRectangle *area,
+ GtkWidget *widget,
+ const gchar *detail,
+ gint x,
+ gint y,
+ gint width,
+ gint height,
+ GtkOrientation orientation)
+{
+ if(GTK_IS_SCALE(widget) &&
+ xp_theme_draw(window, ((orientation == GTK_ORIENTATION_VERTICAL) ? XP_THEME_ELEMENT_SCALE_SLIDER_V : XP_THEME_ELEMENT_SCALE_SLIDER_H), style, x, y, width, height, state_type, area)) {
+ return;
+ }
+
+ parent_class->draw_slider (style, window, state_type, shadow_type, area, widget,
+ detail, x, y, width, height, orientation);
+}
+
static void
draw_resize_grip (GtkStyle *style,
GdkWindow *window,
gint height)
{
if (detail && !strcmp(detail, "statusbar")) {
-#if 0
- /* DAL: TODO: find out why this regressed */
if (xp_theme_draw(window, XP_THEME_ELEMENT_STATUS_GRIPPER, style, x, y, width, height,
state_type, area))
return;
-#endif
}
parent_class->draw_resize_grip (style, window, state_type, area,
{
return;
}
+ }
- /* grippers are just flat boxes when they're not a toolbar */
- parent_class->draw_box (style, window, state_type, shadow_type,
- area, widget, detail, x, y, width, height);
- }
- else if (!GTK_IS_PANED (widget))
- {
- /* TODO: Draw handle boxes as double lines: || */
- parent_class->draw_handle (style, window, state_type, shadow_type,
- area, widget, detail, x, y, width, height,
- orientation);
- }
-}
+ if (!GTK_IS_PANED(widget)) {
+ gint xthick, ythick;
+ GdkGC *light_gc, *dark_gc, *shadow_gc;
+ GdkRectangle dest;
-static GdkPixbuf *
-render_icon (GtkStyle *style,
- const GtkIconSource *source,
- GtkTextDirection direction,
- GtkStateType state,
- GtkIconSize size,
- GtkWidget *widget,
- const gchar *detail)
-{
- if (gtk_icon_source_get_state_wildcarded (source) && state == GTK_STATE_INSENSITIVE)
+ sanitize_size (window, &width, &height);
+
+ gtk_paint_box(style, window, state_type, shadow_type, area, widget,
+ detail, x, y, width, height);
+
+ light_gc = style->light_gc[state_type];
+ dark_gc = style->dark_gc[state_type];
+ shadow_gc = style->mid_gc[state_type];
+
+ xthick = style->xthickness;
+ ythick = style->ythickness;
+
+ dest.x = x + xthick;
+ dest.y = y + ythick;
+ dest.width = width - (xthick * 2);
+ dest.height = height - (ythick * 2);
+
+ gdk_gc_set_clip_rectangle(light_gc, &dest);
+ gdk_gc_set_clip_rectangle(dark_gc, &dest);
+ gdk_gc_set_clip_rectangle(shadow_gc, &dest);
+
+ if (dest.width < dest.height)
{
- GdkPixbuf *normal, *insensitive;
- int i, j, w, h, rs;
- guchar *pixels, *row;
-
- normal = parent_class->render_icon (style, source, direction,
- GTK_STATE_NORMAL, size,
- widget, detail);
- /* copy and add alpha channel at the same time */
- insensitive = gdk_pixbuf_add_alpha (normal, FALSE, 0, 0, 0);
- g_object_unref (normal);
- /* remove all colour */
- gdk_pixbuf_saturate_and_pixelate (insensitive, insensitive, 0.0, FALSE);
- /* make partially transparent */
- w = gdk_pixbuf_get_width (insensitive);
- h = gdk_pixbuf_get_height (insensitive);
- rs = gdk_pixbuf_get_rowstride (insensitive);
- pixels = gdk_pixbuf_get_pixels (insensitive);
- for (j=0; j<h; j++)
- {
- row = pixels + j * rs;
- for (i=0; i<w; i++)
- {
- row[i*4 + 3] = (guchar)(row[i*4 + 3] * 0.6);
- }
- }
- return insensitive;
+ gdk_draw_line(window, light_gc, dest.x, dest.y, dest.x, dest.height);
+ gdk_draw_line(window, dark_gc, dest.x + (dest.width / 2), dest.y, dest.x + (dest.width / 2), dest.height);
+ gdk_draw_line(window, shadow_gc, dest.x + dest.width, dest.y, dest.x + dest.width, dest.height);
}
else
{
- return parent_class->render_icon (style, source, direction,
- state, size,
- widget, detail);
+
+ gdk_draw_line(window, light_gc, dest.x, dest.y, dest.x + dest.width, dest.y);
+ gdk_draw_line(window, dark_gc, dest.x, dest.y + (dest.height / 2), dest.x + dest.width, dest.y + (dest.height / 2));
+ gdk_draw_line(window, shadow_gc, dest.x, dest.y + dest.height, dest.x + dest.width, dest.y + dest.height);
+ }
+
+ gdk_gc_set_clip_rectangle(shadow_gc, NULL);
+ gdk_gc_set_clip_rectangle(light_gc, NULL);
+ gdk_gc_set_clip_rectangle(dark_gc, NULL);
}
}
style_class->draw_vline = draw_vline;
style_class->draw_handle = draw_handle;
style_class->draw_resize_grip = draw_resize_grip;
- style_class->render_icon = render_icon;
+ style_class->draw_slider = draw_slider;
}
GType msw_type_style = 0;