Bug 465402 - Tree header cells shouldn't draw borders around them, only between each other. r+sr=roc, a191=beltzner
authorMarkus Stange <mstange@themasta.com>
Thu, 27 Nov 2008 23:14:54 +0100
changeset 22055 2b5ae7db4e991644eb9bfa22d5fa836236fe579c
parent 22054 4ff260cb5feab1570f85f8bed834d9a9931d466d
child 22056 ae7706acc2d20d0d60f18a6bc2aedc068a3786e5
push idunknown
push userunknown
push dateunknown
bugs465402
milestone1.9.1b3pre
Bug 465402 - Tree header cells shouldn't draw borders around them, only between each other. r+sr=roc, a191=beltzner
widget/src/cocoa/nsNativeThemeCocoa.mm
widget/src/windows/nsNativeThemeWin.cpp
widget/src/xpwidgets/nsNativeTheme.cpp
widget/src/xpwidgets/nsNativeTheme.h
widget/src/xpwidgets/nsWidgetAtomList.h
--- a/widget/src/cocoa/nsNativeThemeCocoa.mm
+++ b/widget/src/cocoa/nsNativeThemeCocoa.mm
@@ -714,16 +714,28 @@ nsNativeThemeCocoa::DrawButton(CGContext
           needsScaling = PR_TRUE;
         }
       }
     }
     else {
       // leave things alone on Tiger
       drawFrame.size.height -= 1;
     }
+  } else if (inKind == kThemeListHeaderButton) {
+    CGContextClipToRect(cgContext, inBoxRect);
+    // Always remove the top border.
+    drawFrame.origin.y -= 1;
+    drawFrame.size.height += 1;
+    // Remove the left border in LTR mode and the right border in RTL mode.
+    drawFrame.size.width += 1;
+    PRBool isLast = IsLastTreeHeaderCell(aFrame);
+    if (isLast)
+      drawFrame.size.width += 1; // Also remove the other border.
+    if (!IsFrameRTL(aFrame) || isLast)
+      drawFrame.origin.x -= 1;
   }
 
   if (!needsScaling) {
     HIThemeDrawButton(&drawFrame, &bdi, cgContext, kHIThemeOrientationNormal, NULL);
   } else {
     int w = drawWidth + MAX_FOCUS_RING_WIDTH*2;
     int h = drawHeight + MAX_FOCUS_RING_WIDTH*2;
 
@@ -1456,17 +1468,17 @@ nsNativeThemeCocoa::DrawWidgetBackground
       DrawButton(cgContext, kThemeDisclosureButton, macRect, PR_FALSE, IsDisabled(aFrame), 
                  kThemeDisclosureDown, kThemeAdornmentNone, eventState, aFrame);
       break;
 
     case NS_THEME_TREEVIEW_HEADER_CELL: {
       TreeSortDirection sortDirection = GetTreeSortDirection(aFrame);
       DrawButton(cgContext, kThemeListHeaderButton, macRect, PR_FALSE, IsDisabled(aFrame), 
                  sortDirection == eTreeSortDirection_Natural ? kThemeButtonOff : kThemeButtonOn,
-                 sortDirection == eTreeSortDirection_Descending ?
+                 sortDirection == eTreeSortDirection_Ascending ?
                  kThemeAdornmentHeaderButtonSortUp : kThemeAdornmentNone, eventState, aFrame);      
     }
       break;
 
     case NS_THEME_TREEVIEW_TREEITEM:
     case NS_THEME_TREEVIEW:
       // HIThemeSetFill is not available on 10.3
       // HIThemeSetFill(kThemeBrushWhite, NULL, cgContext, HITHEME_ORIENTATION);
@@ -1812,17 +1824,17 @@ nsNativeThemeCocoa::GetMinimumWidgetSize
       break;
     }
     
     case NS_THEME_TREEVIEW_HEADER:
     case NS_THEME_TREEVIEW_HEADER_CELL:
     {
       SInt32 headerHeight = 0;
       ::GetThemeMetric(kThemeMetricListHeaderHeight, &headerHeight);
-      aResult->SizeTo(0, headerHeight);
+      aResult->SizeTo(0, headerHeight - 1); // We don't need the top border.
       break;
     }
 
     case NS_THEME_SCALE_HORIZONTAL:
     {
       SInt32 scaleHeight = 0;
       ::GetThemeMetric(kThemeMetricHSliderHeight, &scaleHeight);
       aResult->SizeTo(scaleHeight, scaleHeight);
--- a/widget/src/windows/nsNativeThemeWin.cpp
+++ b/widget/src/windows/nsNativeThemeWin.cpp
@@ -163,21 +163,16 @@ static SIZE GetGutterSize(HANDLE theme, 
     int width = PR_MAX(itemSize.cx, checkboxSize.cx + gutterSize.cx);
     int height = PR_MAX(itemSize.cy, checkboxSize.cy);
     SIZE ret;
     ret.cx = width;
     ret.cy = height;
     return ret;
 }
 
-static inline PRBool IsFrameRTL(nsIFrame *frame)
-{
-  return frame->GetStyleVisibility()->mDirection == NS_STYLE_DIRECTION_RTL;
-}
-
 static HRESULT DrawThemeBGRTLAware(HANDLE theme, HDC hdc, int part, int state,
                                    const RECT *widgetRect, const RECT *clipRect,
                                    PRBool isRTL)
 {
   /* Some widgets are not direction-neutral and need to be drawn reversed for
    * RTL.  Windows provides a way to do this with SetLayout, but this reverses
    * the entire drawing area of a given device context, which means that its
    * use will also affect the positioning of the widget.  There are two ways
--- a/widget/src/xpwidgets/nsNativeTheme.cpp
+++ b/widget/src/xpwidgets/nsNativeTheme.cpp
@@ -164,16 +164,22 @@ nsNativeTheme::IsWidgetStyled(nsPresCont
           aWidgetType == NS_THEME_LISTBOX ||
           aWidgetType == NS_THEME_DROPDOWN) &&
          aFrame->GetContent()->IsNodeOfType(nsINode::eHTML) &&
          aPresContext->HasAuthorSpecifiedRules(aFrame,
                                                NS_AUTHOR_SPECIFIED_BORDER |
                                                NS_AUTHOR_SPECIFIED_BACKGROUND);
 }
 
+PRBool
+nsNativeTheme::IsFrameRTL(nsIFrame* aFrame)
+{
+  return aFrame && aFrame->GetStyleVisibility()->mDirection == NS_STYLE_DIRECTION_RTL;
+}
+
 // scrollbar button:
 PRInt32
 nsNativeTheme::GetScrollbarButtonType(nsIFrame* aFrame)
 {
   if (!aFrame)
     return 0;
 
   static nsIContent::AttrValuesArray strings[] =
@@ -207,16 +213,44 @@ nsNativeTheme::GetTreeSortDirection(nsIF
                                                 strings, eCaseMatters)) {
     case 0: return eTreeSortDirection_Descending;
     case 1: return eTreeSortDirection_Ascending;
   }
 
   return eTreeSortDirection_Natural;
 }
 
+PRBool
+nsNativeTheme::IsLastTreeHeaderCell(nsIFrame* aFrame)
+{
+  if (!aFrame)
+    return PR_FALSE;
+
+  // A tree column picker is always the last header cell.
+  if (aFrame->GetContent()->Tag() == nsWidgetAtoms::treecolpicker)
+    return PR_TRUE;
+
+  // Find the parent tree.
+  nsIContent* parent = aFrame->GetContent()->GetParent();
+  while (parent && parent->Tag() != nsWidgetAtoms::tree) {
+    parent = parent->GetParent();
+  }
+
+  // If the column picker is visible, this can't be the last column.
+  if (parent && !parent->AttrValueIs(kNameSpaceID_None, nsWidgetAtoms::hidecolumnpicker,
+                                     NS_LITERAL_STRING("true"), eCaseMatters))
+    return PR_FALSE;
+
+  while ((aFrame = aFrame->GetNextSibling())) {
+    if (aFrame->GetRect().width > 0)
+      return PR_FALSE;
+  }
+  return PR_TRUE;
+}
+
 // tab:
 PRBool
 nsNativeTheme::IsBottomTab(nsIFrame* aFrame)
 {
   if (!aFrame)
     return PR_FALSE;
 
   nsAutoString classStr;
--- a/widget/src/xpwidgets/nsNativeTheme.h
+++ b/widget/src/xpwidgets/nsNativeTheme.h
@@ -80,16 +80,19 @@ class nsNativeTheme
 
   // Accessors to widget-specific state information
 
   // all widgets:
   PRBool IsDisabled(nsIFrame* aFrame) {
     return CheckBooleanAttr(aFrame, nsWidgetAtoms::disabled);
   }
 
+  // RTL chrome direction
+  PRBool IsFrameRTL(nsIFrame* aFrame);
+
   // button:
   PRBool IsDefaultButton(nsIFrame* aFrame) {
     return CheckBooleanAttr(aFrame, nsWidgetAtoms::_default);
   }
 
   // checkbox:
   PRBool IsChecked(nsIFrame* aFrame) {
     return GetCheckedOrSelected(aFrame, PR_FALSE);
@@ -114,16 +117,17 @@ class nsNativeTheme
 
   // toolbarbutton:
   PRBool IsCheckedButton(nsIFrame* aFrame) {
     return CheckBooleanAttr(aFrame, nsWidgetAtoms::checked);
   }
 
   // treeheadercell:
   TreeSortDirection GetTreeSortDirection(nsIFrame* aFrame);
+  PRBool IsLastTreeHeaderCell(nsIFrame* aFrame);
 
   // tab:
   PRBool IsBottomTab(nsIFrame* aFrame);
   PRBool IsFirstTab(nsIFrame* aFrame);
   PRBool IsLastTab(nsIFrame* aFrame);
   
   PRBool IsHorizontal(nsIFrame* aFrame);
 
--- a/widget/src/xpwidgets/nsWidgetAtomList.h
+++ b/widget/src/xpwidgets/nsWidgetAtomList.h
@@ -72,16 +72,17 @@ WIDGET_ATOM(descending, "descending")
 WIDGET_ATOM(dir, "dir")
 WIDGET_ATOM(disabled, "disabled")
 WIDGET_ATOM(_false, "false")
 WIDGET_ATOM(firsttab, "first-tab")
 WIDGET_ATOM(focused, "focused")
 WIDGET_ATOM(Forward, "Forward")
 WIDGET_ATOM(Home, "Home")
 WIDGET_ATOM(hidden, "hidden")
+WIDGET_ATOM(hidecolumnpicker, "hidecolumnpicker")
 WIDGET_ATOM(horizontal, "horizontal")
 WIDGET_ATOM(vertical, "vertical")
 WIDGET_ATOM(id, "id")
 WIDGET_ATOM(image, "image")
 WIDGET_ATOM(input, "input")
 WIDGET_ATOM(key, "key") // The key element / attribute
 WIDGET_ATOM(label, "label")
 WIDGET_ATOM(lasttab, "last-tab")
@@ -113,11 +114,13 @@ WIDGET_ATOM(scrollbarUpBottom, "scrollba
 WIDGET_ATOM(scrollbarUpTop, "scrollbar-up-top")
 WIDGET_ATOM(Search, "Search")
 WIDGET_ATOM(selected, "selected")
 WIDGET_ATOM(sortdirection, "sortDirection")
 WIDGET_ATOM(state, "state")
 WIDGET_ATOM(step, "step")
 WIDGET_ATOM(Stop, "Stop")
 WIDGET_ATOM(_true, "true")
+WIDGET_ATOM(tree, "tree")
+WIDGET_ATOM(treecolpicker, "treecolpicker")
 WIDGET_ATOM(type, "type")
 WIDGET_ATOM(value, "value")