Fixing the painting of the overlap area between tabs. Not part of the build.

This commit is contained in:
bryner%netscape.com 2005-08-20 07:12:32 +00:00
parent 17a19830f2
commit df93d1fad3
7 changed files with 80 additions and 57 deletions

View File

@ -413,22 +413,53 @@ moz_gtk_progress_chunk_paint(GdkWindow* window, GtkStyle* style,
void
moz_gtk_tab_paint(GdkWindow* window, GtkStyle* style, GdkRectangle* rect,
GdkRectangle* cliprect, GtkTabType type)
GdkRectangle* cliprect, gint flags)
{
/*
* In order to get the correct shadows and highlights, GTK paints tabs
* right-to-left (end-to-beginning, to be generic), leaving out the
* active tab, and then paints the current tab once everything else is
* painted. In addition, GTK uses a 2-pixel overlap between adjacent tabs
* (this value is hard-coded in gtknotebook.c). For purposes of mapping to
* gecko's frame positions, we put this overlap on the far edge of the frame
* (i.e., for a horizontal/top tab strip, we shift the left side of each tab
* 2px to the left, into the neighboring tab's frame rect. The right 2px
* of a tab's frame will be referred to as the "overlap area".
*
* Since we can't guarantee painting order with gecko, we need to manage
* the overlap area manually. There are three types of tab boundaries we need to handle:
*
* * two non-active tabs: In this case, we just have both tabs paint normally.
*
* * non-active to active tab: Here, we need the tab on the left to paint itself
* normally, then paint the edge of the active tab
* in its overlap area.
*
* * active to non-active tab: In this case, we just have both tabs paint normally.
*
* We need to make an exception for the first tab - since there is no tab to the
* left to paint the overlap area, we do _not_ shift the tab left by 2px.
*/
if (!(flags & MOZ_GTK_TAB_FIRST)) {
rect->x -= 2;
rect->width += 2;
}
gtk_paint_extension(style, window,
(type == kTabSelected ? GTK_STATE_NORMAL : GTK_STATE_ACTIVE),
((flags & MOZ_GTK_TAB_SELECTED) ? GTK_STATE_NORMAL : GTK_STATE_ACTIVE),
GTK_SHADOW_OUT, cliprect, gTabWidget, "tab", rect->x,
rect->y, rect->width, rect->height, GTK_POS_BOTTOM);
/* Here is the sleazy hack for before/after selected tab */
if (type == kTabBeforeSelected)
gtk_paint_extension(style, window, GTK_STATE_NORMAL, GTK_SHADOW_OUT,
cliprect, gTabWidget, "tab", rect->x + rect->width,
rect->y, rect->width, rect->height, GTK_POS_BOTTOM);
else if (type == kTabAfterSelected)
gtk_paint_extension(style, window, GTK_STATE_NORMAL, GTK_SHADOW_OUT,
cliprect, gTabWidget, "tab", rect->x - rect->width,
rect->y, rect->width, rect->height, GTK_POS_BOTTOM);
if (flags & MOZ_GTK_TAB_BEFORE_SELECTED) {
gboolean before_selected = ((flags & MOZ_GTK_TAB_BEFORE_SELECTED) != 0);
cliprect->y -= 2;
cliprect->height += 2;
gtk_paint_extension(style, window, GTK_STATE_NORMAL, GTK_SHADOW_OUT, cliprect,
gTabWidget, "tab", rect->x + rect->width - 2,
rect->y - (2 * before_selected), rect->width,
rect->height + (2 * before_selected), GTK_POS_BOTTOM);
}
}
void

View File

