mirror of
https://github.com/cappuccino/cappuccino.git
synced 2026-08-25 04:57:03 +00:00
444 lines
12 KiB
Plaintext
444 lines
12 KiB
Plaintext
/*
|
|
* CPFontPanel.j
|
|
* AppKit
|
|
*
|
|
* TODOs:
|
|
* 1. make browser-width for size smaller and fix columns
|
|
* 2. add all the missing features from the MacOS X counterpart (sampleview)
|
|
*
|
|
*
|
|
* Created by Daniel Boehringer on 2/JAN/2014.
|
|
* All modifications copyright Daniel Boehringer 2013.
|
|
* Extensive code formatting and review by Andrew Hankinson
|
|
* Based on original work by
|
|
* Created by Emmanuel Maillard on 06/03/2010.
|
|
* Copyright Emmanuel Maillard 2010.
|
|
*
|
|
* 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 "CPPanel.j"
|
|
@import "CPColorWell.j"
|
|
@import "CPColorPanel.j"
|
|
@import "CPBrowser.j"
|
|
@import "CPText.j"
|
|
@import "CPFontManager.j"
|
|
|
|
|
|
@class CPTextStorage
|
|
@class CPLayoutManager
|
|
@class CPTextContainer
|
|
@class CPFontManager
|
|
|
|
/*
|
|
Collection indexes
|
|
*/
|
|
var kTypefaceIndex_Normal = 0,
|
|
kTypefaceIndex_Italic = 1,
|
|
kTypefaceIndex_Bold = 2,
|
|
kTypefaceIndex_BoldItalic = 3,
|
|
kToolbarHeight = 32,
|
|
kBorderSpacing = 6,
|
|
kInnerSpacing = 2,
|
|
kNothingChanged = 0,
|
|
kFontNameChanged = 1,
|
|
kTypefaceChanged = 2,
|
|
kSizeChanged = 3,
|
|
kTextColorChanged = 4,
|
|
kBackgroundColorChanged = 5,
|
|
kUnderlineChanged = 6,
|
|
kWeightChanged = 7,
|
|
_sharedFontPanel;
|
|
|
|
// FIXME<!> Locale support
|
|
var _availableTraits= [@"Normal", @"Italic", @"Bold", @"Bold Italic"],
|
|
_availableSizes = [@"9", @"10", @"11", @"12", @"13", @"14", @"18", @"24", @"36", @"48", @"72", @"96"];
|
|
|
|
|
|
/*!
|
|
@ingroup appkit
|
|
@class CPFontPanel
|
|
*/
|
|
@implementation CPFontPanel : CPPanel
|
|
{
|
|
id _fontBrowser;
|
|
id _traitBrowser;
|
|
id _sizeBrowser;
|
|
CPArray _availableFonts;
|
|
id _textColorWell;
|
|
CPColor _textColor;
|
|
int _currentColorButtonTag;
|
|
BOOL _setupDone;
|
|
int _fontChanges;
|
|
}
|
|
|
|
|
|
#pragma mark -
|
|
#pragma mark Class methods
|
|
|
|
/*!
|
|
Check if the shared Font panel exists.
|
|
*/
|
|
+ (BOOL)sharedFontPanelExists
|
|
{
|
|
return _sharedFontPanel !== nil;
|
|
}
|
|
|
|
/*!
|
|
Return the shared Font panel.
|
|
*/
|
|
+ (CPFontPanel)sharedFontPanel
|
|
{
|
|
if (!_sharedFontPanel)
|
|
_sharedFontPanel = [[CPFontPanel alloc] init];
|
|
|
|
return _sharedFontPanel;
|
|
}
|
|
|
|
|
|
#pragma mark -
|
|
#pragma mark Init methods
|
|
|
|
/*! @ignore */
|
|
- (id)init
|
|
{
|
|
if (self = [super initWithContentRect:CGRectMake(100, 90, 450, 394) styleMask:(CPTitledWindowMask | CPClosableWindowMask /*| CPResizableWindowMask*/ )])
|
|
{
|
|
[[self contentView] setBackgroundColor:[CPColor colorWithWhite:0.95 alpha:1.0]];
|
|
[self setTitle:@"Font Panel"];
|
|
[self setLevel:CPFloatingWindowLevel];
|
|
[self setFloatingPanel:YES];
|
|
[self setBecomesKeyOnlyIfNeeded:YES];
|
|
[self setMinSize:CGSizeMake(378, 394)];
|
|
|
|
_availableFonts = [[CPFontManager sharedFontManager] availableFonts];
|
|
_textColor = [CPColor blackColor];
|
|
_setupDone = NO;
|
|
_fontChanges = kNothingChanged;
|
|
}
|
|
|
|
return self;
|
|
}
|
|
|
|
/*! @ignore */
|
|
- (void)_setupToolbarView
|
|
{
|
|
_toolbarView = [[CPView alloc] initWithFrame:CGRectMake(0, kBorderSpacing, CGRectGetWidth([self frame]), kToolbarHeight)];
|
|
[_toolbarView setAutoresizingMask:CPViewWidthSizable];
|
|
|
|
// Text color
|
|
_textColorWell = [[CPColorWell alloc] initWithFrame:CGRectMake(10, 0, 25, 25)];
|
|
[_textColorWell setColor:_textColor];
|
|
[_toolbarView addSubview:_textColorWell];
|
|
}
|
|
|
|
- (void)_setupBrowser:(CPBrowser)aBrowser
|
|
{
|
|
[aBrowser setTarget:self];
|
|
[aBrowser setAction:@selector(browserClicked:)];
|
|
[aBrowser setDoubleAction:@selector(dblClicked:)];
|
|
[aBrowser setAllowsEmptySelection:NO];
|
|
[aBrowser setAllowsMultipleSelection:NO];
|
|
[aBrowser setDelegate:self];
|
|
[[self contentView] addSubview:aBrowser];
|
|
}
|
|
|
|
- (void)_setupContents
|
|
{
|
|
if (_setupDone)
|
|
return;
|
|
|
|
_setupDone = YES;
|
|
|
|
[self _setupToolbarView];
|
|
|
|
var contentView = [self contentView],
|
|
label = [CPTextField labelWithTitle:@"Font name"],
|
|
contentBounds = [contentView bounds],
|
|
upperView = [[CPView alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth(contentBounds), CGRectGetHeight(contentBounds) - (kBorderSpacing + kToolbarHeight + kInnerSpacing))];
|
|
|
|
[contentView addSubview:_toolbarView];
|
|
|
|
_fontBrowser = [[CPBrowser alloc] initWithFrame:CGRectMake(10, 35, 150, 350)];
|
|
_traitBrowser = [[CPBrowser alloc] initWithFrame:CGRectMake(155, 35, 150, 350)];
|
|
_sizeBrowser = [[CPBrowser alloc] initWithFrame:CGRectMake(300, 35, 140, 350)];
|
|
|
|
[self _setupBrowser:_fontBrowser];
|
|
[self _setupBrowser:_traitBrowser];
|
|
[self _setupBrowser:_sizeBrowser];
|
|
|
|
[[CPNotificationCenter defaultCenter] addObserver:self
|
|
selector:@selector(textViewDidChangeSelection:)
|
|
name:CPTextViewDidChangeSelectionNotification
|
|
object:nil];
|
|
}
|
|
|
|
- (void)textViewDidChangeSelection:(CPNotification)notification
|
|
{
|
|
[self _refreshWithTextView:[notification object]];
|
|
|
|
}
|
|
|
|
- (void)_refreshWithTextView:(CPTextView)textView
|
|
{
|
|
if (![self isVisible])
|
|
return;
|
|
|
|
var attribs = [textView _attributesForFontPanel],
|
|
font = [attribs objectForKey:CPFontAttributeName] || [[textView textStorage] font] || [CPFont systemFontOfSize:12.0],
|
|
color = [attribs objectForKey:CPForegroundColorAttributeName];
|
|
|
|
if (!font)
|
|
return;
|
|
|
|
var trait = kTypefaceIndex_Normal;
|
|
|
|
if ([font isItalic] && [font isBold])
|
|
trait = kTypefaceIndex_BoldItalic;
|
|
else if ([font isItalic])
|
|
trait = kTypefaceIndex_Italic;
|
|
else if ([font isBold])
|
|
trait = kTypefaceIndex_Bold;
|
|
|
|
[self setCurrentFont:font];
|
|
[self setCurrentTrait:trait];
|
|
[self setCurrentSize:[font size] + ""]; //cast to string
|
|
|
|
if (!color)
|
|
return;
|
|
|
|
[_textColorWell setColor:color];
|
|
}
|
|
|
|
- (void)orderFront:(id)sender
|
|
{
|
|
[self _setupContents];
|
|
[super orderFront:sender];
|
|
[self _refreshWithTextView:[[CPApp keyWindow] firstResponder]];
|
|
}
|
|
|
|
- (void)reloadDefaultFontFamilies
|
|
{
|
|
_availableFonts = [[CPFontManager sharedFontManager] availableFonts];
|
|
}
|
|
|
|
- (BOOL)worksWhenModal
|
|
{
|
|
return YES;
|
|
}
|
|
|
|
/*!
|
|
@param aFont the font to convert.
|
|
@return The converted font or \c aFont if failed to convert.
|
|
*/
|
|
- (CPFont)panelConvertFont:(CPFont)aFont
|
|
{
|
|
var newFont = aFont,
|
|
index = 0;
|
|
|
|
switch (_fontChanges)
|
|
{
|
|
case kFontNameChanged:
|
|
newFont = [CPFont fontWithDescriptor:[[aFont fontDescriptor] fontDescriptorByAddingAttributes:
|
|
[CPDictionary dictionaryWithObject:[self currentFont] forKey:CPFontNameAttribute]] size:0.0];
|
|
break;
|
|
|
|
case kTypefaceChanged:
|
|
index = [self currentTrait];
|
|
if (index == kTypefaceIndex_BoldItalic)
|
|
newFont = [[CPFontManager sharedFontManager] convertFont:aFont toHaveTrait:CPBoldFontMask | CPItalicFontMask];
|
|
else if (index == kTypefaceIndex_Bold)
|
|
newFont = [[CPFontManager sharedFontManager] convertFont:aFont toHaveTrait:CPBoldFontMask];
|
|
else if (index == kTypefaceIndex_Italic)
|
|
newFont = [[CPFontManager sharedFontManager] convertFont:aFont toHaveTrait:CPItalicFontMask];
|
|
else
|
|
newFont = [[CPFontManager sharedFontManager] convertFont:aFont toNotHaveTrait:CPBoldFontMask | CPItalicFontMask];
|
|
break;
|
|
|
|
case kSizeChanged:
|
|
newFont = [[CPFontManager sharedFontManager] convertFont:aFont toSize:[self currentSize]];
|
|
break;
|
|
|
|
case kNothingChanged:
|
|
break;
|
|
|
|
default:
|
|
CPLog.trace(@"FIXME: -[" + [self className] + " " + _cmd + "] unhandled _fontChanges: " + _fontChanges);
|
|
break;
|
|
}
|
|
|
|
return newFont;
|
|
}
|
|
|
|
- (void)setCurrentSize:(CGSize)aSize
|
|
{
|
|
[_sizeBrowser selectRow:[_availableSizes indexOfObject:aSize] inColumn:0];
|
|
}
|
|
|
|
- (CPString)currentSize
|
|
{
|
|
return [_sizeBrowser selectedItem];
|
|
}
|
|
|
|
- (void)setCurrentFont:(CPFont)aFont
|
|
{
|
|
[_fontBrowser selectRow:[_availableFonts indexOfObject:[aFont familyName]] inColumn:0];
|
|
}
|
|
|
|
- (CPString)currentFont
|
|
{
|
|
return [_fontBrowser selectedItem];
|
|
}
|
|
|
|
- (void)setCurrentTrait:(unsigned)aTrait
|
|
{
|
|
var row = 0;
|
|
|
|
switch (aTrait)
|
|
{
|
|
case kTypefaceIndex_Italic:
|
|
row = 1;
|
|
break;
|
|
|
|
case kTypefaceIndex_Bold:
|
|
row = 2;
|
|
break;
|
|
|
|
case kTypefaceIndex_BoldItalic:
|
|
row = 3;
|
|
break;
|
|
}
|
|
|
|
[_traitBrowser selectRow:row inColumn:0];
|
|
}
|
|
|
|
// FIXME<!> Locale support
|
|
- (unsigned)currentTrait
|
|
{
|
|
var sel = [_traitBrowser selectedItem];
|
|
|
|
if (sel === "Italic")
|
|
return kTypefaceIndex_Italic;
|
|
|
|
if (sel === "Bold")
|
|
return kTypefaceIndex_Bold;
|
|
|
|
if (sel === "Bold Italic")
|
|
return kTypefaceIndex_BoldItalic;
|
|
|
|
return kTypefaceIndex_Normal;
|
|
}
|
|
|
|
/*!
|
|
Set the selected font in Font panel.
|
|
@param font the selected font
|
|
@param flag if \c the current selection have multiple fonts.
|
|
*/
|
|
- (void)setPanelFont:(CPFont)font isMultiple:(BOOL)flag
|
|
{
|
|
[self _setupContents];
|
|
|
|
if ([self currentFont] !== [font familyName])
|
|
[self setCurrentFont:[font familyName]];
|
|
|
|
if ([self currentSize] != [font size])
|
|
[self setCurrentSize:[font size]];
|
|
|
|
var typefaceIndex = kTypefaceIndex_Normal,
|
|
symbolicTraits = [[font fontDescriptor] symbolicTraits];
|
|
|
|
if ((symbolicTraits & CPFontItalicTrait) && (symbolicTraits & CPFontBoldTrait))
|
|
typefaceIndex = kTypefaceIndex_BoldItalic;
|
|
else if (symbolicTraits & CPFontItalicTrait)
|
|
typefaceIndex = kTypefaceIndex_Italic;
|
|
else if (symbolicTraits & CPFontBoldTrait)
|
|
typefaceIndex = kTypefaceIndex_Bold;
|
|
|
|
if ([self currentTrait] != typefaceIndex)
|
|
[self setCurrentTrait:typefaceIndex ];
|
|
|
|
_fontChanges = kNothingChanged;
|
|
}
|
|
|
|
- (void)changeColor:(id)sender
|
|
{
|
|
_textColor = [sender color];
|
|
_fontChanges = kTextColorChanged;
|
|
[[CPFontManager sharedFontManager] modifyFontViaPanel:self];
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// TODO: ask CPFontManager for traits //
|
|
- (void)browserClicked:(id)aBrowser
|
|
{
|
|
if (aBrowser === _fontBrowser)
|
|
{
|
|
_fontChanges = kFontNameChanged;
|
|
[[CPFontManager sharedFontManager] modifyFontViaPanel:self];
|
|
}
|
|
else if (aBrowser === _traitBrowser)
|
|
{
|
|
_fontChanges = kTypefaceChanged;
|
|
[[CPFontManager sharedFontManager] modifyFontViaPanel:self];
|
|
}
|
|
else if (aBrowser === _sizeBrowser)
|
|
{
|
|
_fontChanges = kSizeChanged;
|
|
[[CPFontManager sharedFontManager] modifyFontViaPanel:self];
|
|
}
|
|
}
|
|
|
|
- (void)dblClicked:(id)sender
|
|
{
|
|
// alert("DOUBLE");
|
|
}
|
|
|
|
- (id)browser:(id)aBrowser numberOfChildrenOfItem:(id)anItem
|
|
{
|
|
if (aBrowser === _fontBrowser)
|
|
return [_availableFonts count];
|
|
|
|
if (aBrowser === _traitBrowser)
|
|
return [_availableTraits count];
|
|
|
|
return [_availableSizes count]
|
|
}
|
|
|
|
- (id)browser:(id)aBrowser child:(int)index ofItem:(id)anItem
|
|
{
|
|
if (aBrowser === _fontBrowser)
|
|
return [_availableFonts objectAtIndex:index];
|
|
|
|
if (aBrowser === _traitBrowser)
|
|
return [_availableTraits objectAtIndex:index];
|
|
|
|
return [_availableSizes objectAtIndex:index];
|
|
}
|
|
|
|
- (id)browser:(id)aBrowser objectValueForItem:(id)anItem
|
|
{
|
|
return anItem;
|
|
}
|
|
|
|
- (BOOL)browser:(id)aBrowser isLeafItem:(id)anItem
|
|
{
|
|
return YES;
|
|
}
|
|
|
|
@end
|
|
|
|
[CPFontManager setFontPanelFactory:[CPFontPanel class]];
|