mirror of
https://github.com/cappuccino/cappuccino.git
synced 2026-08-25 13:07:02 +00:00
This patch fix the blink problem with FF, by changing the positionning of tooltips, which by the way reflects more the Cocoa behaviour.
296 lines
7.9 KiB
Plaintext
296 lines
7.9 KiB
Plaintext
/*
|
|
* _CPToolTip.j
|
|
* AppKit
|
|
*
|
|
* Created by Antoine Mercadal
|
|
* Copyright 2011 <primalmotion@archipelproject.org>
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
|
|
@import "CPTextField.j"
|
|
@import "CPView.j"
|
|
@import "CPWindow.j"
|
|
|
|
_CPToolTipWindowMask = 1 << 27;
|
|
|
|
var _CPToolTipHeight = 24.0,
|
|
_CPToolTipFontSize = 11.0,
|
|
_CPCurrentToolTip,
|
|
_CPCurrentToolTipTimer,
|
|
_CPToolTipDelay = 1.0;
|
|
|
|
/*! @ingroup appkit
|
|
This is a basic tooltip that behaves mostly like Cocoa ones.
|
|
*/
|
|
@implementation _CPToolTip : CPWindow
|
|
{
|
|
CPTextField _content;
|
|
}
|
|
|
|
|
|
#pragma mark -
|
|
#pragma mark Class Methods
|
|
|
|
/*! Returns an initialized _CPToolTip with the given text and attach it to given view.
|
|
@param aString the content of the tooltip
|
|
*/
|
|
+ (_CPToolTip)toolTipWithString:(CPString)aString
|
|
{
|
|
var tooltip = [[_CPToolTip alloc] initWithString:aString styleMask:_CPToolTipWindowMask];
|
|
|
|
[tooltip showToolTip];
|
|
|
|
return tooltip;
|
|
}
|
|
|
|
/*!
|
|
Compute a cool size for the given string.
|
|
|
|
@param aToolTipSize a frame with the maximum width desired for the tooltip
|
|
@param aText the wanted text
|
|
@return CPArray containing the computer toolTipSize and textFrameSize
|
|
*/
|
|
+ (CPSize)computeCorrectSize:(CPSize)aToolTipSize text:(CPString)aText
|
|
{
|
|
var font = [CPFont systemFontOfSize:_CPToolTipFontSize],
|
|
textFrameSizeSingleLine = [aText sizeWithFont:font],
|
|
textFrameSize = [aText sizeWithFont:font inWidth:(aToolTipSize.width)];
|
|
|
|
// If the text fully fits within the maximum width, shrink to fit.
|
|
if (textFrameSizeSingleLine.width < aToolTipSize.width)
|
|
{
|
|
var textField = [[CPTextField alloc] initWithFrame:CGRectMakeZero()],
|
|
inset = [textField currentValueForThemeAttribute:@"content-inset"] || CGInsetMakeZero();
|
|
textFrameSize = textFrameSizeSingleLine;
|
|
textFrameSize.width += inset.left + inset.right;
|
|
aToolTipSize.width = textFrameSize.width;
|
|
}
|
|
|
|
if (textFrameSize.height < 100)
|
|
{
|
|
aToolTipSize.height = textFrameSize.height + 4;
|
|
return [aToolTipSize, textFrameSize];
|
|
}
|
|
|
|
var newWidth = aToolTipSize.width + ((parseInt(textFrameSize.height - 100) / _CPToolTipHeight) * _CPToolTipHeight);
|
|
textFrameSize = [aText sizeWithFont:font inWidth:newWidth - 4];
|
|
aToolTipSize.width = newWidth + 2;
|
|
aToolTipSize.height = textFrameSize.height + 4;
|
|
|
|
return [aToolTipSize, textFrameSize];
|
|
}
|
|
|
|
/*!
|
|
Override default windowView class loader.
|
|
|
|
@param aStyleMask the window mask
|
|
@return the windowView class
|
|
*/
|
|
+ (Class)_windowViewClassForStyleMask:(unsigned)aStyleMask
|
|
{
|
|
return _CPToolTipWindowView;
|
|
}
|
|
|
|
|
|
#pragma mark -
|
|
#pragma mark Initialization
|
|
|
|
/*!
|
|
Returns an initialized _CPToolTip with string.
|
|
|
|
@param aString the content of the tooltip
|
|
@param aStyleMask the tooltip's style mask
|
|
*/
|
|
- (id)initWithString:(CPString)aString styleMask:(unsigned)aStyleMask
|
|
{
|
|
var toolTipFrame = CPRectMake(0.0, 0.0, 250.0, _CPToolTipHeight),
|
|
layout = [_CPToolTip computeCorrectSize:toolTipFrame.size text:aString],
|
|
textFrameSize = layout[1];
|
|
|
|
toolTipFrame.size = layout[0];
|
|
|
|
if (self = [super initWithContentRect:toolTipFrame styleMask:aStyleMask])
|
|
{
|
|
textFrameSize.height += 4;
|
|
|
|
_content = [CPTextField labelWithTitle:aString];
|
|
[_content setFont:[CPFont systemFontOfSize:_CPToolTipFontSize]]
|
|
[_content setLineBreakMode:CPLineBreakByCharWrapping];
|
|
[_content setAlignment:CPJustifiedTextAlignment];
|
|
[_content setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
|
|
[_content setFrameOrigin:CPPointMake(0.0, 0.0)];
|
|
[_content setFrameSize:textFrameSize];
|
|
[_content setTextShadowOffset:CGSizeMake(0.0, 1.0)];
|
|
[_content setTextColor:[CPColor blackColor]];
|
|
|
|
[[self contentView] addSubview:_content];
|
|
|
|
[self setLevel:CPStatusWindowLevel];
|
|
[self setAlphaValue:0.9];
|
|
|
|
[_windowView setNeedsDisplay:YES];
|
|
}
|
|
|
|
return self;
|
|
}
|
|
|
|
|
|
#pragma mark -
|
|
#pragma mark Controls
|
|
|
|
/*!
|
|
Show the tooltip after computing the position.
|
|
*/
|
|
- (void)showToolTip
|
|
{
|
|
var mousePosition = [[CPApp currentEvent] globalLocation],
|
|
nativeRect = [[[CPApp mainWindow] platformWindow] nativeContentRect];
|
|
|
|
mousePosition.y += 20;
|
|
|
|
if (mousePosition.x < 0)
|
|
mousePosition.x = 5;
|
|
if (mousePosition.x + CPRectGetWidth([self frame]) > nativeRect.size.width)
|
|
mousePosition.x = nativeRect.size.width - CPRectGetWidth([self frame]) - 5;
|
|
if (mousePosition.y < 0)
|
|
mousePosition.y = 5;
|
|
if (mousePosition.y + CPRectGetHeight([self frame]) > nativeRect.size.height)
|
|
mousePosition.y = mousePosition.y - CPRectGetHeight([self frame]) - 40;
|
|
|
|
[self setFrameOrigin:mousePosition];
|
|
[self orderFront:nil];
|
|
}
|
|
|
|
@end
|
|
|
|
|
|
|
|
/*! @ingroup appkit
|
|
Add tooltip support to CPView.
|
|
*/
|
|
@implementation CPView (toolTips)
|
|
|
|
/*!
|
|
Sets the tooltip for the receiver.
|
|
|
|
@param aToolTip the tooltip
|
|
*/
|
|
- (void)setToolTip:(CPString)aToolTip
|
|
{
|
|
if (_toolTip == aToolTip)
|
|
return;
|
|
|
|
_toolTip = aToolTip;
|
|
|
|
if (!_DOMElement)
|
|
return;
|
|
|
|
var fIn = function(e)
|
|
{
|
|
[self _fireToolTip];
|
|
},
|
|
fOut = function(e)
|
|
{
|
|
[self _invalidateToolTip];
|
|
};
|
|
|
|
if (_toolTip)
|
|
{
|
|
if (_DOMElement.addEventListener)
|
|
{
|
|
_DOMElement.addEventListener("mouseover", fIn, NO);
|
|
_DOMElement.addEventListener("keypress", fOut, NO);
|
|
_DOMElement.addEventListener("mouseout", fOut, NO);
|
|
}
|
|
else if (_DOMElement.attachEvent)
|
|
{
|
|
_DOMElement.attachEvent("onmouseover", fIn);
|
|
_DOMElement.attachEvent("onkeypress", fOut);
|
|
_DOMElement.attachEvent("onmouseout", fOut);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (_DOMElement.removeEventListener)
|
|
{
|
|
_DOMElement.removeEventListener("mouseover", fIn, NO);
|
|
_DOMElement.removeEventListener("keypress", fOut, NO);
|
|
_DOMElement.removeEventListener("mouseout", fOut, NO);
|
|
}
|
|
else if (_DOMElement.detachEvent)
|
|
{
|
|
_DOMElement.detachEvent("onmouseover", fIn);
|
|
_DOMElement.detachEvent("onkeypress", fOut);
|
|
_DOMElement.detachEvent("onmouseout", fOut);
|
|
}
|
|
}
|
|
}
|
|
|
|
/*!
|
|
Returns the receiver's tooltip.
|
|
*/
|
|
- (CPString)toolTip
|
|
{
|
|
return _toolTip;
|
|
}
|
|
|
|
/*! @ignore
|
|
Starts the tooltip timer.
|
|
*/
|
|
- (void)_fireToolTip
|
|
{
|
|
if (_CPCurrentToolTipTimer)
|
|
{
|
|
[_CPCurrentToolTipTimer invalidate];
|
|
if (_CPCurrentToolTip)
|
|
[_CPCurrentToolTip close];
|
|
_CPCurrentToolTip = nil;
|
|
}
|
|
|
|
if (_toolTip)
|
|
_CPCurrentToolTipTimer = [CPTimer scheduledTimerWithTimeInterval:_CPToolTipDelay target:self selector:@selector(_showToolTip:) userInfo:nil repeats:NO];
|
|
}
|
|
|
|
/*! @ignore
|
|
Stop the tooltip timer if any
|
|
*/
|
|
- (void)_invalidateToolTip
|
|
{
|
|
if (_CPCurrentToolTipTimer)
|
|
{
|
|
[_CPCurrentToolTipTimer invalidate];
|
|
_CPCurrentToolTipTimer = nil;
|
|
}
|
|
|
|
if (_CPCurrentToolTip)
|
|
{
|
|
[_CPCurrentToolTip close];
|
|
_CPCurrentToolTip = nil;
|
|
}
|
|
}
|
|
|
|
/*! @ignore
|
|
Actually shows the tooltip if any
|
|
*/
|
|
- (void)_showToolTip:(CPTimer)aTimer
|
|
{
|
|
if (_CPCurrentToolTip)
|
|
[_CPCurrentToolTip close];
|
|
_CPCurrentToolTip = [_CPToolTip toolTipWithString:_toolTip];
|
|
}
|
|
|
|
@end
|