Permalink
Browse files

Merge pull request #2068 from daboe01/NEW--CPTextView

New: CPTextView, CPTextStorage, CPTextContainer, CPLayoutManager and CPSimpleTypesetter + CPFontPanel + RTF parser/producer [+2]
  • Loading branch information...
2 parents 0aeccbb + bdec147 commit bea03de5627a149f6b9ce9dd75ef8bd93596b10d @mrcarlberg mrcarlberg committed on GitHub Sep 26, 2016
Showing with 9,798 additions and 21 deletions.
  1. +1 −0 AppKit/AppKit.j
  2. +14 −2 AppKit/CPColor.j
  3. +1 −1 AppKit/CPControl.j
  4. +3 −1 AppKit/CPEvent.j
  5. +38 −0 AppKit/CPFont.j
  6. +208 −1 AppKit/CPFontManager.j
  7. +1 −0 AppKit/CPPasteboard.j
  8. +62 −5 AppKit/CPStringDrawing.j
  9. +300 −5 AppKit/CPText.j
  10. +315 −0 AppKit/CPTextView/CPFontDescriptor.j
  11. +502 −0 AppKit/CPTextView/CPFontPanel.j
  12. +1,373 −0 AppKit/CPTextView/CPLayoutManager.j
  13. +223 −0 AppKit/CPTextView/CPParagraphStyle.j
  14. +255 −0 AppKit/CPTextView/CPTextContainer.j
  15. +303 −0 AppKit/CPTextView/CPTextStorage.j
  16. +2,670 −0 AppKit/CPTextView/CPTextView.j
  17. +430 −0 AppKit/CPTextView/CPTypesetter.j
  18. +788 −0 AppKit/CPTextView/_CPRTFParser.j
  19. +615 −0 AppKit/CPTextView/_CPRTFProducer.j
  20. +3 −1 AppKit/Platform/DOM/CPPlatformString.j
  21. +5 −2 AppKit/Themes/Aristo/ThemeDescriptors.j
  22. +4 −2 AppKit/Themes/Aristo2/ThemeDescriptors.j
  23. +87 −0 Tests/AppKit/CPTextViewTest.j
  24. +105 −0 Tests/Manual/CPTextView/AppController.j
  25. +12 −0 Tests/Manual/CPTextView/Info.plist
  26. +94 −0 Tests/Manual/CPTextView/Jakefile
  27. BIN Tests/Manual/CPTextView/Resources/spinner.gif
  28. +103 −0 Tests/Manual/CPTextView/index-debug.html
  29. +74 −0 Tests/Manual/CPTextView/index.html
  30. +18 −0 Tests/Manual/CPTextView/main.j
  31. +34 −0 Tests/Manual/CPTextViewCibTest/AppController.j
  32. +14 −0 Tests/Manual/CPTextViewCibTest/Info.plist
  33. +184 −0 Tests/Manual/CPTextViewCibTest/Jakefile
  34. +1 −0 Tests/Manual/CPTextViewCibTest/Resources/MainMenu.cib
  35. +77 −0 Tests/Manual/CPTextViewCibTest/Resources/MainMenu.xib
  36. +191 −0 Tests/Manual/CPTextViewCibTest/index-debug.html
  37. +161 −0 Tests/Manual/CPTextViewCibTest/index.html
  38. +18 −0 Tests/Manual/CPTextViewCibTest/main.j
  39. +7 −1 Tools/nib2cib/NSAppKit.j
  40. +2 −0 Tools/nib2cib/NSAttributedString.j
  41. +63 −0 Tools/nib2cib/NSLayoutManager.j
  42. +66 −0 Tools/nib2cib/NSParagraphStyle.j
  43. +61 −0 Tools/nib2cib/NSText.j
  44. +64 −0 Tools/nib2cib/NSTextContainer.j
  45. +74 −0 Tools/nib2cib/NSTextStorage.j
  46. +74 −0 Tools/nib2cib/NSTextView.j
  47. +100 −0 Tools/nib2cib/NSTextViewSharedData.j