@ -56,12 +56,10 @@ typedef struct {
PRPackedBool canDefault;
} GtkWidgetState;
typedef enum {
kTabNormal,
kTabBeforeSelected,
kTabSelected,
kTabAfterSelected
} GtkTabType;
/* flags for tab state */
#define MOZ_GTK_TAB_FIRST (1<<0)
#define MOZ_GTK_TAB_BEFORE_SELECTED (1<<1)
#define MOZ_GTK_TAB_SELECTED (1<<2)
void
moz_gtk_button_paint(GdkWindow* window, GtkStyle* style, GdkRectangle* rect,
@ -132,7 +130,7 @@ moz_gtk_progress_chunk_paint(GdkWindow* window, GtkStyle* style,
void
moz_gtk_tab_paint(GdkWindow* window, GtkStyle* style, GdkRectangle* rect,
GdkRectangle* cliprect, GtkTabType type);
GdkRectangle* cliprect, gint flags);
void
moz_gtk_tabpanels_paint(GdkWindow* window, GtkStyle* style,

View File

@ -80,6 +80,7 @@ nsNativeThemeGTK::nsNativeThemeGTK()
mInputCheckedAtom = do_GetAtom("_moz-input-checked");
mInputAtom = do_GetAtom("input");
mFocusedAtom = do_GetAtom("focused");
mFirstTabAtom = do_GetAtom("first-tab");
}
nsNativeThemeGTK::~nsNativeThemeGTK() {
@ -364,24 +365,20 @@ nsNativeThemeGTK::DrawWidgetBackground(nsIRenderingContext* aContext,
case NS_THEME_TAB_RIGHT_EDGE:
{
EnsureTabWidget();
GtkTabType tab_type;
switch (aWidgetType) {
case NS_THEME_TAB:
{
PRBool isSelected = CheckBooleanAttr(aFrame, mSelectedAtom);
tab_type = (isSelected ? kTabSelected : kTabNormal);
}
break;
case NS_THEME_TAB_LEFT_EDGE:
tab_type = kTabBeforeSelected;
break;
case NS_THEME_TAB_RIGHT_EDGE:
tab_type = kTabAfterSelected;
break;
}
gint tab_flags = 0;
if (aWidgetType == NS_THEME_TAB && CheckBooleanAttr(aFrame, mSelectedAtom))
tab_flags |= MOZ_GTK_TAB_SELECTED;
else if (aWidgetType == NS_THEME_TAB_LEFT_EDGE)
tab_flags |= MOZ_GTK_TAB_BEFORE_SELECTED;
nsCOMPtr<nsIContent> content;
aFrame->GetContent(getter_AddRefs(content));
if (content->HasAttr(kNameSpaceID_None, mFirstTabAtom))
tab_flags |= MOZ_GTK_TAB_FIRST;
moz_gtk_tab_paint(window, gTabWidget->style, &gdk_rect, &gdk_clip,
tab_type);
tab_flags);
break;
}
}

View File

@ -109,6 +109,7 @@ private:
nsCOMPtr<nsIAtom> mInputCheckedAtom;
nsCOMPtr<nsIAtom> mInputAtom;
nsCOMPtr<nsIAtom> mFocusedAtom;
nsCOMPtr<nsIAtom> mFirstTabAtom;
GtkWidget* mProtoLayout;
};

View File

@ -56,12 +56,10 @@ typedef struct {
PRPackedBool canDefault;
} GtkWidgetState;
typedef enum {
kTabNormal,
kTabBeforeSelected,
kTabSelected,
kTabAfterSelected
} GtkTabType;
/* flags for tab state */
#define MOZ_GTK_TAB_FIRST (1<<0)
#define MOZ_GTK_TAB_BEFORE_SELECTED (1<<1)
#define MOZ_GTK_TAB_SELECTED (1<<2)
void
moz_gtk_button_paint(GdkWindow* window, GtkStyle* style, GdkRectangle* rect,
@ -132,7 +130,7 @@ moz_gtk_progress_chunk_paint(GdkWindow* window, GtkStyle* style,
void
moz_gtk_tab_paint(GdkWindow* window, GtkStyle* style, GdkRectangle* rect,
GdkRectangle* cliprect, GtkTabType type);
GdkRectangle* cliprect, gint flags);
void
moz_gtk_tabpanels_paint(GdkWindow* window, GtkStyle* style,

View File

@ -80,6 +80,7 @@ nsNativeThemeGTK::nsNativeThemeGTK()
mInputCheckedAtom = do_GetAtom("_moz-input-checked");
mInputAtom = do_GetAtom("input");
mFocusedAtom = do_GetAtom("focused");
mFirstTabAtom = do_GetAtom("first-tab");
}
nsNativeThemeGTK::~nsNativeThemeGTK() {
@ -364,24 +365,20 @@ nsNativeThemeGTK::DrawWidgetBackground(nsIRenderingContext* aContext,
case NS_THEME_TAB_RIGHT_EDGE:
{
EnsureTabWidget();
GtkTabType tab_type;
switch (aWidgetType) {
case NS_THEME_TAB:
{
PRBool isSelected = CheckBooleanAttr(aFrame, mSelectedAtom);
tab_type = (isSelected ? kTabSelected : kTabNormal);
}
break;
case NS_THEME_TAB_LEFT_EDGE:
tab_type = kTabBeforeSelected;
break;
case NS_THEME_TAB_RIGHT_EDGE:
tab_type = kTabAfterSelected;
break;
}
gint tab_flags = 0;
if (aWidgetType == NS_THEME_TAB && CheckBooleanAttr(aFrame, mSelectedAtom))
tab_flags |= MOZ_GTK_TAB_SELECTED;
else if (aWidgetType == NS_THEME_TAB_LEFT_EDGE)
tab_flags |= MOZ_GTK_TAB_BEFORE_SELECTED;
nsCOMPtr<nsIContent> content;
aFrame->GetContent(getter_AddRefs(content));
if (content->HasAttr(kNameSpaceID_None, mFirstTabAtom))
tab_flags |= MOZ_GTK_TAB_FIRST;
moz_gtk_tab_paint(window, gTabWidget->style, &gdk_rect, &gdk_clip,
tab_type);
tab_flags);
break;
}
}

View File

@ -109,6 +109,7 @@ private:
nsCOMPtr<nsIAtom> mInputCheckedAtom;
nsCOMPtr<nsIAtom> mInputAtom;
nsCOMPtr<nsIAtom> mFocusedAtom;
nsCOMPtr<nsIAtom> mFirstTabAtom;
GtkWidget* mProtoLayout;
};