rework of tooltips to use only CSS + support for HUD

This commit is contained in:
daboe01 committed 2026-03-05 08:31:01 +01:00
1 parent 063f2f0283
commit a56458384c
3 files changed
+86 -54

No files matched your search

+34 -42
View File
@@ -25,11 +25,10 @@
@implementation _CPToolTipWindowView : _CPWindowView
{
BOOL _mouseDownPressed @accessors(getter=isMouseDownPressed, setter=setMouseDownPressed:);
unsigned _gravity @accessors(property=gravity);
BOOL _mouseDownPressed @accessors(getter=isMouseDownPressed, setter=setMouseDownPressed:);
unsigned _gravity @accessors(property=gravity);
}
#pragma mark -
#pragma mark Class methods
@@ -41,21 +40,30 @@
+ (CPDictionary)themeAttributes
{
return @{
@"stroke-color": [CPColor colorWithHexString:@"E3E3E3"],
@"background-color": [CPColor colorWithHexString:@"FFFFCA"],
@"border-radius": 2.0,
@"stroke-width": 1.0,
@"color": [CPColor blackColor],
};
// 1. The DOM-based CSS rendering attributes.
// _CPWindowView will natively apply this to the outer window bounds.
@"bezel-color":[CPColor colorWithCSSDictionary:@{
@"background-color": @"#FFFFCA",
@"border": @"1px solid #B0B0B0",
@"border-radius": @"2px",
@"box-sizing": @"border-box",
@"box-shadow": @"0px 1px 3px rgba(0,0,0,0.25)"
}],
@"color": [CPColor blackColor],
// 2. Legacy attributes zeroed out to satisfy the build process/theme inheritance
@"background-color": [CPColor clearColor],
@"stroke-color": [CPColor clearColor],
@"stroke-width": 0.0,
@"border-radius": 0.0
};
}
/*! compute the contentView frame from a given window frame
@param aFrameRect the window frame
*/
+ (CGRect)contentRectForFrameRect:(CGRect)aFrameRect
{
var contentRect = [super contentRectForFrameRect:aFrameRect];
// This pushes the text inwards so it doesn't touch the outer CSS border
contentRect.origin.x += 3;
contentRect.origin.y += 3;
contentRect.size.width -= 6;
@@ -64,50 +72,34 @@
return contentRect;
}
/*! compute the window frame from a given contentView frame
@param aContentRect the contentView frame
*/
+ (CGRect)frameRectForContentRect:(CGRect)aContentRect
{
var aFrameRect = CGRectMakeCopy(aContentRect);
aFrameRect.origin.x -= 3;
aFrameRect.origin.y -= 3;
aFrameRect.size.width += 6;
aFrameRect.size.height += 6;
aFrameRect.size.width += 9;
aFrameRect.size.height += 9;
return aFrameRect;
}
#pragma mark -
#pragma mark drawing
#pragma mark DOM/CSS Rendering
- (void)layoutSubviews
{
[super layoutSubviews];
// Apply the CSS dictionary to the standard CPView subview (contentView).
// This bypasses the _CPWindowView canvas interceptor and applies directly to the DOM.
[self setBackgroundColor:[self currentValueForThemeAttribute:@"bezel-color"]];
}
- (void)drawRect:(CGRect)aRect
{
[super drawRect:aRect];
var context = [[CPGraphicsContext currentContext] graphicsPort],
radius = [self currentValueForThemeAttribute:@"border-radius"],
strokeWidth = [self currentValueForThemeAttribute:@"stroke-width"],
strokeColor = [self currentValueForThemeAttribute:@"stroke-color"],
bgColor = [self currentValueForThemeAttribute:@"background-color"];
CGContextSetStrokeColor(context, strokeColor);
CGContextSetFillColor(context, bgColor);
CGContextSetLineWidth(context, strokeWidth);
aRect.origin.x += strokeWidth;
aRect.origin.y += strokeWidth;
aRect.size.width -= strokeWidth * 2;
aRect.size.height -= strokeWidth * 2;
var path = CGPathWithRoundedRectangleInRect(aRect, radius, radius, YES, YES, YES, YES);
CGContextAddPath(context, path);
CGContextStrokePath(context);
CGContextAddPath(context, path);
CGContextFillPath(context);
// Intentionally empty to disable legacy Canvas drawing.
}
@end
+32 -7
View File
@@ -8492,13 +8492,38 @@ var themedButtonValues = nil,
{
var toolTipView = [[_CPToolTipWindowView alloc] initWithFrame:CGRectMake(0.0, 0.0, 200.0, 100.0) styleMask:_CPToolTipWindowMask],
themeValues =
[
[@"stroke-color", [CPColor colorWithHexString:@"B0B0B0"]],
[@"stroke-width", 1.0],
[@"border-radius", 2.0],
[@"background-color", [CPColor colorWithHexString:@"FFFFCA"]],
[@"color", [CPColor blackColor]]
// Pure DOM CSS dictionary for Standard Tooltip
bezelColor =[CPColor colorWithCSSDictionary:@{
@"background-color": @"#FFFFCA",
@"border": @"1px solid #B0B0B0",
@"border-radius": @"2px",
@"box-sizing": @"border-box",
@"box-shadow": @"0px 1px 3px rgba(0,0,0,0.25)"
}],
// Pure DOM CSS dictionary for HUD Tooltip
hudBezelColor =[CPColor colorWithCSSDictionary:@{
@"background-color": @"rgba(0, 0, 0, 0.85)",
@"border": @"1px solid rgba(255, 255, 255, 0.25)",
@"border-radius": @"2px",
@"box-sizing": @"border-box",
@"box-shadow": @"0px 2px 5px rgba(0,0,0,0.5)"
}],
themeValues = [
// Legacy overrides zeroed out to prevent canvas interference
[@"stroke-color", [CPColor clearColor]],
[@"stroke-width", 0.0],
[@"border-radius", 0.0],
[@"background-color", [CPColor clearColor]],
// --- Standard Theme Mappings ---
[@"bezel-color", bezelColor],
[@"color", [CPColor blackColor]],
// --- HUD Theme Mappings ---
[@"bezel-color", hudBezelColor, CPThemeStateHUD],
[@"color", [CPColor whiteColor], CPThemeStateHUD]
];
[self registerThemeValues:themeValues forView:toolTipView];
+20 -5
View File
@@ -118,13 +118,9 @@ var _CPToolTipHeight = 24.0,
textFrameSizeSingleLine = [aText sizeWithFont:font],
textFrameSize = [aText sizeWithFont:font inWidth:(aToolTipSize.width)];
// this small adjustement fixes
// tooltips wrapping issues from fractional pixels.
textFrameSizeSingleLine.width += 1;
textFrameSize.width += 1;
// If the text fully fits within the maximum width, shrink to fit.
if (textFrameSizeSingleLine.width < aToolTipSize.width)
{
var textField = [[CPTextField alloc] initWithFrame:CGRectMakeZero()],
@@ -137,7 +133,14 @@ var _CPToolTipHeight = 24.0,
if (textFrameSize.height < 100)
{
aToolTipSize.height = textFrameSize.height + 4;
return [aToolTipSize, textFrameSize];
// FIX: Snap to whole pixels
aToolTipSize.width = CEIL(aToolTipSize.width);
aToolTipSize.height = CEIL(aToolTipSize.height);
textFrameSize.width = CEIL(textFrameSize.width);
textFrameSize.height = CEIL(textFrameSize.height);
return[aToolTipSize, textFrameSize];
}
var newWidth = aToolTipSize.width + ((parseInt(textFrameSize.height - 100) / _CPToolTipHeight) * _CPToolTipHeight);
@@ -145,6 +148,12 @@ var _CPToolTipHeight = 24.0,
aToolTipSize.width = newWidth + 2;
aToolTipSize.height = textFrameSize.height + 4;
// FIX: Snap to whole pixels
aToolTipSize.width = CEIL(aToolTipSize.width);
aToolTipSize.height = CEIL(aToolTipSize.height);
textFrameSize.width = CEIL(textFrameSize.width);
textFrameSize.height = CEIL(textFrameSize.height);
return [aToolTipSize, textFrameSize];
}
@@ -200,6 +209,12 @@ var _CPToolTipHeight = 24.0,
[self setLevel:CPStatusWindowLevel];
[self setAlphaValue:0.9];
if ([_toolTipWindow styleMask] & CPHUDBackgroundWindowMask)
{
[_content setThemeState:CPThemeStateHUD];
[_windowView setThemeState:CPThemeStateHUD];
}
[_windowView setNeedsDisplay:YES];
}