View
@@ -101,6 +101,7 @@
@import "CPTabView.j"
@import "CPText.j"
@import "CPTextField.j"
+@import "CPTextView.j"
@import "CPTokenField.j"
@import "CPToolbar.j"
@import "CPToolbarItem.j"
View
@@ -100,8 +100,10 @@ var cachedBlackColor,
+ (CPDictionary)themeAttributes
{
return @{
- @"alternate-selected-control-color": [CPNull null],
- @"secondary-selected-control-color" : [CPNull null]
+ @"alternate-selected-control-color": [CPNull null],
+ @"secondary-selected-control-color": [CPNull null],
+ @"selected-text-background-color": [CPNull null],
+ @"selected-text-inactive-background-color": [CPNull null]
};
}
@@ -498,6 +500,16 @@ var cachedBlackColor,
return [[CPColor alloc] _initWithCSSString: aString];
}
++ (CPColor)selectedTextBackgroundColor
+{
+ return [[self _cachedThemeColor] valueForThemeAttribute:@"selected-text-background-color"] || [CPColor colorWithHexString:"99CCFF"];
+}
+
++ (CPColor)_selectedTextBackgroundColorUnfocussed
+{
+ return [[self _cachedThemeColor] valueForThemeAttribute:@"selected-text-inactive-background-color"] || [CPColor colorWithHexString:"CCCCCC"];
+}
+
/* @ignore */
- (id)_initWithCSSString:(CPString)aString
{
View
@@ -25,7 +25,7 @@
@import "CPFont.j"
@import "CPShadow.j"
-@import "CPView.j"
+@import "CPText.j"
@import "CPKeyValueBinding.j"
@import "CPTrackingArea.j"
View
@@ -28,14 +28,16 @@
@import "CPCompatibility.j"
@import "CGGeometry.j"
-@import "CPText.j"
@import "CPTrackingArea.j"
@class CPTextField
@class CPWindow
@class CPGraphicsContext
@global CPApp
+@global CPNewlineCharacter
+@global CPCarriageReturnCharacter
+@global CPEnterCharacter
@typedef DOMEvent
@typedef CPEventType
View
@@ -24,6 +24,7 @@
@import <Foundation/CPBundle.j>
@import "CPView.j"
+@import "CPFontDescriptor.j"
CPFontDefaultSystemFontFace = @"Arial, sans-serif";
CPFontDefaultSystemFontSize = 12;
@@ -433,6 +434,43 @@ following:
@end
+@implementation CPFont(DescriptorAdditions)
+
+- (id)_initWithFontDescriptor:(CPFontDescriptor)fontDescriptor
+{
+ var aName = [fontDescriptor objectForKey: CPFontNameAttribute] ,
+ aSize = [fontDescriptor pointSize],
+ isBold = [fontDescriptor symbolicTraits] & CPFontBoldTrait,
+ isItalic = [fontDescriptor symbolicTraits] & CPFontItalicTrait;
+
+ return [self _initWithName:aName size:aSize bold:isBold italic:isItalic system:NO];
+}
+
++ (CPFont)fontWithDescriptor:(CPFontDescriptor)fontDescriptor size:(float)aSize
+{
+ var aName = [fontDescriptor objectForKey: CPFontNameAttribute],
+ isBold = [fontDescriptor symbolicTraits] & CPFontBoldTrait,
+ isItalic = [fontDescriptor symbolicTraits] & CPFontItalicTrait;
+
+ return [self _fontWithName:aName size:aSize || [fontDescriptor pointSize] bold:isBold italic:isItalic];
+}
+
+- (CPFontDescriptor)fontDescriptor
+{
+ var traits = 0;
+
+ if ([self isBold])
+ traits |= CPFontBoldTrait;
+
+ if ([self isItalic])
+ traits |= CPFontItalicTrait;
+
+ return [[CPFontDescriptor fontDescriptorWithName:_name size:_size] fontDescriptorWithSymbolicTraits:traits];
+}
+
+@end
+
+
var CPFontNameKey = @"CPFontNameKey",
CPFontSizeKey = @"CPFontSizeKey",
CPFontIsBoldKey = @"CPFontIsBoldKey",
View
@@ -22,9 +22,12 @@
@import <Foundation/CPObject.j>
+@import "CPControl.j"
@import "CPFont.j"
+@import "CPFontDescriptor.j"
@global CPApp
+@class CPFontPanel
CPItalicFontMask = 1 << 0;
CPBoldFontMask = 1 << 1;
@@ -41,7 +44,20 @@ CPUnitalicFontMask = 1 << 24;
var CPSharedFontManager = nil,
- CPFontManagerFactory = Nil;
+ CPFontManagerFactory = nil,
+ CPFontPanelFactory = nil;
+
+/*
+ modifyFont: sender's tag
+*/
+CPNoFontChangeAction = 0;
+CPViaPanelFontAction = 1;
+CPAddTraitFontAction = 2;
+CPSizeUpFontAction = 3;
+CPSizeDownFontAction = 4;
+CPHeavierFontAction = 5;
+CPLighterFontAction = 6;
+CPRemoveTraitFontAction = 7;
/*!
@ingroup appkit
@@ -59,6 +75,8 @@ var CPSharedFontManager = nil,
BOOL _multiple @accessors(getter=isMultiple, setter=setMultiple:);
CPDictionary _activeChange;
+
+ unsigned _fontAction;
}
// Getting the Shared Font Manager
@@ -83,6 +101,15 @@ var CPSharedFontManager = nil,
{
CPFontManagerFactory = aClass;
}
+/*!
+ Sets the class that will be used to create the application's
+ Font panel.
+*/
++ (void)setFontPanelFactory:(Class)aClass
+{
+ CPFontPanelFactory = aClass;
+}
+
- (id)init
{
@@ -210,6 +237,7 @@ var CPSharedFontManager = nil,
{
var tag = [sender tag];
_activeChange = tag === nil ? @{} : @{ @"addTraits": tag };
+ _fontAction = CPAddTraitFontAction;
[self sendAction];
}
@@ -219,6 +247,185 @@ var CPSharedFontManager = nil,
return [CPApp sendAction:_action to:_target from:self];
}
+
+/*!
+ This method open the font panel, create it if necessary.
+ @param sender The object that sent the message.
+*/
+- (CPFontPanel)fontPanel:(BOOL)createIt
+{
+ var panel = nil,
+ panelExists = [CPFontPanelFactory sharedFontPanelExists];
+
+ if ((panelExists) || (!panelExists && createIt))
+ panel = [CPFontPanelFactory sharedFontPanel];
+
+ return panel;
+}
+
+/*!
+ Convert a font to have the specified Font traits. The font is unchanged expect for the specified Font traits.
+ Using CPUnboldFontMask or CPUnitalicFontMask will respectively remove Bold and Italic traits.
+ @param aFont The font to convert.
+ @param fontTrait The new font traits mask.
+ @result The converted font or \c aFont if the conversion failed.
+*/
+- (CPFont)convertFont:(CPFont)aFont toHaveTrait:(CPFontTraitMask)fontTrait
+{
+ var attributes = [[[aFont fontDescriptor] fontAttributes] copy],
+ symbolicTrait = [[aFont fontDescriptor] symbolicTraits];
+
+ if (fontTrait & CPBoldFontMask)
+ symbolicTrait |= CPFontBoldTrait;
+
+ if (fontTrait & CPItalicFontMask)
+ symbolicTrait |= CPFontItalicTrait;
+
+ if (fontTrait & CPUnboldFontMask) /* FIXME: this only change CPFontSymbolicTrait what about CPFontWeightTrait */
+ symbolicTrait &= ~CPFontBoldTrait;
+
+ if (fontTrait & CPUnitalicFontMask)
+ symbolicTrait &= ~CPFontItalicTrait;
+
+ if (fontTrait & CPExpandedFontMask)
+ symbolicTrait |= CPFontExpandedTrait;
+
+ if (fontTrait & CPSmallCapsFontMask)
+ symbolicTrait |= CPFontSmallCapsTrait;
+
+ if (![attributes containsKey:CPFontTraitsAttribute])
+ [attributes setObject:[CPDictionary dictionaryWithObject:[CPNumber numberWithUnsignedInt:symbolicTrait]
+ forKey:CPFontSymbolicTrait]
+ forKey:CPFontTraitsAttribute];
+ else
+ [[attributes objectForKey:CPFontTraitsAttribute] setObject:[CPNumber numberWithUnsignedInt:symbolicTrait]
+ forKey:CPFontSymbolicTrait];
+
+ return [[aFont class] fontWithDescriptor:[CPFontDescriptor fontDescriptorWithFontAttributes:attributes] size:0.0];
+}
+
+/*!
+ Convert a font to not have the specified Font traits. The font is unchanged expect for the specified Font traits.
+ @param aFont The font to convert.
+ @param fontTrait The font traits mask to remove.
+ @result The converted font or \c aFont if the conversion failed.
+*/
+- (CPFont)convertFont:(CPFont)aFont toNotHaveTrait:(CPFontTraitMask)fontTrait
+{
+ var attributes = [[[aFont fontDescriptor] fontAttributes] copy],
+ symbolicTrait = [[aFont fontDescriptor] symbolicTraits];
+
+ if ((fontTrait & CPBoldFontMask) || (fontTrait & CPUnboldFontMask)) /* FIXME: see convertFont:toHaveTrait: about CPFontWeightTrait */
+ symbolicTrait &= ~CPFontBoldTrait;
+
+ if ((fontTrait & CPItalicFontMask) || (fontTrait & CPUnitalicFontMask))
+ symbolicTrait &= ~CPFontItalicTrait;
+
+ if (fontTrait & CPExpandedFontMask)
+ symbolicTrait &= ~CPFontExpandedTrait;
+
+ if (fontTrait & CPSmallCapsFontMask)
+ symbolicTrait &= ~CPFontSmallCapsTrait;
+
+ if (![attributes containsKey:CPFontTraitsAttribute])
+ [attributes setObject:[CPDictionary dictionaryWithObject:[CPNumber numberWithUnsignedInt:symbolicTrait]
+ forKey:CPFontSymbolicTrait]
+ forKey:CPFontTraitsAttribute];
+ else
+ [[attributes objectForKey:CPFontTraitsAttribute] setObject:[CPNumber numberWithUnsignedInt:symbolicTrait]
+ forKey:CPFontSymbolicTrait];
+
+ return [[aFont class] fontWithDescriptor:[CPFontDescriptor fontDescriptorWithFontAttributes:attributes] size:0.0];
+}
+
+/*!
+ Convert a font to have specified size. The font is unchanged expect for the specified size.
+ @param aFont The font to convert.
+ @param aSize The new font size.
+ @result The converted font or \c aFont if the conversion failed.
+*/
+- (CPFont)convertFont:(CPFont)aFont toSize:(float)aSize
+{
+ var descriptor = [aFont fontDescriptor];
+
+ return [[aFont class] fontWithDescriptor: descriptor size:aSize]
+}
+
+- (void)orderFrontFontPanel:(id)sender
+{
+ [[self fontPanel:YES] orderFront:sender];
+}
+
+- (void)modifyFont:(id)sender
+{
+ _fontAction = [sender tag];
+ [self sendAction];
+
+ if (_selectedFont)
+ [self setSelectedFont:[self convertFont:_selectedFont] isMultiple:NO];
+}
+
+/*!
+ This method causes the receiver to send its action message.
+ @param sender The object that sent the message. (a Font panel)
+*/
+- (void)modifyFontViaPanel:(id)sender
+{
+ _fontAction = CPViaPanelFontAction;
+ if (_selectedFont)
+ [self setSelectedFont:[self convertFont:_selectedFont] isMultiple:NO];
+
+ [self sendAction];
+}
+
+/*!
+ Convert a font according to current font changes, provided by the object that initiated the font change.
+ @param aFont The font to convert.
+ @result The converted font or \c aFont if the conversion failed.
+*/
+- (CPFont)convertFont:(CPFont)aFont
+{
+ var newFont = nil;
+ switch (_fontAction)
+ {
+ case CPNoFontChangeAction:
+ newFont = aFont;
+ break;
+
+ case CPViaPanelFontAction:
+ newFont = [[self fontPanel:NO] panelConvertFont:aFont];
+ break;
+
+ case CPAddTraitFontAction:
+ newFont = aFont;
+ if (!_activeChange)
+ break;
+
+ var addTraits = [_activeChange valueForKey:@"addTraits"];
+
+ if (addTraits)
+ newFont = [self convertFont:aFont toHaveTrait:addTraits];
+ break;
+
+ case CPSizeUpFontAction:
+ newFont = [self convertFont:aFont toSize:[aFont size] + 1.0]; /* any limit ? */
+ break;
+
+ case CPSizeDownFontAction:
+ if ([aFont size] > 1)
+ newFont = [self convertFont:aFont toSize:[aFont size] - 1.0];
+ /* else CPBeep() :-p */
+ break;
+
+ default:
+ CPLog.trace(@"-[" + [self className] + " " + _cmd + "] unsupported font action: " + _fontAction + " aFont unchanged");
+ newFont = aFont;
+ break;
+ }
+
+ return newFont;
+}
+
@end
var _CPFontDetectSpan,
@@ -44,6 +44,7 @@ CPStringPboardType = @"CPStringPboardType";
CPURLPboardType = @"CPURLPboardType";
CPImagesPboardType = @"CPImagesPboardType";
CPVideosPboardType = @"CPVideosPboardType";
+CPRTFPboardType = @"CPRTFPboardType";
UTF8PboardType = @"public.utf8-plain-text";
Oops, something went wrong.

0 comments on commit bea03de

Please sign in to comment.