mirror of
https://github.com/cappuccino/cappuccino.git
synced 2026-09-29 05:37:41 +00:00
fixed: outlineview arrow colors
This commit is contained in:
+80
-19
@@ -2219,20 +2219,22 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
|
||||
{
|
||||
[self setBordered:NO];
|
||||
[self setBezelStyle:CPDisclosureBezelStyle];
|
||||
_angle = 0.0;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
// 1. Tell the animation system that 'angle' must be animated via a Timer loop
|
||||
// (Software animation) because it affects drawRect, not CSS.
|
||||
+ (BOOL)needsPeriodicFrameUpdatesForKey:(CPString)aKey
|
||||
{
|
||||
if (aKey === @"angle")
|
||||
return YES;
|
||||
|
||||
return [super needsPeriodicFrameUpdatesForKey:aKey];
|
||||
}
|
||||
|
||||
// 1. Expose angle as a property so the animator proxy can interpolate it.
|
||||
// 2. Accessor for the animator to set the value
|
||||
- (void)setAngle:(float)anAngle
|
||||
{
|
||||
_angle = anAngle;
|
||||
@@ -2246,27 +2248,29 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
|
||||
|
||||
- (void)setState:(CPInteger)aState
|
||||
{
|
||||
// If the state isn't changing, do nothing
|
||||
if ([self state] === aState)
|
||||
return;
|
||||
|
||||
[super setState:aState];
|
||||
|
||||
// Calculate target angle: 0.0 for Expanded (Down), -PI_2 for Collapsed (Right)
|
||||
var targetAngle = ([self state] === CPOnState) ? 0.0 : -PI_2;
|
||||
|
||||
// 2. Only animate if the view is currently in a window (visible).
|
||||
// This prevents rows from spinning into place during initial load or scrolling.
|
||||
// Only animate if the view is visible in a window
|
||||
if ([self window])
|
||||
{
|
||||
[CPAnimationContext beginGrouping];
|
||||
|
||||
// Duration of the rotation (0.2s is standard for macOS-like toggles)
|
||||
[[CPAnimationContext currentContext] setDuration:0.2];
|
||||
|
||||
// Use the animator proxy to smoothly interpolate the 'angle' property
|
||||
// Because we implemented +needsPeriodicFrameUpdatesForKey:,
|
||||
// calling this on the animator automatically starts the timer loop.
|
||||
[[self animator] setAngle:targetAngle];
|
||||
debugger
|
||||
|
||||
[CPAnimationContext endGrouping];
|
||||
}
|
||||
else
|
||||
{
|
||||
// If not visible/loading, set immediately
|
||||
[self setAngle:targetAngle];
|
||||
}
|
||||
}
|
||||
@@ -2279,38 +2283,95 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
|
||||
height = CGRectGetHeight(bounds);
|
||||
|
||||
CGContextBeginPath(context);
|
||||
CGContextSaveGState(context);
|
||||
|
||||
// 3. The drawing logic uses _angle, which is now being interpolated by the animator
|
||||
if (_angle)
|
||||
// 3. Apply rotation centered on the view
|
||||
if (_angle !== 0.0)
|
||||
{
|
||||
var centre = CGPointMake(FLOOR(width / 2.0), FLOOR(height / 2.0));
|
||||
CGContextTranslateCTM(context, centre.x, centre.y);
|
||||
var centreX = FLOOR(width / 2.0),
|
||||
centreY = FLOOR(height / 2.0);
|
||||
|
||||
CGContextTranslateCTM(context, centreX, centreY);
|
||||
CGContextRotateCTM(context, _angle);
|
||||
CGContextTranslateCTM(context, -centre.x, -centre.y);
|
||||
CGContextTranslateCTM(context, -centreX, -centreY);
|
||||
}
|
||||
|
||||
// Center, but crisp.
|
||||
// Center the triangle visually
|
||||
CGContextTranslateCTM(context, FLOOR((width - 9.0) / 2.0), FLOOR((height - 8.0) / 2.0));
|
||||
|
||||
// Draw the triangle
|
||||
CGContextMoveToPoint(context, 0.0, 0.0);
|
||||
CGContextAddLineToPoint(context, 9.0, 0.0);
|
||||
CGContextAddLineToPoint(context, 4.5, 8.0);
|
||||
CGContextClosePath(context);
|
||||
|
||||
CGContextSetFillColor(context,
|
||||
colorForDisclosureTriangle([self hasThemeState:CPThemeStateSelected],
|
||||
[self hasThemeState:CPThemeStateHighlighted]));
|
||||
// Calculate Color based on HUD and KeyWindow states ---
|
||||
var isSelected = [self hasThemeState:CPThemeStateSelected],
|
||||
isHighlighted = [self hasThemeState:CPThemeStateHighlighted],
|
||||
isKeyWindow = [self hasThemeState:CPThemeStateKeyWindow],
|
||||
// Detect HUD style mask on the window
|
||||
isHUD = [self window] && ([[self window] styleMask] & CPHUDBackgroundWindowMask),
|
||||
triangleColor = nil;
|
||||
|
||||
if (isHUD)
|
||||
{
|
||||
// 2. HUD Logic
|
||||
if (isSelected)
|
||||
triangleColor = [CPColor blackColor]; // Selected HUD row = White BG -> Black Triangle
|
||||
else
|
||||
triangleColor = [CPColor whiteColor]; // Normal HUD row = Dark BG -> White Triangle
|
||||
|
||||
// Handle click highlight in HUD (dim it)
|
||||
if (isHighlighted)
|
||||
triangleColor = [triangleColor colorWithAlphaComponent:0.5];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Standard Logic
|
||||
if (isSelected)
|
||||
{
|
||||
if (isKeyWindow)
|
||||
triangleColor = [CPColor whiteColor]; // Key Window + Selected = Blue BG -> White Triangle
|
||||
else
|
||||
triangleColor = [CPColor blackColor]; // 1. Non-Key Window + Selected = Gray BG -> Black Triangle
|
||||
}
|
||||
else
|
||||
{
|
||||
// Standard Unselected
|
||||
triangleColor = [CPColor colorWithCalibratedWhite:0.45 alpha: 1.0];
|
||||
}
|
||||
|
||||
// Handle click highlight in Standard
|
||||
if (isHighlighted)
|
||||
{
|
||||
if (isSelected && isKeyWindow)
|
||||
triangleColor = [CPColor colorWithCalibratedWhite:0.9 alpha: 1.0];
|
||||
else if (isSelected && !isKeyWindow)
|
||||
triangleColor = [CPColor colorWithCalibratedWhite:0.2 alpha: 1.0];
|
||||
else
|
||||
triangleColor = [CPColor colorWithCalibratedWhite:0.25 alpha: 1.0];
|
||||
}
|
||||
}
|
||||
|
||||
CGContextSetFillColor(context, triangleColor);
|
||||
|
||||
CGContextFillPath(context);
|
||||
|
||||
// Draw the outline
|
||||
CGContextBeginPath(context);
|
||||
CGContextMoveToPoint(context, 0.0, 0.0);
|
||||
CGContextAddLineToPoint(context, 4.5, 8.0);
|
||||
|
||||
// Only draw the top line (completing the triangle) if not rotated (standard Cocoa look)
|
||||
if (_angle === 0.0)
|
||||
CGContextAddLineToPoint(context, 9.0, 0.0);
|
||||
|
||||
CGContextSetStrokeColor(context, [CPColor colorWithCalibratedWhite:1.0 alpha:0.7]);
|
||||
// Adjust stroke opacity for HUD/Non-Key to avoid "ghostly" white borders on light backgrounds
|
||||
var strokeAlpha = (isHUD || (isSelected && !isKeyWindow)) ? 0.3 : 0.7;
|
||||
CGContextSetStrokeColor(context, [CPColor colorWithCalibratedWhite:1.0 alpha:strokeAlpha]);
|
||||
CGContextStrokePath(context);
|
||||
|
||||
CGContextRestoreGState(context);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
* Refactored: Fixed RuleEditor action handling.
|
||||
* Refactored: Added OutlineView and reordered tabs.
|
||||
* Refactored: Fixed control disabling logic for all tabs.
|
||||
* Added: CPAlert demonstrations wired to control buttons.
|
||||
*/
|
||||
|
||||
@import <Foundation/Foundation.j>
|
||||
@@ -196,20 +197,35 @@
|
||||
|
||||
// Buttons
|
||||
var pushButton = [[CPButton alloc] initWithFrame:CGRectMake(innerX, currentY, controlWidth, fieldHeight)];
|
||||
[pushButton setTitle:@"Push Button"];
|
||||
[pushButton setTitle:@"Push Button (Info Alert)"];
|
||||
[pushButton setBezelStyle:CPRoundedBezelStyle];
|
||||
|
||||
// ACTION: Standard Informational Alert
|
||||
[pushButton setTarget:self];
|
||||
[pushButton setAction:@selector(showStandardAlert:)];
|
||||
|
||||
[leftContent addSubview:pushButton];
|
||||
currentY += gapY;
|
||||
|
||||
var gradientButton = [[CPButton alloc] initWithFrame:CGRectMake(innerX, currentY, controlWidth, fieldHeight)];
|
||||
[gradientButton setTitle:@"Gradient Button"];
|
||||
[gradientButton setTitle:@"Gradient (HUD Alert)"];
|
||||
[gradientButton setBezelStyle:CPSmallSquareBezelStyle];
|
||||
|
||||
// ACTION: Critical / HUD Alert
|
||||
[gradientButton setTarget:self];
|
||||
[gradientButton setAction:@selector(showHUDAlert:)];
|
||||
|
||||
[leftContent addSubview:gradientButton];
|
||||
currentY += gapY;
|
||||
|
||||
var roundRectButton = [[CPButton alloc] initWithFrame:CGRectMake(innerX, currentY, controlWidth, fieldHeight)];
|
||||
[roundRectButton setTitle:@"Round Rect Button"];
|
||||
[roundRectButton setTitle:@"Round (Sheet Alert)"];
|
||||
[roundRectButton setBezelStyle:CPRoundRectBezelStyle];
|
||||
|
||||
// ACTION: Warning Sheet
|
||||
[roundRectButton setTarget:self];
|
||||
[roundRectButton setAction:@selector(showSheetAlert:)];
|
||||
|
||||
[leftContent addSubview:roundRectButton];
|
||||
currentY += gapY + 5.0;
|
||||
|
||||
@@ -385,6 +401,68 @@
|
||||
[self _applyHUDStateToView:containerView];
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
// ALERT ACTIONS
|
||||
// --------------------------------------------------------------------------------
|
||||
|
||||
- (void)showStandardAlert:(id)sender
|
||||
{
|
||||
var alert = [[CPAlert alloc] init];
|
||||
[alert setTitle:@"Standard Alert"];
|
||||
[alert setMessageText:@"Informational Alert"];
|
||||
[alert setInformativeText:@"This is a standard CPAlert with the CPInformationalAlertStyle. It behaves like a standard modal dialog."];
|
||||
[alert setAlertStyle:CPInformationalAlertStyle];
|
||||
|
||||
[alert addButtonWithTitle:@"OK"];
|
||||
[alert runModal];
|
||||
}
|
||||
|
||||
- (void)showHUDAlert:(id)sender
|
||||
{
|
||||
var alert = [[CPAlert alloc] init];
|
||||
[alert setTitle:@"HUD Alert"];
|
||||
[alert setMessageText:@"Critical HUD Alert"];
|
||||
[alert setInformativeText:@"This alert uses the CPCriticalAlertStyle and explicitly sets the HUD theme."];
|
||||
[alert setAlertStyle:CPCriticalAlertStyle];
|
||||
|
||||
// Explicitly set the HUD theme like in the example
|
||||
[alert setTheme:[CPTheme defaultHudTheme]];
|
||||
|
||||
[alert addButtonWithTitle:@"Destroy"];
|
||||
[alert addButtonWithTitle:@"Cancel"];
|
||||
|
||||
// We can use a block for the return handler if desired, or standard modal
|
||||
[alert runModal];
|
||||
}
|
||||
|
||||
- (void)showSheetAlert:(id)sender
|
||||
{
|
||||
var alert = [[CPAlert alloc] init];
|
||||
[alert setMessageText:@"Document Warning"];
|
||||
[alert setInformativeText:@"This is a Sheet (CPDocModalWindowMask). It is attached to the parent window."];
|
||||
[alert setAlertStyle:CPWarningAlertStyle];
|
||||
|
||||
[alert addButtonWithTitle:@"Save"];
|
||||
[alert addButtonWithTitle:@"Cancel"];
|
||||
|
||||
// If the parent window is HUD, make the sheet match
|
||||
if (_isHUD)
|
||||
[alert setTheme:[CPTheme defaultHudTheme]];
|
||||
|
||||
// Using the delegate method pattern
|
||||
[alert beginSheetModalForWindow:[self window]
|
||||
modalDelegate:self
|
||||
didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:)
|
||||
contextInfo:@"SheetContext"];
|
||||
}
|
||||
|
||||
- (void)alertDidEnd:(CPAlert)anAlert returnCode:(CPInteger)returnCode contextInfo:(id)context
|
||||
{
|
||||
CPLog.info(@"Alert ended. Return Code: %d. Context: %@", returnCode, context);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
|
||||
- (void)_buildTableTab:(CPView)containerView isHUD:(BOOL)isHUD
|
||||
{
|
||||
var bounds = [containerView bounds];
|
||||
@@ -503,7 +581,7 @@
|
||||
[textView setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
|
||||
[textView setEditable:YES];
|
||||
[textView setRichText:YES];
|
||||
[textView setString:@"Select text here and use the 'Format' or 'Edit' menus.\n\n(This is a Rich Text enabled CPTextView)"];
|
||||
[textView setString:@"Enter an animal name such as 'Duck' in the Textfield above in order to filter the table dynamically.\nMove the columns around!\n\nBTW: this is a Rich Text enabled CPTextView"];
|
||||
[textView setFont:[CPFont fontWithName:@"Courier" size:13.0]];
|
||||
|
||||
[textScroll setDocumentView:textView];
|
||||
|
||||
Reference in New Issue
Block a user