mirror of
https://github.com/gnustep/libs-gui.git
synced 2025-04-25 14:00:54 +00:00
* Headers/Additions/GNUstepGUI/GSTheme.h: Remove GSScrollViewBottomCorner
part name, instead themes should just provide a part called NSScrollView. Add -scrollViewScrollersOverlapBorders method. * Source/GSTheme.m: Remove GSScrollViewBottomCorner part name. * Source/GSThemeDrawing.m: Add -scrollViewScrollersOverlapBorders. * Source/GSThemeDrawing.m (-drawBrowserRect:...): If -scrollViewScrollersOverlapBorders is enabled, fill the browser background with the NSScrollView tile. * Source/GSThemeDrawing.m (-drawScrollViewRect:...): If -scrollViewScrollersOverlapBorders is enabled, fill the scroll view background with the NSScrollView tile. * Source/NSScroller.m (-rectForPart:): Change the meaning of the GSScrollerKnobOvershoot default so the knob only overlaps the buttons by this much (rather than both ends of the track). Turns out this is more useful for themes. * Source/NSScrollView.m (-tile): Add support for -[GSTheme scrollViewScrollersOverlapBorders] * Source/NSBrowser.m (-tile): Add support for -[GSTheme scrollViewScrollersOverlapBorders] and -[GSTheme scrollViewUseBottomCorner] The overall point of these additions is to support NSScrollView and NSBrowser looking like: http://jesseross.com/clients/gnustep/ui/concepts/ git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@37238 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
7ebdcd6517
commit
240f754c33
7 changed files with 209 additions and 54 deletions
28
ChangeLog
28
ChangeLog
|
@ -1,3 +1,31 @@
|
|||
2013-10-15 Eric Wasylishen <ewasylishen@gmail.com>
|
||||
|
||||
* Headers/Additions/GNUstepGUI/GSTheme.h: Remove GSScrollViewBottomCorner
|
||||
part name, instead themes should just provide a part called NSScrollView.
|
||||
|
||||
Add -scrollViewScrollersOverlapBorders method.
|
||||
|
||||
* Source/GSTheme.m: Remove GSScrollViewBottomCorner part name.
|
||||
* Source/GSThemeDrawing.m: Add -scrollViewScrollersOverlapBorders.
|
||||
* Source/GSThemeDrawing.m (-drawBrowserRect:...): If
|
||||
-scrollViewScrollersOverlapBorders is enabled, fill the browser background
|
||||
with the NSScrollView tile.
|
||||
* Source/GSThemeDrawing.m (-drawScrollViewRect:...): If
|
||||
-scrollViewScrollersOverlapBorders is enabled, fill the scroll view background
|
||||
with the NSScrollView tile.
|
||||
* Source/NSScroller.m (-rectForPart:): Change the meaning of the
|
||||
GSScrollerKnobOvershoot default so the knob only overlaps the buttons
|
||||
by this much (rather than both ends of the track). Turns out this is more
|
||||
useful for themes.
|
||||
* Source/NSScrollView.m (-tile): Add support for
|
||||
-[GSTheme scrollViewScrollersOverlapBorders]
|
||||
* Source/NSBrowser.m (-tile): Add support for
|
||||
-[GSTheme scrollViewScrollersOverlapBorders] and
|
||||
-[GSTheme scrollViewUseBottomCorner]
|
||||
|
||||
The overall point of these additions is to support NSScrollView and
|
||||
NSBrowser looking like: http://jesseross.com/clients/gnustep/ui/concepts/
|
||||
|
||||
2013-10-15 Eric Wasylishen <ewasylishen@gmail.com>
|
||||
|
||||
* Source/NSTableView.m (-tile): Check the GSScrollViewNoInnerBorder
|
||||
|
|
|
@ -268,9 +268,6 @@ APPKIT_EXPORT NSString *GSScrollerUpArrow;
|
|||
APPKIT_EXPORT NSString *GSScrollerVerticalKnob;
|
||||
APPKIT_EXPORT NSString *GSScrollerVerticalSlot;
|
||||
|
||||
/* Scroll view parts */
|
||||
APPKIT_EXPORT NSString *GSScrollViewBottomCorner;
|
||||
|
||||
/* Names for table view parts */
|
||||
APPKIT_EXPORT NSString *GSTableHeader;
|
||||
APPKIT_EXPORT NSString *GSTableCorner;
|
||||
|
@ -891,7 +888,22 @@ APPKIT_EXPORT NSString *GSThemeWillDeactivateNotification;
|
|||
*/
|
||||
- (float) defaultScrollerWidth;
|
||||
|
||||
- (BOOL) scrolViewUseBottomCorner;
|
||||
/**
|
||||
* If YES, instructs NSScrollView to leave an empty square space where
|
||||
* the horizontal and vertical scrollers meet.
|
||||
*
|
||||
* Controlled by user default GSScrollViewUseBottomCorner; default YES.
|
||||
*/
|
||||
- (BOOL) scrollViewUseBottomCorner;
|
||||
|
||||
/**
|
||||
* If YES, instructs NSScrollView to make the scrollers overlap the border.
|
||||
* The scroll view border is drawn using the NSScrollView part, which
|
||||
* must be provided by the theme if this method returns YES.
|
||||
*
|
||||
* Controlled by user default GSScrollViewScrollersOverlapBorders; default NO;
|
||||
*/
|
||||
- (BOOL) scrollViewScrollersOverlapBorders;
|
||||
|
||||
/**
|
||||
* Method for toolbar theming.
|
||||
|
|
|
@ -77,9 +77,6 @@ NSString *GSScrollerUpArrow = @"GSScrollerUpArrow";
|
|||
NSString *GSScrollerVerticalKnob = @"GSScrollerVerticalKnob";
|
||||
NSString *GSScrollerVerticalSlot = @"GSScrollerVerticalSlot";
|
||||
|
||||
// Scroll view parts
|
||||
NSString *GSScrollViewBottomCorner = @"GSScrollViewBottomCorner";
|
||||
|
||||
// Table view part names
|
||||
NSString *GSTableHeader = @"GSTableHeader";
|
||||
NSString *GSTableCorner = @"GSTableCorner";
|
||||
|
|
|
@ -611,7 +611,7 @@
|
|||
return defaultScrollerWidth;
|
||||
}
|
||||
|
||||
- (BOOL) scrolViewUseBottomCorner
|
||||
- (BOOL) scrollViewUseBottomCorner
|
||||
{
|
||||
NSUserDefaults *defs = [NSUserDefaults standardUserDefaults];
|
||||
if ([defs objectForKey: @"GSScrollViewUseBottomCorner"] != nil)
|
||||
|
@ -621,6 +621,16 @@
|
|||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL) scrollViewScrollersOverlapBorders
|
||||
{
|
||||
NSUserDefaults *defs = [NSUserDefaults standardUserDefaults];
|
||||
if ([defs objectForKey: @"GSScrollViewScrollersOverlapBorders"] != nil)
|
||||
{
|
||||
return [defs boolForKey: @"GSScrollViewScrollersOverlapBorders"];
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (NSColor *) toolbarBackgroundColor
|
||||
{
|
||||
NSColor *color;
|
||||
|
@ -2435,6 +2445,21 @@ typedef enum {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (![self browserUseBezels]
|
||||
&& [self scrollViewScrollersOverlapBorders])
|
||||
{
|
||||
NSRect baseRect = NSMakeRect(0, 0, bounds.size.width, 1);
|
||||
NSRect colFrame = [browser frameOfColumn: [browser firstVisibleColumn]];
|
||||
NSRect scrollViewRect = NSUnionRect(baseRect, colFrame);
|
||||
|
||||
GSDrawTiles *tiles = [self tilesNamed: @"NSScrollView"
|
||||
state: GSThemeNormalState];
|
||||
|
||||
[self fillRect: scrollViewRect
|
||||
withTiles: tiles
|
||||
background: [NSColor clearColor]];
|
||||
}
|
||||
}
|
||||
|
||||
- (CGFloat) browserColumnSeparation
|
||||
|
@ -2521,6 +2546,7 @@ typedef enum {
|
|||
NSRect bounds = [view bounds];
|
||||
BOOL hasInnerBorder = ![[NSUserDefaults standardUserDefaults]
|
||||
boolForKey: @"GSScrollViewNoInnerBorder"];
|
||||
GSDrawTiles *tiles = nil;
|
||||
|
||||
name = [theme nameForElement: self];
|
||||
if (name == nil)
|
||||
|
@ -2528,28 +2554,38 @@ typedef enum {
|
|||
name = @"NSScrollView";
|
||||
}
|
||||
color = [theme colorNamed: name state: GSThemeNormalState];
|
||||
tiles = [theme tilesNamed: name state: GSThemeNormalState];
|
||||
if (color == nil)
|
||||
{
|
||||
color = [NSColor controlDarkShadowColor];
|
||||
}
|
||||
|
||||
switch (borderType)
|
||||
|
||||
if (tiles == nil)
|
||||
{
|
||||
case NSNoBorder:
|
||||
break;
|
||||
|
||||
case NSLineBorder:
|
||||
[color set];
|
||||
NSFrameRect(bounds);
|
||||
break;
|
||||
|
||||
case NSBezelBorder:
|
||||
[theme drawGrayBezel: bounds withClip: rect];
|
||||
break;
|
||||
|
||||
case NSGrooveBorder:
|
||||
[theme drawGroove: bounds withClip: rect];
|
||||
break;
|
||||
switch (borderType)
|
||||
{
|
||||
case NSNoBorder:
|
||||
break;
|
||||
|
||||
case NSLineBorder:
|
||||
[color set];
|
||||
NSFrameRect(bounds);
|
||||
break;
|
||||
|
||||
case NSBezelBorder:
|
||||
[theme drawGrayBezel: bounds withClip: rect];
|
||||
break;
|
||||
|
||||
case NSGrooveBorder:
|
||||
[theme drawGroove: bounds withClip: rect];
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
[self fillRect: bounds
|
||||
withTiles: tiles
|
||||
background: [NSColor clearColor]];
|
||||
}
|
||||
|
||||
if (hasInnerBorder)
|
||||
|
@ -2600,26 +2636,6 @@ typedef enum {
|
|||
DPSstroke(ctxt);
|
||||
}
|
||||
}
|
||||
|
||||
if (![self scrolViewUseBottomCorner]
|
||||
&& [scrollView hasHorizontalScroller]
|
||||
&& [scrollView hasVerticalScroller])
|
||||
{
|
||||
NSScroller *vertScroller = [scrollView verticalScroller];
|
||||
NSScroller *horizScroller = [scrollView horizontalScroller];
|
||||
|
||||
NSRect bottomCornerRect = NSMakeRect([vertScroller frame].origin.x,
|
||||
[horizScroller frame].origin.y,
|
||||
NSWidth([vertScroller frame]),
|
||||
NSHeight([horizScroller frame]));
|
||||
|
||||
GSDrawTiles *tiles = [self tilesNamed: GSScrollViewBottomCorner
|
||||
state: GSThemeNormalState];
|
||||
|
||||
[self fillRect: bottomCornerRect
|
||||
withTiles: tiles
|
||||
background: [NSColor clearColor]];
|
||||
}
|
||||
}
|
||||
|
||||
- (void) drawSliderBorderAndBackground: (NSBorderType)aType
|
||||
|
|
|
@ -1811,6 +1811,12 @@ static BOOL browserUseBezels;
|
|||
else
|
||||
rect.size.width = _frame.size.width -
|
||||
(rect.origin.x + bezelBorderSize.width);
|
||||
|
||||
// FIXME: Assumes left-side scrollers
|
||||
if ([[GSTheme theme] scrollViewScrollersOverlapBorders])
|
||||
{
|
||||
rect.size.width -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (rect.size.width < 0)
|
||||
|
@ -1863,6 +1869,8 @@ static BOOL browserUseBezels;
|
|||
NSSize bezelBorderSize = NSZeroSize;
|
||||
NSInteger i, num, columnCount, delta;
|
||||
CGFloat frameWidth;
|
||||
const BOOL overlapBorders = [[GSTheme theme] scrollViewScrollersOverlapBorders];
|
||||
const BOOL useBottomCorner = [[GSTheme theme] scrollViewUseBottomCorner];
|
||||
|
||||
if (browserUseBezels)
|
||||
bezelBorderSize = [[GSTheme theme] sizeForBorderType: NSBezelBorder];
|
||||
|
@ -1892,6 +1900,21 @@ static BOOL browserUseBezels;
|
|||
else
|
||||
_columnSize.height -= scrollerWidth + (2 * bezelBorderSize.height);
|
||||
|
||||
// "Bottom corner" box
|
||||
if (!browserUseBezels && !useBottomCorner)
|
||||
{
|
||||
_scrollerRect.origin.x += scrollerWidth;
|
||||
_scrollerRect.size.width -= scrollerWidth;
|
||||
}
|
||||
|
||||
/** Horizontall expand the scroller by GSScrollerKnobOvershoot on the left */
|
||||
if (overlapBorders)
|
||||
{
|
||||
// FIXME: Assumes left scroller
|
||||
_scrollerRect.origin.x -= 1;
|
||||
_scrollerRect.size.width += 1;
|
||||
}
|
||||
|
||||
if (!NSEqualRects(_scrollerRect, [_horizontalScroller frame]))
|
||||
{
|
||||
[_horizontalScroller setFrame: _scrollerRect];
|
||||
|
|
|
@ -1064,6 +1064,12 @@ static CGFloat scrollerWidth;
|
|||
[self tile];
|
||||
}
|
||||
|
||||
static NSRectEdge
|
||||
GSOppositeEdge(NSRectEdge edge)
|
||||
{
|
||||
return (edge == NSMinXEdge) ? NSMaxXEdge : NSMinXEdge;
|
||||
}
|
||||
|
||||
- (void) tile
|
||||
{
|
||||
NSRect headerRect, contentRect;
|
||||
|
@ -1075,8 +1081,9 @@ static CGFloat scrollerWidth;
|
|||
CGFloat innerBorderWidth = [[NSUserDefaults standardUserDefaults]
|
||||
boolForKey: @"GSScrollViewNoInnerBorder"] ? 0.0 : 1.0;
|
||||
|
||||
BOOL useBottomCorner = [[GSTheme theme] scrolViewUseBottomCorner];
|
||||
|
||||
const BOOL useBottomCorner = [[GSTheme theme] scrollViewUseBottomCorner];
|
||||
const BOOL overlapBorders = [[GSTheme theme] scrollViewScrollersOverlapBorders];
|
||||
|
||||
style = NSInterfaceStyleForKey(@"NSScrollViewInterfaceStyle", nil);
|
||||
|
||||
if (style == NSMacintoshInterfaceStyle
|
||||
|
@ -1098,7 +1105,11 @@ static CGFloat scrollerWidth;
|
|||
}
|
||||
|
||||
/* Prepare the contentRect by insetting the borders. */
|
||||
contentRect = NSInsetRect(_bounds, border.width, border.height);
|
||||
contentRect = _bounds;
|
||||
|
||||
if (!overlapBorders)
|
||||
contentRect = NSInsetRect(contentRect, border.width, border.height);
|
||||
|
||||
if (contentRect.size.width < 0 || contentRect.size.height < 0)
|
||||
{
|
||||
/* FIXME ... should we do something else when given
|
||||
|
@ -1108,6 +1119,32 @@ static CGFloat scrollerWidth;
|
|||
|
||||
[self _synchronizeHeaderAndCornerView];
|
||||
|
||||
if (overlapBorders)
|
||||
{
|
||||
if (_borderType != NSNoBorder)
|
||||
{
|
||||
if (!(_hasHeaderView || _hasCornerView))
|
||||
{
|
||||
// Inset 1px on the top
|
||||
NSDivideRect(contentRect, NULL, &contentRect, 1, topEdge);
|
||||
}
|
||||
if (!_hasVertScroller)
|
||||
{
|
||||
// Inset 1px on the edge where the vertical scroller would be
|
||||
NSDivideRect(contentRect, NULL, &contentRect, 1, verticalScrollerEdge);
|
||||
}
|
||||
if (!_hasHorizScroller)
|
||||
{
|
||||
NSDivideRect(contentRect, NULL, &contentRect, 1, bottomEdge);
|
||||
}
|
||||
// The vertical edge without a scroller
|
||||
{
|
||||
NSDivideRect(contentRect, NULL, &contentRect, 1,
|
||||
GSOppositeEdge(verticalScrollerEdge));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* First, allocate vertical space for the headerView / cornerView
|
||||
(but - NB - the headerView needs to be placed above the clipview
|
||||
later on, we can't place it now). */
|
||||
|
@ -1151,6 +1188,13 @@ static CGFloat scrollerWidth;
|
|||
scrollerWidth, bottomEdge);
|
||||
}
|
||||
|
||||
/** Vertically expand the scroller by 1pt on each end */
|
||||
if (overlapBorders)
|
||||
{
|
||||
vertScrollerRect.origin.y -= 1;
|
||||
vertScrollerRect.size.height += 2;
|
||||
}
|
||||
|
||||
[_vertScroller setFrame: vertScrollerRect];
|
||||
|
||||
/* Substract 1 for the line that separates the vertical scroller
|
||||
|
@ -1167,6 +1211,13 @@ static CGFloat scrollerWidth;
|
|||
NSDivideRect (contentRect, &horizScrollerRect, &contentRect,
|
||||
scrollerWidth, bottomEdge);
|
||||
|
||||
/** Horizontall expand the scroller by 1pt on each end */
|
||||
if (overlapBorders)
|
||||
{
|
||||
horizScrollerRect.origin.x -= 1;
|
||||
horizScrollerRect.size.width += 2;
|
||||
}
|
||||
|
||||
[_horizScroller setFrame: horizScrollerRect];
|
||||
|
||||
/* Substract 1 for the width for the line that separates the
|
||||
|
@ -1300,10 +1351,10 @@ static CGFloat scrollerWidth;
|
|||
- (BOOL) isOpaque
|
||||
{
|
||||
// FIXME: Only needs to be NO in a corner case,
|
||||
// when [[GSTheme theme] scrolViewUseBottomCorner] is NO
|
||||
// when [[GSTheme theme] scrollViewUseBottomCorner] is NO
|
||||
// and the theme tile for the bottom corner is transparent.
|
||||
// So maybe cache the value of
|
||||
// [[GSTheme theme] scrolViewUseBottomCorner] and check it here.
|
||||
// [[GSTheme theme] scrollViewUseBottomCorner] and check it here.
|
||||
return NO;
|
||||
}
|
||||
|
||||
|
@ -1739,6 +1790,13 @@ static CGFloat scrollerWidth;
|
|||
|
||||
- (void) _themeDidActivate: (NSNotification*)notification
|
||||
{
|
||||
// N.B. Reload cached [NSScroller scrollerWidth] since the
|
||||
// new theme may have a different scroller width.
|
||||
//
|
||||
// Since scrollerWidth is a static, it will get overwritten
|
||||
// several times; doesn't matter though.
|
||||
scrollerWidth = [NSScroller scrollerWidth];
|
||||
|
||||
[self tile];
|
||||
}
|
||||
|
||||
|
|
|
@ -68,8 +68,8 @@ static NSCell *horizontalKnobSlotCell = nil;
|
|||
static NSCell *verticalKnobSlotCell = nil;
|
||||
static CGFloat scrollerWidth = 0.0;
|
||||
/**
|
||||
* This is the amount (in userspace points) by which the knob slides beyond
|
||||
* either end of the track. Typical use would be to set it to 1 when both
|
||||
* This is the amount (in userspace points) by which the knob slides over the
|
||||
* button ends of the track. Typical use would be to set it to 1 when both
|
||||
* the knob and the buttons have a 1-point border, so that when the knob is
|
||||
* at its maximum, it overlaps the button by 1 point giving a resulting
|
||||
* 1-point wide border.
|
||||
|
@ -1229,8 +1229,29 @@ static float buttonsOffset = 1.0; // buttonsWidth = sw - 2*buttonsOffset
|
|||
knobHeight = buttonsWidth;
|
||||
|
||||
/* calc knob's position */
|
||||
knobPosition = floor((float)_doubleValue * (slotHeight - knobHeight + (2 * scrollerKnobOvershoot)))
|
||||
- scrollerKnobOvershoot;
|
||||
|
||||
{
|
||||
CGFloat knobOvershootAbove = scrollerKnobOvershoot;
|
||||
CGFloat knobOvershootBelow = scrollerKnobOvershoot;
|
||||
if (arrowsSameEnd
|
||||
&& _arrowsPosition == NSScrollerArrowsMinEnd)
|
||||
{
|
||||
knobOvershootBelow = 0;
|
||||
}
|
||||
else if (arrowsSameEnd
|
||||
&& _arrowsPosition == NSScrollerArrowsMaxEnd)
|
||||
{
|
||||
knobOvershootAbove = 0;
|
||||
}
|
||||
else if (_arrowsPosition == NSScrollerArrowsNone)
|
||||
{
|
||||
knobOvershootAbove = 0;
|
||||
knobOvershootBelow = 0;
|
||||
}
|
||||
|
||||
knobPosition = floor((float)_doubleValue * (slotHeight - knobHeight + knobOvershootAbove + knobOvershootBelow))
|
||||
- knobOvershootAbove;
|
||||
}
|
||||
|
||||
if (arrowsSameEnd)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue