mirror of
https://github.com/cappuccino/cappuccino.git
synced 2026-09-09 20:27:13 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0f160f648e | ||
|
|
f53a922ed4 | ||
|
|
40cdc9108a | ||
|
|
69c8c3d0a2 | ||
|
|
a42f597463 | ||
|
|
a1eddb9e50 | ||
|
|
29163884ce | ||
|
|
aa592b8bc6 | ||
|
|
e0ce1603ff | ||
|
|
0597e477ae | ||
|
|
b9e734a21b | ||
|
|
45bd822c28 | ||
|
|
3467a60215 | ||
|
|
831e0b4b85 | ||
|
|
d64966594d | ||
|
|
f2c10e9f4c | ||
|
|
a091a7c5d6 | ||
|
|
f06bdbb14f | ||
|
|
76a3d0b6da | ||
|
|
078ab40d99 | ||
|
|
d44dd5da19 | ||
|
|
35132e7f46 | ||
|
|
231b3052fc | ||
|
|
9bec13a72b | ||
|
|
fb348ed4f7 | ||
|
|
e49144c80a | ||
|
|
94799f19dc | ||
|
|
e1762fdcdd | ||
|
|
fa077e4fc7 | ||
|
|
fd745d37a9 | ||
|
|
2da26b2de2 | ||
|
|
17dc653149 | ||
|
|
e779198a80 | ||
|
|
092550e2a3 | ||
|
|
579129b891 | ||
|
|
ec8bb7e14d | ||
|
|
4af4c6706f | ||
|
|
fb9c0715b3 | ||
|
|
8cedfebc07 | ||
|
|
93736b7ba9 | ||
|
|
e801064bd9 | ||
|
|
6b9bad37c2 | ||
|
|
915047b996 | ||
|
|
8231d8ddf1 | ||
|
|
125673880c | ||
|
|
b24cb2c48e | ||
|
|
a56458384c | ||
|
|
063f2f0283 | ||
|
|
4aac83b50d | ||
|
|
48b4345e80 | ||
|
|
4636c0f3b8 | ||
|
|
db5f5ba332 | ||
|
|
7c093e1a64 | ||
|
|
d9859af73c | ||
|
|
83bc94d1c3 | ||
|
|
3a4b8fe947 | ||
|
|
5385e63fd2 | ||
|
|
e1a3f2b64d | ||
|
|
3d3674a7d8 | ||
|
|
192b6ecfc4 | ||
|
|
79ff197cde | ||
|
|
836698f8d2 | ||
|
|
ac52d32c29 | ||
|
|
e66a0656c8 | ||
|
|
7dcf5629d7 | ||
|
|
facb129183 | ||
|
|
13557bd13f | ||
|
|
dccdfb5635 | ||
|
|
aba4c865e4 | ||
|
|
9709ca8b52 | ||
|
|
ea74a503a3 | ||
|
|
675d1ebd57 | ||
|
|
7eb042d985 | ||
|
|
dc4aa545f0 | ||
|
|
b70abb730d | ||
|
|
36a2cc9a62 | ||
|
|
113be1254e | ||
|
|
674a03dc23 | ||
|
|
9656985dbd | ||
|
|
0b4fe62f89 | ||
|
|
847a9c2b98 | ||
|
|
ce78d098ec | ||
|
|
18c1866db7 | ||
|
|
1ae0566cf1 | ||
|
|
383fb9d704 | ||
|
|
7f281d0442 | ||
|
|
2d76a03b01 | ||
|
|
f96ffde1fb | ||
|
|
39fb7c6b5b | ||
|
|
0fa2b62cc9 | ||
|
|
ea69f8b9cc | ||
|
|
b0e88390e5 | ||
|
|
4882f26142 | ||
|
|
373737cfd0 | ||
|
|
475945d329 | ||
|
|
5111a02672 | ||
|
|
12477179cb | ||
|
|
ab81b1ad32 | ||
|
|
0af674ca74 | ||
|
|
5b95490371 | ||
|
|
993e9a9e86 | ||
|
|
2f32e5eaef | ||
|
|
fcd1897883 | ||
|
|
77063efe58 | ||
|
|
57a53abbf7 | ||
|
|
e30380a8f9 | ||
|
|
cdcaf1c4d4 | ||
|
|
e62b22da55 | ||
|
|
7bd8660f89 | ||
|
|
d0c63345f2 | ||
|
|
1a7b7054fb | ||
|
|
01fc279709 | ||
|
|
5540ef8ca7 | ||
|
|
ef3ee2e660 | ||
|
|
d661c83acc | ||
|
|
437bcc8078 | ||
|
|
68316732de | ||
|
|
0a42b39a94 | ||
|
|
ac1407484a | ||
|
|
a531dc6fc0 | ||
|
|
e42d5b860e | ||
|
|
57858db161 | ||
|
|
f3392c7df1 | ||
|
|
18c2145138 | ||
|
|
ff6981bf10 | ||
|
|
db82911b1f | ||
|
|
768f5121cb | ||
|
|
c2d7a1dc74 | ||
|
|
61efb2fcdf | ||
|
|
b6716f77e0 | ||
|
|
47c4bb957b | ||
|
|
1a64819ab5 | ||
|
|
ff7939df03 | ||
|
|
443ced0dce | ||
|
|
baf505df52 | ||
|
|
90331b075a | ||
|
|
900e3b6ea1 | ||
|
|
74d8463255 | ||
|
|
af6692d616 | ||
|
|
6611b74c19 | ||
|
|
37bff8b70b | ||
|
|
d964b9f10a | ||
|
|
189a2ddc3d | ||
|
|
641b35d965 | ||
|
|
433e6606b6 | ||
|
|
bc88af047e | ||
|
|
b93beb8730 | ||
|
|
24a176c736 | ||
|
|
4d741040b6 | ||
|
|
92a30edf6c | ||
|
|
031c3acc57 | ||
|
|
500541a785 | ||
|
|
60e01cdb33 | ||
|
|
c0c5325d8a | ||
|
|
fbe4b3d439 | ||
|
|
aa72c9e081 | ||
|
|
91db2f409e | ||
|
|
2c2211026f | ||
|
|
578f00172f | ||
|
|
fb93d3dcf0 | ||
|
|
10989ada31 | ||
|
|
28e9063c04 | ||
|
|
63ec5e78b6 | ||
|
|
52f6503631 | ||
|
|
a5a91d7258 | ||
|
|
a00b94ec33 | ||
|
|
78b1e292f9 | ||
|
|
d9d86df1bd | ||
|
|
b5f9f05f9f | ||
|
|
245561d40f | ||
|
|
9301ba7c25 | ||
|
|
24e9eadfab | ||
|
|
fe8f2deb6e | ||
|
|
1ae19f88b9 | ||
|
|
50702a0560 | ||
|
|
fbee21dad3 | ||
|
|
13c3fe5771 | ||
|
|
fde9f56d4d | ||
|
|
f2ca8ab940 | ||
|
|
3d0b1b7680 | ||
|
|
40172028e6 | ||
|
|
49923fa140 | ||
|
|
b96a4e5b94 | ||
|
|
9a50fc4789 | ||
|
|
601daf9e72 | ||
|
|
2658852ec2 | ||
|
|
737fd115e4 | ||
|
|
461f341abc | ||
|
|
c26feeb73e | ||
|
|
29714ae18f | ||
|
|
496f934adb | ||
|
|
bf15c2bf11 | ||
|
|
07cf8ac9be | ||
|
|
9708f80ad4 | ||
|
|
0bd0dc6216 | ||
|
|
d3e5583070 | ||
|
|
10eedb2bb5 | ||
|
|
d381a602b7 | ||
|
|
266251ffbf | ||
|
|
cd9bb7a86e | ||
|
|
97f98e3c93 | ||
|
|
c72c761a60 | ||
|
|
2fe83853ac | ||
|
|
cd940d64ed | ||
|
|
15d4575b0a | ||
|
|
e21d23e911 | ||
|
|
9e649ce96a | ||
|
|
68526721b7 | ||
|
|
be3c5dac8a | ||
|
|
26cac2b84d | ||
|
|
2f552abf94 | ||
|
|
7129ebe884 | ||
|
|
b9992215f8 | ||
|
|
0c55a5f372 | ||
|
|
8cc33d1e37 | ||
|
|
73169f0be5 | ||
|
|
7f8d3f289b | ||
|
|
d8c74e81b8 | ||
|
|
3000254e67 | ||
|
|
2356340f0b | ||
|
|
227d743666 | ||
|
|
b53feeb04c | ||
|
|
3b1043a6b4 | ||
|
|
ba32f92e69 | ||
|
|
5c7d978245 | ||
|
|
d96b642f4f | ||
|
|
2366c5c1fd | ||
|
|
84a85a767c | ||
|
|
e0c9bd10a4 | ||
|
|
eed6c93349 | ||
|
|
7023bb8b90 | ||
|
|
579814a5de | ||
|
|
a2786a9aee | ||
|
|
bcd0c725ce | ||
|
|
3c1c01fd9f | ||
|
|
3364d1c5cc | ||
|
|
639a0fe1c2 | ||
|
|
d3cc6c29c9 | ||
|
|
89c00e193b | ||
|
|
b38a5d19b1 | ||
|
|
f7ae515d84 | ||
|
|
37fedd41e3 | ||
|
|
3711461201 | ||
|
|
4ddd8ac263 | ||
|
|
aa7a96cfb8 | ||
|
|
2c2768a34f | ||
|
|
91c2fd2085 | ||
|
|
9ab63ee854 | ||
|
|
ef1dd16766 | ||
|
|
39f4b573da | ||
|
|
2a0306b14d | ||
|
|
e0735a1d82 | ||
|
|
6f44fe9f93 | ||
|
|
f390e5ed17 | ||
|
|
ede3eb64ae | ||
|
|
d0d4972681 | ||
|
|
4be4a65c72 | ||
|
|
3e009bbf26 | ||
|
|
3db3f03e5d | ||
|
|
698f58eaa0 | ||
|
|
95cf933ab2 | ||
|
|
692f365fed | ||
|
|
96aa310839 | ||
|
|
8d3da8e4fa | ||
|
|
885145d43d | ||
|
|
c893e4a809 | ||
|
|
1536c55b99 | ||
|
|
f3f94eec66 | ||
|
|
51b633f0d7 | ||
|
|
5f1007dcbc | ||
|
|
ae7ce81b8c | ||
|
|
8b72e5db31 | ||
|
|
0d35ceda31 | ||
|
|
ed59003a95 | ||
|
|
94501c4618 | ||
|
|
bf3847ce59 | ||
|
|
c6ea894f10 | ||
|
|
8df4e1ee6e | ||
|
|
b608709014 | ||
|
|
0450136af3 | ||
|
|
29e4695503 | ||
|
|
a7a080f416 | ||
|
|
effb274410 | ||
|
|
45f6f4bc90 | ||
|
|
82b91b2f64 | ||
|
|
59a9d8c093 | ||
|
|
ae42acaef3 | ||
|
|
531be2db49 | ||
|
|
8089973b7b | ||
|
|
1e8cc3101b | ||
|
|
a27a5fbc32 | ||
|
|
fccd76ec4c | ||
|
|
39738b9ded | ||
|
|
3a18574838 | ||
|
|
ec238f2cc3 | ||
|
|
8c08803fd0 | ||
|
|
cc084692ae | ||
|
|
96a25dfcaa | ||
|
|
500237b2c8 | ||
|
|
67a0098c7a | ||
|
|
4fc80f4bbd | ||
|
|
eca41e7474 | ||
|
|
9107322d28 | ||
|
|
f5ca6c39f6 | ||
|
|
653fdb999e | ||
|
|
f25d76d0d6 | ||
|
|
41b0f80360 | ||
|
|
31fe918b3d | ||
|
|
32495792dc | ||
|
|
30bdbb4544 |
@@ -93,7 +93,6 @@
|
||||
@import "CPSlider.j"
|
||||
@import "CPSound.j"
|
||||
@import "CPSplitView.j"
|
||||
@import "CPStackView.j"
|
||||
@import "CPStepper.j"
|
||||
@import "CPTableColumn.j"
|
||||
@import "CPTableView.j"
|
||||
|
||||
+82
-32
@@ -418,20 +418,25 @@ var bottomHeight = 71;
|
||||
*/
|
||||
- (void)addButtonWithTitle:(CPString)aTitle
|
||||
{
|
||||
var bounds = [[_window contentView] bounds],
|
||||
count = [_buttons count],
|
||||
|
||||
var count = [_buttons count],
|
||||
button = [[CPButton alloc] initWithFrame:CGRectMakeZero()];
|
||||
|
||||
[button setTitle:aTitle];
|
||||
[button setTag:count];
|
||||
[button setTarget:self];
|
||||
[button setAction:@selector(_takeReturnCodeFrom:)];
|
||||
[button setBezelStyle:CPSmallSquareBezelStyle];
|
||||
|
||||
[[_window contentView] addSubview:button];
|
||||
// Only add subview if the window has been created.
|
||||
// Otherwise, _createWindowWithStyle will handle adding the buttons from the _buttons array later.
|
||||
if (_window)
|
||||
[[_window contentView] addSubview:button];
|
||||
|
||||
if (count == 0)
|
||||
{
|
||||
[button setKeyEquivalent:CPCarriageReturnCharacter];
|
||||
[button setBezelStyle:CPRoundedBezelStyle];
|
||||
}
|
||||
else if ([aTitle lowercaseString] === @"cancel")
|
||||
[button setKeyEquivalent:CPEscapeFunctionKey];
|
||||
|
||||
@@ -530,6 +535,9 @@ var bottomHeight = 71;
|
||||
[[_window contentView] addSubview:_suppressionButton];
|
||||
}
|
||||
|
||||
/*!
|
||||
@ignore
|
||||
*/
|
||||
/*!
|
||||
@ignore
|
||||
*/
|
||||
@@ -539,25 +547,17 @@ var bottomHeight = 71;
|
||||
minimumSize = [_themeView currentValueForThemeAttribute:@"size"],
|
||||
buttonOffset = [_themeView currentValueForThemeAttribute:@"button-offset"],
|
||||
helpLeftOffset = [_themeView currentValueForThemeAttribute:@"help-image-left-offset"],
|
||||
aRepresentativeButton = [_buttons objectAtIndex:0],
|
||||
defaultElementsMargin = [_themeView currentValueForThemeAttribute:@"default-elements-margin"],
|
||||
panelSize = [[_window contentView] frame].size,
|
||||
|
||||
buttonsOriginY,
|
||||
buttonMarginY,
|
||||
buttonMarginX,
|
||||
theme = [self theme],
|
||||
offsetX;
|
||||
|
||||
[aRepresentativeButton setTheme:[self theme]];
|
||||
[aRepresentativeButton sizeToFit];
|
||||
|
||||
panelSize.height = CGRectGetMaxY([lastView frame]) + defaultElementsMargin + [aRepresentativeButton frameSize].height;
|
||||
if (panelSize.height < minimumSize.height)
|
||||
panelSize.height = minimumSize.height;
|
||||
|
||||
buttonsOriginY = panelSize.height - [aRepresentativeButton frameSize].height + buttonOffset;
|
||||
offsetX = panelSize.width - inset.right;
|
||||
var isHUD = (_defaultWindowStyle & CPHUDBackgroundWindowMask) || (theme === [CPTheme defaultHudTheme]);
|
||||
|
||||
// 1. Determine Margins (Moved up so we can use them in height calculation)
|
||||
switch ([_window styleMask])
|
||||
{
|
||||
case _CPModalWindowMask:
|
||||
@@ -571,27 +571,61 @@ var bottomHeight = 71;
|
||||
break;
|
||||
}
|
||||
|
||||
// 2. Prepare buttons and get row height
|
||||
var maxButtonHeight = 0.0;
|
||||
|
||||
for (var i = 0; i < [_buttons count]; i++)
|
||||
{
|
||||
var btn = _buttons[i];
|
||||
[btn sizeToFit];
|
||||
|
||||
if (isHUD)
|
||||
[btn setThemeState:CPThemeStateHUD];
|
||||
else
|
||||
[btn unsetThemeState:CPThemeStateHUD];
|
||||
|
||||
maxButtonHeight = MAX(maxButtonHeight, CGRectGetHeight([btn frame]));
|
||||
}
|
||||
|
||||
// 3. Calculate Content Height
|
||||
var lastViewMaxY = CGRectGetMaxY([lastView frame]);
|
||||
// Use bottomHeight (71) to reserve space for the footer
|
||||
var requiredContentHeight = lastViewMaxY + bottomHeight;
|
||||
|
||||
var finalContentSize = CGSizeMake(
|
||||
[[_window contentView] frame].size.width,
|
||||
MAX(requiredContentHeight, minimumSize.height)
|
||||
);
|
||||
|
||||
// 4. Position Buttons
|
||||
// Calculate the top Y coordinate to vertically center the button row within the bottomHeight area
|
||||
// Center Y of footer = Height - (bottomHeight / 2.0)
|
||||
// Top Y of button = Center Y - (maxButtonHeight / 2.0)
|
||||
buttonsOriginY = finalContentSize.height - ((bottomHeight + maxButtonHeight) / 2.0) - buttonMarginY;
|
||||
|
||||
offsetX = finalContentSize.width - inset.right;
|
||||
// Loop and set frames
|
||||
for (var i = [_buttons count] - 1; i >= 0 ; i--)
|
||||
{
|
||||
var button = _buttons[i];
|
||||
[button setTheme:[self theme]];
|
||||
[button sizeToFit];
|
||||
|
||||
var buttonFrame = [button frame],
|
||||
var button = _buttons[i],
|
||||
buttonFrame = [button frame],
|
||||
width = MAX(80.0, CGRectGetWidth(buttonFrame)),
|
||||
height = CGRectGetHeight(buttonFrame);
|
||||
height = CGRectGetHeight(buttonFrame),
|
||||
yOffset = FLOOR((maxButtonHeight - height) / 2.0);
|
||||
|
||||
offsetX -= width;
|
||||
[button setFrame:CGRectMake(offsetX + buttonMarginX, buttonsOriginY + buttonMarginY, width, height)];
|
||||
[button setFrame:CGRectMake(offsetX + buttonMarginX, buttonsOriginY + buttonMarginY + yOffset, width, height)];
|
||||
offsetX -= 10;
|
||||
}
|
||||
|
||||
// Position Help Button if needed
|
||||
if (_showHelp)
|
||||
{
|
||||
var helpImage = [_themeView currentValueForThemeAttribute:@"help-image"],
|
||||
helpImagePressed = [_themeView currentValueForThemeAttribute:@"help-image-pressed"],
|
||||
helpImageSize = helpImage ? [helpImage size] : CGSizeMakeZero(),
|
||||
helpFrame = CGRectMake(helpLeftOffset, buttonsOriginY, helpImageSize.width, helpImageSize.height);
|
||||
helpYOffset = FLOOR((maxButtonHeight - helpImageSize.height) / 2.0),
|
||||
helpFrame = CGRectMake(helpLeftOffset, buttonsOriginY + buttonMarginY + helpYOffset, helpImageSize.width, helpImageSize.height);
|
||||
|
||||
[_alertHelpButton setImage:helpImage];
|
||||
[_alertHelpButton setAlternateImage:helpImagePressed];
|
||||
@@ -599,8 +633,7 @@ var bottomHeight = 71;
|
||||
[_alertHelpButton setFrame:helpFrame];
|
||||
}
|
||||
|
||||
panelSize.height += [aRepresentativeButton frameSize].height + inset.bottom + buttonOffset;
|
||||
return panelSize;
|
||||
return finalContentSize;
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -614,9 +647,14 @@ var bottomHeight = 71;
|
||||
if (!_window)
|
||||
[self _createWindowWithStyle:nil];
|
||||
|
||||
// Ensure the theme view knows if we are in HUD mode so it picks up the right specificities
|
||||
if ((_defaultWindowStyle & CPHUDBackgroundWindowMask) || ([self theme] === [CPTheme defaultHudTheme]))
|
||||
[_themeView setThemeState:CPThemeStateHUD];
|
||||
else
|
||||
[_themeView unsetThemeState:CPThemeStateHUD];
|
||||
|
||||
var iconOffset = [_themeView currentValueForThemeAttribute:@"image-offset"],
|
||||
theImage = _icon,
|
||||
finalSize;
|
||||
theImage = _icon;
|
||||
|
||||
if (!theImage)
|
||||
switch (_alertStyle)
|
||||
@@ -648,11 +686,17 @@ var bottomHeight = 71;
|
||||
else if (_accessoryView)
|
||||
lastView = _accessoryView;
|
||||
|
||||
finalSize = [self _layoutButtonsFromView:lastView];
|
||||
if ([_window styleMask] & CPDocModalWindowMask)
|
||||
finalSize.height -= 26; // adjust the absence of title bar
|
||||
|
||||
[_window setFrameSize:finalSize];
|
||||
// 1. Get the size needed for the *content* (text, buttons, padding)
|
||||
var finalContentSize = [self _layoutButtonsFromView:lastView];
|
||||
|
||||
// 2. Convert Content Size -> Frame Size
|
||||
// This accounts for the Title Bar and borders automatically.
|
||||
var contentRect = CGRectMake(0.0, 0.0, finalContentSize.width, finalContentSize.height);
|
||||
var frameRect = [[_window class] frameRectForContentRect:contentRect styleMask:[_window styleMask]];
|
||||
|
||||
// 3. Apply the calculated Frame Size
|
||||
[_window setFrameSize:frameRect.size];
|
||||
|
||||
[_window center];
|
||||
|
||||
if ([_window styleMask] & _CPModalWindowMask || [_window styleMask] & CPHUDBackgroundWindowMask)
|
||||
@@ -752,6 +796,12 @@ var bottomHeight = 71;
|
||||
var frame = CGRectMakeZero();
|
||||
frame.size = [_themeView currentValueForThemeAttribute:@"size"];
|
||||
|
||||
// Propagate CPHUDBackgroundWindowMask from _defaultWindowStyle to forceStyle.
|
||||
// This ensures that even if we force CPDocModalWindowMask (for sheets),
|
||||
// the window still knows it should be a HUD.
|
||||
if (_defaultWindowStyle & CPHUDBackgroundWindowMask)
|
||||
forceStyle |= CPHUDBackgroundWindowMask;
|
||||
|
||||
_window = [[CPPanel alloc] initWithContentRect:frame styleMask:forceStyle || _defaultWindowStyle];
|
||||
[_window setLevel:CPStatusWindowLevel];
|
||||
[_window setPlatformWindow:[[CPApp keyWindow] platformWindow]];
|
||||
|
||||
+75
-2
@@ -122,6 +122,10 @@ var CPApplicationDelegate_applicationShouldTerminate_ = 1 << 0,
|
||||
CPPanel _aboutPanel;
|
||||
|
||||
CPThemeBlend _themeBlend @accessors(property=themeBlend);
|
||||
|
||||
// OS behavior
|
||||
CPApplicationOSBehavior _OSBehavior;
|
||||
BOOL _simulatesWindows;
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -154,6 +158,9 @@ var CPApplicationDelegate_applicationShouldTerminate_ = 1 << 0,
|
||||
_eventListenerInsertionIndex = 0;
|
||||
|
||||
_windows = [[CPNull null]];
|
||||
|
||||
_OSBehavior = CPApplicationLegacyOSBehavior;
|
||||
_simulatesWindows = NO;
|
||||
}
|
||||
|
||||
return self;
|
||||
@@ -1260,7 +1267,45 @@ var CPApplicationDelegate_applicationShouldTerminate_ = 1 << 0,
|
||||
|
||||
+ (CPString)defaultThemeName
|
||||
{
|
||||
return ([[CPBundle mainBundle] objectForInfoDictionaryKey:"CPDefaultTheme"] || @"Aristo2");
|
||||
return ([[CPBundle mainBundle] objectForInfoDictionaryKey:"CPDefaultTheme"] || @"Aristo3");
|
||||
}
|
||||
|
||||
// See CPApplication_Constants.j for comments
|
||||
- (void)setOSBehavior:(CPApplicationOSBehavior)anOSBehavior
|
||||
{
|
||||
// Verify if provided OS behavior is valid
|
||||
if ([[CPApplicationOSBehaviors allKeysForObject:anOSBehavior] count] == 0)
|
||||
{
|
||||
CPLog.warn("CPApplication setOSBehavior: invalid CPApplicationOSBehavior (received "+anOSBehavior+"). Ignored.");
|
||||
return;
|
||||
}
|
||||
|
||||
_OSBehavior = anOSBehavior;
|
||||
|
||||
[[CPNotificationCenter defaultCenter] postNotificationName:CPApplicationOSBehaviorDidChangeNotification object:CPApp userInfo:nil];
|
||||
}
|
||||
|
||||
- (CPApplicationOSBehavior)OSBehavior
|
||||
{
|
||||
return _OSBehavior;
|
||||
}
|
||||
|
||||
- (BOOL)shouldMimicWindows
|
||||
{
|
||||
return (_OSBehavior == CPApplicationFollowOSBehavior) && (CPBrowserIsOperatingSystem(CPWindowsOperatingSystem) || _simulatesWindows);
|
||||
}
|
||||
|
||||
- (void)setSimulatesWindows:(BOOL)shouldSimulateWindows
|
||||
{
|
||||
if (_simulatesWindows === shouldSimulateWindows)
|
||||
return;
|
||||
|
||||
_simulatesWindows = shouldSimulateWindows;
|
||||
}
|
||||
|
||||
- (BOOL)simulatesWindows
|
||||
{
|
||||
return _simulatesWindows;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -1375,7 +1420,7 @@ var _CPAppBootstrapperActions = nil;
|
||||
var defaultThemeName = [CPApplication defaultThemeName],
|
||||
themeURL = nil;
|
||||
|
||||
if (defaultThemeName === @"Aristo" || defaultThemeName === @"Aristo2")
|
||||
if (defaultThemeName === @"Aristo" || defaultThemeName === @"Aristo2" || defaultThemeName === @"Aristo3")
|
||||
themeURL = [[CPBundle bundleForClass:[CPApplication class]] pathForResource:defaultThemeName + @".blend"];
|
||||
else
|
||||
themeURL = [[CPBundle mainBundle] pathForResource:defaultThemeName + @".blend"];
|
||||
@@ -1391,6 +1436,34 @@ var _CPAppBootstrapperActions = nil;
|
||||
[[CPApplication sharedApplication] setThemeBlend:aThemeBlend];
|
||||
[CPTheme setDefaultTheme:[CPTheme themeNamed:[CPApplication defaultThemeName]]];
|
||||
|
||||
// Search in the Info.plist if the special CPApplicationSimulateWindowsOS flag is set (for testing)
|
||||
[CPApp setSimulatesWindows:!![[CPBundle mainBundle] objectForInfoDictionaryKey:"CPApplicationSimulateWindowsOS"]];
|
||||
|
||||
// Before loading the main CIB, try to find if a CPApplicationOSBehavior is specified in the Info.plist or in the user defaults
|
||||
// (with user defaults precedence). Value stored must be a string representing the name of the OS behavior.
|
||||
var plistOSBehavior = [[CPBundle mainBundle] objectForInfoDictionaryKey:"CPApplicationOSBehavior"],
|
||||
userOSBehavior = [[CPUserDefaults standardUserDefaults] objectForKey:@"CPApplicationOSBehavior"];
|
||||
|
||||
if (userOSBehavior)
|
||||
{
|
||||
var osBehavior = [CPApplicationOSBehaviors objectForKey:userOSBehavior];
|
||||
|
||||
if (osBehavior)
|
||||
[CPApp setOSBehavior:osBehavior];
|
||||
else
|
||||
CPLog.warn("Invalid CPApplicationOSBehavior specified in user defaults (found:"+userOSBehavior+"). Ignored.");
|
||||
}
|
||||
|
||||
else if (plistOSBehavior)
|
||||
{
|
||||
var osBehavior = [CPApplicationOSBehaviors objectForKey:plistOSBehavior];
|
||||
|
||||
if (osBehavior)
|
||||
[CPApp setOSBehavior:osBehavior];
|
||||
else
|
||||
CPLog.warn("Invalid CPApplicationOSBehavior specified in Info.plist (found:"+plistOSBehavior+"). Ignored.");
|
||||
}
|
||||
|
||||
[self performActions];
|
||||
}
|
||||
|
||||
|
||||
@@ -39,3 +39,15 @@ CPTerminateLater = -1; // not currently supported
|
||||
CPRunStoppedResponse = -1000;
|
||||
CPRunAbortedResponse = -1001;
|
||||
CPRunContinuesResponse = -1002;
|
||||
|
||||
// Should the application follow Cappuccino UX-UI (which is OSX like) or OS UX-UI (mainly Windows) ?
|
||||
// See explanation on https://github.com/cappuccino/cappuccino/wiki/CPApplicationSelectedOSBehavior
|
||||
@typedef CPApplicationOSBehavior
|
||||
CPApplicationLegacyOSBehavior = 1;
|
||||
CPApplicationFollowOSBehavior = 2;
|
||||
|
||||
CPApplicationOSBehaviorDidChangeNotification = @"CPApplicationOSBehaviorDidChangeNotification";
|
||||
CPApplicationOSBehaviors = @{
|
||||
@"CPApplicationLegacyOSBehavior": CPApplicationLegacyOSBehavior,
|
||||
@"CPApplicationFollowOSBehavior": CPApplicationFollowOSBehavior
|
||||
};
|
||||
|
||||
+2
-2
@@ -285,7 +285,7 @@ CPBelowBottom = 6;
|
||||
// MARK: borderColor
|
||||
- (CPColor)borderColor
|
||||
{
|
||||
return [self valueForThemeAttribute:@"border-color"];
|
||||
return [self currentValueForThemeAttribute:@"border-color"];
|
||||
}
|
||||
|
||||
- (void)setBorderColor:(CPColor)color
|
||||
@@ -785,7 +785,7 @@ CPBelowBottom = 6;
|
||||
[_boxView setFrame:CGRectMake(0,2,bounds.size.width,1)];
|
||||
}
|
||||
|
||||
[_boxView setBackgroundColor:[self valueForThemeAttribute:@"border-color"]];
|
||||
[_boxView setBackgroundColor:[self currentValueForThemeAttribute:@"border-color"]];
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
+1
-1
@@ -153,7 +153,7 @@ var CPBrowserDelegate_browser_acceptDrop_atRow_column_dropOperation_
|
||||
|
||||
_prototypeView = [[CPTextField alloc] initWithFrame:CGRectMakeZero()];
|
||||
[_prototypeView setVerticalAlignment:CPCenterVerticalTextAlignment];
|
||||
[_prototypeView setValue:[CPColor whiteColor] forThemeAttribute:"text-color" inState:CPThemeStateSelectedDataView];
|
||||
[_prototypeView setValue:[CPColor whiteColor] forThemeAttribute:"text-color" inState:CPThemeStateSelectedDataView.and(CPThemeStateTableDataView)];
|
||||
[_prototypeView setLineBreakMode:CPLineBreakByTruncatingTail];
|
||||
|
||||
_horizontalScrollView = [[CPScrollView alloc] initWithFrame:[self bounds]];
|
||||
|
||||
+10
-4
@@ -98,7 +98,8 @@ var CPButtonBezelStyleStateMap = @{
|
||||
CPRegularSquareBezelStyle: CPButtonStateBezelStyleRegularSquare,
|
||||
CPTexturedSquareBezelStyle: CPButtonStateBezelStyleTextured,
|
||||
CPDisclosureBezelStyle: CPButtonStateBezelStyleDisclosure,
|
||||
CPRoundedDisclosureBezelStyle: CPButtonStateBezelStyleRoundedDisclosure
|
||||
CPRoundedDisclosureBezelStyle: CPButtonStateBezelStyleRoundedDisclosure,
|
||||
CPHUDBezelStyle: CPThemeStateHUD
|
||||
};
|
||||
|
||||
/// @cond IGNORE
|
||||
@@ -707,12 +708,17 @@ CPButtonImageOffset = 3.0;
|
||||
// Note : We have to split content and image visual states as, for example, radio buttons don't follow push buttons behavior
|
||||
- (CPThemeState)_contentVisualState
|
||||
{
|
||||
var visualState = [self themeState] || CPThemeStateNormal, // Needed during theme compilation
|
||||
var visualState = [self themeState] || CPThemeStateNormal,
|
||||
currentState = [self state],
|
||||
buttonIsOn = (currentState !== CPOffState);
|
||||
|
||||
// If the button is pushed (_isHighlighted), always add the highlighted state
|
||||
if (_isHighlighted || (((_showsStateBy & CPChangeGrayCellMask) || (_showsStateBy & CPChangeBackgroundCellMask)) && buttonIsOn))
|
||||
// Define masks that imply the background changes color (Blue/Gray)
|
||||
// If the background changes, we usually want the text to turn White (Highlighted state).
|
||||
var highlightMask = CPPushInCellMask | CPChangeGrayCellMask | CPChangeBackgroundCellMask;
|
||||
|
||||
// Only add CPThemeStateHighlighted if the button is configured to highlight visually (Background change)
|
||||
if ((_isHighlighted && (_highlightsBy & highlightMask)) ||
|
||||
(((_showsStateBy & CPChangeGrayCellMask) || (_showsStateBy & CPChangeBackgroundCellMask)) && buttonIsOn))
|
||||
visualState = visualState.and(CPThemeStateHighlighted);
|
||||
else
|
||||
visualState = visualState.without(CPThemeStateHighlighted);
|
||||
|
||||
+1687
-167
File diff suppressed because it is too large
Load Diff
+9
-19
@@ -91,7 +91,7 @@ var CPComboBoxTextSubview = @"text",
|
||||
{
|
||||
return @{
|
||||
@"popup-button-size": CGSizeMake(21.0, 29.0),
|
||||
@"border-inset": CGInsetMake(3.0, 3.0, 3.0, 3.0),
|
||||
@"border-inset": CGInsetMake(3.0, 3.0, 3.0, 3.0)
|
||||
};
|
||||
}
|
||||
|
||||
@@ -533,7 +533,7 @@ var CPComboBoxTextSubview = @"text",
|
||||
CPComboBoxFocusRingWidth = inset.bottom;
|
||||
}
|
||||
|
||||
[_listDelegate popUpRelativeToRect:[self _borderFrame] view:self offset:CPComboBoxFocusRingWidth - 1];
|
||||
[_listDelegate popUpRelativeToRect:[self bounds] view:self offset:CPComboBoxFocusRingWidth - 1];
|
||||
[self _selectMatchingItem];
|
||||
}
|
||||
|
||||
@@ -570,6 +570,13 @@ var CPComboBoxTextSubview = @"text",
|
||||
_selectedStringValue = selectedStringValue;
|
||||
|
||||
[self setStringValue:_selectedStringValue];
|
||||
|
||||
[self _updatePlaceholderState];
|
||||
|
||||
#if PLATFORM(DOM)
|
||||
[self _setCSSStyleForInputElement];
|
||||
#endif
|
||||
|
||||
[self _reverseSetBinding];
|
||||
|
||||
return YES;
|
||||
@@ -975,23 +982,6 @@ var CPComboBoxTextSubview = @"text",
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
Calculate the frame in base coordinates that will nestle just below the visible border of the text field.
|
||||
@ignore
|
||||
*/
|
||||
- (CGRect)_borderFrame
|
||||
{
|
||||
var inset = [self currentValueForThemeAttribute:@"border-inset"],
|
||||
frame = [self bounds];
|
||||
|
||||
frame.origin.x += inset.left;
|
||||
frame.origin.y += inset.top;
|
||||
frame.size.width -= inset.left + inset.right;
|
||||
frame.size.height -= inset.top + inset.bottom;
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
/* @ignore */
|
||||
- (void)_popUpButtonWasClicked
|
||||
{
|
||||
|
||||
+5
-1
@@ -48,9 +48,10 @@
|
||||
CPRegularControlSize = 0;
|
||||
CPSmallControlSize = 1;
|
||||
CPMiniControlSize = 2;
|
||||
CPLargeControlSize = 3; // Since MacOS 11, there's a new control size "Large"
|
||||
|
||||
// To get the theme state corresponding to a control size, use CPControlSizeThemeStates[controlSize]
|
||||
CPControlSizeThemeStates = @[CPThemeStateControlSizeRegular, CPThemeStateControlSizeSmall, CPThemeStateControlSizeMini];
|
||||
CPControlSizeThemeStates = @[CPThemeStateControlSizeRegular, CPThemeStateControlSizeSmall, CPThemeStateControlSizeMini, CPThemeStateControlSizeLarge];
|
||||
|
||||
@typedef CPLineBreakMode
|
||||
CPLineBreakByWordWrapping = 0;
|
||||
@@ -248,6 +249,9 @@ var CPControlBlackColor = [CPColor blackColor];
|
||||
|
||||
case CPMiniControlSize:
|
||||
return CPThemeStateControlSizeMini;
|
||||
|
||||
case CPLargeControlSize:
|
||||
return CPThemeStateControlSizeLarge;
|
||||
|
||||
case CPRegularControlSize:
|
||||
default:
|
||||
|
||||
@@ -24,14 +24,11 @@
|
||||
@import <Foundation/CPKeyedUnarchiver.j>
|
||||
@import "CPView.j"
|
||||
@import "CPTextField.j"
|
||||
@import "CPImageView.j"
|
||||
@import "CPImage.j"
|
||||
@import "CALayer.j"
|
||||
|
||||
@class _CPCibCustomResource
|
||||
@class CPDatePicker
|
||||
@class HandImageLayer
|
||||
@class HoursLayer
|
||||
@class HandLayer
|
||||
|
||||
@global CPHourMinuteSecondDatePickerElementFlag
|
||||
@global CPTextFieldAndStepperDatePickerStyle
|
||||
@@ -47,15 +44,19 @@ _CPDatePickerClockSeconds = 3;
|
||||
@implementation _CPDatePickerClock : CPControl
|
||||
{
|
||||
BOOL _isEnabled;
|
||||
HoursLayer _rootLayer;
|
||||
HandLayer _hourHandLayer;
|
||||
HandLayer _minuteHandLayer;
|
||||
HandLayer _secondHandLayer;
|
||||
CALayer _middleHandLayer;
|
||||
CPDatePicker _datePicker;
|
||||
|
||||
// Pure DOM Views
|
||||
CPImageView _hourHandView;
|
||||
CPImageView _minuteHandView;
|
||||
CPImageView _secondHandView;
|
||||
CPImageView _middleHandView;
|
||||
|
||||
CPArray _hourLabels;
|
||||
CPTextField _PMAMTextField;
|
||||
|
||||
CALayer _currentHandLayer;
|
||||
CPDatePicker _datePicker;
|
||||
|
||||
CPView _currentHandView;
|
||||
_CPDatePickerClockHand _currentHand;
|
||||
CPInteger _currentRepresentedValue;
|
||||
float _currentValueShift;
|
||||
@@ -67,9 +68,13 @@ _CPDatePickerClockSeconds = 3;
|
||||
CPInteger _representedSeconds;
|
||||
BOOL _representedHourIsPM;
|
||||
|
||||
CPInteger _datePickerElements @accessors(getter=datePickerElements);
|
||||
}
|
||||
// Angles for Hit-Testing
|
||||
float _hourAngle;
|
||||
float _minuteAngle;
|
||||
float _secondAngle;
|
||||
|
||||
CPInteger _datePickerElements @accessors(getter=datePickerElements);
|
||||
}
|
||||
|
||||
// MARK: -
|
||||
// MARK: Init methods
|
||||
@@ -81,69 +86,53 @@ _CPDatePickerClockSeconds = 3;
|
||||
_datePicker = aDatePicker;
|
||||
_datePickerElements = [_datePicker datePickerElements];
|
||||
_trackingHand = NO;
|
||||
_isEnabled = YES;
|
||||
|
||||
// 1. Initialize AM/PM Label
|
||||
_PMAMTextField = [[CPTextField alloc] initWithFrame:CGRectMakeZero()];
|
||||
|
||||
[_PMAMTextField setValue:[_datePicker valueForThemeAttribute:@"clock-font" inState:CPThemeStateNormal] forThemeAttribute:@"font" inState:CPThemeStateNormal];
|
||||
[_PMAMTextField setValue:[_datePicker valueForThemeAttribute:@"clock-text-color" inState:CPThemeStateNormal] forThemeAttribute:@"text-color" inState:CPThemeStateNormal];
|
||||
[_PMAMTextField setValue:[_datePicker valueForThemeAttribute:@"clock-text-shadow-color" inState:CPThemeStateNormal] forThemeAttribute:@"text-shadow-color" inState:CPThemeStateNormal];
|
||||
[_PMAMTextField setValue:[_datePicker valueForThemeAttribute:@"clock-text-shadow-offset" inState:CPThemeStateNormal] forThemeAttribute:@"text-shadow-offset" inState:CPThemeStateNormal];
|
||||
|
||||
[_PMAMTextField setValue:[_datePicker valueForThemeAttribute:@"clock-font" inState:CPThemeStateDisabled] forThemeAttribute:@"font" inState:CPThemeStateDisabled];
|
||||
[_PMAMTextField setValue:[_datePicker valueForThemeAttribute:@"clock-text-color" inState:CPThemeStateDisabled] forThemeAttribute:@"text-color" inState:CPThemeStateDisabled];
|
||||
[_PMAMTextField setValue:[_datePicker valueForThemeAttribute:@"clock-text-shadow-color" inState:CPThemeStateDisabled] forThemeAttribute:@"text-shadow-color" inState:CPThemeStateDisabled];
|
||||
[_PMAMTextField setValue:[_datePicker valueForThemeAttribute:@"clock-text-shadow-offset" inState:CPThemeStateDisabled] forThemeAttribute:@"text-shadow-offset" inState:CPThemeStateDisabled];
|
||||
|
||||
[_PMAMTextField setAlignment:CPCenterTextAlignment];
|
||||
[_PMAMTextField setVerticalAlignment:CPCenterVerticalTextAlignment];
|
||||
[self addSubview:_PMAMTextField];
|
||||
|
||||
var middleHandSize = [_datePicker valueForThemeAttribute:@"middle-hand-size"],
|
||||
minuteHandSize = [_datePicker valueForThemeAttribute:@"minute-hand-size"],
|
||||
hourHandSize = [_datePicker valueForThemeAttribute:@"hour-hand-size"],
|
||||
secondHandSize = [_datePicker valueForThemeAttribute:@"second-hand-size"];
|
||||
// 2. Initialize Number Labels (1 to 12)
|
||||
_hourLabels = [CPArray array];
|
||||
|
||||
// We use layer to make the rotation possible
|
||||
_hourHandLayer = [[HandLayer alloc] initWithSize:hourHandSize];
|
||||
[_hourHandLayer setBounds:CGRectMake(0, 0, aFrame.size.width, aFrame.size.height)];
|
||||
[_hourHandLayer setAnchorPoint:CGPointMakeZero()];
|
||||
[_hourHandLayer setPosition:CGPointMake(0.0, 0.0)];
|
||||
for (var i = 1; i <= 12; i++)
|
||||
{
|
||||
var label = [[CPTextField alloc] initWithFrame:CGRectMakeZero()];
|
||||
[label setStringValue:String(i)];
|
||||
[label setAlignment:CPCenterTextAlignment];
|
||||
[label setVerticalAlignment:CPCenterVerticalTextAlignment];
|
||||
[self addSubview:label];
|
||||
[_hourLabels addObject:label];
|
||||
}
|
||||
|
||||
_minuteHandLayer = [[HandLayer alloc] initWithSize:minuteHandSize];
|
||||
[_minuteHandLayer setBounds:CGRectMake(0, 0, aFrame.size.width, aFrame.size.height)];
|
||||
[_minuteHandLayer setAnchorPoint:CGPointMakeZero()];
|
||||
[_minuteHandLayer setPosition:CGPointMake(0.0, 0.0)];
|
||||
// 3. Initialize Hand Views
|
||||
_hourHandView = [[CPImageView alloc] initWithFrame:CGRectMakeZero()];
|
||||
_minuteHandView = [[CPImageView alloc] initWithFrame:CGRectMakeZero()];
|
||||
_secondHandView = [[CPImageView alloc] initWithFrame:CGRectMakeZero()];
|
||||
_middleHandView = [[CPImageView alloc] initWithFrame:CGRectMakeZero()];
|
||||
|
||||
_secondHandLayer = [[HandLayer alloc] initWithSize:secondHandSize];
|
||||
[_secondHandLayer setBounds:CGRectMake(0, 0, aFrame.size.width, aFrame.size.height)];
|
||||
[_secondHandLayer setAnchorPoint:CGPointMakeZero()];
|
||||
[_secondHandLayer setPosition:CGPointMake(0.0, 0.0)];
|
||||
// Ensure images stretch accurately across the bounds of the image view
|
||||
[_hourHandView setImageScaling:CPImageScaleAxesIndependently];
|
||||
[_minuteHandView setImageScaling:CPImageScaleAxesIndependently];
|
||||
[_secondHandView setImageScaling:CPImageScaleAxesIndependently];
|
||||
[_middleHandView setImageScaling:CPImageScaleAxesIndependently];
|
||||
|
||||
_middleHandLayer = [[HandLayer alloc] initWithSize:middleHandSize];
|
||||
[_middleHandLayer setBounds:CGRectMake(0, 0, aFrame.size.width, aFrame.size.height)];
|
||||
[_middleHandLayer setAnchorPoint:CGPointMakeZero()];
|
||||
[_middleHandLayer setPosition:CGPointMake(0.0, 0.0)];
|
||||
|
||||
_rootLayer = [[HoursLayer alloc] init];
|
||||
[self setWantsLayer:YES];
|
||||
[self setLayer:_rootLayer];
|
||||
|
||||
[self _initHands];
|
||||
|
||||
[_rootLayer addSublayer:_hourHandLayer];
|
||||
[_rootLayer addSublayer:_minuteHandLayer];
|
||||
// 4. Add subviews in correct Z-Order
|
||||
[self addSubview:_hourHandView];
|
||||
[self addSubview:_minuteHandView];
|
||||
|
||||
if ([_datePicker valueForThemeAttribute:@"clock-second-hand-over"])
|
||||
{
|
||||
[_rootLayer addSublayer:_middleHandLayer];
|
||||
[_rootLayer addSublayer:_secondHandLayer];
|
||||
[self addSubview:_middleHandView];
|
||||
[self addSubview:_secondHandView];
|
||||
}
|
||||
else
|
||||
{
|
||||
[_rootLayer addSublayer:_secondHandLayer];
|
||||
[_rootLayer addSublayer:_middleHandLayer];
|
||||
[self addSubview:_secondHandView];
|
||||
[self addSubview:_middleHandView];
|
||||
}
|
||||
|
||||
[_rootLayer setDrawsHours:[_datePicker valueForThemeAttribute:@"clock-draws-hours"]];
|
||||
[_rootLayer setNeedsDisplay];
|
||||
}
|
||||
|
||||
return self;
|
||||
@@ -151,60 +140,58 @@ _CPDatePickerClockSeconds = 3;
|
||||
|
||||
- (void)_initHands
|
||||
{
|
||||
var middleHandImage = [_datePicker currentValueForThemeAttribute:@"middle-hand-image"],
|
||||
hourHandImage = [_datePicker currentValueForThemeAttribute:@"hour-hand-image"],
|
||||
minuteHandImage = [_datePicker currentValueForThemeAttribute:@"minute-hand-image"],
|
||||
secondHandImage = [_datePicker currentValueForThemeAttribute:@"second-hand-image"];
|
||||
// FIX: Using 'duplicate' prevents CPImageViews from stealing the DOM element from each other!
|
||||
[_middleHandView setImage:[[_datePicker currentValueForThemeAttribute:@"middle-hand-image"] duplicate]];
|
||||
[_hourHandView setImage:[[_datePicker currentValueForThemeAttribute:@"hour-hand-image"] duplicate]];
|
||||
[_minuteHandView setImage:[[_datePicker currentValueForThemeAttribute:@"minute-hand-image"] duplicate]];
|
||||
[_secondHandView setImage:[[_datePicker currentValueForThemeAttribute:@"second-hand-image"] duplicate]];
|
||||
|
||||
// If hand images are true CPImage, we have to duplicate them to avoid
|
||||
// the multiple delegates bug when multiple clocks are displayed
|
||||
var font = [_datePicker currentValueForThemeAttribute:@"clock-font"],
|
||||
textColor = [_datePicker currentValueForThemeAttribute:@"clock-text-color"],
|
||||
shadowCol = [_datePicker currentValueForThemeAttribute:@"clock-text-shadow-color"],
|
||||
shadowOff = [_datePicker currentValueForThemeAttribute:@"clock-text-shadow-offset"];
|
||||
|
||||
if ([middleHandImage isKindOfClass:[CPImage class]])
|
||||
middleHandImage = [middleHandImage duplicate];
|
||||
if (font)
|
||||
[_PMAMTextField setFont:font];
|
||||
|
||||
if ([hourHandImage isKindOfClass:[CPImage class]])
|
||||
hourHandImage = [hourHandImage duplicate];
|
||||
if (textColor)
|
||||
[_PMAMTextField setTextColor:textColor];
|
||||
|
||||
if ([minuteHandImage isKindOfClass:[CPImage class]])
|
||||
minuteHandImage = [minuteHandImage duplicate];
|
||||
if (shadowCol)
|
||||
[_PMAMTextField setTextShadowColor:shadowCol];
|
||||
|
||||
if ([secondHandImage isKindOfClass:[CPImage class]])
|
||||
secondHandImage = [secondHandImage duplicate];
|
||||
if (shadowOff)
|
||||
[_PMAMTextField setTextShadowOffset:shadowOff];
|
||||
|
||||
[_middleHandLayer setImage:middleHandImage];
|
||||
[_hourHandLayer setImage:hourHandImage];
|
||||
[_minuteHandLayer setImage:minuteHandImage];
|
||||
[_secondHandLayer setImage:secondHandImage];
|
||||
var hoursFont = [_datePicker currentValueForThemeAttribute:@"clock-hours-font"],
|
||||
hoursColor = [_datePicker currentValueForThemeAttribute:@"clock-hours-text-color"],
|
||||
drawsHours = [_datePicker currentValueForThemeAttribute:@"clock-draws-hours"];
|
||||
|
||||
[_hourHandLayer setNeedsDisplay];
|
||||
[_middleHandLayer setNeedsDisplay];
|
||||
[_secondHandLayer setNeedsDisplay];
|
||||
[_minuteHandLayer setNeedsDisplay];
|
||||
|
||||
[_rootLayer setFont:[_datePicker currentValueForThemeAttribute:@"clock-hours-font"]];
|
||||
[_rootLayer setTextColor:[_datePicker currentValueForThemeAttribute:@"clock-hours-text-color"]];
|
||||
[_rootLayer setRadius:[_datePicker currentValueForThemeAttribute:@"clock-hours-radius"]];
|
||||
|
||||
[_rootLayer setNeedsDisplay];
|
||||
for (var i = 0; i < 12; i++)
|
||||
{
|
||||
var label = _hourLabels[i];
|
||||
[label setHidden:!drawsHours];
|
||||
if (drawsHours) {
|
||||
if (hoursFont) [label setFont:hoursFont];
|
||||
if (hoursColor) [label setTextColor:hoursColor];
|
||||
[label sizeToFit];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setDatePickerElements:(CPInteger)aDatePickerElements
|
||||
{
|
||||
_datePickerElements = aDatePickerElements;
|
||||
|
||||
// Check if we have to display the hand second
|
||||
// FIXME: Don't know why but next line will cause theme compilation to fail...
|
||||
// Workaround: added "if PLATFORM(DOM)"
|
||||
#if PLATFORM(DOM)
|
||||
[_secondHandLayer setHidden:!((_datePickerElements & CPHourMinuteSecondDatePickerElementFlag) == CPHourMinuteSecondDatePickerElementFlag)];
|
||||
#endif
|
||||
[_secondHandView setHidden:!((_datePickerElements & CPHourMinuteSecondDatePickerElementFlag) == CPHourMinuteSecondDatePickerElementFlag)];
|
||||
}
|
||||
|
||||
// MARK: Layout methods
|
||||
|
||||
- (void)layoutSubviews
|
||||
{
|
||||
// While tracking a hand, we don't want the whole thing to be relayouted at each mouse movement
|
||||
[self _initHands];
|
||||
|
||||
if (_trackingHand)
|
||||
return;
|
||||
|
||||
@@ -219,31 +206,65 @@ _CPDatePickerClockSeconds = 3;
|
||||
_representedSeconds = dateValue.getSeconds();
|
||||
_representedHourIsPM = (_representedHours > 11);
|
||||
|
||||
// Hours are expressed in 24 hours format, we need 12 hours format
|
||||
_representedHours -= (_representedHourIsPM ? 12 : 0);
|
||||
|
||||
[self _updateHands];
|
||||
var bounds = [self bounds],
|
||||
centerX = bounds.size.width / 2.0,
|
||||
centerY = bounds.size.height / 2.0;
|
||||
|
||||
// FIXME: Workaround. Seems that CALayer doesn't redraw without an event
|
||||
[CALayer runLoopUpdateLayers];
|
||||
[_PMAMTextField setStringValue:_representedHourIsPM ? @"PM" : @"AM"];
|
||||
[_PMAMTextField sizeToFit];
|
||||
[_PMAMTextField setFrameOrigin:CGPointMake(centerX - [_PMAMTextField frameSize].width / 2.0, centerY + 15.0)];
|
||||
|
||||
if ([_datePicker currentValueForThemeAttribute:@"clock-draws-hours"])
|
||||
{
|
||||
var radius = [_datePicker currentValueForThemeAttribute:@"clock-hours-radius"] || 50.0;
|
||||
for (var i = 0, angle = 60.0; i < 12; i++, angle -= 30.0)
|
||||
{
|
||||
var label = _hourLabels[i],
|
||||
size = [label frameSize],
|
||||
x = centerX + radius * COS(angle * RADIANS) - size.width / 2.0,
|
||||
y = centerY - radius * SIN(angle * RADIANS) - size.height / 2.0;
|
||||
|
||||
[label setFrameOrigin:CGPointMake(x, y)];
|
||||
}
|
||||
}
|
||||
|
||||
var centerView = function(view, size) {[view setFrame:CGRectMake(centerX - size.width / 2.0, centerY - size.height / 2.0, size.width, size.height)];
|
||||
};
|
||||
|
||||
var hSize = [_datePicker currentValueForThemeAttribute:@"hour-hand-size"] || CGSizeMake(4, 64),
|
||||
mSize = [_datePicker currentValueForThemeAttribute:@"minute-hand-size"] || CGSizeMake(4, 96),
|
||||
sSize = [_datePicker currentValueForThemeAttribute:@"second-hand-size"] || CGSizeMake(4, 96),
|
||||
midSize = [_datePicker currentValueForThemeAttribute:@"middle-hand-size"] || CGSizeMake(8, 8);
|
||||
|
||||
centerView(_hourHandView, hSize);
|
||||
centerView(_minuteHandView, mSize);
|
||||
centerView(_secondHandView, sSize);
|
||||
centerView(_middleHandView, midSize);
|
||||
|
||||
[self _updateHands];
|
||||
}
|
||||
|
||||
// Applies Pure CSS Transforms to rotate the elements natively in the browser
|
||||
- (void)_rotateView:(CPView)view byAngle:(float)radians
|
||||
{
|
||||
#if PLATFORM(DOM)
|
||||
var style = view._DOMElement.style;
|
||||
style[CPBrowserStyleProperty("transformOrigin")] = "50% 50%";
|
||||
style[CPBrowserStyleProperty("transform")] = "rotate(" + radians + "rad)";
|
||||
#endif
|
||||
}
|
||||
|
||||
- (void)_updateHands
|
||||
{
|
||||
var bounds = [self bounds];
|
||||
_hourAngle = (360.0 * (_representedHours + _representedMinutes / 60.0) / 12.0) * RADIANS;
|
||||
_minuteAngle = (360.0 * (_representedMinutes + _representedSeconds / 60.0) / 60.0) * RADIANS;
|
||||
_secondAngle = (360.0 * _representedSeconds / 60.0) * RADIANS;
|
||||
|
||||
[_PMAMTextField setStringValue:_representedHourIsPM ? @"PM" : @"AM"];
|
||||
[_PMAMTextField sizeToFit];
|
||||
[_PMAMTextField setFrameOrigin:CGPointMake(bounds.size.width / 2 - [_PMAMTextField frameSize].width / 2, bounds.size.height / 2 + 15)];
|
||||
|
||||
[_hourHandLayer setRotationRadians:(360 * (_representedHours + _representedMinutes / 60) / 12) * RADIANS];
|
||||
[_minuteHandLayer setRotationRadians:(360 * (_representedMinutes + _representedSeconds / 60) / 60) * RADIANS];
|
||||
[_secondHandLayer setRotationRadians:(360 * _representedSeconds / 60) * RADIANS];
|
||||
|
||||
[_hourHandLayer setNeedsDisplay];
|
||||
[_minuteHandLayer setNeedsDisplay];
|
||||
[_secondHandLayer setNeedsDisplay];
|
||||
// [_middleHandLayer setNeedsDisplay];
|
||||
[self _rotateView:_hourHandView byAngle:_hourAngle];
|
||||
[self _rotateView:_minuteHandView byAngle:_minuteAngle];
|
||||
[self _rotateView:_secondHandView byAngle:_secondAngle];
|
||||
}
|
||||
|
||||
// MARK: Accessors
|
||||
@@ -257,12 +278,40 @@ _CPDatePickerClockSeconds = 3;
|
||||
|
||||
_isEnabled = shouldEnable;
|
||||
|
||||
[self _initHands];
|
||||
[self setNeedsLayout];
|
||||
}
|
||||
|
||||
// MARK: Mouse actions
|
||||
|
||||
// Since we rotate using Pure CSS, Cappuccino's `convertPoint:` doesn't know about it.
|
||||
// So we use standard Trigonometry to perfectly hit-test the rotated hands!
|
||||
- (BOOL)_hitTestHandWithSize:(CGSize)size angle:(float)radians atPoint:(CGPoint)aPoint
|
||||
{
|
||||
var bounds = [self bounds],
|
||||
centerX = bounds.size.width / 2.0,
|
||||
centerY = bounds.size.height / 2.0;
|
||||
|
||||
// 1. Move point to center
|
||||
var tx = aPoint.x - centerX,
|
||||
ty = aPoint.y - centerY;
|
||||
|
||||
// 2. Rotate point backwards by the angle of the hand
|
||||
var cosA = COS(-radians),
|
||||
sinA = SIN(-radians),
|
||||
rx = tx * cosA - ty * sinA,
|
||||
ry = tx * sinA + ty * cosA;
|
||||
|
||||
// 3. Test if point is within the unrotated hand's rectangle
|
||||
// The visual needle is in the top half of the hand's box (y from -h/2 to 0)
|
||||
var w2 = size.width / 2.0,
|
||||
h2 = size.height / 2.0;
|
||||
|
||||
if (rx >= -w2 && rx <= w2 && ry >= -h2 && ry <= 0)
|
||||
return YES;
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (void)mouseDown:(CPEvent)anEvent
|
||||
{
|
||||
if (!_isEnabled)
|
||||
@@ -270,25 +319,29 @@ _CPDatePickerClockSeconds = 3;
|
||||
|
||||
var currentLocation = [self convertPoint:[anEvent locationInWindow] fromView:nil];
|
||||
|
||||
if ([_secondHandLayer handIsHitAtPoint:currentLocation])
|
||||
var sSize = [_datePicker currentValueForThemeAttribute:@"second-hand-size"] || CGSizeMake(4, 96),
|
||||
mSize = [_datePicker currentValueForThemeAttribute:@"minute-hand-size"] || CGSizeMake(4, 96),
|
||||
hSize = [_datePicker currentValueForThemeAttribute:@"hour-hand-size"] || CGSizeMake(4, 64);
|
||||
|
||||
if (![_secondHandView isHidden] && [self _hitTestHandWithSize:sSize angle:_secondAngle atPoint:currentLocation])
|
||||
{
|
||||
_currentHandLayer = _secondHandLayer;
|
||||
_currentHandView = _secondHandView;
|
||||
_currentHand = _CPDatePickerClockSeconds;
|
||||
_currentRepresentedValue = _representedSeconds;
|
||||
_currentValueShift = 0;
|
||||
_numberOfUnits = 60;
|
||||
}
|
||||
else if ([_minuteHandLayer handIsHitAtPoint:currentLocation])
|
||||
else if (![_minuteHandView isHidden] && [self _hitTestHandWithSize:mSize angle:_minuteAngle atPoint:currentLocation])
|
||||
{
|
||||
_currentHandLayer = _minuteHandLayer;
|
||||
_currentHandView = _minuteHandView;
|
||||
_currentHand = _CPDatePickerClockMinutes;
|
||||
_currentRepresentedValue = _representedMinutes;
|
||||
_currentValueShift = _representedSeconds / 60;
|
||||
_numberOfUnits = 60;
|
||||
}
|
||||
else if ([_hourHandLayer handIsHitAtPoint:currentLocation])
|
||||
else if (![_hourHandView isHidden] && [self _hitTestHandWithSize:hSize angle:_hourAngle atPoint:currentLocation])
|
||||
{
|
||||
_currentHandLayer = _hourHandLayer;
|
||||
_currentHandView = _hourHandView;
|
||||
_currentHand = _CPDatePickerClockHours;
|
||||
_currentRepresentedValue = _representedHours;
|
||||
_currentValueShift = _representedMinutes / 60;
|
||||
@@ -296,14 +349,14 @@ _CPDatePickerClockSeconds = 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
_currentHandLayer = nil;
|
||||
_currentHandView = nil;
|
||||
_currentHand = CPNotFound;
|
||||
_currentRepresentedValue = CPNotFound;
|
||||
_currentValueShift = CPNotFound;
|
||||
_numberOfUnits = CPNotFound;
|
||||
}
|
||||
|
||||
if (_currentHandLayer)
|
||||
if (_currentHandView)
|
||||
[self trackMouse:anEvent];
|
||||
}
|
||||
|
||||
@@ -315,13 +368,12 @@ _CPDatePickerClockSeconds = 3;
|
||||
- (BOOL)startTrackingAt:(CGPoint)aPoint
|
||||
{
|
||||
_trackingHand = YES;
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)continueTracking:(CGPoint)lastPoint at:(CGPoint)aPoint
|
||||
{
|
||||
var dx = aPoint.x -_bounds.size.width / 2,
|
||||
var dx = aPoint.x - _bounds.size.width / 2,
|
||||
dy = _bounds.size.height / 2 - aPoint.y,
|
||||
angle = (PI_2 - ATAN2(dy,dx) + PI2) % PI2,
|
||||
value = ROUND(angle * _numberOfUnits / PI2 - _currentValueShift) % _numberOfUnits;
|
||||
@@ -343,14 +395,10 @@ _CPDatePickerClockSeconds = 3;
|
||||
_representedHourIsPM = !_representedHourIsPM;
|
||||
|
||||
if (movedForward && !_representedHourIsPM)
|
||||
// Day++
|
||||
dateValue.setDate(dateValue.getDate() + 1);
|
||||
|
||||
else if (movedBackward && _representedHourIsPM)
|
||||
// Day--
|
||||
dateValue.setDate(dateValue.getDate() - 1);
|
||||
}
|
||||
|
||||
dateValue.setHours(value + (_representedHourIsPM ? 12 : 0));
|
||||
break;
|
||||
|
||||
@@ -384,29 +432,26 @@ _CPDatePickerClockSeconds = 3;
|
||||
#if PLATFORM(DOM)
|
||||
_datePicker._invokedByUserEvent = YES;
|
||||
#endif
|
||||
[_datePicker _setDateValue:dateValue timeInterval:[_datePicker timeInterval]];
|
||||
|
||||
[_datePicker _setDateValue:dateValue timeInterval:[_datePicker timeInterval]];
|
||||
|
||||
#if PLATFORM(DOM)
|
||||
_datePicker._invokedByUserEvent = NO;
|
||||
#endif
|
||||
|
||||
// We have to adapt represented values
|
||||
_representedHours = dateValue.getHours();
|
||||
_representedMinutes = dateValue.getMinutes();
|
||||
_representedSeconds = dateValue.getSeconds();
|
||||
_representedHourIsPM = (_representedHours > 11);
|
||||
|
||||
// Hours are expressed in 24 hours format, we need 12 hours format
|
||||
_representedHours -= (_representedHourIsPM ? 12 : 0);
|
||||
|
||||
switch (_currentHand) {
|
||||
case _CPDatePickerClockHours:
|
||||
_currentRepresentedValue = _representedHours;
|
||||
break;
|
||||
|
||||
case _CPDatePickerClockMinutes:
|
||||
_currentRepresentedValue = _representedMinutes;
|
||||
break;
|
||||
|
||||
case _CPDatePickerClockSeconds:
|
||||
_currentRepresentedValue = _representedSeconds;
|
||||
break;
|
||||
@@ -424,188 +469,3 @@ _CPDatePickerClockSeconds = 3;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
// MARK: -
|
||||
|
||||
@implementation HandLayer : CALayer
|
||||
{
|
||||
CPImage _image;
|
||||
HandImageLayer _imageLayer;
|
||||
float _rotationRadians;
|
||||
}
|
||||
|
||||
// MARK: Init methods
|
||||
|
||||
- (id)initWithSize:(CGSize)aSize
|
||||
{
|
||||
if (self = [super init])
|
||||
{
|
||||
_imageLayer = [HandImageLayer layer];
|
||||
_rotationRadians = 0;
|
||||
|
||||
[_imageLayer setDelegate:self];
|
||||
[_imageLayer setBounds:CGRectMake(0.0, 0.0, aSize.width, aSize.height)];
|
||||
|
||||
[self addSublayer:_imageLayer];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
// MARK: Setter Getter methods
|
||||
|
||||
/*!
|
||||
Set the bounds of the layer. The imageLayer will be at the center of this bounds.
|
||||
*/
|
||||
- (void)setBounds:(CGRect)aRect
|
||||
{
|
||||
[super setBounds:aRect];
|
||||
|
||||
[_imageLayer setPosition:CGPointMake(CGRectGetMidX(aRect), CGRectGetMidY(aRect))];
|
||||
}
|
||||
|
||||
- (void)setImage:(CPImage)anImage
|
||||
{
|
||||
if (_image === anImage)
|
||||
return;
|
||||
|
||||
if ([anImage isKindOfClass:[_CPCibCustomResource class]])
|
||||
_image = [anImage imageFromCoder:nil];
|
||||
else
|
||||
_image = anImage;
|
||||
|
||||
[_imageLayer setNeedsDisplay];
|
||||
}
|
||||
|
||||
- (void)setRotationRadians:(float)radians
|
||||
{
|
||||
if (_rotationRadians === radians)
|
||||
return;
|
||||
|
||||
_rotationRadians = radians;
|
||||
|
||||
[_imageLayer setAffineTransform:CGAffineTransformScale(
|
||||
CGAffineTransformMakeRotation(_rotationRadians),
|
||||
1.0, 1.0)];
|
||||
}
|
||||
|
||||
- (void)imageDidLoad:(CPImage)anImage
|
||||
{
|
||||
[_imageLayer setNeedsDisplay];
|
||||
}
|
||||
|
||||
- (void)drawLayer:(CALayer)aLayer inContext:(CGContext)aContext
|
||||
{
|
||||
if ([_image loadStatus] != CPImageLoadStatusCompleted)
|
||||
[_image setDelegate:self];
|
||||
else
|
||||
CGContextDrawImage(aContext, [aLayer bounds], _image);
|
||||
}
|
||||
|
||||
- (BOOL)handIsHitAtPoint:(CGPoint)aPoint
|
||||
{
|
||||
return (!_isHidden && [_imageLayer hitTest:aPoint] === _imageLayer);
|
||||
}
|
||||
|
||||
- (void)setNeedsDisplay
|
||||
{
|
||||
[super setNeedsDisplay];
|
||||
[_imageLayer setNeedsDisplay];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
// MARK: -
|
||||
|
||||
@implementation HandImageLayer : CALayer
|
||||
{
|
||||
CGRect _handBounds;
|
||||
}
|
||||
|
||||
// We have to adapt hitTest so it only takes the hand into account (that's the top half of the image layer)
|
||||
// We are also sure there's no sublayers
|
||||
- (CALayer)hitTest:(CGPoint)aPoint
|
||||
{
|
||||
if (_isHidden)
|
||||
return nil;
|
||||
|
||||
var point = CGPointApplyAffineTransform(aPoint, _transformToLayer);
|
||||
|
||||
return CGRectContainsPoint(_handBounds, point) ? self : nil;
|
||||
}
|
||||
|
||||
- (void)setBounds:(CGRect)aBounds
|
||||
{
|
||||
if (CGRectEqualToRect(_bounds, aBounds))
|
||||
return;
|
||||
|
||||
_handBounds = CGRectMakeCopy(aBounds);
|
||||
|
||||
_handBounds.size.height = _handBounds.size.height / 2;
|
||||
|
||||
[super setBounds:aBounds];
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
|
||||
// MARK: -
|
||||
|
||||
@implementation HoursLayer : CALayer
|
||||
{
|
||||
BOOL _drawsHours;
|
||||
|
||||
CPFont _font @accessors(property=font);
|
||||
CPColor _textColor @accessors(property=textColor);
|
||||
float _radius @accessors(property=radius);
|
||||
}
|
||||
|
||||
|
||||
- (id)init
|
||||
{
|
||||
if (self = [super init])
|
||||
{
|
||||
_drawsHours = NO;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)setDrawsHours:(BOOL)shouldDrawHours
|
||||
{
|
||||
shouldDrawHours = !!shouldDrawHours;
|
||||
|
||||
if (_drawsHours === shouldDrawHours)
|
||||
return;
|
||||
|
||||
_drawsHours = shouldDrawHours;
|
||||
[self setNeedsDisplay];
|
||||
}
|
||||
|
||||
- (void)drawInContext:(CGContext)aContext
|
||||
{
|
||||
[super drawInContext:aContext];
|
||||
|
||||
if (_drawsHours)
|
||||
{
|
||||
var bounds = [self bounds],
|
||||
centerX = bounds.size.width / 2,
|
||||
centerY = bounds.size.height / 2;
|
||||
|
||||
CGContextSelectFont(aContext, _font);
|
||||
CGContextSetFillColor(aContext, _textColor);
|
||||
aContext.textBaseline = @"middle";
|
||||
aContext.textAlign = @"center";
|
||||
|
||||
for (var i = 1, angle = 60.0, x, y; i < 13; i++, angle -= 30.0)
|
||||
{
|
||||
x = centerX + _radius * COS(angle * RADIANS);
|
||||
y = centerY - _radius * SIN(angle * RADIANS);
|
||||
|
||||
aContext.fillText(i, x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
+1
-1
@@ -220,7 +220,7 @@ following:
|
||||
if (systemFontStyle)
|
||||
{
|
||||
// Yes, so install it in the DOM Style element
|
||||
document.getElementsByTagName("STYLE")[0].innerHTML += "\n" + [aTheme setCSSResourcesPathInString:systemFontStyle];
|
||||
document.getElementsByTagName("STYLE")[0].innerHTML += "\n" + [aTheme setCSSResourcesPath:systemFontStyle];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -237,6 +237,8 @@ var CPImageViewEmptyPlaceholderImage = nil;
|
||||
|
||||
if (_hasShadow)
|
||||
{
|
||||
[self setClipsToBounds:NO];
|
||||
|
||||
_shadowView = [[CPShadowView alloc] initWithFrame:[self bounds]];
|
||||
|
||||
[self addSubview:_shadowView];
|
||||
@@ -456,6 +458,12 @@ var CPImageViewEmptyPlaceholderImage = nil;
|
||||
styleNode:_cssStyleNode
|
||||
previousState:@ref(_cssStylePreviousState)];
|
||||
}
|
||||
|
||||
if ([image isCSSBased])
|
||||
{
|
||||
_DOMImageElement.style.width = _DOMImageElement.width + 'px';
|
||||
_DOMImageElement.style.height = _DOMImageElement.height + 'px';
|
||||
}
|
||||
#endif
|
||||
|
||||
_imageRect = CGRectMake(x, y, width, height);
|
||||
|
||||
+26
-22
@@ -88,43 +88,61 @@ CPRatingLevelIndicatorStyle = 3;
|
||||
|
||||
- (void)layoutSubviews
|
||||
{
|
||||
// 1. Calculate the Theme State
|
||||
// We explicitly check the window style mask to see if we are in a HUD.
|
||||
// This allows us to pass CPThemeStateHUD to the theme system, even if the control
|
||||
// itself isn't explicitly set to HUD, inheriting the style from the window.
|
||||
var themeState = [self themeState];
|
||||
|
||||
if ([[self window] styleMask] & CPHUDBackgroundWindowMask)
|
||||
themeState = themeState.and(CPThemeStateHUD);
|
||||
|
||||
// 2. Layout the Bezel
|
||||
var bezelView = [self layoutEphemeralSubviewNamed:"bezel"
|
||||
positioned:CPWindowBelow
|
||||
relativeToEphemeralSubviewNamed:nil];
|
||||
// TODO Make themable.
|
||||
[bezelView setBackgroundColor:[self valueForThemeAttribute:@"bezel-color"]];
|
||||
|
||||
[bezelView setBackgroundColor:[self valueForThemeAttribute:@"bezel-color" inState:themeState]];
|
||||
|
||||
var segmentCount = _maxValue - _minValue;
|
||||
|
||||
if (segmentCount <= 0)
|
||||
return;
|
||||
|
||||
var filledColor = [self valueForThemeAttribute:@"color-normal"],
|
||||
// 3. Determine the Color based on Value and Thresholds
|
||||
// We pass 'themeState' here. If it contains CPThemeStateHUD, the ThemeDescriptor
|
||||
// will return the monochrome color for normal/warning/critical.
|
||||
// If not, it returns Green/Yellow/Red.
|
||||
var filledColor = [self valueForThemeAttribute:@"color-normal" inState:themeState],
|
||||
value = [self doubleValue];
|
||||
|
||||
if (_warningValue < _criticalValue)
|
||||
{
|
||||
// Standard ascending scale (e.g. Volume)
|
||||
if (value >= _criticalValue)
|
||||
filledColor = [self valueForThemeAttribute:@"color-critical"];
|
||||
filledColor = [self valueForThemeAttribute:@"color-critical" inState:themeState];
|
||||
else if (value >= _warningValue)
|
||||
filledColor = [self valueForThemeAttribute:@"color-warning"];
|
||||
filledColor = [self valueForThemeAttribute:@"color-warning" inState:themeState];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Descending scale (e.g. Battery Life)
|
||||
if (value <= _criticalValue)
|
||||
filledColor = [self valueForThemeAttribute:@"color-critical"];
|
||||
filledColor = [self valueForThemeAttribute:@"color-critical" inState:themeState];
|
||||
else if (value <= _warningValue)
|
||||
filledColor = [self valueForThemeAttribute:@"color-warning"];
|
||||
filledColor = [self valueForThemeAttribute:@"color-warning" inState:themeState];
|
||||
}
|
||||
|
||||
var emptyColor = [self valueForThemeAttribute:@"color-empty" inState:themeState];
|
||||
|
||||
// 4. Paint Segments
|
||||
for (var i = 0; i < segmentCount; i++)
|
||||
{
|
||||
var segmentView = [self layoutEphemeralSubviewNamed:"segment-bezel-" + i
|
||||
positioned:CPWindowAbove
|
||||
relativeToEphemeralSubviewNamed:bezelView];
|
||||
|
||||
[segmentView setBackgroundColor:(_minValue + i) < value ? filledColor : [self valueForThemeAttribute:@"color-empty"]];
|
||||
[segmentView setBackgroundColor:(_minValue + i) < value ? filledColor : emptyColor];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -305,20 +323,6 @@ CPRatingLevelIndicatorStyle = 3;
|
||||
[self setNeedsLayout];
|
||||
}
|
||||
|
||||
/*
|
||||
- (CPTickMarkPosition)tickMarkPosition;
|
||||
- (void)setTickMarkPosition:(CPTickMarkPosition)position;
|
||||
|
||||
- (int)numberOfTickMarks;
|
||||
- (void)setNumberOfTickMarks:(int)count;
|
||||
|
||||
- (int)numberOfMajorTickMarks;
|
||||
- (void)setNumberOfMajorTickMarks:(int)count;
|
||||
|
||||
- (double)tickMarkValueAtIndex:(int)index;
|
||||
- (CGRect)rectOfTickMarkAtIndex:(int)index;
|
||||
*/
|
||||
|
||||
@end
|
||||
|
||||
var CPLevelIndicatorStyleKey = "CPLevelIndicatorStyleKey",
|
||||
|
||||
@@ -274,6 +274,8 @@ var _CPMenuBarVisible = NO,
|
||||
|
||||
_autoenablesItems = YES;
|
||||
_showsStateColumn = YES;
|
||||
|
||||
_themeState = CPThemeStateNormal;
|
||||
|
||||
[self setMinimumWidth:0];
|
||||
}
|
||||
@@ -286,6 +288,37 @@ var _CPMenuBarVisible = NO,
|
||||
return [self initWithTitle:@""];
|
||||
}
|
||||
|
||||
// Managing Theme States (HUD Support)
|
||||
|
||||
- (void)setThemeState:(CPThemeState)aState
|
||||
{
|
||||
if ([self hasThemeState:aState])
|
||||
return;
|
||||
|
||||
_themeState = _themeState.and(aState);
|
||||
|
||||
// Propagate to the view if the menu is currently visible
|
||||
if (_menuWindow)
|
||||
[[_menuWindow _menuView] setThemeState:_themeState];
|
||||
}
|
||||
|
||||
- (void)unsetThemeState:(CPThemeState)aState
|
||||
{
|
||||
if (![self hasThemeState:aState])
|
||||
return;
|
||||
|
||||
_themeState = _themeState.without(aState);
|
||||
|
||||
// Propagate to the view if the menu is currently visible
|
||||
if (_menuWindow)
|
||||
[[_menuWindow _menuView] setThemeState:_themeState];
|
||||
}
|
||||
|
||||
- (CPThemeState)themeState
|
||||
{
|
||||
return _themeState;
|
||||
}
|
||||
|
||||
// Setting Up Menu Commands
|
||||
/*!
|
||||
Inserts a menu item at the specified index.
|
||||
@@ -798,6 +831,10 @@ var _CPMenuBarVisible = NO,
|
||||
// Create the window for our menu.
|
||||
var menuWindow = [_CPMenuWindow menuWindowWithMenu:self font:[self font]];
|
||||
|
||||
// This pushes the state (e.g., CPThemeStateHUD) to the actual view that renders the menu
|
||||
if (_themeState)
|
||||
[[menuWindow _menuView] setThemeState:_themeState];
|
||||
|
||||
[menuWindow setBackgroundStyle:_CPMenuWindowPopUpBackgroundStyle];
|
||||
|
||||
if (anItem)
|
||||
@@ -888,6 +925,10 @@ var _CPMenuBarVisible = NO,
|
||||
var theWindow = [aView window],
|
||||
menuWindow = [_CPMenuWindow menuWindowWithMenu:aMenu font:aFont];
|
||||
|
||||
// --- APPLY THEME STATE FROM MENU OBJECT TO VIEW ---
|
||||
if ([aMenu respondsToSelector:@selector(themeState)])
|
||||
[[menuWindow _menuView] setThemeState:[aMenu themeState]];
|
||||
|
||||
[menuWindow setBackgroundStyle:_CPMenuWindowPopUpBackgroundStyle];
|
||||
|
||||
var constraintRect = [CPMenu _constraintRectForView:aView],
|
||||
@@ -1328,6 +1369,9 @@ var CPMenuTitleKey = @"CPMenuTitleKey",
|
||||
|
||||
_autoenablesItems = ![aCoder containsValueForKey:CPMenuAutoEnablesItemsKey] || [aCoder decodeBoolForKey:CPMenuAutoEnablesItemsKey];
|
||||
|
||||
// Ensure theme state is initialized to avoid undefined issues.
|
||||
_themeState = CPThemeStateNormal;
|
||||
|
||||
[self setMinimumWidth:0];
|
||||
}
|
||||
|
||||
|
||||
@@ -62,6 +62,9 @@ _CPMenuWindowAttachedMenuBackgroundStyle = 2;
|
||||
|
||||
// Do this so that coordinates will be accurate.
|
||||
[menuWindow setFrameOrigin:CGPointMakeZero()];
|
||||
// we need to reset the HUD state as this may be a recycled instance with HUD rund on non-HUD
|
||||
[[menuWindow _windowView] unsetThemeState:CPThemeStateHUD];
|
||||
[[menuWindow _menuView] unsetThemeState:CPThemeStateHUD];
|
||||
}
|
||||
else
|
||||
menuWindow = [[_CPMenuWindow alloc] init];
|
||||
@@ -108,23 +111,33 @@ _CPMenuWindowAttachedMenuBackgroundStyle = 2;
|
||||
[contentView addSubview:_menuClipView];
|
||||
|
||||
_moreAboveView = [[CPImageView alloc] initWithFrame:CGRectMakeZero()];
|
||||
|
||||
[_moreAboveView setImage:[_menuView valueForThemeAttribute:@"menu-window-more-above-image"]];
|
||||
[_moreAboveView setFrameSize:[[_menuView valueForThemeAttribute:@"menu-window-more-above-image"] size]];
|
||||
|
||||
[contentView addSubview:_moreAboveView];
|
||||
|
||||
_moreBelowView = [[CPImageView alloc] initWithFrame:CGRectMakeZero()];
|
||||
|
||||
[_moreBelowView setImage:[_menuView valueForThemeAttribute:@"menu-window-more-below-image"]];
|
||||
[_moreBelowView setFrameSize:[[_menuView valueForThemeAttribute:@"menu-window-more-below-image"] size]];
|
||||
|
||||
[contentView addSubview:_moreBelowView];
|
||||
|
||||
// Initial setup using default attributes
|
||||
[self updateScrollArrows];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)updateScrollArrows
|
||||
{
|
||||
if (!_menuView)
|
||||
return;
|
||||
|
||||
var aboveImage = [_menuView currentValueForThemeAttribute:@"menu-window-more-above-image"],
|
||||
belowImage = [_menuView currentValueForThemeAttribute:@"menu-window-more-below-image"];
|
||||
|
||||
[_moreAboveView setImage:aboveImage];
|
||||
[_moreAboveView setFrameSize:[aboveImage size]];
|
||||
|
||||
[_moreBelowView setImage:belowImage];
|
||||
[_moreBelowView setFrameSize:[belowImage size]];
|
||||
}
|
||||
|
||||
+ (float)_standardLeftMargin
|
||||
{
|
||||
return [[CPTheme defaultTheme] valueForAttributeWithName:@"menu-window-margin-inset" forClass:_CPMenuView].left;
|
||||
@@ -162,7 +175,12 @@ _CPMenuWindowAttachedMenuBackgroundStyle = 2;
|
||||
|
||||
- (void)setBackgroundStyle:(_CPMenuWindowBackgroundStyle)aBackgroundStyle
|
||||
{
|
||||
[self setBackgroundColor:[[self class] backgroundColorForBackgroundStyle:aBackgroundStyle]];
|
||||
var color = [_menuView currentValueForThemeAttribute:@"menu-window-pop-up-background-style-color"];
|
||||
|
||||
if (!color)
|
||||
color = [[self class] backgroundColorForBackgroundStyle:aBackgroundStyle];
|
||||
|
||||
[self setBackgroundColor:color];
|
||||
}
|
||||
|
||||
- (void)setMenu:(CPMenu)aMenu
|
||||
@@ -237,16 +255,29 @@ _CPMenuWindowAttachedMenuBackgroundStyle = 2;
|
||||
// If we are a submenu and we are being displayed off the right of the screen,
|
||||
// we should try and display on the left of our supermenu.
|
||||
var supermenu = [[self menu] supermenu];
|
||||
if (supermenu && (CGRectGetMaxX(_unconstrainedFrame) > CGRectGetMaxX(_constraintRect)))
|
||||
|
||||
if (supermenu)
|
||||
{
|
||||
var supermenuWindow = supermenu._menuWindow;
|
||||
if (supermenuWindow)
|
||||
if (CGRectGetMaxX(_unconstrainedFrame) > CGRectGetMaxX(_constraintRect))
|
||||
{
|
||||
var supermenuFrame = [supermenuWindow frame];
|
||||
_unconstrainedFrame.origin.x = CGRectGetMinX(supermenuFrame) - CGRectGetWidth(_unconstrainedFrame);
|
||||
var supermenuWindow = supermenu._menuWindow;
|
||||
if (supermenuWindow)
|
||||
{
|
||||
var supermenuFrame = [supermenuWindow frame];
|
||||
_unconstrainedFrame.origin.x = CGRectGetMinX(supermenuFrame) - CGRectGetWidth(_unconstrainedFrame);
|
||||
}
|
||||
}
|
||||
|
||||
// Shift true submenus vertically to fit within the screen if they extend past the bottom
|
||||
if (supermenu !== [CPApp mainMenu] && CGRectGetMaxY(_unconstrainedFrame) > CGRectGetMaxY(_constraintRect))
|
||||
_unconstrainedFrame.origin.y -= CGRectGetMaxY(_unconstrainedFrame) - CGRectGetMaxY(_constraintRect);
|
||||
}
|
||||
|
||||
// Ensure no menu starts above the visible screen area, preventing it from incorrectly
|
||||
// starting scrolled with a top arrow.
|
||||
if (CGRectGetMinY(_unconstrainedFrame) < CGRectGetMinY(_constraintRect))
|
||||
_unconstrainedFrame.origin.y = CGRectGetMinY(_constraintRect);
|
||||
|
||||
var constrainedFrame = CGRectIntersection(_unconstrainedFrame, _constraintRect),
|
||||
marginInset = [_menuView valueForThemeAttribute:@"menu-window-margin-inset"],
|
||||
scrollIndicatorHeight = [_menuView valueForThemeAttribute:@"menu-window-scroll-indicator-height"];
|
||||
@@ -268,7 +299,8 @@ _CPMenuWindowAttachedMenuBackgroundStyle = 2;
|
||||
[super setFrame:constrainedFrame display:shouldDisplay animate:shouldAnimate];
|
||||
|
||||
// This needs to happen before changing the frame.
|
||||
var menuViewOrigin = CGPointMake(CGRectGetMinX(aFrame) + marginInset.left, CGRectGetMinY(aFrame) + marginInset.top),
|
||||
// Base the view origin on our modified _unconstrainedFrame instead of aFrame
|
||||
var menuViewOrigin = CGPointMake(CGRectGetMinX(_unconstrainedFrame) + marginInset.left, CGRectGetMinY(_unconstrainedFrame) + marginInset.top),
|
||||
moreAbove = menuViewOrigin.y < CGRectGetMinY(constrainedFrame) + marginInset.top,
|
||||
moreBelow = menuViewOrigin.y + CGRectGetHeight([_menuView frame]) > CGRectGetMaxY(constrainedFrame) - marginInset.bottom,
|
||||
|
||||
@@ -502,6 +534,21 @@ _CPMenuWindowAttachedMenuBackgroundStyle = 2;
|
||||
};
|
||||
}
|
||||
|
||||
- (void)setThemeState:(CPThemeState)aState
|
||||
{
|
||||
[super setThemeState:aState];
|
||||
[_menuItemViews makeObjectsPerformSelector:@selector(setThemeState:) withObject:aState];
|
||||
|
||||
if ([[self window] respondsToSelector:@selector(updateScrollArrows)])
|
||||
[[self window] updateScrollArrows];
|
||||
}
|
||||
|
||||
- (void)unsetThemeState:(CPThemeState)aState
|
||||
{
|
||||
[super unsetThemeState:aState];
|
||||
[_menuItemViews makeObjectsPerformSelector:@selector(unsetThemeState:) withObject:aState];
|
||||
}
|
||||
|
||||
- (unsigned)numberOfUnhiddenItems
|
||||
{
|
||||
return _visibleMenuItemInfos.length;
|
||||
|
||||
@@ -145,6 +145,26 @@
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)setThemeState:(CPThemeState)aState
|
||||
{
|
||||
var oldState = [self themeState];
|
||||
[super setThemeState:aState];
|
||||
// If the state changed (e.g. adding HUD), we must re-run update
|
||||
// to fetch the new text color defined for that state.
|
||||
if (oldState !== [self themeState])
|
||||
[self update];
|
||||
}
|
||||
|
||||
- (void)unsetThemeState:(CPThemeState)aState
|
||||
{
|
||||
var oldState = [self themeState];
|
||||
[super unsetThemeState:aState];
|
||||
|
||||
if (oldState !== [self themeState])
|
||||
[self update];
|
||||
}
|
||||
|
||||
|
||||
- (CPColor)textColor
|
||||
{
|
||||
if (![_menuItem isEnabled])
|
||||
@@ -153,7 +173,7 @@
|
||||
if (_highlighted)
|
||||
return [CPColor whiteColor];
|
||||
|
||||
return [self valueForThemeAttribute:@"menu-item-text-color"];
|
||||
return [self currentValueForThemeAttribute:@"menu-item-text-color"];
|
||||
}
|
||||
|
||||
- (CPColor)textShadowColor
|
||||
@@ -164,7 +184,7 @@
|
||||
if (_highlighted)
|
||||
return nil;
|
||||
|
||||
return [self valueForThemeAttribute:@"menu-item-text-shadow-color"];
|
||||
return [self currentValueForThemeAttribute:@"menu-item-text-shadow-color"];
|
||||
}
|
||||
|
||||
- (void)setFont:(CPFont)aFont
|
||||
@@ -178,6 +198,11 @@
|
||||
return _font || [_menuItem font] || [CPFont systemFontOfSize:CPFontCurrentSystemSize];
|
||||
}
|
||||
|
||||
// override needed to cancel out the standard HUD propagation
|
||||
- (void)viewDidMoveToWindow
|
||||
{
|
||||
}
|
||||
|
||||
// FIXME: update is called 2 times at each display. Find why and fix.
|
||||
- (void)update
|
||||
{
|
||||
@@ -188,6 +213,8 @@
|
||||
|
||||
// When possible, use specific vertical margin/offset value based on font size (which could have been set by control size)
|
||||
correspondingControlSize = [myFont controlSizeCorrespondingToFontSize],
|
||||
controlSizeState = CPControlSizeThemeStates[correspondingControlSize],
|
||||
queryState = [self themeState] ? [self themeState].and(controlSizeState) : controlSizeState,
|
||||
verticalMargin = [self valueForThemeAttribute:@"vertical-margin" inState:CPControlSizeThemeStates[correspondingControlSize]],
|
||||
verticalOffset = [self valueForThemeAttribute:@"vertical-offset" inState:CPControlSizeThemeStates[correspondingControlSize]];
|
||||
|
||||
@@ -199,15 +226,15 @@
|
||||
switch ([_menuItem state])
|
||||
{
|
||||
case CPOnState:
|
||||
[_stateView setImage:[_menuItem onStateImage] || [self valueForThemeAttribute:@"menu-item-default-on-state-image" inState:CPControlSizeThemeStates[correspondingControlSize]]];
|
||||
[_stateView setImage:[self valueForThemeAttribute:@"menu-item-default-on-state-image" inState:queryState] || [_menuItem onStateImage]];
|
||||
break;
|
||||
|
||||
case CPOffState:
|
||||
[_stateView setImage:[_menuItem offStateImage] || [self valueForThemeAttribute:@"menu-item-default-off-state-image" inState:CPControlSizeThemeStates[correspondingControlSize]]];
|
||||
[_stateView setImage:[self valueForThemeAttribute:@"menu-item-default-off-state-image" inState:queryState] || [_menuItem offStateImage]];
|
||||
break;
|
||||
|
||||
case CPMixedState:
|
||||
[_stateView setImage:[_menuItem mixedStateImage] || [self valueForThemeAttribute:@"menu-item-default-mixed-state-image" inState:CPControlSizeThemeStates[correspondingControlSize]]];
|
||||
[_stateView setImage:[self valueForThemeAttribute:@"menu-item-default-mixed-state-image" inState:queryState] || [_menuItem mixedStateImage]];
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -326,7 +353,10 @@
|
||||
|
||||
_highlighted = shouldHighlight;
|
||||
|
||||
var correspondingControlSize = [[self font] controlSizeCorrespondingToFontSize];
|
||||
var correspondingControlSize = [[self font] controlSizeCorrespondingToFontSize],
|
||||
// Construct the query state including the view's current theme state (e.g. HUD)
|
||||
controlSizeState = CPControlSizeThemeStates[correspondingControlSize],
|
||||
queryState = [self themeState] ? [self themeState].and(controlSizeState) : controlSizeState;
|
||||
|
||||
[_imageAndTextView setTextColor:[self textColor]];
|
||||
[_keyEquivalentView setTextColor:[self textColor]];
|
||||
@@ -339,7 +369,7 @@
|
||||
[_imageAndTextView setImage:[_menuItem alternateImage] || [_menuItem image]];
|
||||
|
||||
if (_hasSubmenuIndicatorImage)
|
||||
[_submenuIndicatorView setImage:[self valueForThemeAttribute:@"submenu-indicator-highlighted-image" inState:CPControlSizeThemeStates[correspondingControlSize]]];
|
||||
[_submenuIndicatorView setImage:[self valueForThemeAttribute:@"submenu-indicator-highlighted-image" inState:queryState]];
|
||||
else
|
||||
[_submenuIndicatorView setColor:[self textColor]];
|
||||
}
|
||||
@@ -349,7 +379,7 @@
|
||||
[_imageAndTextView setImage:[_menuItem image]];
|
||||
|
||||
if (_hasSubmenuIndicatorImage)
|
||||
[_submenuIndicatorView setImage:[self valueForThemeAttribute:@"submenu-indicator-image" inState:CPControlSizeThemeStates[correspondingControlSize]]];
|
||||
[_submenuIndicatorView setImage:[self valueForThemeAttribute:@"submenu-indicator-image" inState:queryState]];
|
||||
else
|
||||
[_submenuIndicatorView setColor:[self valueForThemeAttribute:@"submenu-indicator-color"]];
|
||||
}
|
||||
@@ -361,15 +391,15 @@
|
||||
switch ([_menuItem state])
|
||||
{
|
||||
case CPOnState:
|
||||
[_stateView setImage:[_menuItem onStateImage] || [self valueForThemeAttribute:@"menu-item-default-on-state-highlighted-image" inState:CPControlSizeThemeStates[correspondingControlSize]]];
|
||||
[_stateView setImage:[_menuItem onStateImage] || [self valueForThemeAttribute:@"menu-item-default-on-state-highlighted-image" inState:queryState]];
|
||||
break;
|
||||
|
||||
case CPOffState:
|
||||
[_stateView setImage:[_menuItem offStateImage] || [self valueForThemeAttribute:@"menu-item-default-off-state-highlighted-image" inState:CPControlSizeThemeStates[correspondingControlSize]]];
|
||||
[_stateView setImage:[_menuItem offStateImage] || [self valueForThemeAttribute:@"menu-item-default-off-state-highlighted-image" inState:queryState]];
|
||||
break;
|
||||
|
||||
case CPMixedState:
|
||||
[_stateView setImage:[_menuItem mixedImage] || [self valueForThemeAttribute:@"menu-item-default-mixed-state-highlighted-image" inState:CPControlSizeThemeStates[correspondingControlSize]]];
|
||||
[_stateView setImage:[_menuItem mixedImage] || [self valueForThemeAttribute:@"menu-item-default-mixed-state-highlighted-image" inState:queryState]];
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -381,15 +411,15 @@
|
||||
switch ([_menuItem state])
|
||||
{
|
||||
case CPOnState:
|
||||
[_stateView setImage:[_menuItem onStateImage] || [self valueForThemeAttribute:@"menu-item-default-on-state-image" inState:CPControlSizeThemeStates[correspondingControlSize]]];
|
||||
[_stateView setImage:[_menuItem onStateImage] || [self valueForThemeAttribute:@"menu-item-default-on-state-image" inState:queryState]];
|
||||
break;
|
||||
|
||||
case CPOffState:
|
||||
[_stateView setImage:[_menuItem offStateImage] || [self valueForThemeAttribute:@"menu-item-default-off-state-image" inState:CPControlSizeThemeStates[correspondingControlSize]]];
|
||||
[_stateView setImage:[_menuItem offStateImage] || [self valueForThemeAttribute:@"menu-item-default-off-state-image" inState:queryState]];
|
||||
break;
|
||||
|
||||
case CPMixedState:
|
||||
[_stateView setImage:[_menuItem mixedImage] || [self valueForThemeAttribute:@"menu-item-default-mixed-state-image" inState:CPControlSizeThemeStates[correspondingControlSize]]];
|
||||
[_stateView setImage:[_menuItem mixedImage] || [self valueForThemeAttribute:@"menu-item-default-mixed-state-image" inState:queryState]];
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
@@ -83,6 +83,28 @@
|
||||
return self;
|
||||
}
|
||||
|
||||
// override needed to cancel out the standard HUD propagation
|
||||
- (void)viewDidMoveToWindow
|
||||
{
|
||||
}
|
||||
|
||||
- (void)setThemeState:(CPThemeState)aState
|
||||
{
|
||||
[super setThemeState:aState];
|
||||
|
||||
// Propagate state to the actual content view (StandardView, Separator, etc.)
|
||||
if ([_view respondsToSelector:@selector(setThemeState:)])
|
||||
[_view setThemeState:aState];
|
||||
}
|
||||
|
||||
- (void)unsetThemeState:(CPThemeState)aState
|
||||
{
|
||||
[super unsetThemeState:aState];
|
||||
|
||||
if ([_view respondsToSelector:@selector(unsetThemeState:)])
|
||||
[_view unsetThemeState:aState];
|
||||
}
|
||||
|
||||
- (CGSize)minSize
|
||||
{
|
||||
return _minSize;
|
||||
|
||||
+565
-53
@@ -23,7 +23,7 @@
|
||||
@import "CPButton.j"
|
||||
@import "CPTableColumn.j"
|
||||
@import "CPTableView.j"
|
||||
@import "CPTreeNode.j"
|
||||
@import "CPViewAnimation.j"
|
||||
|
||||
@global CPApp
|
||||
|
||||
@@ -286,6 +286,12 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
|
||||
|
||||
CPArray _pendingItemToClean;
|
||||
CPArray _itemAddedDuringLastLoading;
|
||||
|
||||
CPIndexSet _animatingDisclosureRows;
|
||||
|
||||
BOOL _animates @accessors(property=animates);
|
||||
CPViewAnimation _rowsAnimation;
|
||||
CPArray _animationGhosts;
|
||||
}
|
||||
|
||||
- (id)initWithFrame:(CGRect)aFrame
|
||||
@@ -316,6 +322,9 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
|
||||
[super setDelegate:self];
|
||||
|
||||
[self setDisclosureControlPrototype:[[CPDisclosureButton alloc] initWithFrame:CGRectMake(0.0, 0.0, 10.0, 10.0)]];
|
||||
|
||||
_animatingDisclosureRows = [CPIndexSet indexSet];
|
||||
_animates = YES;
|
||||
}
|
||||
|
||||
return self;
|
||||
@@ -326,12 +335,22 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
|
||||
_BlockDeselectView = function(view, row, column)
|
||||
{
|
||||
[view unsetThemeState:CPThemeStateSelectedDataView];
|
||||
// Ensure we clear the focus state so the text goes back to normal color
|
||||
[view unsetThemeState:CPThemeStateFirstResponder];
|
||||
|
||||
[_disclosureControlsForRows[row] unsetThemeState:CPThemeStateSelected];
|
||||
};
|
||||
|
||||
_BlockSelectView = function(view, row, column)
|
||||
{
|
||||
[view setThemeState:CPThemeStateSelectedDataView];
|
||||
|
||||
// If the table is focused, apply the state that turns text white immediately
|
||||
if ([self _isFocused])
|
||||
[view setThemeState:CPThemeStateFirstResponder];
|
||||
else
|
||||
[view unsetThemeState:CPThemeStateFirstResponder];
|
||||
|
||||
[_disclosureControlsForRows[row] setThemeState:CPThemeStateSelected];
|
||||
};
|
||||
}
|
||||
@@ -483,6 +502,60 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
|
||||
return itemInfo.shouldShowOutlineDisclosureControl;
|
||||
}
|
||||
|
||||
- (void)_noteDisclosureAnimationWillStartForRow:(CPInteger)aRow
|
||||
{
|
||||
[_animatingDisclosureRows addIndex:aRow];
|
||||
// We do not need to setNeedsDisplay here because the button itself
|
||||
// will trigger a redraw when its state changes or when the animation setup occurs.
|
||||
}
|
||||
|
||||
- (void)_noteDisclosureAnimationDidStopForRow:(CPInteger)aRow
|
||||
{
|
||||
[_animatingDisclosureRows removeIndex:aRow];
|
||||
|
||||
// Explicitly find the button for this row and force it to redraw.
|
||||
// The button was returning early from drawRect during the animation.
|
||||
// Now that the flag is cleared, we must tell it to paint again.
|
||||
if (_disclosureControlsForRows && aRow < _disclosureControlsForRows.length)
|
||||
{
|
||||
var button = _disclosureControlsForRows[aRow];
|
||||
|
||||
if (button)
|
||||
[button display];
|
||||
}
|
||||
}
|
||||
- (BOOL)_isRowAnimatingDisclosure:(CPInteger)aRow
|
||||
{
|
||||
return [_animatingDisclosureRows containsIndex:aRow];
|
||||
}
|
||||
|
||||
- (CPInteger)rowForView:(CPView)aView
|
||||
{
|
||||
// 1. Try the standard lookup (for normal cells)
|
||||
var row = [super rowForView:aView];
|
||||
|
||||
if (row !== CPNotFound)
|
||||
return row;
|
||||
|
||||
// 2. If not found, check if it is a disclosure button
|
||||
if ([aView isKindOfClass:[CPDisclosureButton class]])
|
||||
{
|
||||
// Check the list of active disclosure buttons
|
||||
// _disclosureControlsForRows is a native JS array, so we use indexOf
|
||||
var index = _disclosureControlsForRows.indexOf(aView);
|
||||
|
||||
if (index > -1)
|
||||
return index;
|
||||
|
||||
// 3. Check if it is an animation clone (from the fix in the previous step)
|
||||
// The clone is not in the array, but it carries the row index.
|
||||
if (aView._animatingRowIndex !== undefined && aView._animatingRowIndex !== null)
|
||||
return aView._animatingRowIndex;
|
||||
}
|
||||
|
||||
return CPNotFound;
|
||||
}
|
||||
|
||||
/*!
|
||||
Used to find if an item is already expanded.
|
||||
|
||||
@@ -622,6 +695,9 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
|
||||
*/
|
||||
- (void)expandItem:(id)anItem expandChildren:(BOOL)shouldExpandChildren
|
||||
{
|
||||
var oldRowCount = [self numberOfRows],
|
||||
parentIndex = [self rowForItem:anItem];
|
||||
|
||||
if ([self _delegateRespondsToShouldExpandItem])
|
||||
if ([_outlineViewDelegate outlineView:self shouldExpandItem:anItem] == NO)
|
||||
return;
|
||||
@@ -664,7 +740,7 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
|
||||
if (rowCountDelta)
|
||||
{
|
||||
var selection = [self selectedRowIndexes],
|
||||
expandIndex = [self rowForItem:anItem] + 1;
|
||||
expandIndex = parentIndex + 1;
|
||||
|
||||
if ([selection intersectsIndexesInRange:CPMakeRange(expandIndex, _itemsForRows.length)])
|
||||
{
|
||||
@@ -691,6 +767,17 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
|
||||
if (r === CPOutlineViewCoalesceSelectionNotificationStateDid)
|
||||
[self _noteSelectionDidChange];
|
||||
}
|
||||
|
||||
// FIX: Animation logic moved to the end to match Version 1 behavior.
|
||||
// This ensures views are ready and handles both single and recursive expansion.
|
||||
var newRowCount = [self numberOfRows],
|
||||
addedCount = newRowCount - oldRowCount;
|
||||
|
||||
if (_animates && addedCount > 0)
|
||||
{
|
||||
[self layoutSubviews]; // Force views to spawn so we can animate them
|
||||
[self _animateExpandFromIndex:parentIndex addedCount:addedCount];
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -703,29 +790,30 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
|
||||
if (!anItem)
|
||||
return;
|
||||
|
||||
var collapseTopIndex = [self rowForItem:anItem];
|
||||
|
||||
// FIX 1: Safety check to prevent "jumping".
|
||||
// If the parent row isn't found or invisible, we cannot animate.
|
||||
if (collapseTopIndex === CPNotFound || collapseTopIndex < 0)
|
||||
return;
|
||||
|
||||
if ([self _delegateRespondsToShouldCollapseItem])
|
||||
if ([_outlineViewDelegate outlineView:self shouldCollapseItem:anItem] == NO)
|
||||
return;
|
||||
|
||||
var itemInfo = _itemInfosForItems[[anItem UID]];
|
||||
|
||||
if (!itemInfo)
|
||||
if (!itemInfo || !itemInfo.isExpanded)
|
||||
return;
|
||||
|
||||
if (!itemInfo.isExpanded)
|
||||
return;
|
||||
|
||||
// Don't spam notifications.
|
||||
_coalesceSelectionNotificationState = CPOutlineViewCoalesceSelectionNotificationStateOn;
|
||||
|
||||
[self _noteItemWillCollapse:anItem];
|
||||
// Update selections:
|
||||
// * Deselect items inside the collapsed item.
|
||||
// * Shift row selections below the collapsed item so that the same logical items remain selected.
|
||||
var collapseTopIndex = [self rowForItem:anItem],
|
||||
topLevel = [self levelForRow:collapseTopIndex],
|
||||
|
||||
var topLevel = [self levelForRow:collapseTopIndex],
|
||||
collapseEndIndex = collapseTopIndex;
|
||||
|
||||
// Calculate how many items are being removed
|
||||
while (collapseEndIndex + 1 < _itemsForRows.length && [self levelForRow:collapseEndIndex + 1] > topLevel)
|
||||
collapseEndIndex++;
|
||||
|
||||
@@ -739,31 +827,288 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
|
||||
{
|
||||
[self _noteSelectionIsChanging];
|
||||
[selection removeIndexesInRange:collapseRange];
|
||||
[self _setSelectedRowIndexes:selection]; // _noteSelectionDidChange will be suppressed.
|
||||
[self _setSelectedRowIndexes:selection];
|
||||
}
|
||||
|
||||
// Shift any selected rows below upwards.
|
||||
if ([selection intersectsIndexesInRange:CPMakeRange(collapseEndIndex + 1, _itemsForRows.length)])
|
||||
{
|
||||
[self _noteSelectionIsChanging];
|
||||
[selection shiftIndexesStartingAtIndex:collapseEndIndex + 1 by:-collapseRange.length];
|
||||
[self _setSelectedRowIndexes:selection]; // _noteSelectionDidChange will be suppressed.
|
||||
[self _setSelectedRowIndexes:selection];
|
||||
}
|
||||
}
|
||||
|
||||
itemInfo.isExpanded = NO;
|
||||
// Capture visual ghosts BEFORE the data is removed
|
||||
var ghosts = nil;
|
||||
if (_animates && collapseRange.length > 0)
|
||||
ghosts = [self _createGhostsForRowsFrom:collapseRange.location to:CPMaxRange(collapseRange) - 1];
|
||||
|
||||
// Collapse the model
|
||||
itemInfo.isExpanded = NO;
|
||||
[self reloadItem:anItem reloadChildren:YES];
|
||||
[self _noteItemDidCollapse:anItem];
|
||||
|
||||
// Send selection notifications only after the items have loaded so that
|
||||
// the new selection is consistent with the actual rows for any observers.
|
||||
// Trigger Animation
|
||||
if (_animates && collapseRange.length > 0)
|
||||
{
|
||||
[self layoutSubviews];
|
||||
[self _animateCollapseFromIndex:collapseTopIndex removedCount:collapseRange.length ghosts:ghosts];
|
||||
}
|
||||
|
||||
var r = _coalesceSelectionNotificationState;
|
||||
_coalesceSelectionNotificationState = CPOutlineViewCoalesceSelectionNotificationStateOff;
|
||||
|
||||
if (r === CPOutlineViewCoalesceSelectionNotificationStateDid)
|
||||
[self _noteSelectionDidChange];
|
||||
}
|
||||
|
||||
- (void)_animateCollapseFromIndex:(CPInteger)parentIndex removedCount:(CPInteger)removedCount ghosts:(CPArray)ghosts
|
||||
{
|
||||
// Ensure we don't animate if parent is invalid
|
||||
if (parentIndex < 0)
|
||||
return;
|
||||
|
||||
if (_rowsAnimation && [_rowsAnimation isAnimating])
|
||||
[_rowsAnimation stopAnimation];
|
||||
|
||||
var viewAnimations = [],
|
||||
// The Y position the ghosts will slide INTO (the parent row's Y position)
|
||||
parentY = [self frameOfDataViewAtColumn:0 row:parentIndex].origin.y;
|
||||
|
||||
// Calculate shift offset based on ghost height or row height
|
||||
var shiftOffset = 0;
|
||||
if (ghosts && ghosts.length > 0)
|
||||
{
|
||||
var firstGhostFrame = [ghosts[0] frame],
|
||||
maxY = CGRectGetMaxY(firstGhostFrame);
|
||||
for(var i = 1; i < ghosts.length; i++)
|
||||
maxY = MAX(maxY, CGRectGetMaxY([ghosts[i] frame]));
|
||||
shiftOffset = maxY - firstGhostFrame.origin.y;
|
||||
}
|
||||
else
|
||||
{
|
||||
shiftOffset = removedCount * [self rowHeight];
|
||||
}
|
||||
|
||||
// 1. Ghost views slide up into parent and fade out
|
||||
if (ghosts)
|
||||
{
|
||||
for (var i = 0; i < ghosts.length; i++)
|
||||
{
|
||||
var ghost = ghosts[i],
|
||||
startFrame = [ghost frame],
|
||||
targetFrame = CGRectMake(startFrame.origin.x, parentY, startFrame.size.width, startFrame.size.height);
|
||||
|
||||
// FIX 3: Removed [self addSubview:positioned:relativeTo:]
|
||||
// Ghosts remain at the top of the view stack (where they were created)
|
||||
// ensuring they are visible and don't get hidden behind the background.
|
||||
|
||||
[viewAnimations addObject:@{
|
||||
CPViewAnimationTargetKey: ghost,
|
||||
CPViewAnimationStartFrameKey: startFrame,
|
||||
CPViewAnimationEndFrameKey: targetFrame,
|
||||
CPViewAnimationEffectKey: CPViewAnimationFadeOutEffect
|
||||
}];
|
||||
}
|
||||
}
|
||||
|
||||
// 2. Siblings (rows below the collapsed group) slide UP to fill the gap
|
||||
var columns = [self tableColumns],
|
||||
colIndexes = [CPIndexSet indexSetWithIndexesInRange:CPMakeRange(0, columns.length)],
|
||||
startIndex = parentIndex + 1,
|
||||
rowCount = [self numberOfRows];
|
||||
|
||||
// FIX 4: Only animate rows that actually exist after the parent
|
||||
if (startIndex < rowCount)
|
||||
{
|
||||
var rowIndexes = [CPIndexSet indexSetWithIndexesInRange:CPMakeRange(startIndex, rowCount - startIndex)];
|
||||
|
||||
[self _enumerateViewsInRows:rowIndexes columns:colIndexes usingBlock:function(view, row, column, stop) {
|
||||
|
||||
var targetFrame = [view frame];
|
||||
|
||||
// Siblings start lower (at target Y + shift) and move UP to target Y
|
||||
var startFrame = CGRectMake(targetFrame.origin.x, targetFrame.origin.y + shiftOffset, targetFrame.size.width, targetFrame.size.height);
|
||||
|
||||
[view setFrame:startFrame];
|
||||
|
||||
[viewAnimations addObject:@{
|
||||
CPViewAnimationTargetKey: view,
|
||||
CPViewAnimationStartFrameKey: startFrame,
|
||||
CPViewAnimationEndFrameKey: targetFrame
|
||||
}];
|
||||
}];
|
||||
|
||||
// Also animate disclosure triangles for the siblings
|
||||
var disclosureRows = [];
|
||||
[rowIndexes getIndexes:disclosureRows maxCount:-1 inIndexRange:nil];
|
||||
|
||||
for (var i = 0; i < disclosureRows.length; i++)
|
||||
{
|
||||
var btn = _disclosureControlsForRows[disclosureRows[i]];
|
||||
if (btn)
|
||||
{
|
||||
var targetBtnFrame = [btn frame],
|
||||
startBtnFrame = CGRectMake(targetBtnFrame.origin.x, targetBtnFrame.origin.y + shiftOffset, targetBtnFrame.size.width, targetBtnFrame.size.height);
|
||||
|
||||
[btn setFrame:startBtnFrame];
|
||||
|
||||
[viewAnimations addObject:@{
|
||||
CPViewAnimationTargetKey: btn,
|
||||
CPViewAnimationStartFrameKey: startBtnFrame,
|
||||
CPViewAnimationEndFrameKey: targetBtnFrame
|
||||
}];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[self _runAnimation:viewAnimations withGhosts:ghosts];
|
||||
}
|
||||
|
||||
// MARK: - CPRuleEditor Style Animations
|
||||
|
||||
- (CPArray)_createGhostsForRowsFrom:(CPInteger)startRow to:(CPInteger)endRow
|
||||
{
|
||||
var ghosts = [];
|
||||
var columns = [self tableColumns];
|
||||
var rowIndexes =[CPIndexSet indexSetWithIndexesInRange:CPMakeRange(startRow, endRow - startRow + 1)];
|
||||
var colIndexes =[CPIndexSet indexSetWithIndexesInRange:CPMakeRange(0, columns.length)];[self _enumerateViewsInRows:rowIndexes columns:colIndexes usingBlock:function(view, row, column, stop) {
|
||||
var ghost = [[CPView alloc] initWithFrame:[view frame]];
|
||||
if (view._DOMElement)
|
||||
ghost._DOMElement.innerHTML = view._DOMElement.innerHTML;
|
||||
[self addSubview:ghost];
|
||||
[ghosts addObject:ghost];
|
||||
}];
|
||||
|
||||
var disclosureRows = [];[rowIndexes getIndexes:disclosureRows maxCount:-1 inIndexRange:nil];
|
||||
for (var i = 0; i < disclosureRows.length; i++)
|
||||
{
|
||||
var btn = _disclosureControlsForRows[disclosureRows[i]];
|
||||
if (btn)
|
||||
{
|
||||
var ghostBtn = [[CPView alloc] initWithFrame:[btn frame]];
|
||||
if (btn._DOMElement)
|
||||
ghostBtn._DOMElement.innerHTML = btn._DOMElement.innerHTML;[self addSubview:ghostBtn];
|
||||
[ghosts addObject:ghostBtn];
|
||||
}
|
||||
}
|
||||
|
||||
return ghosts;
|
||||
}
|
||||
|
||||
- (void)_animateExpandFromIndex:(CPInteger)parentIndex addedCount:(CPInteger)addedCount
|
||||
{
|
||||
if (_rowsAnimation && [_rowsAnimation isAnimating])
|
||||
[_rowsAnimation stopAnimation];
|
||||
|
||||
var viewAnimations = [];
|
||||
var columns = [self tableColumns];
|
||||
var colIndexes = [CPIndexSet indexSetWithIndexesInRange:CPMakeRange(0, columns.length)];
|
||||
|
||||
var startIndex = parentIndex + 1;
|
||||
var rowIndexes =[CPIndexSet indexSetWithIndexesInRange:CPMakeRange(startIndex, [self numberOfRows] - startIndex)];
|
||||
var parentY = parentIndex >= 0 ? [self frameOfDataViewAtColumn:0 row:parentIndex].origin.y : 0;
|
||||
|
||||
// Safely calculate the shift gap even with variable row heights
|
||||
var shiftOffset = 0;
|
||||
if (addedCount > 0 && (startIndex + addedCount) < [self numberOfRows])
|
||||
{
|
||||
var firstNewTarget = [self frameOfDataViewAtColumn:0 row:startIndex].origin.y;
|
||||
var firstDisplacedTarget = [self frameOfDataViewAtColumn:0 row:startIndex + addedCount].origin.y;
|
||||
shiftOffset = firstDisplacedTarget - firstNewTarget;
|
||||
}
|
||||
else
|
||||
shiftOffset = addedCount * [self rowHeight];[self _enumerateViewsInRows:rowIndexes columns:colIndexes usingBlock:function(view, row, column, stop) {
|
||||
var isNewRow = (row < startIndex + addedCount);
|
||||
var targetFrame = [view frame];
|
||||
var startFrame;
|
||||
var animDict = @{ CPViewAnimationTargetKey: view, CPViewAnimationEndFrameKey: targetFrame };
|
||||
|
||||
if (isNewRow)
|
||||
{
|
||||
startFrame = CGRectMake(targetFrame.origin.x, parentY, targetFrame.size.width, targetFrame.size.height);
|
||||
[animDict setObject:CPViewAnimationFadeInEffect forKey:CPViewAnimationEffectKey];[view setAlphaValue:0.0];
|
||||
}
|
||||
else
|
||||
startFrame = CGRectMake(targetFrame.origin.x, targetFrame.origin.y - shiftOffset, targetFrame.size.width, targetFrame.size.height);
|
||||
|
||||
[view setFrame:startFrame];[animDict setObject:startFrame forKey:CPViewAnimationStartFrameKey];
|
||||
[viewAnimations addObject:animDict];
|
||||
}];
|
||||
|
||||
var disclosureRows = [];
|
||||
[rowIndexes getIndexes:disclosureRows maxCount:-1 inIndexRange:nil];
|
||||
for (var i = 0; i < disclosureRows.length; i++)
|
||||
{
|
||||
var r = disclosureRows[i];
|
||||
var btn = _disclosureControlsForRows[r];
|
||||
if (btn)
|
||||
{
|
||||
var isNewRow = (r < startIndex + addedCount);
|
||||
var targetBtnFrame = [btn frame];
|
||||
var startBtnFrame;
|
||||
var animBtnDict = @{ CPViewAnimationTargetKey: btn, CPViewAnimationEndFrameKey: targetBtnFrame };
|
||||
|
||||
if (isNewRow)
|
||||
{
|
||||
startBtnFrame = CGRectMake(targetBtnFrame.origin.x, parentY, targetBtnFrame.size.width, targetBtnFrame.size.height);[animBtnDict setObject:CPViewAnimationFadeInEffect forKey:CPViewAnimationEffectKey];[btn setAlphaValue:0.0];
|
||||
}
|
||||
else
|
||||
startBtnFrame = CGRectMake(targetBtnFrame.origin.x, targetBtnFrame.origin.y - shiftOffset, targetBtnFrame.size.width, targetBtnFrame.size.height);
|
||||
|
||||
[btn setFrame:startBtnFrame];[animBtnDict setObject:startBtnFrame forKey:CPViewAnimationStartFrameKey];
|
||||
[viewAnimations addObject:animBtnDict];
|
||||
}
|
||||
}
|
||||
|
||||
[self _runAnimation:viewAnimations withGhosts:nil];
|
||||
}
|
||||
|
||||
- (void)_runAnimation:(CPArray)viewAnimations withGhosts:(CPArray)ghosts
|
||||
{
|
||||
// Clean up interrupted animations
|
||||
if (_animationGhosts)
|
||||
{
|
||||
for (var i = 0; i < _animationGhosts.length; i++)
|
||||
[_animationGhosts[i] removeFromSuperview];
|
||||
}
|
||||
_animationGhosts = ghosts;
|
||||
|
||||
if (viewAnimations.length > 0)
|
||||
{
|
||||
_rowsAnimation = [[CPViewAnimation alloc] initWithViewAnimations:viewAnimations];
|
||||
[_rowsAnimation setDuration:0.25];[_rowsAnimation setAnimationCurve:CPAnimationEaseInOut];
|
||||
[_rowsAnimation setDelegate:self];
|
||||
[_rowsAnimation startAnimation];
|
||||
}
|
||||
else if (ghosts)
|
||||
{
|
||||
for (var i = 0; i < ghosts.length; i++)
|
||||
[ghosts[i] removeFromSuperview];
|
||||
_animationGhosts = nil;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)animationDidEnd:(CPViewAnimation)animation
|
||||
{
|
||||
var animations = [animation viewAnimations];
|
||||
|
||||
for (var i = 0; i < animations.length; i++)
|
||||
{
|
||||
var view = animations[i][CPViewAnimationTargetKey];
|
||||
if (!_animationGhosts || ![_animationGhosts containsObject:view])[view setAlphaValue:1.0];
|
||||
}
|
||||
|
||||
if (_animationGhosts)
|
||||
{
|
||||
for (var i = 0; i < _animationGhosts.length; i++)
|
||||
[_animationGhosts[i] removeFromSuperview];
|
||||
_animationGhosts = nil;
|
||||
}
|
||||
|
||||
[self setNeedsLayout];
|
||||
}
|
||||
|
||||
/*!
|
||||
Reloads the data for an item.
|
||||
|
||||
@@ -787,6 +1132,11 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
|
||||
*/
|
||||
- (void)reloadItem:(id)anItem reloadChildren:(BOOL)shouldReloadChildren
|
||||
{
|
||||
if (_rowsAnimation && [_rowsAnimation isAnimating])
|
||||
{
|
||||
[_rowsAnimation stopAnimation];
|
||||
[self animationDidEnd:_rowsAnimation];
|
||||
}
|
||||
|
||||
_pendingItemToClean = [];
|
||||
_itemAddedDuringLastLoading = [];
|
||||
@@ -2230,7 +2580,15 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
|
||||
|
||||
@implementation CPDisclosureButton : CPButton
|
||||
{
|
||||
float _angle;
|
||||
float _angle;
|
||||
|
||||
// Animation state tracking
|
||||
BOOL _isAnimatingClone;
|
||||
CPInteger _animatingRowIndex;
|
||||
CPOutlineView _parentOutlineView;
|
||||
|
||||
DOMElement _arrowElement;
|
||||
CPString _lastColorCSS;
|
||||
}
|
||||
|
||||
- (id)initWithFrame:(CGRect)aFrame
|
||||
@@ -2238,66 +2596,220 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
|
||||
self = [super initWithFrame:aFrame];
|
||||
|
||||
if (self)
|
||||
{
|
||||
[self setBordered:NO];
|
||||
|
||||
[self setWantsLayer:YES];
|
||||
[self setHighlightsBy:0];
|
||||
|
||||
[self _setupDisclosureButton];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (id)initWithCoder:(CPCoder)aCoder
|
||||
{
|
||||
self = [super initWithCoder:aCoder];
|
||||
|
||||
if (self)
|
||||
{
|
||||
[self _setupDisclosureButton];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)_setupDisclosureButton
|
||||
{
|
||||
_isAnimatingClone = NO; // Default for real buttons
|
||||
|
||||
#if PLATFORM(DOM)
|
||||
|
||||
// Add a dedicated DOM element for the SVG arrow
|
||||
_arrowElement = document.createElement("div");
|
||||
_arrowElement.style.position = "absolute";
|
||||
_arrowElement.style.top = "0px";
|
||||
_arrowElement.style.left = "0px";
|
||||
_arrowElement.style.width = "100%";
|
||||
_arrowElement.style.height = "100%";
|
||||
_arrowElement.style.backgroundPosition = "center center";
|
||||
_arrowElement.style.backgroundRepeat = "no-repeat";
|
||||
// 24px maps the 24x24 viewBox to exact pixels, making the 10x5 path scale perfectly
|
||||
_arrowElement.style.backgroundSize = "24px 24px";
|
||||
_arrowElement.style.pointerEvents = "none";
|
||||
|
||||
self._DOMElement.appendChild(_arrowElement);
|
||||
#endif
|
||||
}
|
||||
|
||||
- (void)setAngle:(float)anAngle
|
||||
{
|
||||
_angle = anAngle;
|
||||
|
||||
// Rotate the DOM element directly using standard CSS transforms
|
||||
var deg = _angle * (180.0 / Math.PI);
|
||||
|
||||
#if PLATFORM(DOM)
|
||||
_arrowElement.style.transform = "rotate(" + deg + "deg)";
|
||||
#endif
|
||||
|
||||
[self display];
|
||||
}
|
||||
|
||||
- (float)angle
|
||||
{
|
||||
return _angle;
|
||||
}
|
||||
|
||||
- (void)setState:(CPInteger)aState
|
||||
{
|
||||
[super setState:aState];
|
||||
|
||||
// Using setAngle immediately triggers the transform
|
||||
if ([self state] === CPOnState)
|
||||
_angle = 0.0;
|
||||
|
||||
[self setAngle:0.0];
|
||||
else
|
||||
_angle = -PI_2;
|
||||
[self setAngle:-PI_2];
|
||||
}
|
||||
|
||||
- (void)stopTracking:(CGPoint)lastPoint at:(CGPoint)point mouseIsUp:(BOOL)mouseIsUp
|
||||
{
|
||||
var bounds = [self bounds];
|
||||
|
||||
if (CGRectContainsPoint(bounds, point))
|
||||
{
|
||||
var outlineView = [self superview],
|
||||
row = [outlineView rowForView:self];
|
||||
|
||||
if ([outlineView isKindOfClass:[CPOutlineView class]] && row !== CPNotFound)
|
||||
{
|
||||
// 1. Tell OutlineView to suppress drawing of the real button
|
||||
[outlineView _noteDisclosureAnimationWillStartForRow:row];
|
||||
|
||||
// 2. Create the clone
|
||||
var clone = [[CPDisclosureButton alloc] initWithFrame:[self frame]];
|
||||
|
||||
[clone setWantsLayer:YES];
|
||||
[clone setThemeState:[self themeState]];
|
||||
[clone unsetThemeState:CPThemeStateHighlighted];
|
||||
[clone setHighlighted:NO];
|
||||
[clone setAngle:_angle];
|
||||
[clone setHitTests:NO];
|
||||
|
||||
// 3. Mark this as a clone so drawRect knows to draw it
|
||||
clone._isAnimatingClone = YES;
|
||||
clone._animatingRowIndex = row;
|
||||
clone._parentOutlineView = outlineView;[outlineView addSubview:clone positioned:CPWindowAbove relativeTo:self];
|
||||
|
||||
// 4. Calculate angles
|
||||
var isCurrentlyExpanded = ([self state] === CPOnState),
|
||||
targetAngle = isCurrentlyExpanded ? -PI_2 : 0.0;
|
||||
|
||||
// 5. Setup Animation
|
||||
var anim = [CABasicAnimation animationWithKeyPath:@"angle"];
|
||||
[anim setFromValue:_angle];
|
||||
[anim setToValue:targetAngle];
|
||||
[anim setDuration:0.25];
|
||||
[anim setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
|
||||
|
||||
[[clone layer] setDelegate:clone];
|
||||
[anim setDelegate:clone];
|
||||
|
||||
[[clone layer] addAnimation:anim forKey:@"angle"];
|
||||
|
||||
// Set final angle on clone to avoid flicker at end
|
||||
[clone setAngle:targetAngle];
|
||||
}
|
||||
}
|
||||
|
||||
[super stopTracking:lastPoint at:point mouseIsUp:mouseIsUp];
|
||||
}
|
||||
|
||||
- (void)animationDidStop:(CAAnimation)anim finished:(BOOL)flag
|
||||
{
|
||||
// This runs on the CLONE
|
||||
if (_parentOutlineView)
|
||||
[_parentOutlineView _noteDisclosureAnimationDidStopForRow:_animatingRowIndex];
|
||||
|
||||
[self removeFromSuperview];
|
||||
}
|
||||
|
||||
- (void)drawRect:(CGRect)aRect
|
||||
{
|
||||
var bounds = [self bounds],
|
||||
context = [[CPGraphicsContext currentContext] graphicsPort],
|
||||
width = CGRectGetWidth(bounds),
|
||||
height = CGRectGetHeight(bounds);
|
||||
|
||||
CGContextBeginPath(context);
|
||||
#if PLATFORM(DOM)
|
||||
if (_arrowElement && _arrowElement.parentNode !== self._DOMElement)
|
||||
self._DOMElement.appendChild(_arrowElement);
|
||||
#endif
|
||||
|
||||
if (_angle)
|
||||
// If I am NOT the clone, I must check if my row is animating.
|
||||
// If it is animating, the clone is drawing on top of me, so I should be invisible.
|
||||
if (!_isAnimatingClone)
|
||||
{
|
||||
var centre = CGPointMake(FLOOR(width / 2.0), FLOOR(height / 2.0));
|
||||
CGContextTranslateCTM(context, centre.x, centre.y);
|
||||
CGContextRotateCTM(context, _angle);
|
||||
CGContextTranslateCTM(context, -centre.x, -centre.y);
|
||||
var outlineView = [self superview];
|
||||
if ([outlineView isKindOfClass:[CPOutlineView class]])
|
||||
{
|
||||
var row = [outlineView rowForView:self];
|
||||
if (row !== CPNotFound && [outlineView _isRowAnimatingDisclosure:row])
|
||||
{
|
||||
|
||||
#if PLATFORM(DOM)
|
||||
_arrowElement.style.display = "none";
|
||||
#endif
|
||||
return; // Suppress the real button
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Center, but crisp.
|
||||
CGContextTranslateCTM(context, FLOOR((width - 9.0) / 2.0), FLOOR((height - 8.0) / 2.0));
|
||||
_arrowElement.style.display = "block";
|
||||
|
||||
var isSelected = [self hasThemeState:CPThemeStateSelected],
|
||||
isHighlighted = [self hasThemeState:CPThemeStateHighlighted],
|
||||
isKeyWindow = [self hasThemeState:CPThemeStateKeyWindow],
|
||||
isHUD = [self window] && ([[self window] styleMask] & CPHUDBackgroundWindowMask),
|
||||
triangleColor = nil;
|
||||
|
||||
CGContextMoveToPoint(context, 0.0, 0.0);
|
||||
CGContextAddLineToPoint(context, 9.0, 0.0);
|
||||
CGContextAddLineToPoint(context, 4.5, 8.0);
|
||||
CGContextClosePath(context);
|
||||
// Establish the required color based on the state/outline selection
|
||||
if (isHUD)
|
||||
{
|
||||
triangleColor = isSelected ? [CPColor blackColor] : [CPColor whiteColor];
|
||||
|
||||
CGContextSetFillColor(context,
|
||||
colorForDisclosureTriangle([self hasThemeState:CPThemeStateSelected],
|
||||
[self hasThemeState:CPThemeStateHighlighted]));
|
||||
CGContextFillPath(context);
|
||||
if (isHighlighted)
|
||||
triangleColor = [triangleColor colorWithAlphaComponent:0.5];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isSelected)
|
||||
triangleColor = isKeyWindow ? [CPColor whiteColor] : [CPColor blackColor];
|
||||
else triangleColor = [CPColor colorWithCalibratedWhite:0.45 alpha: 1.0];
|
||||
|
||||
CGContextBeginPath(context);
|
||||
CGContextMoveToPoint(context, 0.0, 0.0);
|
||||
CGContextAddLineToPoint(context, 4.5, 8.0);
|
||||
if (isHighlighted)
|
||||
{
|
||||
if (isSelected && isKeyWindow)
|
||||
triangleColor = [CPColor colorWithCalibratedWhite:0.9 alpha: 1.0];
|
||||
|
||||
if (_angle === 0.0)
|
||||
CGContextAddLineToPoint(context, 9.0, 0.0);
|
||||
else if (isSelected && !isKeyWindow)
|
||||
triangleColor = [CPColor colorWithCalibratedWhite:0.2 alpha: 1.0];
|
||||
else
|
||||
triangleColor = [CPColor colorWithCalibratedWhite:0.25 alpha: 1.0];
|
||||
}
|
||||
}
|
||||
|
||||
CGContextSetStrokeColor(context, [CPColor colorWithCalibratedWhite:1.0 alpha: 0.7]);
|
||||
CGContextStrokePath(context);
|
||||
var colorCSS = [triangleColor cssString];
|
||||
|
||||
// Convert and inject the updated SVG only when the required color has changed
|
||||
if (_lastColorCSS !== colorCSS)
|
||||
{
|
||||
_lastColorCSS = colorCSS;
|
||||
var svgString = '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M7 10L12 15L17 10H7Z" fill="' + colorCSS + '"/></svg>';
|
||||
var b64 = window.btoa(svgString);
|
||||
|
||||
#if PLATFORM(DOM)
|
||||
_arrowElement.style.backgroundImage = "url('data:image/svg+xml;charset=utf-8;base64," + b64 + "')";
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
var CPOutlineViewIndentationPerLevelKey = @"CPOutlineViewIndentationPerLevelKey",
|
||||
CPOutlineViewOutlineTableColumnKey = @"CPOutlineViewOutlineTableColumnKey",
|
||||
CPOutlineViewDataSourceKey = @"CPOutlineViewDataSourceKey",
|
||||
@@ -2331,6 +2843,8 @@ var CPOutlineViewIndentationPerLevelKey = @"CPOutlineViewIndentationPerLevelKey"
|
||||
[super setDelegate:self];
|
||||
|
||||
[self _updateIsViewBased];
|
||||
|
||||
_animatingDisclosureRows = [CPIndexSet indexSet];
|
||||
}
|
||||
|
||||
return self;
|
||||
@@ -2532,8 +3046,6 @@ var colorForDisclosureTriangle = function(isSelected, isHighlighted)
|
||||
selector:@selector(outlineViewSelectionDidChange:)
|
||||
name:CPOutlineViewSelectionDidChangeNotification
|
||||
object:aSource];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
+ (void)unbind:(CPString)aBinding forObject:(id)anObject
|
||||
|
||||
@@ -79,6 +79,8 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
|
||||
|
||||
if (self)
|
||||
{
|
||||
[self setBezelStyle:CPRoundedBezelStyle];
|
||||
|
||||
[self selectItemAtIndex:CPNotFound];
|
||||
|
||||
_preferredEdge = CPMaxYEdge;
|
||||
@@ -689,6 +691,12 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
|
||||
// FIXME: setFont: should set the font on the menu.
|
||||
[menu setFont:[self font]];
|
||||
|
||||
// Propagate the HUD theme state to the menu
|
||||
if ([self hasThemeState:CPThemeStateHUD])
|
||||
[menu setThemeState:CPThemeStateHUD];
|
||||
else
|
||||
[menu unsetThemeState:CPThemeStateHUD];
|
||||
|
||||
if ([self pullsDown])
|
||||
{
|
||||
var positionedItem = nil,
|
||||
|
||||
+121
-33
@@ -43,7 +43,6 @@ CPProgressIndicatorSpinningStyle = 1;
|
||||
*/
|
||||
CPProgressIndicatorHUDBarStyle = 2;
|
||||
|
||||
var CPProgressIndicatorSpinningStyleColors = [];
|
||||
|
||||
/*!
|
||||
@ingroup appkit
|
||||
@@ -71,6 +70,43 @@ var CPProgressIndicatorSpinningStyleColors = [];
|
||||
BOOL _isDisplayedWhenStopped;
|
||||
}
|
||||
|
||||
// Inject CSS Keyframes for spinning animation (Standard + WebKit)
|
||||
|
||||
+ (void)initialize
|
||||
{
|
||||
if (self !== [CPProgressIndicator class])
|
||||
return;
|
||||
|
||||
#if PLATFORM(DOM)
|
||||
|
||||
if (document.getElementById("cp-progress-indicator-style"))
|
||||
return;
|
||||
|
||||
var style = document.createElement("style");
|
||||
style.id = "cp-progress-indicator-style";
|
||||
style.type = "text/css";
|
||||
|
||||
// We define two animations:
|
||||
// 1. cp-progress-indicator-spin: Rotates 360 degrees (for spinners)
|
||||
// 2. cp-progress-indicator-bar-slide: Moves background-position (for striped bars)
|
||||
var css =
|
||||
"@keyframes cp-progress-indicator-spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } " +
|
||||
"@-webkit-keyframes cp-progress-indicator-spin { 0% { -webkit-transform: rotate(0deg); } 100% { -webkit-transform: rotate(360deg); } } " +
|
||||
|
||||
"@keyframes cp-progress-indicator-bar-slide { 0% { background-position: 0 0; } 100% { background-position: 30px 0; } } " +
|
||||
"@-webkit-keyframes cp-progress-indicator-bar-slide { 0% { background-position: 0 0; } 100% { background-position: 30px 0; } }";
|
||||
|
||||
if (style.styleSheet)
|
||||
style.styleSheet.cssText = css;
|
||||
else
|
||||
style.appendChild(document.createTextNode(css));
|
||||
|
||||
var head = document.getElementsByTagName("head")[0];
|
||||
if (head)
|
||||
head.appendChild(style);
|
||||
#endif
|
||||
}
|
||||
|
||||
+ (CPString)defaultThemeClass
|
||||
{
|
||||
return @"progress-indicator";
|
||||
@@ -83,12 +119,19 @@ var CPProgressIndicatorSpinningStyleColors = [];
|
||||
@"bar-color": [CPNull null],
|
||||
@"default-height": 20,
|
||||
@"bezel-color": [CPNull null],
|
||||
@"spinning-mini-gif": [CPNull null],
|
||||
@"spinning-small-gif": [CPNull null],
|
||||
@"spinning-regular-gif": [CPNull null],
|
||||
|
||||
// CSS Spinner Attributes
|
||||
@"spinner-color": [CPColor grayColor],
|
||||
@"spinner-track-color": [CPColor colorWithWhite:0.9 alpha:1.0],
|
||||
@"spinner-line-width": 3.0,
|
||||
|
||||
@"circular-border-color": [CPNull null],
|
||||
@"circular-border-size": 1,
|
||||
@"circular-color": [CPNull null]
|
||||
@"circular-color": [CPNull null],
|
||||
|
||||
@"spinning-mini-gif": [CPNull null],
|
||||
@"spinning-small-gif": [CPNull null],
|
||||
@"spinning-regular-gif": [CPNull null]
|
||||
};
|
||||
}
|
||||
|
||||
@@ -138,6 +181,7 @@ var CPProgressIndicatorSpinningStyleColors = [];
|
||||
_isAnimating = YES;
|
||||
|
||||
[self _hideOrDisplay];
|
||||
[self setNeedsLayout]; // Trigger layout to update CSS animation state
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -149,6 +193,7 @@ var CPProgressIndicatorSpinningStyleColors = [];
|
||||
_isAnimating = NO;
|
||||
|
||||
[self _hideOrDisplay];
|
||||
[self setNeedsLayout]; // Trigger layout to remove CSS animation state
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -233,7 +278,7 @@ var CPProgressIndicatorSpinningStyleColors = [];
|
||||
|
||||
_controlSize = aControlSize;
|
||||
|
||||
[self updateBackgroundColor];
|
||||
[self setNeedsLayout];
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -285,7 +330,7 @@ var CPProgressIndicatorSpinningStyleColors = [];
|
||||
|
||||
_indeterminate = indeterminate;
|
||||
|
||||
[self updateBackgroundColor];
|
||||
[self setNeedsLayout];
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -307,9 +352,7 @@ var CPProgressIndicatorSpinningStyleColors = [];
|
||||
|
||||
_style = aStyle;
|
||||
|
||||
[self setTheme:(_style === CPProgressIndicatorHUDBarStyle) ? [CPTheme defaultHudTheme] : [CPTheme defaultTheme]];
|
||||
|
||||
[self updateBackgroundColor];
|
||||
[self setNeedsLayout];
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -318,7 +361,14 @@ var CPProgressIndicatorSpinningStyleColors = [];
|
||||
- (void)sizeToFit
|
||||
{
|
||||
if (_style == CPProgressIndicatorSpinningStyle)
|
||||
[self setFrameSize:[[CPProgressIndicatorSpinningStyleColors[_controlSize] patternImage] size]];
|
||||
{
|
||||
var size = 32.0;
|
||||
if (_controlSize === CPMiniControlSize) size = 16.0;
|
||||
else if (_controlSize === CPSmallControlSize) size = 24.0;
|
||||
else if (_controlSize === CPRegularControlSize) size = 32.0;
|
||||
|
||||
[self setFrameSize:CGSizeMake(size, size)];
|
||||
}
|
||||
else
|
||||
[self setFrameSize:CGSizeMake(CGRectGetWidth([self frame]), [self valueForThemeAttribute:@"default-height"])];
|
||||
}
|
||||
@@ -381,6 +431,7 @@ var CPProgressIndicatorSpinningStyleColors = [];
|
||||
|
||||
- (CGRect)rectForEphemeralSubviewNamed:(CPString)aViewName
|
||||
{
|
||||
// Handle the standard Bar View
|
||||
if (aViewName === @"bar-view" && _style !== CPProgressIndicatorSpinningStyle)
|
||||
{
|
||||
var width = CGRectGetWidth([self bounds]),
|
||||
@@ -394,41 +445,78 @@ var CPProgressIndicatorSpinningStyleColors = [];
|
||||
|
||||
return CGRectMake(0, 0, barWidth, [self valueForThemeAttribute:@"default-height"]);
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
/* @ignore */
|
||||
- (void)updateBackgroundColor
|
||||
{
|
||||
if ([CPProgressIndicatorSpinningStyleColors count] === 0)
|
||||
|
||||
// Handle the Spinning View (CSS Spinner)
|
||||
if (aViewName === @"spinner-view" && _style == CPProgressIndicatorSpinningStyle && _indeterminate)
|
||||
{
|
||||
CPProgressIndicatorSpinningStyleColors[CPMiniControlSize] = [self valueForThemeAttribute:@"spinning-mini-gif"];
|
||||
CPProgressIndicatorSpinningStyleColors[CPSmallControlSize] = [self valueForThemeAttribute:@"spinning-small-gif"];
|
||||
CPProgressIndicatorSpinningStyleColors[CPRegularControlSize] = [self valueForThemeAttribute:@"spinning-regular-gif"];
|
||||
return [self bounds];
|
||||
}
|
||||
|
||||
[self setNeedsLayout];
|
||||
// Return nil for views that shouldn't appear in the current style
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (void)layoutSubviews
|
||||
{
|
||||
if (YES)//_isBezeled)
|
||||
{
|
||||
// === SPINNING STYLE ===
|
||||
if (_style == CPProgressIndicatorSpinningStyle)
|
||||
{
|
||||
if (!_indeterminate)
|
||||
return;
|
||||
// If indeterminate, use CSS spinner
|
||||
if (_indeterminate)
|
||||
{
|
||||
var spinnerView = [self layoutEphemeralSubviewNamed:"spinner-view"
|
||||
positioned:CPWindowAbove
|
||||
relativeToEphemeralSubviewNamed:nil];
|
||||
|
||||
// Ensure other views are hidden
|
||||
[self layoutEphemeralSubviewNamed:"bar-view" positioned:CPWindowBelow relativeToEphemeralSubviewNamed:nil];
|
||||
|
||||
// This will cause the bar view to go away due to having a nil rect when _style == CPProgressIndicatorSpinningStyle.
|
||||
[self layoutEphemeralSubviewNamed:"bar-view"
|
||||
positioned:CPWindowBelow
|
||||
relativeToEphemeralSubviewNamed:nil];
|
||||
// Configure CSS on the subview, NOT self._DOMElement, to avoid transform conflicts
|
||||
var domEl = spinnerView._DOMElement,
|
||||
spinnerColor = [self currentValueForThemeAttribute:@"spinner-color"],
|
||||
trackColor = [self currentValueForThemeAttribute:@"spinner-track-color"],
|
||||
lineWidth = [self currentValueForThemeAttribute:@"spinner-line-width"],
|
||||
widthStr = lineWidth + "px";
|
||||
|
||||
[self setBackgroundColor:CPProgressIndicatorSpinningStyleColors[_controlSize]];
|
||||
domEl.style.boxSizing = "border-box";
|
||||
domEl.style.borderRadius = "50%";
|
||||
domEl.style.borderStyle = "solid";
|
||||
domEl.style.borderWidth = widthStr;
|
||||
domEl.style.borderColor = [trackColor cssString];
|
||||
domEl.style.borderTopColor = [spinnerColor cssString];
|
||||
|
||||
// Animation logic
|
||||
if (_isAnimating)
|
||||
{
|
||||
var anim = "cp-progress-indicator-spin 1s linear infinite";
|
||||
domEl.style.animation = anim;
|
||||
domEl.style.WebkitAnimation = anim;
|
||||
}
|
||||
else
|
||||
{
|
||||
domEl.style.animation = "none";
|
||||
domEl.style.WebkitAnimation = "none";
|
||||
}
|
||||
|
||||
// Ensure main view is transparent
|
||||
[self setBackgroundColor:nil];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Determinate Spinner (Pie Chart drawn in drawRect)
|
||||
// Hide CSS spinner
|
||||
[self layoutEphemeralSubviewNamed:"spinner-view" positioned:CPWindowBelow relativeToEphemeralSubviewNamed:nil];
|
||||
[self setBackgroundColor:nil];
|
||||
}
|
||||
}
|
||||
// === BAR STYLE ===
|
||||
else
|
||||
{
|
||||
// Hide spinner
|
||||
[self layoutEphemeralSubviewNamed:"spinner-view" positioned:CPWindowBelow relativeToEphemeralSubviewNamed:nil];
|
||||
|
||||
[self setBackgroundColor:[self currentValueForThemeAttribute:@"bezel-color"]];
|
||||
|
||||
var barView = [self layoutEphemeralSubviewNamed:"bar-view"
|
||||
@@ -447,6 +535,8 @@ var CPProgressIndicatorSpinningStyleColors = [];
|
||||
|
||||
- (void)drawRect:(CGRect)aRect
|
||||
{
|
||||
// Handle determinate state for Spinning style (Pie chart progress) via CoreGraphics.
|
||||
// If indeterminate, the CSS animation (spinner-view) takes over and we draw nothing.
|
||||
if (_style == CPProgressIndicatorSpinningStyle && !_indeterminate)
|
||||
{
|
||||
var context = [[CPGraphicsContext currentContext] graphicsPort],
|
||||
@@ -512,7 +602,7 @@ var CPProgressIndicatorSpinningStyleColors = [];
|
||||
_isDisplayedWhenStoppedSet = [aCoder decodeObjectForKey:@"_isDisplayedWhenStoppedSet"];
|
||||
_isDisplayedWhenStopped = [aCoder decodeObjectForKey:@"_isDisplayedWhenStopped"];
|
||||
|
||||
[self updateBackgroundColor];
|
||||
[self setNeedsLayout];
|
||||
}
|
||||
|
||||
return self;
|
||||
@@ -520,8 +610,6 @@ var CPProgressIndicatorSpinningStyleColors = [];
|
||||
|
||||
- (void)encodeWithCoder:(CPCoder)aCoder
|
||||
{
|
||||
// Don't encode the background colour. It can be recreated based on the flags
|
||||
// and if encoded causes hardcoded image paths in the cib while just wasting space.
|
||||
var backgroundColor = [self backgroundColor];
|
||||
[self setBackgroundColor:nil];
|
||||
[super encodeWithCoder:aCoder];
|
||||
|
||||
@@ -1957,57 +1957,63 @@ TODO: implement
|
||||
|
||||
- (CPArray)_backgroundColors
|
||||
{
|
||||
return [self valueForThemeAttribute:@"alternating-row-colors"];
|
||||
return [self currentValueForThemeAttribute:@"alternating-row-colors"];
|
||||
}
|
||||
|
||||
- (CPColor)_selectedRowColor
|
||||
{
|
||||
return [self valueForThemeAttribute:@"selected-color"];
|
||||
return [self currentValueForThemeAttribute:@"selected-color"];
|
||||
}
|
||||
|
||||
- (CPColor)_sliceTopBorderColor
|
||||
{
|
||||
return [self valueForThemeAttribute:@"slice-top-border-color"];
|
||||
return [self currentValueForThemeAttribute:@"slice-top-border-color"];
|
||||
}
|
||||
|
||||
- (CPColor)_sliceBottomBorderColor
|
||||
{
|
||||
return [self valueForThemeAttribute:@"slice-bottom-border-color"];
|
||||
return [self currentValueForThemeAttribute:@"slice-bottom-border-color"];
|
||||
}
|
||||
|
||||
- (CPColor)_sliceLastBottomBorderColor
|
||||
{
|
||||
return [self valueForThemeAttribute:@"slice-last-bottom-border-color"];
|
||||
return [self currentValueForThemeAttribute:@"slice-last-bottom-border-color"];
|
||||
}
|
||||
|
||||
- (CPFont)font
|
||||
{
|
||||
return [self valueForThemeAttribute:@"font"];
|
||||
return [self currentValueForThemeAttribute:@"font"];
|
||||
}
|
||||
|
||||
- (CPColor)_fontColor
|
||||
{
|
||||
return [self valueForThemeAttribute:@"font-color"];
|
||||
return [self currentValueForThemeAttribute:@"font-color"];
|
||||
}
|
||||
|
||||
- (void)setThemeState:(CPThemeState)aState
|
||||
{
|
||||
[super setThemeState:aState];
|
||||
[_slices makeObjectsPerformSelector:@selector(setThemeState:) withObject:aState];
|
||||
}
|
||||
|
||||
- (CPImage)_imageAdd
|
||||
{
|
||||
return [self valueForThemeAttribute:@"add-image" inState:CPThemeStateNormal];
|
||||
return [self valueForThemeAttribute:@"add-image" inState:CPThemeStateNormal.and([self themeState])];
|
||||
}
|
||||
|
||||
- (CPImage)_imageAddHighlighted
|
||||
{
|
||||
return [self valueForThemeAttribute:@"add-image" inState:CPThemeStateHighlighted];
|
||||
return [self valueForThemeAttribute:@"add-image" inState:CPThemeStateHighlighted.and([self themeState])];
|
||||
}
|
||||
|
||||
- (CPImage)_imageRemove
|
||||
{
|
||||
return [self valueForThemeAttribute:@"remove-image" inState:CPThemeStateNormal];
|
||||
return [self valueForThemeAttribute:@"remove-image" inState:CPThemeStateNormal.and([self themeState])];
|
||||
}
|
||||
|
||||
- (CPImage)_imageRemoveHighlighted
|
||||
{
|
||||
return [self valueForThemeAttribute:@"remove-image" inState:CPThemeStateHighlighted];
|
||||
return [self valueForThemeAttribute:@"remove-image" inState:CPThemeStateHighlighted.and([self themeState])];
|
||||
}
|
||||
|
||||
- (CPVerticalTextAlignment)_verticalAlignment
|
||||
@@ -2219,7 +2225,13 @@ TODO: implement
|
||||
return;
|
||||
|
||||
var point = [self convertPoint:[event locationInWindow] fromView:nil],
|
||||
view = [_slices objectAtIndex:FLOOR(MAX(0, point.y) / _sliceHeight)];
|
||||
index = FLOOR(MAX(0, point.y) / _sliceHeight);
|
||||
|
||||
// Check bounds before accessing the array to prevent CPRangeException
|
||||
if (index >= [_slices count])
|
||||
return;
|
||||
|
||||
var view = [_slices objectAtIndex:FLOOR(MAX(0, point.y) / _sliceHeight)];
|
||||
|
||||
if ([self _dragShouldBeginFromMouseDown:view])
|
||||
[self _performDragForSlice:view withEvent:event];
|
||||
|
||||
@@ -49,6 +49,13 @@
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)setRowIndex:(int)anIndex
|
||||
{
|
||||
_rowIndex = anIndex;
|
||||
[self _updateBackgroundColor];
|
||||
[self setNeedsDisplay:YES];
|
||||
}
|
||||
|
||||
- (void)_setSelected:(BOOL)select
|
||||
{
|
||||
if (select == _selected)
|
||||
@@ -57,6 +64,47 @@
|
||||
var selector = select ? @selector(setThemeState:) : @selector(unsetThemeState:);
|
||||
[[self subviews] makeObjectsPerformSelector:selector withObject:CPThemeStateSelectedDataView];
|
||||
_selected = select;
|
||||
|
||||
[self _updateBackgroundColor];
|
||||
[self setNeedsDisplay:YES];
|
||||
}
|
||||
|
||||
- (void)_updateBackgroundColor
|
||||
{
|
||||
var color = nil;
|
||||
|
||||
if ([self _isSelected])
|
||||
{
|
||||
color = [_ruleEditor _selectedRowColor];
|
||||
}
|
||||
else
|
||||
{
|
||||
var colors = [_ruleEditor _backgroundColors],
|
||||
count = [colors count];
|
||||
|
||||
if (count > 0)
|
||||
color = [colors objectAtIndex:(_rowIndex % count)];
|
||||
}
|
||||
|
||||
[self setBackgroundColor:color];
|
||||
}
|
||||
|
||||
- (void)viewDidMoveToWindow
|
||||
{
|
||||
[super viewDidMoveToWindow];
|
||||
[self _updateBackgroundColor];
|
||||
}
|
||||
|
||||
- (void)setThemeState:(CPThemeState)aState
|
||||
{
|
||||
[super setThemeState:aState];
|
||||
[self _updateBackgroundColor];
|
||||
}
|
||||
|
||||
- (void)unsetThemeState:(CPThemeState)aState
|
||||
{
|
||||
[super unsetThemeState:aState];
|
||||
[self _updateBackgroundColor];
|
||||
}
|
||||
|
||||
- (void)drawRect:(CGRect)rect
|
||||
@@ -66,35 +114,31 @@
|
||||
maxX = CGRectGetWidth(bounds),
|
||||
maxY = CGRectGetHeight(bounds);
|
||||
|
||||
// Draw background
|
||||
if ([self _isSelected])
|
||||
_backgroundColor = [_ruleEditor _selectedRowColor];
|
||||
else
|
||||
{
|
||||
var colors = [_ruleEditor _backgroundColors],
|
||||
count = [colors count];
|
||||
_backgroundColor = [colors objectAtIndex:(_rowIndex % count)];
|
||||
}
|
||||
|
||||
CGContextSetFillColor(context, _backgroundColor);
|
||||
CGContextFillRect(context, rect);
|
||||
// Note: Background is now handled by setBackgroundColor in _updateBackgroundColor
|
||||
// to support CSS-based colors and transparency correctly.
|
||||
|
||||
// Draw Top Border
|
||||
CGContextBeginPath(context);
|
||||
CGContextMoveToPoint(context, 0, 0);
|
||||
CGContextAddLineToPoint(context, maxX, 0);
|
||||
CGContextSetStrokeColor(context, [_ruleEditor _sliceTopBorderColor]);
|
||||
CGContextStrokePath(context);
|
||||
var topColor = [_ruleEditor _sliceTopBorderColor];
|
||||
if (topColor)
|
||||
{
|
||||
CGContextBeginPath(context);
|
||||
CGContextMoveToPoint(context, 0, 0);
|
||||
CGContextAddLineToPoint(context, maxX, 0);
|
||||
CGContextSetStrokeColor(context, topColor);
|
||||
CGContextStrokePath(context);
|
||||
}
|
||||
|
||||
// Draw Bottom Border
|
||||
CGContextBeginPath(context);
|
||||
CGContextMoveToPoint(context, 0, maxY);
|
||||
CGContextAddLineToPoint(context, maxX, maxY);
|
||||
|
||||
var bottomColor = (_rowIndex == [_ruleEditor _lastRow]) ? [_ruleEditor _sliceLastBottomBorderColor] : [_ruleEditor _sliceBottomBorderColor];
|
||||
|
||||
CGContextSetStrokeColor(context, bottomColor);
|
||||
CGContextStrokePath(context);
|
||||
if (bottomColor)
|
||||
{
|
||||
CGContextBeginPath(context);
|
||||
CGContextMoveToPoint(context, 0, maxY);
|
||||
CGContextAddLineToPoint(context, maxX, maxY);
|
||||
CGContextSetStrokeColor(context, bottomColor);
|
||||
CGContextStrokePath(context);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)mouseDown:(CPEvent)theEvent
|
||||
|
||||
@@ -67,6 +67,23 @@
|
||||
[self setAutoresizingMask:CPViewWidthSizable];
|
||||
}
|
||||
|
||||
- (void)_setSelected:(BOOL)isSelected
|
||||
{
|
||||
[super _setSelected:isSelected];
|
||||
[self _updateButtonImages];
|
||||
}
|
||||
|
||||
- (void)_updateButtonImages
|
||||
{
|
||||
var rowState = [self themeState];
|
||||
|
||||
if ([self _isSelected])
|
||||
rowState = rowState.and(CPThemeStateSelected);
|
||||
|
||||
[_addButton setImage:[_ruleEditor valueForThemeAttribute:@"add-image" inState:rowState]];
|
||||
[_subtractButton setImage:[_ruleEditor valueForThemeAttribute:@"remove-image" inState:rowState]];
|
||||
}
|
||||
|
||||
- (CPButton)_createRowButton
|
||||
{
|
||||
var button = [[CPButton alloc] initWithFrame:CGRectMakeZero()];
|
||||
@@ -89,6 +106,8 @@
|
||||
var button = [self _createRowButton];
|
||||
|
||||
[button setToolTip:[_ruleEditor _toolTipForAddSimpleRowButton]];
|
||||
|
||||
// Initial setup, _updateButtonImages will be called later to set correct state-based images
|
||||
[button setValue:[_ruleEditor _imageAdd] forThemeAttribute:@"image" inState:CPThemeStateNormal];
|
||||
[button setValue:[_ruleEditor _imageAddHighlighted] forThemeAttribute:@"image" inState:CPThemeStateHighlighted];
|
||||
|
||||
@@ -103,6 +122,8 @@
|
||||
var button = [self _createRowButton];
|
||||
|
||||
[button setToolTip:[_ruleEditor _toolTipForDeleteRowButton]];
|
||||
|
||||
// Initial setup
|
||||
[button setValue:[_ruleEditor _imageRemove] forThemeAttribute:@"image" inState:CPThemeStateNormal];
|
||||
[button setValue:[_ruleEditor _imageRemoveHighlighted] forThemeAttribute:@"image" inState:CPThemeStateHighlighted];
|
||||
|
||||
@@ -525,9 +546,23 @@
|
||||
|
||||
- (void)viewDidMoveToWindow
|
||||
{
|
||||
[super viewDidMoveToWindow];
|
||||
[self _updateButtonImages];
|
||||
[self layoutSubviews];
|
||||
}
|
||||
|
||||
- (void)setThemeState:(CPThemeState)aState
|
||||
{
|
||||
[super setThemeState:aState];
|
||||
[self _updateButtonImages];
|
||||
}
|
||||
|
||||
- (void)unsetThemeState:(CPThemeState)aState
|
||||
{
|
||||
[super unsetThemeState:aState];
|
||||
[self _updateButtonImages];
|
||||
}
|
||||
|
||||
- (void)_addObservers
|
||||
{
|
||||
if (_isObserving)
|
||||
|
||||
+78
-17
@@ -103,6 +103,12 @@ var CPScrollViewWillStartLiveScrollNotification = @"CPScrollViewWillStartLiveScr
|
||||
var CPScrollerStyleGlobal = CPScrollerStyleOverlay,
|
||||
CPScrollerStyleGlobalChangeNotification = @"CPScrollerStyleGlobalChangeNotification";
|
||||
|
||||
var CPScrollViewBorderSuffixes = @[@"no-border", @"line-border", @"bezel-border", @"groove-border"];
|
||||
|
||||
// _CPScrollViews will hold all created CPScrollView's in order to propagate changes
|
||||
// of scroller global style
|
||||
var _CPScrollViews;
|
||||
|
||||
/*!
|
||||
@ingroup appkit
|
||||
@class CPScrollView
|
||||
@@ -167,6 +173,8 @@ var CPScrollerStyleGlobal = CPScrollerStyleOverlay,
|
||||
CPScrollerStyleGlobal = _isBrowserUsingOverlayScrollers() ? CPScrollerStyleOverlay : CPScrollerStyleLegacy
|
||||
else
|
||||
CPScrollerStyleGlobal = globalValue;
|
||||
|
||||
_CPScrollViews = @[];
|
||||
}
|
||||
|
||||
+ (CPString)defaultThemeClass
|
||||
@@ -178,7 +186,15 @@ var CPScrollerStyleGlobal = CPScrollerStyleOverlay,
|
||||
{
|
||||
return @{
|
||||
@"bottom-corner-color": [CPColor whiteColor],
|
||||
@"border-color": [CPColor blackColor]
|
||||
@"border-color": [CPColor blackColor],
|
||||
@"content-inset-no-border": CGInsetMake(0, 0, 0, 0),
|
||||
@"content-inset-line-border": CGInsetMake(1, 1, 1, 1),
|
||||
@"content-inset-bezel-border": CGInsetMake(1, 1, 1, 1),
|
||||
@"content-inset-groove-border": CGInsetMake(2, 2, 2, 2),
|
||||
@"background-color-no-border": [CPNull null],
|
||||
@"background-color-line-border": [CPNull null],
|
||||
@"background-color-bezel-border": [CPNull null],
|
||||
@"background-color-groove-border": [CPNull null]
|
||||
};
|
||||
}
|
||||
|
||||
@@ -247,19 +263,35 @@ var CPScrollerStyleGlobal = CPScrollerStyleOverlay,
|
||||
|
||||
+ (CGRect)_insetBounds:(CGRect)bounds borderType:(CPBorderType)borderType
|
||||
{
|
||||
// First, we have to check if we are compiling a theme or running an application because if working on a theme,
|
||||
// we can't use theme attributes to determine the inset ! This would be a kind of circular reference...
|
||||
|
||||
var compilingATheme = [[[CPBundle mainBundle] objectForInfoDictionaryKey:@"CPApplicationDelegateClass"] isEqualToString:@"BKShowcaseController"];
|
||||
|
||||
if (compilingATheme)
|
||||
return bounds;
|
||||
|
||||
var contentInset = [[CPTheme defaultTheme] valueForAttributeWithName:@"content-inset-"+CPScrollViewBorderSuffixes[borderType] forClass:CPScrollView];
|
||||
|
||||
// As this is a class method, we don't have object attributes, so if the theme doesn't declare content insets, we don't automatically get default value.
|
||||
// Get it by hand.
|
||||
if (!contentInset)
|
||||
contentInset = [[self themeAttributes] objectForKey:@"content-inset-"+CPScrollViewBorderSuffixes[borderType]];
|
||||
|
||||
switch (borderType)
|
||||
{
|
||||
case CPNoBorder:
|
||||
case CPLineBorder:
|
||||
case CPBezelBorder:
|
||||
return CGRectInset(bounds, 1.0, 1.0);
|
||||
return CGRectInsetByInset(bounds, contentInset);
|
||||
|
||||
case CPGrooveBorder:
|
||||
bounds = CGRectInset(bounds, 2.0, 2.0);
|
||||
// FIXME: Do something better with this
|
||||
bounds = CGRectInsetByInset(bounds, contentInset);
|
||||
++bounds.origin.y;
|
||||
--bounds.size.height;
|
||||
return bounds;
|
||||
|
||||
case CPNoBorder:
|
||||
default:
|
||||
return bounds;
|
||||
}
|
||||
@@ -281,7 +313,10 @@ var CPScrollerStyleGlobal = CPScrollerStyleOverlay,
|
||||
+ (void)setGlobalScrollerStyle:(CPScrollerStyle)aStyle
|
||||
{
|
||||
CPScrollerStyleGlobal = aStyle;
|
||||
[[CPNotificationCenter defaultCenter] postNotificationName:CPScrollerStyleGlobalChangeNotification object:nil];
|
||||
|
||||
// We propagate the new scroller global style to all existing CPScrollView's
|
||||
for (var i = 0, count = [_CPScrollViews count]; i < count; i++)
|
||||
[_CPScrollViews[i] setScrollerStyle:CPScrollerStyleGlobal];
|
||||
}
|
||||
|
||||
|
||||
@@ -323,6 +358,8 @@ var CPScrollerStyleGlobal = CPScrollerStyleOverlay,
|
||||
_delegate = nil;
|
||||
_scrollTimer = nil;
|
||||
_implementedDelegateMethods = 0;
|
||||
|
||||
[_CPScrollViews addObject:self];
|
||||
}
|
||||
|
||||
return self;
|
||||
@@ -1416,7 +1453,9 @@ Notifies the delegate when the scroll view has finished scrolling.
|
||||
|
||||
if (_scrollerStyle === CPScrollerStyleLegacy)
|
||||
{
|
||||
[[self bottomCornerView] setFrame:[self _bottomCornerViewFrame]];
|
||||
var bottomCornerFrame = [self _bottomCornerViewFrame];
|
||||
[[self bottomCornerView] setFrame:bottomCornerFrame];
|
||||
[[self bottomCornerView] setHidden:CGRectIsEmpty(bottomCornerFrame)];
|
||||
[[self bottomCornerView] setBackgroundColor:[self currentValueForThemeAttribute:@"bottom-corner-color"]];
|
||||
}
|
||||
|
||||
@@ -1494,7 +1533,6 @@ Notifies the delegate when the scroll view has finished scrolling.
|
||||
// MARK: -
|
||||
// MARK: Overrides
|
||||
|
||||
|
||||
- (void)_removeObservers
|
||||
{
|
||||
if (!_isObserving)
|
||||
@@ -1512,9 +1550,6 @@ Notifies the delegate when the scroll view has finished scrolling.
|
||||
if (_isObserving)
|
||||
return;
|
||||
|
||||
//Make sure to have the last global style for the scroller
|
||||
[self _didReceiveDefaultStyleChange:nil];
|
||||
|
||||
[[CPNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(_didReceiveDefaultStyleChange:)
|
||||
name:CPScrollerStyleGlobalChangeNotification
|
||||
@@ -1523,13 +1558,11 @@ Notifies the delegate when the scroll view has finished scrolling.
|
||||
[super _addObservers];
|
||||
}
|
||||
|
||||
|
||||
|
||||
- (void)drawRect:(CGRect)aRect
|
||||
{
|
||||
[super drawRect:aRect];
|
||||
|
||||
if (_borderType == CPNoBorder)
|
||||
if ([self isCSSBased] || (_borderType == CPNoBorder))
|
||||
return;
|
||||
|
||||
var strokeRect = [self bounds],
|
||||
@@ -1734,6 +1767,37 @@ Notifies the delegate when the scroll view has finished scrolling.
|
||||
|
||||
// MARK: -
|
||||
|
||||
@implementation CPScrollView (CSSTheming)
|
||||
|
||||
- (void)layoutSubviews
|
||||
{
|
||||
if (![self isCSSBased])
|
||||
return;
|
||||
|
||||
if (_borderType !== CPNoBorder)
|
||||
[self setBackgroundColor:[self currentValueForThemeAttribute:@"background-color-"+CPScrollViewBorderSuffixes[_borderType]]];
|
||||
|
||||
if (_scrollerStyle === CPScrollerStyleLegacy)
|
||||
[[self bottomCornerView] setBackgroundColor:[self currentValueForThemeAttribute:@"bottom-corner-color"]];
|
||||
}
|
||||
|
||||
- (BOOL)isCSSBased
|
||||
{
|
||||
return [[self theme] isCSSBased];
|
||||
}
|
||||
|
||||
- (void)refreshDisplay
|
||||
{
|
||||
if ([self isCSSBased])
|
||||
[self setNeedsLayout:YES];
|
||||
else
|
||||
[self setNeedsDisplay:YES];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark -
|
||||
|
||||
@implementation CPScrollView (FirstResponder)
|
||||
|
||||
// Those 4 next methods are needed to (un)set CPThemeStateFirstResponder based on content view
|
||||
@@ -1850,10 +1914,7 @@ var CPScrollViewContentViewKey = @"CPScrollViewContentView",
|
||||
_scrollerStyle = [aCoder decodeObjectForKey:CPScrollViewScrollerStyleKey] || CPScrollerStyleGlobal;
|
||||
_scrollerKnobStyle = [aCoder decodeObjectForKey:CPScrollViewScrollerKnobStyleKey] || CPScrollerKnobStyleDefault;
|
||||
|
||||
[[CPNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(_didReceiveDefaultStyleChange:)
|
||||
name:CPScrollerStyleGlobalChangeNotification
|
||||
object:nil];
|
||||
[_CPScrollViews addObject:self];
|
||||
}
|
||||
|
||||
return self;
|
||||
|
||||
+19
-1
@@ -320,7 +320,25 @@ CPThemeStateScrollerKnobDark = CPThemeState("scroller-knob-dark");
|
||||
if (![self hasThemeState:CPThemeStateSelected] && ![self hasThemeState:CPThemeStateScrollViewLegacy])
|
||||
return CPScrollerNoPart;
|
||||
|
||||
if (CGRectContainsPoint([self rectForPart:CPScrollerKnob], aPoint))
|
||||
// Fetch the visual rect for the knob
|
||||
var bounds = [self bounds],
|
||||
knobRect = [self rectForPart:CPScrollerKnob],
|
||||
hitKnobRect = CGRectMake(CGRectGetMinX(knobRect), CGRectGetMinY(knobRect), CGRectGetWidth(knobRect), CGRectGetHeight(knobRect));
|
||||
|
||||
// Expand the hit test rect to span the entire track on the minor axis
|
||||
// so dragging works smoothly even if the user clicks slightly off-center.
|
||||
if ([self isVertical])
|
||||
{
|
||||
hitKnobRect.origin.x = 0;
|
||||
hitKnobRect.size.width = CGRectGetWidth(bounds);
|
||||
}
|
||||
else
|
||||
{
|
||||
hitKnobRect.origin.y = 0;
|
||||
hitKnobRect.size.height = CGRectGetHeight(bounds);
|
||||
}
|
||||
|
||||
if (CGRectContainsPoint(hitKnobRect, aPoint))
|
||||
return CPScrollerKnob;
|
||||
|
||||
if (CGRectContainsPoint([self rectForPart:CPScrollerDecrementPage], aPoint))
|
||||
|
||||
@@ -104,6 +104,8 @@ var CPAutosavedRecentsChangedNotification = @"CPAutosavedRecentsChangedNotificat
|
||||
_sendsWholeSearchString = NO;
|
||||
_sendsSearchStringImmediately = NO;
|
||||
_recentsAutosaveName = nil;
|
||||
|
||||
[self setPlaceholderString:@"Search"];
|
||||
|
||||
[self _init];
|
||||
}
|
||||
@@ -122,8 +124,13 @@ var CPAutosavedRecentsChangedNotification = @"CPAutosavedRecentsChangedNotificat
|
||||
[self setContinuous:YES];
|
||||
|
||||
var bounds = [self bounds],
|
||||
cancelButton = [[CPButton alloc] initWithFrame:[self cancelButtonRectForBounds:bounds]],
|
||||
searchButton = [[CPButton alloc] initWithFrame:[self searchButtonRectForBounds:bounds]];
|
||||
cancelButton = nil,
|
||||
searchButton = nil;
|
||||
|
||||
#if PLATFORM(DOM)
|
||||
cancelButton = [[CPButton alloc] initWithFrame:[self cancelButtonRectForBounds:bounds]];
|
||||
searchButton = [[CPButton alloc] initWithFrame:[self searchButtonRectForBounds:bounds]];
|
||||
#endif
|
||||
|
||||
[self setCancelButton:cancelButton];
|
||||
[self resetCancelButton];
|
||||
|
||||
+278
-149
@@ -71,7 +71,7 @@ CPSegmentSwitchTrackingMomentary = 2;
|
||||
@"right-segment-bezel-color": [CPNull null],
|
||||
@"center-segment-bezel-color": [CPNull null],
|
||||
@"divider-bezel-color": [CPNull null],
|
||||
@"divider-thickness": 1.0,
|
||||
@"divider-thickness": 1.0
|
||||
};
|
||||
}
|
||||
|
||||
@@ -316,7 +316,7 @@ CPSegmentSwitchTrackingMomentary = 2;
|
||||
// Working with Individual Segments
|
||||
/*!
|
||||
Sets the width of the specified segment.
|
||||
@param aWidth the new width for the segment
|
||||
@param aWidth the new width for the segment (0 for automatic width)
|
||||
@param aSegment the segment to set the width for
|
||||
@throws CPRangeException if \c aSegment is out of bounds
|
||||
*/
|
||||
@@ -420,7 +420,14 @@ CPSegmentSwitchTrackingMomentary = 2;
|
||||
|
||||
[segment setSelected:isSelected];
|
||||
|
||||
_themeStates[aSegment] = isSelected ? CPThemeStateSelected : CPThemeStateNormal;
|
||||
if (_themeStates[aSegment] == undefined)
|
||||
_themeStates[aSegment] = CPThemeStateNormal;
|
||||
|
||||
// Update state using .and() / .without() to preserve existing states (like Disabled)
|
||||
if (isSelected)
|
||||
_themeStates[aSegment] = _themeStates[aSegment].and(CPThemeStateSelected);
|
||||
else
|
||||
_themeStates[aSegment] = _themeStates[aSegment].without(CPThemeStateSelected);
|
||||
|
||||
// We need to do some cleanup if we only allow one selection.
|
||||
if (isSelected)
|
||||
@@ -432,7 +439,10 @@ CPSegmentSwitchTrackingMomentary = 2;
|
||||
if (_trackingMode == CPSegmentSwitchTrackingSelectOne && oldSelectedSegment != aSegment && oldSelectedSegment != -1 && oldSelectedSegment < _segments.length)
|
||||
{
|
||||
[_segments[oldSelectedSegment] setSelected:NO];
|
||||
_themeStates[oldSelectedSegment] = CPThemeStateNormal;
|
||||
|
||||
// Update old segment using .without() to preserve other states
|
||||
// Previously: _themeStates[oldSelectedSegment] = CPThemeStateNormal;
|
||||
_themeStates[oldSelectedSegment] = _themeStates[oldSelectedSegment].without(CPThemeStateSelected);
|
||||
|
||||
[self drawSegmentBezel:oldSelectedSegment highlight:NO];
|
||||
}
|
||||
@@ -530,12 +540,24 @@ CPSegmentSwitchTrackingMomentary = 2;
|
||||
|
||||
- (float)_leftOffsetForSegment:(unsigned)segment
|
||||
{
|
||||
if (segment == 0)
|
||||
return [self currentValueForThemeAttribute:@"bezel-inset"].left;
|
||||
if ([[self actualTheme] isCSSBased])
|
||||
{
|
||||
// CSS styling
|
||||
if (segment == 0)
|
||||
return 0;
|
||||
|
||||
var thickness = [self currentValueForThemeAttribute:@"divider-thickness"];
|
||||
return [self _leftOffsetForSegment:segment - 1] + CGRectGetWidth([self frameForSegment:segment - 1]) - 2; // FIXME: -2 for collapse of borders
|
||||
}
|
||||
else
|
||||
{
|
||||
// Legacy styling
|
||||
if (segment == 0)
|
||||
return [self currentValueForThemeAttribute:@"bezel-inset"].left;
|
||||
|
||||
return [self _leftOffsetForSegment:segment - 1] + CGRectGetWidth([self frameForSegment:segment - 1]) + thickness;
|
||||
var thickness = [self currentValueForThemeAttribute:@"divider-thickness"];
|
||||
|
||||
return [self _leftOffsetForSegment:segment - 1] + CGRectGetWidth([self frameForSegment:segment - 1]) + thickness;
|
||||
}
|
||||
}
|
||||
|
||||
- (unsigned)_indexOfLastSegment
|
||||
@@ -569,19 +591,28 @@ CPSegmentSwitchTrackingMomentary = 2;
|
||||
}
|
||||
else if (aName.indexOf("segment-bezel") === 0)
|
||||
{
|
||||
var segment = parseInt(aName.substring("segment-bezel-".length), 10),
|
||||
if ([[self actualTheme] isCSSBased])
|
||||
{
|
||||
var segment = parseInt(aName.substring("segment-bezel-".length), 10);
|
||||
|
||||
return [self bezelFrameForSegment:segment];
|
||||
}
|
||||
else
|
||||
{
|
||||
var segment = parseInt(aName.substring("segment-bezel-".length), 10),
|
||||
frame = CGRectCreateCopy([self frameForSegment:segment]);
|
||||
|
||||
if (segment === 0)
|
||||
{
|
||||
frame.origin.x += contentInset.left;
|
||||
frame.size.width -= contentInset.left;
|
||||
if (segment === 0)
|
||||
{
|
||||
frame.origin.x += contentInset.left;
|
||||
frame.size.width -= contentInset.left;
|
||||
}
|
||||
|
||||
if (segment === [self segmentCount] - 1)
|
||||
frame.size.width = CGRectGetWidth([self bounds]) - contentInset.right - frame.origin.x;
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
if (segment === [self segmentCount] - 1)
|
||||
frame.size.width = CGRectGetWidth([self bounds]) - contentInset.right - frame.origin.x;
|
||||
|
||||
return frame;
|
||||
}
|
||||
else if (aName.indexOf("divider-bezel") === 0)
|
||||
{
|
||||
@@ -620,48 +651,85 @@ CPSegmentSwitchTrackingMomentary = 2;
|
||||
if ([self segmentCount] <= 0)
|
||||
return;
|
||||
|
||||
var themeState = _themeStates[0],
|
||||
isDisabled = [self hasThemeState:CPThemeStateDisabled],
|
||||
isControlSizeSmall = [self hasThemeState:CPThemeStateControlSizeSmall],
|
||||
isControlSizeMini = [self hasThemeState:CPThemeStateControlSizeMini];
|
||||
// Check for HUD state globally
|
||||
var isHUD = [self hasThemeState:CPThemeStateHUD];
|
||||
|
||||
themeState = isDisabled ? themeState.and(CPThemeStateDisabled) : themeState;
|
||||
|
||||
if (isControlSizeSmall)
|
||||
themeState = themeState.and(CPThemeStateControlSizeSmall);
|
||||
else if (isControlSizeMini)
|
||||
themeState = themeState.and(CPThemeStateControlSizeMini);
|
||||
|
||||
var leftCapColor = [self valueForThemeAttribute:@"left-segment-bezel-color"
|
||||
inState:themeState],
|
||||
|
||||
leftBezelView = [self layoutEphemeralSubviewNamed:@"left-segment-bezel"
|
||||
positioned:CPWindowBelow
|
||||
relativeToEphemeralSubviewNamed:nil];
|
||||
|
||||
[leftBezelView setBackgroundColor:leftCapColor];
|
||||
|
||||
var themeState = _themeStates[_themeStates.length - 1];
|
||||
|
||||
themeState = isDisabled ? themeState.and(CPThemeStateDisabled) : themeState;
|
||||
|
||||
if (isControlSizeSmall)
|
||||
themeState = themeState.and(CPThemeStateControlSizeSmall);
|
||||
else if (isControlSizeMini)
|
||||
themeState = themeState.and(CPThemeStateControlSizeMini);
|
||||
|
||||
var rightCapColor = [self valueForThemeAttribute:@"right-segment-bezel-color"
|
||||
inState:themeState],
|
||||
|
||||
rightBezelView = [self layoutEphemeralSubviewNamed:@"right-segment-bezel"
|
||||
positioned:CPWindowBelow
|
||||
relativeToEphemeralSubviewNamed:nil];
|
||||
|
||||
[rightBezelView setBackgroundColor:rightCapColor];
|
||||
|
||||
for (var i = 0, count = _themeStates.length; i < count; i++)
|
||||
if ([[self actualTheme] isCSSBased])
|
||||
{
|
||||
var themeState = _themeStates[i];
|
||||
// CSS Styling
|
||||
|
||||
var isDisabled = [self hasThemeState:CPThemeStateDisabled],
|
||||
isControlSizeSmall = [self hasThemeState:CPThemeStateControlSizeSmall],
|
||||
isControlSizeMini = [self hasThemeState:CPThemeStateControlSizeMini],
|
||||
isKeyWindow = [self hasThemeState:CPThemeStateKeyWindow];
|
||||
|
||||
for (var i = 0, count = _themeStates.length; i < count; i++)
|
||||
{
|
||||
var themeState = _themeStates[i];
|
||||
|
||||
themeState = isDisabled ? themeState.and(CPThemeStateDisabled) : themeState;
|
||||
|
||||
if (isControlSizeSmall)
|
||||
themeState = themeState.and(CPThemeStateControlSizeSmall);
|
||||
else if (isControlSizeMini)
|
||||
themeState = themeState.and(CPThemeStateControlSizeMini);
|
||||
|
||||
// Apply HUD state to lookup
|
||||
if (isHUD)
|
||||
themeState = themeState.and(CPThemeStateHUD);
|
||||
|
||||
themeState = isKeyWindow ? themeState.and(CPThemeStateKeyWindow) : themeState;
|
||||
|
||||
var bezelColor,
|
||||
segment = _segments[i],
|
||||
bezelView = [self layoutEphemeralSubviewNamed:"segment-bezel-" + i
|
||||
positioned:CPWindowBelow
|
||||
relativeToEphemeralSubviewNamed:nil],
|
||||
contentView = [self layoutEphemeralSubviewNamed:@"segment-content-" + i
|
||||
positioned:CPWindowAbove
|
||||
relativeToEphemeralSubviewNamed:"segment-bezel-" + i];
|
||||
|
||||
if (i == 0)
|
||||
bezelColor = [self valueForThemeAttribute:@"left-segment-bezel-color" inState:themeState];
|
||||
else if (i < count - 1)
|
||||
bezelColor = [self valueForThemeAttribute:@"center-segment-bezel-color" inState:themeState];
|
||||
else
|
||||
bezelColor = [self valueForThemeAttribute:@"right-segment-bezel-color" inState:themeState];
|
||||
|
||||
[bezelView setBackgroundColor:bezelColor];
|
||||
|
||||
// Trick : Put selected segments over unselected ones to automaticaly manage borders
|
||||
|
||||
#if PLATFORM(DOM)
|
||||
contentView._DOMElement.style.zIndex = ([segment selected] ? 1 : 0);
|
||||
bezelView._DOMElement.style.zIndex = ([segment selected] ? 1 : 0);
|
||||
#endif
|
||||
|
||||
[contentView setText:[segment label]];
|
||||
[contentView setImage:[segment image]];
|
||||
|
||||
[contentView setFont:[self valueForThemeAttribute:@"font" inState:themeState]];
|
||||
[contentView setTextColor:[self valueForThemeAttribute:@"text-color" inState:([segment enabled] ? themeState : themeState.and(CPThemeStateDisabled))]];
|
||||
[contentView setAlignment:[self valueForThemeAttribute:@"alignment" inState:themeState]];
|
||||
[contentView setVerticalAlignment:[self valueForThemeAttribute:@"vertical-alignment" inState:themeState]];
|
||||
[contentView setLineBreakMode:[self valueForThemeAttribute:@"line-break-mode" inState:themeState]];
|
||||
[contentView setTextShadowColor:[self valueForThemeAttribute:@"text-shadow-color" inState:themeState]];
|
||||
[contentView setTextShadowOffset:[self valueForThemeAttribute:@"text-shadow-offset" inState:themeState]];
|
||||
[contentView setImageScaling:[self valueForThemeAttribute:@"image-scaling" inState:themeState]];
|
||||
|
||||
if ([segment image] && [segment label])
|
||||
[contentView setImagePosition:[self valueForThemeAttribute:@"image-position" inState:themeState]];
|
||||
else if ([segment image])
|
||||
[contentView setImagePosition:CPImageOnly];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Legacy (Canvas) Styling
|
||||
var themeState = _themeStates[0],
|
||||
isDisabled = [self hasThemeState:CPThemeStateDisabled],
|
||||
isControlSizeSmall = [self hasThemeState:CPThemeStateControlSizeSmall],
|
||||
isControlSizeMini = [self hasThemeState:CPThemeStateControlSizeMini];
|
||||
|
||||
themeState = isDisabled ? themeState.and(CPThemeStateDisabled) : themeState;
|
||||
|
||||
@@ -670,59 +738,114 @@ CPSegmentSwitchTrackingMomentary = 2;
|
||||
else if (isControlSizeMini)
|
||||
themeState = themeState.and(CPThemeStateControlSizeMini);
|
||||
|
||||
var bezelColor = [self valueForThemeAttribute:@"center-segment-bezel-color"
|
||||
inState:themeState],
|
||||
// Apply HUD state to Left Cap
|
||||
if (isHUD)
|
||||
themeState = themeState.and(CPThemeStateHUD);
|
||||
|
||||
bezelView = [self layoutEphemeralSubviewNamed:"segment-bezel-" + i
|
||||
positioned:CPWindowBelow
|
||||
relativeToEphemeralSubviewNamed:nil];
|
||||
var leftCapColor = [self valueForThemeAttribute:@"left-segment-bezel-color"
|
||||
inState:themeState],
|
||||
|
||||
[bezelView setBackgroundColor:bezelColor];
|
||||
leftBezelView = [self layoutEphemeralSubviewNamed:@"left-segment-bezel"
|
||||
positioned:CPWindowBelow
|
||||
relativeToEphemeralSubviewNamed:nil];
|
||||
|
||||
// layout image/title views
|
||||
var segment = _segments[i],
|
||||
contentView = [self layoutEphemeralSubviewNamed:@"segment-content-" + i
|
||||
positioned:CPWindowAbove
|
||||
relativeToEphemeralSubviewNamed:@"segment-bezel-" + i];
|
||||
[leftBezelView setBackgroundColor:leftCapColor];
|
||||
|
||||
[contentView setText:[segment label]];
|
||||
[contentView setImage:[segment image]];
|
||||
var themeState = _themeStates[_themeStates.length - 1];
|
||||
|
||||
[contentView setFont:[self valueForThemeAttribute:@"font" inState:themeState]];
|
||||
[contentView setTextColor:[self valueForThemeAttribute:@"text-color" inState:themeState]];
|
||||
[contentView setAlignment:[self valueForThemeAttribute:@"alignment" inState:themeState]];
|
||||
[contentView setVerticalAlignment:[self valueForThemeAttribute:@"vertical-alignment" inState:themeState]];
|
||||
[contentView setLineBreakMode:[self valueForThemeAttribute:@"line-break-mode" inState:themeState]];
|
||||
[contentView setTextShadowColor:[self valueForThemeAttribute:@"text-shadow-color" inState:themeState]];
|
||||
[contentView setTextShadowOffset:[self valueForThemeAttribute:@"text-shadow-offset" inState:themeState]];
|
||||
[contentView setImageScaling:[self valueForThemeAttribute:@"image-scaling" inState:themeState]];
|
||||
|
||||
if ([segment image] && [segment label])
|
||||
[contentView setImagePosition:[self valueForThemeAttribute:@"image-position" inState:themeState]];
|
||||
else if ([segment image])
|
||||
[contentView setImagePosition:CPImageOnly];
|
||||
|
||||
if (i == count - 1)
|
||||
continue;
|
||||
|
||||
|
||||
var borderState = _themeStates[i].and(_themeStates[i + 1]);
|
||||
|
||||
borderState = isDisabled ? borderState.and(CPThemeStateDisabled) : borderState;
|
||||
themeState = isDisabled ? themeState.and(CPThemeStateDisabled) : themeState;
|
||||
|
||||
if (isControlSizeSmall)
|
||||
borderState = borderState.and(CPThemeStateControlSizeSmall);
|
||||
themeState = themeState.and(CPThemeStateControlSizeSmall);
|
||||
else if (isControlSizeMini)
|
||||
borderState = borderState.and(CPThemeStateControlSizeMini);
|
||||
themeState = themeState.and(CPThemeStateControlSizeMini);
|
||||
|
||||
var borderColor = [self valueForThemeAttribute:@"divider-bezel-color"
|
||||
inState:borderState],
|
||||
// Apply HUD state to Right Cap
|
||||
if (isHUD)
|
||||
themeState = themeState.and(CPThemeStateHUD);
|
||||
|
||||
var rightCapColor = [self valueForThemeAttribute:@"right-segment-bezel-color"
|
||||
inState:themeState],
|
||||
|
||||
rightBezelView = [self layoutEphemeralSubviewNamed:@"right-segment-bezel"
|
||||
positioned:CPWindowBelow
|
||||
relativeToEphemeralSubviewNamed:nil];
|
||||
|
||||
[rightBezelView setBackgroundColor:rightCapColor];
|
||||
|
||||
for (var i = 0, count = _themeStates.length; i < count; i++)
|
||||
{
|
||||
var themeState = _themeStates[i];
|
||||
|
||||
themeState = isDisabled ? themeState.and(CPThemeStateDisabled) : themeState;
|
||||
|
||||
if (isControlSizeSmall)
|
||||
themeState = themeState.and(CPThemeStateControlSizeSmall);
|
||||
else if (isControlSizeMini)
|
||||
themeState = themeState.and(CPThemeStateControlSizeMini);
|
||||
|
||||
// Apply HUD state to Center Segments
|
||||
if (isHUD)
|
||||
themeState = themeState.and(CPThemeStateHUD);
|
||||
|
||||
var bezelColor = [self valueForThemeAttribute:@"center-segment-bezel-color"
|
||||
inState:themeState],
|
||||
|
||||
bezelView = [self layoutEphemeralSubviewNamed:"segment-bezel-" + i
|
||||
positioned:CPWindowBelow
|
||||
relativeToEphemeralSubviewNamed:nil];
|
||||
|
||||
[bezelView setBackgroundColor:bezelColor];
|
||||
|
||||
// layout image/title views
|
||||
var segment = _segments[i],
|
||||
contentView = [self layoutEphemeralSubviewNamed:@"segment-content-" + i
|
||||
positioned:CPWindowAbove
|
||||
relativeToEphemeralSubviewNamed:@"segment-bezel-" + i];
|
||||
|
||||
[contentView setText:[segment label]];
|
||||
[contentView setImage:[segment image]];
|
||||
|
||||
[contentView setFont:[self valueForThemeAttribute:@"font" inState:themeState]];
|
||||
[contentView setTextColor:[self valueForThemeAttribute:@"text-color" inState:themeState]];
|
||||
[contentView setAlignment:[self valueForThemeAttribute:@"alignment" inState:themeState]];
|
||||
[contentView setVerticalAlignment:[self valueForThemeAttribute:@"vertical-alignment" inState:themeState]];
|
||||
[contentView setLineBreakMode:[self valueForThemeAttribute:@"line-break-mode" inState:themeState]];
|
||||
[contentView setTextShadowColor:[self valueForThemeAttribute:@"text-shadow-color" inState:themeState]];
|
||||
[contentView setTextShadowOffset:[self valueForThemeAttribute:@"text-shadow-offset" inState:themeState]];
|
||||
[contentView setImageScaling:[self valueForThemeAttribute:@"image-scaling" inState:themeState]];
|
||||
|
||||
if ([segment image] && [segment label])
|
||||
[contentView setImagePosition:[self valueForThemeAttribute:@"image-position" inState:themeState]];
|
||||
else if ([segment image])
|
||||
[contentView setImagePosition:CPImageOnly];
|
||||
|
||||
if (i == count - 1)
|
||||
continue;
|
||||
|
||||
|
||||
var borderState = _themeStates[i].and(_themeStates[i + 1]);
|
||||
|
||||
borderState = isDisabled ? borderState.and(CPThemeStateDisabled) : borderState;
|
||||
|
||||
if (isControlSizeSmall)
|
||||
borderState = borderState.and(CPThemeStateControlSizeSmall);
|
||||
else if (isControlSizeMini)
|
||||
borderState = borderState.and(CPThemeStateControlSizeMini);
|
||||
|
||||
// Apply HUD state to Dividers
|
||||
if (isHUD)
|
||||
borderState = borderState.and(CPThemeStateHUD);
|
||||
|
||||
var borderColor = [self valueForThemeAttribute:@"divider-bezel-color"
|
||||
inState:borderState],
|
||||
|
||||
borderView = [self layoutEphemeralSubviewNamed:"divider-bezel-" + i
|
||||
positioned:CPWindowBelow
|
||||
relativeToEphemeralSubviewNamed:nil];
|
||||
|
||||
[borderView setBackgroundColor:borderColor];
|
||||
[borderView setBackgroundColor:borderColor];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -803,8 +926,10 @@ CPSegmentSwitchTrackingMomentary = 2;
|
||||
label = [segment label],
|
||||
image = [segment image];
|
||||
|
||||
contentInsetWidth += ([[self actualTheme] isCSSBased] && ((aSegment == 0) || (aSegment == [self _indexOfLastSegment])) ? [self valueForThemeAttribute:@"divider-thickness" inState:themeState] : 0);
|
||||
|
||||
// add 1 pixel to account for possible fractional pixels at right edge
|
||||
width = (label ? [label sizeWithFont:[self font]].width + 1 : 4.0) + (image ? [image size].width : 0) + contentInsetWidth;
|
||||
width = CEIL((label ? [label sizeWithFont:[self font]].width + 1: 4.0) + (image ? [image size].width : 0) + contentInsetWidth);
|
||||
}
|
||||
|
||||
return CGRectMake(left, top, width, height);
|
||||
@@ -812,6 +937,14 @@ CPSegmentSwitchTrackingMomentary = 2;
|
||||
|
||||
- (CGRect)contentFrameForSegment:(unsigned)aSegment
|
||||
{
|
||||
if ([[self actualTheme] isCSSBased])
|
||||
{
|
||||
var bezelFrame = [self bezelFrameForSegment:aSegment],
|
||||
contentInset = [self currentValueForThemeAttribute:@"content-inset"];
|
||||
|
||||
return CGRectInsetByInset(bezelFrame, contentInset);
|
||||
}
|
||||
|
||||
var height = [self currentValueForThemeAttribute:@"min-size"].height,
|
||||
contentInset = [self currentValueForThemeAttribute:@"content-inset"],
|
||||
width = CGRectGetWidth([self frameForSegment:aSegment]),
|
||||
@@ -874,68 +1007,64 @@ CPSegmentSwitchTrackingMomentary = 2;
|
||||
var type = [anEvent type],
|
||||
location = [self convertPoint:[anEvent locationInWindow] fromView:nil];
|
||||
|
||||
switch (type)
|
||||
if (type == CPLeftMouseUp)
|
||||
{
|
||||
case CPLeftMouseUp:
|
||||
|
||||
if (_trackingSegment === CPNotFound)
|
||||
return;
|
||||
|
||||
if (_trackingSegment === [self testSegment:location])
|
||||
{
|
||||
if (_trackingMode == CPSegmentSwitchTrackingSelectAny)
|
||||
{
|
||||
[self setSelected:![self isSelectedForSegment:_trackingSegment] forSegment:_trackingSegment];
|
||||
|
||||
// With ANY, _selectedSegment means last pressed.
|
||||
_selectedSegment = _trackingSegment;
|
||||
}
|
||||
else
|
||||
[self setSelected:YES forSegment:_trackingSegment];
|
||||
|
||||
[self sendAction:[self action] to:[self target]];
|
||||
|
||||
if (_trackingMode == CPSegmentSwitchTrackingMomentary)
|
||||
{
|
||||
[self setSelected:NO forSegment:_trackingSegment];
|
||||
|
||||
_selectedSegment = CPNotFound;
|
||||
}
|
||||
}
|
||||
|
||||
[self drawSegmentBezel:_trackingSegment highlight:NO];
|
||||
|
||||
_trackingSegment = CPNotFound;
|
||||
|
||||
if (_trackingSegment == -1)
|
||||
return;
|
||||
|
||||
case CPLeftMouseDown:
|
||||
|
||||
var trackingSegment = [self testSegment:location];
|
||||
if (trackingSegment > CPNotFound && [self isEnabledForSegment:trackingSegment])
|
||||
if (_trackingSegment === [self testSegment:location])
|
||||
{
|
||||
if (_trackingMode == CPSegmentSwitchTrackingSelectAny)
|
||||
{
|
||||
_trackingHighlighted = YES;
|
||||
_trackingSegment = trackingSegment;
|
||||
[self drawSegmentBezel:_trackingSegment highlight:YES];
|
||||
[self setSelected:![self isSelectedForSegment:_trackingSegment] forSegment:_trackingSegment];
|
||||
|
||||
// With ANY, _selectedSegment means last pressed.
|
||||
_selectedSegment = _trackingSegment;
|
||||
}
|
||||
else
|
||||
[self setSelected:YES forSegment:_trackingSegment];
|
||||
|
||||
break;
|
||||
[self sendAction:[self action] to:[self target]];
|
||||
|
||||
case CPLeftMouseDragged:
|
||||
|
||||
if (_trackingSegment === CPNotFound)
|
||||
return;
|
||||
|
||||
var highlighted = [self testSegment:location] === _trackingSegment;
|
||||
|
||||
if (highlighted != _trackingHighlighted)
|
||||
if (_trackingMode == CPSegmentSwitchTrackingMomentary)
|
||||
{
|
||||
_trackingHighlighted = highlighted;
|
||||
[self setSelected:NO forSegment:_trackingSegment];
|
||||
|
||||
[self drawSegmentBezel:_trackingSegment highlight:_trackingHighlighted];
|
||||
_selectedSegment = CPNotFound;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
[self drawSegmentBezel:_trackingSegment highlight:NO];
|
||||
|
||||
_trackingSegment = -1;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (type == CPLeftMouseDown)
|
||||
{
|
||||
var trackingSegment = [self testSegment:location];
|
||||
if (trackingSegment > -1 && [self isEnabledForSegment:trackingSegment])
|
||||
{
|
||||
_trackingHighlighted = YES;
|
||||
_trackingSegment = trackingSegment;
|
||||
[self drawSegmentBezel:_trackingSegment highlight:YES];
|
||||
}
|
||||
}
|
||||
|
||||
else if (type == CPLeftMouseDragged)
|
||||
{
|
||||
if (_trackingSegment == -1)
|
||||
return;
|
||||
|
||||
var highlighted = [self testSegment:location] === _trackingSegment;
|
||||
|
||||
if (highlighted != _trackingHighlighted)
|
||||
{
|
||||
_trackingHighlighted = highlighted;
|
||||
|
||||
[self drawSegmentBezel:_trackingSegment highlight:_trackingHighlighted];
|
||||
}
|
||||
}
|
||||
|
||||
[CPApp setTarget:self selector:@selector(trackSegment:) forNextEventMatchingMask:CPLeftMouseDraggedMask | CPLeftMouseUpMask untilDate:nil inMode:nil dequeue:YES];
|
||||
|
||||
@@ -102,6 +102,7 @@ CPThemeStateShadowViewHeavy = CPThemeState("shadowview-style-heavy");
|
||||
[self setWeight:CPLightShadow];
|
||||
|
||||
[self setHitTests:NO];
|
||||
[self setClipsToBounds:NO];
|
||||
}
|
||||
|
||||
return self;
|
||||
@@ -169,7 +170,6 @@ CPThemeStateShadowViewHeavy = CPThemeState("shadowview-style-heavy");
|
||||
- (void)layoutSubviews
|
||||
{
|
||||
[super layoutSubviews];
|
||||
|
||||
[self setBackgroundColor:[self currentValueForThemeAttribute:@"bezel-color"]];
|
||||
}
|
||||
|
||||
|
||||
@@ -822,6 +822,9 @@ var CPThemeStatesForSplitViewDivider = @[@"dummy one as CPSplitViewDividerStyle
|
||||
|
||||
- (void)layoutSubviews
|
||||
{
|
||||
// Retrieve the current color based on the current theme state (Standard vs HUD)
|
||||
var currentDividerColor = [self dividerColor];
|
||||
|
||||
for (var i = 0, count = _arrangedSubviews.length, position = 0, origin; i < count; i++)
|
||||
{
|
||||
origin = CGPointMakeZero();
|
||||
@@ -836,6 +839,9 @@ var CPThemeStatesForSplitViewDivider = @[@"dummy one as CPSplitViewDividerStyle
|
||||
origin[_originComponent] = position;
|
||||
position += [_dividerSubviews[i] frame].size[_sizeComponent];
|
||||
|
||||
// Apply the color to the specific divider view
|
||||
[_dividerSubviews[i] setBackgroundColor:currentDividerColor];
|
||||
|
||||
[_dividerSubviews[i] setFrameOrigin:origin];
|
||||
}
|
||||
}
|
||||
|
||||
+18
-135
@@ -20,80 +20,7 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* PLACEHOLDER IMPLEMENTATION — READ BEFORE USE OR MODIFICATION.
|
||||
*
|
||||
* This class lays out views by direct, procedural arithmetic. It has no
|
||||
* constraint solver. It cannot compress, expand, or negotiate space among
|
||||
* views the way NSStackView does; it only places views at their existing
|
||||
* frame size, in order, separated by fixed spacing.
|
||||
*
|
||||
* Known, accepted limitations:
|
||||
* - `distribution` is stored but has no effect on layout. Fill,
|
||||
* FillEqually, FillProportionally, and EqualSpacing are unimplemented.
|
||||
* - Center-gravity views are clamped against the Leading edge only; if
|
||||
* Leading + Center + Trailing content overflows the container, Center
|
||||
* views can overlap Trailing views instead of compressing.
|
||||
* - `visibilityPriority:forView:` only supports the two extreme values
|
||||
* (MustHold / NotVisible). Intermediate priorities are accepted but
|
||||
* have no defined effect.
|
||||
* - No guarantee is made of correctness beyond what a single manual
|
||||
* test (Tests/Manual/CPStackViewTest) exercises: orientation, the
|
||||
* three gravity areas, alignment switching, spacing, and hidden-view
|
||||
* detachment. Insertion, removal, custom spacing, and the CPCoding
|
||||
* archive path are implemented but not verified by that test.
|
||||
*
|
||||
* This exists to give AppKit a working CPStackView symbol now, not to be
|
||||
* a durable design. It is expected to be replaced by a constraint-solver
|
||||
* based implementation (Kiwi.js) when time permits. Do not build on its
|
||||
* internal layout algorithm as if it were a stable foundation.
|
||||
*/
|
||||
|
||||
@import "CPView.j"
|
||||
@import <Foundation/CPMapTable.j>
|
||||
|
||||
// MARK: -
|
||||
// MARK: Minimal local type definitions
|
||||
//
|
||||
// These types support this file only. They are not shared with the rest
|
||||
// of AppKit. A future constraint-solver based Auto Layout engine will
|
||||
// replace them. Numeric values match the equivalent Cocoa constants
|
||||
// (NSUserInterfaceLayoutOrientation, NSLayoutAttribute) so that a later,
|
||||
// solver-based CPLayoutAttribute can reuse these numbers without a
|
||||
// renumbering pass.
|
||||
|
||||
@typedef CPUserInterfaceLayoutOrientation
|
||||
CPUserInterfaceLayoutOrientationHorizontal = 0;
|
||||
CPUserInterfaceLayoutOrientationVertical = 1;
|
||||
|
||||
@typedef CPLayoutAttribute
|
||||
CPLayoutAttributeLeft = 1;
|
||||
CPLayoutAttributeRight = 2;
|
||||
CPLayoutAttributeTop = 3;
|
||||
CPLayoutAttributeBottom = 4;
|
||||
CPLayoutAttributeLeading = 5;
|
||||
CPLayoutAttributeTrailing = 6;
|
||||
CPLayoutAttributeWidth = 7;
|
||||
CPLayoutAttributeHeight = 8;
|
||||
CPLayoutAttributeCenterX = 9;
|
||||
CPLayoutAttributeCenterY = 10;
|
||||
|
||||
@typedef CPEdgeInsets
|
||||
|
||||
/*!
|
||||
Creates a CPEdgeInsets. Argument order matches Cocoa's NSEdgeInsetsMake
|
||||
(top, left, bottom, right). Storage reuses the existing CGInset struct,
|
||||
whose field order is (top, right, bottom, left).
|
||||
*/
|
||||
function CPEdgeInsetsMake(top, left, bottom, right)
|
||||
{
|
||||
return CGInsetMake(top, right, bottom, left);
|
||||
}
|
||||
|
||||
function CPEdgeInsetsEqualToEdgeInsets(lhsInsets, rhsInsets)
|
||||
{
|
||||
return CGInsetEqualToInset(lhsInsets, rhsInsets);
|
||||
}
|
||||
|
||||
// Gravity Areas
|
||||
@typedef CPStackViewGravity
|
||||
@@ -133,7 +60,6 @@ var CPStackViewSpacingUseDefault = 3.40282347e+38; // FLT_MAX
|
||||
{
|
||||
CPUserInterfaceLayoutOrientation _orientation;
|
||||
CPLayoutAttribute _alignment;
|
||||
CPStackViewDistribution _distribution;
|
||||
float _spacing;
|
||||
CPEdgeInsets _edgeInsets;
|
||||
|
||||
@@ -173,7 +99,6 @@ var CPStackViewSpacingUseDefault = 3.40282347e+38; // FLT_MAX
|
||||
{
|
||||
_orientation = CPUserInterfaceLayoutOrientationHorizontal;
|
||||
_alignment = CPLayoutAttributeCenterY; // Default alignment
|
||||
_distribution = CPStackViewDistributionGravityAreas;
|
||||
_spacing = 8.0; // Default Cocoa spacing
|
||||
_edgeInsets = CPEdgeInsetsMake(0, 0, 0, 0);
|
||||
_detachesHiddenViews = YES;
|
||||
@@ -244,27 +169,6 @@ var CPStackViewSpacingUseDefault = 3.40282347e+38; // FLT_MAX
|
||||
[self setNeedsLayout:YES];
|
||||
}
|
||||
|
||||
/*!
|
||||
The distribution mode for the stack view.
|
||||
@note Not yet applied to layout. All views are laid out at their
|
||||
existing frame size regardless of this value, pending the
|
||||
constraint-solver based layout engine. The value is stored and
|
||||
returned so client code can read back what was set.
|
||||
*/
|
||||
- (CPStackViewDistribution)distribution
|
||||
{
|
||||
return _distribution;
|
||||
}
|
||||
|
||||
- (void)setDistribution:(CPStackViewDistribution)aDistribution
|
||||
{
|
||||
if (_distribution === aDistribution)
|
||||
return;
|
||||
|
||||
_distribution = aDistribution;
|
||||
[self setNeedsLayout:YES];
|
||||
}
|
||||
|
||||
/*!
|
||||
The minimum spacing, in points, between adjacent views in the stack view.
|
||||
*/
|
||||
@@ -329,21 +233,6 @@ var CPStackViewSpacingUseDefault = 3.40282347e+38; // FLT_MAX
|
||||
return _viewsLeading; // Leading or Top
|
||||
}
|
||||
|
||||
/*!
|
||||
Rebuilds _arrangedSubviews from the three gravity containers, in
|
||||
Leading, Center, Trailing order. Call after any change to a gravity
|
||||
container so _arrangedSubviews stays a correct, single source of truth
|
||||
for ordering, rather than an incrementally and separately maintained
|
||||
(and error-prone) copy.
|
||||
*/
|
||||
- (void)_rebuildArrangedSubviews
|
||||
{
|
||||
_arrangedSubviews = [[CPMutableArray alloc] init];
|
||||
[_arrangedSubviews addObjectsFromArray:_viewsLeading];
|
||||
[_arrangedSubviews addObjectsFromArray:_viewsCenter];
|
||||
[_arrangedSubviews addObjectsFromArray:_viewsTrailing];
|
||||
}
|
||||
|
||||
/*!
|
||||
Adds a view to the end of the stack view gravity area.
|
||||
*/
|
||||
@@ -356,7 +245,7 @@ var CPStackViewSpacingUseDefault = 3.40282347e+38; // FLT_MAX
|
||||
[self removeView:aView];
|
||||
|
||||
[container addObject:aView];
|
||||
[self _rebuildArrangedSubviews];
|
||||
[_arrangedSubviews addObject:aView];
|
||||
|
||||
// Add as actual subview
|
||||
if ([aView superview] !== self)
|
||||
@@ -380,7 +269,7 @@ var CPStackViewSpacingUseDefault = 3.40282347e+38; // FLT_MAX
|
||||
else
|
||||
[container insertObject:aView atIndex:index];
|
||||
|
||||
[self _rebuildArrangedSubviews];
|
||||
[_arrangedSubviews addObject:aView];
|
||||
|
||||
if ([aView superview] !== self)
|
||||
[self addSubview:aView];
|
||||
@@ -395,9 +284,13 @@ var CPStackViewSpacingUseDefault = 3.40282347e+38; // FLT_MAX
|
||||
{
|
||||
var container = [self _containerForGravity:gravity];
|
||||
|
||||
// Remove old views from superview
|
||||
// Remove old views from arranged list and superview
|
||||
for (var i = 0; i < [container count]; i++)
|
||||
[container[i] removeFromSuperview];
|
||||
{
|
||||
var oldView = container[i];
|
||||
[oldView removeFromSuperview];
|
||||
[_arrangedSubviews removeObject:oldView];
|
||||
}
|
||||
|
||||
[container removeAllObjects];
|
||||
|
||||
@@ -405,10 +298,10 @@ var CPStackViewSpacingUseDefault = 3.40282347e+38; // FLT_MAX
|
||||
{
|
||||
var newView = views[i];
|
||||
[container addObject:newView];
|
||||
[_arrangedSubviews addObject:newView];
|
||||
[self addSubview:newView];
|
||||
}
|
||||
|
||||
[self _rebuildArrangedSubviews];
|
||||
[self setNeedsLayout:YES];
|
||||
}
|
||||
|
||||
@@ -423,7 +316,7 @@ var CPStackViewSpacingUseDefault = 3.40282347e+38; // FLT_MAX
|
||||
[_viewsLeading removeObject:aView];
|
||||
[_viewsCenter removeObject:aView];
|
||||
[_viewsTrailing removeObject:aView];
|
||||
[self _rebuildArrangedSubviews];
|
||||
[_arrangedSubviews removeObject:aView];
|
||||
|
||||
[aView removeFromSuperview];
|
||||
|
||||
@@ -638,13 +531,6 @@ var CPStackViewSpacingUseDefault = 3.40282347e+38; // FLT_MAX
|
||||
var limit = (dir === 1) ? count : -1;
|
||||
var step = (dir === 1) ? 1 : -1;
|
||||
|
||||
// Spacing is applied as a gap *before* placing an element (except the
|
||||
// first placed one), rather than trailing off the end after the last
|
||||
// element. This keeps the returned cursor at the true content edge,
|
||||
// with no phantom spacing past the final view.
|
||||
var hasPlacedAny = false;
|
||||
var pendingSpacing = 0;
|
||||
|
||||
for (; i !== limit; i += step)
|
||||
{
|
||||
var view = views[i];
|
||||
@@ -652,9 +538,6 @@ var CPStackViewSpacingUseDefault = 3.40282347e+38; // FLT_MAX
|
||||
if (_detachesHiddenViews && [view isHidden])
|
||||
continue;
|
||||
|
||||
if (hasPlacedAny)
|
||||
cursor += (dir === 1) ? pendingSpacing : -pendingSpacing;
|
||||
|
||||
var viewFrame = [view frame];
|
||||
var viewSizePrimary = isVert ? CGRectGetHeight(viewFrame) : CGRectGetWidth(viewFrame);
|
||||
|
||||
@@ -734,10 +617,11 @@ var CPStackViewSpacingUseDefault = 3.40282347e+38; // FLT_MAX
|
||||
|
||||
if (dir === 1) {
|
||||
originY = cursor;
|
||||
cursor += sizeH;
|
||||
cursor += sizeH + [self _spacingAfterView:view];
|
||||
} else {
|
||||
cursor -= sizeH;
|
||||
originY = cursor;
|
||||
cursor -= [self _spacingAfterView:view];
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -749,17 +633,15 @@ var CPStackViewSpacingUseDefault = 3.40282347e+38; // FLT_MAX
|
||||
|
||||
if (dir === 1) {
|
||||
originX = cursor;
|
||||
cursor += sizeW;
|
||||
cursor += sizeW + [self _spacingAfterView:view];
|
||||
} else {
|
||||
cursor -= sizeW;
|
||||
originX = cursor;
|
||||
cursor -= [self _spacingAfterView:view];
|
||||
}
|
||||
}
|
||||
|
||||
[view setFrame:CGRectMake(originX, originY, sizeW, sizeH)];
|
||||
|
||||
pendingSpacing = [self _spacingAfterView:view];
|
||||
hasPlacedAny = true;
|
||||
}
|
||||
|
||||
return cursor;
|
||||
@@ -775,7 +657,6 @@ var CPStackViewSpacingUseDefault = 3.40282347e+38; // FLT_MAX
|
||||
{
|
||||
_orientation = [aCoder decodeIntForKey:@"CPStackViewOrientation"];
|
||||
_alignment = [aCoder decodeIntForKey:@"CPStackViewAlignment"];
|
||||
_distribution = [aCoder decodeIntForKey:@"CPStackViewDistribution"];
|
||||
_spacing = [aCoder decodeFloatForKey:@"CPStackViewSpacing"];
|
||||
_edgeInsets = [aCoder decodeObjectForKey:@"CPStackViewEdgeInsets"]; // Assuming CPEdgeInsets supports obj coding or manual decode
|
||||
if (!_edgeInsets) _edgeInsets = CPEdgeInsetsMake(0,0,0,0);
|
||||
@@ -787,7 +668,10 @@ var CPStackViewSpacingUseDefault = 3.40282347e+38; // FLT_MAX
|
||||
_viewsTrailing = [aCoder decodeObjectForKey:@"CPStackViewViewsTrailing"] || [];
|
||||
|
||||
// Rebuild arranged subviews cache
|
||||
[self _rebuildArrangedSubviews];
|
||||
_arrangedSubviews = [[CPMutableArray alloc] init];
|
||||
[_arrangedSubviews addObjectsFromArray:_viewsLeading];
|
||||
[_arrangedSubviews addObjectsFromArray:_viewsCenter];
|
||||
[_arrangedSubviews addObjectsFromArray:_viewsTrailing];
|
||||
|
||||
_customSpacings = [aCoder decodeObjectForKey:@"CPStackViewCustomSpacings"] || [[CPMapTable alloc] init];
|
||||
_visibilityPriorities = [[CPMapTable alloc] init]; // usually not persisted
|
||||
@@ -800,7 +684,6 @@ var CPStackViewSpacingUseDefault = 3.40282347e+38; // FLT_MAX
|
||||
[super encodeWithCoder:aCoder];
|
||||
[aCoder encodeInt:_orientation forKey:@"CPStackViewOrientation"];
|
||||
[aCoder encodeInt:_alignment forKey:@"CPStackViewAlignment"];
|
||||
[aCoder encodeInt:_distribution forKey:@"CPStackViewDistribution"];
|
||||
[aCoder encodeFloat:_spacing forKey:@"CPStackViewSpacing"];
|
||||
[aCoder encodeObject:_edgeInsets forKey:@"CPStackViewEdgeInsets"];
|
||||
[aCoder encodeBool:_detachesHiddenViews forKey:@"CPStackViewDetachesHiddenViews"];
|
||||
|
||||
+67
-7
@@ -175,12 +175,53 @@
|
||||
[super setFrame:frame];
|
||||
}
|
||||
|
||||
- (void)setThemeState:(CPThemeState)aState
|
||||
{
|
||||
[super setThemeState:aState];
|
||||
|
||||
// Force a layout update because the internal buttons (_buttonUp and _buttonDown)
|
||||
// rely on layoutSubviews to receive the new theme attributes (like HUD colors).
|
||||
[self setNeedsLayout];
|
||||
}
|
||||
|
||||
- (void)unsetThemeState:(CPThemeState)aState
|
||||
{
|
||||
[super unsetThemeState:aState];
|
||||
[self setNeedsLayout];
|
||||
}
|
||||
|
||||
/*! @ignore */
|
||||
- (void)layoutSubviews
|
||||
{
|
||||
var controlSizeThemeState = [self _controlSizeThemeState],
|
||||
aFrame = [self frame],
|
||||
upSize = [self valueForThemeAttribute:@"up-button-size" inState:controlSizeThemeState],
|
||||
isHUD = [self hasThemeState:CPThemeStateHUD],
|
||||
|
||||
// 1. Prepare Lookup States (To fetch the correct image/color from the Stepper's theme)
|
||||
normalLookupStates = [controlSizeThemeState, CPThemeStateBordered],
|
||||
disabledLookupStates = [controlSizeThemeState, CPThemeStateBordered, CPThemeStateDisabled],
|
||||
highlightedLookupStates = [controlSizeThemeState, CPThemeStateBordered, CPThemeStateHighlighted],
|
||||
|
||||
// 2. Prepare Target States (To tell the child buttons when to use this image)
|
||||
normalTargetStates = [CPThemeStateBordered, CPButtonStateBezelStyleRoundRect],
|
||||
disabledTargetStates = [CPThemeStateBordered, CPThemeStateDisabled, CPButtonStateBezelStyleRoundRect],
|
||||
highlightedTargetStates = [CPThemeStateBordered, CPThemeStateHighlighted, CPButtonStateBezelStyleRoundRect];
|
||||
|
||||
// If we are in HUD mode, add CPThemeStateHUD to both lookup and target arrays
|
||||
if (isHUD)
|
||||
{
|
||||
// Lookup: Ask theme for "HUD" version of the stepper arrows
|
||||
normalLookupStates.push(CPThemeStateHUD);
|
||||
disabledLookupStates.push(CPThemeStateHUD);
|
||||
highlightedLookupStates.push(CPThemeStateHUD);
|
||||
|
||||
// Target: Tell the child buttons "Use this when you are in HUD state"
|
||||
normalTargetStates.push(CPThemeStateHUD);
|
||||
disabledTargetStates.push(CPThemeStateHUD);
|
||||
highlightedTargetStates.push(CPThemeStateHUD);
|
||||
}
|
||||
|
||||
var upSize = [self valueForThemeAttribute:@"up-button-size" inState:controlSizeThemeState],
|
||||
downSize = [self valueForThemeAttribute:@"down-button-size" inState:controlSizeThemeState],
|
||||
upFrame = CGRectMake(0, 0, upSize.width, upSize.height),
|
||||
downFrame = CGRectMake(0, upSize.height, downSize.width, downSize.height);
|
||||
@@ -188,12 +229,31 @@
|
||||
[_buttonUp setFrame:upFrame];
|
||||
[_buttonDown setFrame:downFrame];
|
||||
|
||||
[_buttonUp setValue:[self valueForThemeAttribute:@"bezel-color-up-button" inStates:[controlSizeThemeState, CPThemeStateBordered]] forThemeAttribute:@"bezel-color" inStates:[CPThemeStateBordered, CPButtonStateBezelStyleRoundRect]];
|
||||
[_buttonUp setValue:[self valueForThemeAttribute:@"bezel-color-up-button" inStates:[controlSizeThemeState, CPThemeStateBordered, CPThemeStateDisabled]] forThemeAttribute:@"bezel-color" inStates:[CPThemeStateBordered, CPThemeStateDisabled, CPButtonStateBezelStyleRoundRect]];
|
||||
[_buttonUp setValue:[self valueForThemeAttribute:@"bezel-color-up-button" inStates:[controlSizeThemeState, CPThemeStateBordered, CPThemeStateHighlighted]] forThemeAttribute:@"bezel-color" inStates:[CPThemeStateBordered, CPThemeStateHighlighted, CPButtonStateBezelStyleRoundRect]];
|
||||
[_buttonDown setValue:[self valueForThemeAttribute:@"bezel-color-down-button" inStates:[controlSizeThemeState, CPThemeStateBordered]] forThemeAttribute:@"bezel-color" inStates:[CPThemeStateBordered, CPButtonStateBezelStyleRoundRect]];
|
||||
[_buttonDown setValue:[self valueForThemeAttribute:@"bezel-color-down-button" inStates:[controlSizeThemeState, CPThemeStateBordered, CPThemeStateDisabled]] forThemeAttribute:@"bezel-color" inStates:[CPThemeStateBordered, CPThemeStateDisabled, CPButtonStateBezelStyleRoundRect]];
|
||||
[_buttonDown setValue:[self valueForThemeAttribute:@"bezel-color-down-button" inStates:[controlSizeThemeState, CPThemeStateBordered, CPThemeStateHighlighted]] forThemeAttribute:@"bezel-color" inStates:[CPThemeStateBordered, CPThemeStateHighlighted, CPButtonStateBezelStyleRoundRect]];
|
||||
// Apply Up Button Attributes
|
||||
[_buttonUp setValue:[self valueForThemeAttribute:@"bezel-color-up-button" inStates:normalLookupStates]
|
||||
forThemeAttribute:@"bezel-color"
|
||||
inStates:normalTargetStates];
|
||||
|
||||
[_buttonUp setValue:[self valueForThemeAttribute:@"bezel-color-up-button" inStates:disabledLookupStates]
|
||||
forThemeAttribute:@"bezel-color"
|
||||
inStates:disabledTargetStates];
|
||||
|
||||
[_buttonUp setValue:[self valueForThemeAttribute:@"bezel-color-up-button" inStates:highlightedLookupStates]
|
||||
forThemeAttribute:@"bezel-color"
|
||||
inStates:highlightedTargetStates];
|
||||
|
||||
// Apply Down Button Attributes
|
||||
[_buttonDown setValue:[self valueForThemeAttribute:@"bezel-color-down-button" inStates:normalLookupStates]
|
||||
forThemeAttribute:@"bezel-color"
|
||||
inStates:normalTargetStates];
|
||||
|
||||
[_buttonDown setValue:[self valueForThemeAttribute:@"bezel-color-down-button" inStates:disabledLookupStates]
|
||||
forThemeAttribute:@"bezel-color"
|
||||
inStates:disabledTargetStates];
|
||||
|
||||
[_buttonDown setValue:[self valueForThemeAttribute:@"bezel-color-down-button" inStates:highlightedLookupStates]
|
||||
forThemeAttribute:@"bezel-color"
|
||||
inStates:highlightedTargetStates];
|
||||
}
|
||||
|
||||
- (void)_sizeToFit
|
||||
|
||||
+1
-1
@@ -117,7 +117,7 @@ var CPTabViewDidSelectTabViewItemSelector = 1 << 1,
|
||||
var height = [_tabs valueForThemeAttribute:@"min-size"].height;
|
||||
[_tabs setFrameSize:CGSizeMake(0, height)];
|
||||
|
||||
_box = [[_CPTabViewBox alloc] initWithFrame:[self bounds]];
|
||||
_box = [[_CPTabViewBox alloc] initWithFrame:[self bounds]];
|
||||
[_box setTabView:self];
|
||||
[_box setContentInset:[self currentValueForThemeAttribute:@"box-content-inset"]];
|
||||
[_box setContentViewMargins:CGSizeMakeZero()];
|
||||
|
||||
+231
-23
@@ -25,6 +25,10 @@
|
||||
@import "CPCursor.j"
|
||||
@import "_CPImageAndTextView.j"
|
||||
@import "CPTrackingArea.j"
|
||||
@import "CPAnimationContext.j"
|
||||
@import "CPViewAnimator.j"
|
||||
@import "CPScrollView.j"
|
||||
@import <Foundation/CPGeometry.j>
|
||||
|
||||
@class CPTableView
|
||||
|
||||
@@ -50,10 +54,16 @@
|
||||
@"text-color": [CPNull null],
|
||||
@"font": [CPNull null],
|
||||
@"text-shadow-color": [CPNull null],
|
||||
@"text-shadow-offset": CGSizeMakeZero()
|
||||
@"text-shadow-offset": CGSizeMakeZero(),
|
||||
@"dont-draw-separator": NO
|
||||
};
|
||||
}
|
||||
|
||||
- (BOOL)acceptsFirstMouse:(CPEvent)anEvent
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (id)initWithFrame:(CGRect)frame
|
||||
{
|
||||
self = [super initWithFrame:frame];
|
||||
@@ -66,18 +76,22 @@
|
||||
|
||||
- (void)_init
|
||||
{
|
||||
[self setBackgroundColor:[self currentValueForThemeAttribute:@"background-color"]];
|
||||
|
||||
var inset = [self valueForThemeAttribute:@"text-inset"];
|
||||
|
||||
_textField = [[_CPImageAndTextView alloc] initWithFrame:
|
||||
CGRectMake(5.0, 0.0, CGRectGetWidth([self bounds]) - 10.0, CGRectGetHeight([self bounds]))];
|
||||
CGRectMake(inset.left, inset.top, CGRectGetWidth([self bounds]) - (inset.left + inset.right), CGRectGetHeight([self bounds]) - (inset.top + inset.bottom))];
|
||||
|
||||
[_textField setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
|
||||
|
||||
[_textField setLineBreakMode:CPLineBreakByTruncatingTail];
|
||||
[_textField setTextColor:[CPColor colorWithRed:51.0 / 255.0 green:51.0 / 255.0 blue:51.0 / 255.0 alpha:1.0]];
|
||||
[_textField setFont:[CPFont boldSystemFontOfSize:12.0]];
|
||||
[_textField setAlignment:CPLeftTextAlignment];
|
||||
[_textField setLineBreakMode:[self valueForThemeAttribute:@"line-break-mode"]];
|
||||
[_textField setTextColor:[self valueForThemeAttribute:@"text-color"]];
|
||||
[_textField setFont:[self valueForThemeAttribute:@"font"]];
|
||||
[_textField setAlignment:[self valueForThemeAttribute:@"text-alignment"]];
|
||||
[_textField setVerticalAlignment:CPCenterVerticalTextAlignment];
|
||||
[_textField setTextShadowColor:[CPColor whiteColor]];
|
||||
[_textField setTextShadowOffset:CGSizeMake(0,1)];
|
||||
[_textField setTextShadowColor:[self valueForThemeAttribute:@"text-shadow-color"]];
|
||||
[_textField setTextShadowOffset:[self valueForThemeAttribute:@"text-shadow-offset"]];
|
||||
|
||||
[self addSubview:_textField];
|
||||
}
|
||||
@@ -188,6 +202,9 @@
|
||||
|
||||
- (void)drawRect:(CGRect)aRect
|
||||
{
|
||||
if ([self valueForThemeAttribute:@"dont-draw-separator"])
|
||||
return;
|
||||
|
||||
var bounds = [self bounds];
|
||||
|
||||
if (!CGRectIntersectsRect(aRect, bounds))
|
||||
@@ -223,7 +240,8 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal
|
||||
[self _init];
|
||||
[self _setIndicatorImage:[aCoder decodeObjectForKey:_CPTableColumnHeaderViewImageKey]];
|
||||
[self setStringValue:[aCoder decodeObjectForKey:_CPTableColumnHeaderViewStringValueKey]];
|
||||
[self setFont:[aCoder decodeObjectForKey:_CPTableColumnHeaderViewFontKey]];
|
||||
// FIXME: pourquoi dans actif, font=null ?
|
||||
// [self setFont:[aCoder decodeObjectForKey:_CPTableColumnHeaderViewFontKey]];
|
||||
}
|
||||
|
||||
return self;
|
||||
@@ -257,11 +275,13 @@ var CPTableHeaderViewResizeZone = 3.0,
|
||||
|
||||
BOOL _isResizing;
|
||||
BOOL _isDragging;
|
||||
BOOL _isAnimating;
|
||||
BOOL _canDragColumn;
|
||||
|
||||
CPView _columnDragView;
|
||||
CPView _columnDragHeaderView;
|
||||
CPView _columnDragClipView;
|
||||
CPScrollView _columnDragScrollView;
|
||||
|
||||
float _columnOldWidth;
|
||||
|
||||
@@ -278,7 +298,9 @@ var CPTableHeaderViewResizeZone = 3.0,
|
||||
return @{
|
||||
@"background-color": [CPNull null],
|
||||
@"divider-color": [CPColor grayColor],
|
||||
@"divider-thickness": 1.0
|
||||
@"divider-thickness": 1.0,
|
||||
@"swap-animation": [CPNull null],
|
||||
@"return-animation": [CPNull null]
|
||||
};
|
||||
}
|
||||
|
||||
@@ -340,7 +362,24 @@ var CPTableHeaderViewResizeZone = 3.0,
|
||||
|
||||
- (CPInteger)columnAtPoint:(CGPoint)aPoint
|
||||
{
|
||||
return [_tableView columnAtPoint:aPoint];
|
||||
var tableView = [self tableView],
|
||||
tableColumns = [tableView tableColumns],
|
||||
count = [tableColumns count],
|
||||
bounds = [self bounds],
|
||||
// Create a point that keeps the X position but forces Y to be safely
|
||||
// in the middle of the header view.
|
||||
constrainedPoint = CGPointMake(aPoint.x, CGRectGetMidY(bounds));
|
||||
|
||||
// Iterate through columns to find which one contains the constrained X coordinate
|
||||
for (var i = 0; i < count; i++)
|
||||
{
|
||||
// headerRectOfColumn: is a utility method defined in CPTableHeaderView
|
||||
// that handles the coordinate conversion from the table view relative to the header.
|
||||
if (CGRectContainsPoint([self headerRectOfColumn:i], constrainedPoint))
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
- (CGRect)headerRectOfColumn:(CPInteger)aColumnIndex
|
||||
@@ -365,6 +404,8 @@ var CPTableHeaderViewResizeZone = 3.0,
|
||||
|
||||
- (void)layoutSubviews
|
||||
{
|
||||
[self setBackgroundColor:[self currentValueForThemeAttribute:@"background-color"]];
|
||||
|
||||
var tableColumns = [_tableView tableColumns],
|
||||
count = [tableColumns count];
|
||||
|
||||
@@ -442,6 +483,14 @@ var CPTableHeaderViewResizeZone = 3.0,
|
||||
}
|
||||
else if (_isDragging)
|
||||
{
|
||||
// First, we have to avoid a running condition where user stops dragging while a swap animation is running
|
||||
if (_isAnimating)
|
||||
{
|
||||
[CPTimer scheduledTimerWithTimeInterval:0.05 target:self selector:@selector(_retry_mouseUp:) userInfo:theEvent repeats:NO];
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
[self _stopDraggingTableColumn:_activeColumn];
|
||||
}
|
||||
else if (_activeColumn != -1)
|
||||
@@ -458,6 +507,11 @@ var CPTableHeaderViewResizeZone = 3.0,
|
||||
_activeColumn = -1;
|
||||
}
|
||||
|
||||
- (void)_retry_mouseUp:(CPTimer)aTimer
|
||||
{
|
||||
[self mouseUp:[aTimer userInfo]];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation CPTableHeaderView (CPTrackingArea)
|
||||
@@ -562,7 +616,21 @@ var CPTableHeaderViewResizeZone = 3.0,
|
||||
pressure:[theEvent pressure]];
|
||||
|
||||
[self autoscroll:constrainedEvent];
|
||||
|
||||
var contentView = [_tableView superview],
|
||||
boundsOriginBefore = [contentView boundsOrigin];
|
||||
|
||||
[_tableView autoscroll:constrainedEvent];
|
||||
|
||||
var boundsOriginAfter = [contentView boundsOrigin],
|
||||
deltaX = boundsOriginAfter.x - boundsOriginBefore.x;
|
||||
|
||||
if (_isDragging)
|
||||
{
|
||||
var dragContentView = [_columnDragScrollView contentView],
|
||||
dragContentBoundsOrigin = [dragContentView boundsOrigin];
|
||||
[dragContentView setBoundsOrigin:CGPointMake(dragContentBoundsOrigin.x + deltaX, dragContentBoundsOrigin.y)];
|
||||
}
|
||||
}
|
||||
|
||||
- (CGRect)_headerRectOfLastVisibleColumn
|
||||
@@ -584,16 +652,91 @@ var CPTableHeaderViewResizeZone = 3.0,
|
||||
- (CGPoint)_constrainDragPoint:(CGPoint)aPoint
|
||||
{
|
||||
// This effectively clamps the value between the minimum and maximum
|
||||
var visibleRect = [_tableView visibleRect],
|
||||
lastColumnRect = [self _headerRectOfLastVisibleColumn],
|
||||
activeColumnRect = [self headerRectOfColumn:_activeColumn],
|
||||
maxX = CGRectGetMaxX(lastColumnRect) - CGRectGetWidth(activeColumnRect) - CGRectGetMinX(visibleRect),
|
||||
point = CGPointMake(MAX(MIN(aPoint.x, maxX), -CGRectGetMinX(visibleRect)), aPoint.y);
|
||||
var tableFrame = [_tableView frame],
|
||||
dragFrame = [_columnDragView frame],
|
||||
maxX = tableFrame.size.width - dragFrame.size.width,
|
||||
point = CGPointMake(MAX(MIN(aPoint.x, maxX),0), aPoint.y);
|
||||
|
||||
return point;
|
||||
}
|
||||
|
||||
- (void)_moveColumn:(CPInteger)aFromIndex toColumn:(CPInteger)aToIndex
|
||||
{
|
||||
if (_isAnimating)
|
||||
return;
|
||||
|
||||
var swapAnimation = [self currentValueForThemeAttribute:@"swap-animation"];
|
||||
|
||||
if (swapAnimation)
|
||||
{
|
||||
_isAnimating = YES;
|
||||
|
||||
// There's a theme defined animation function, just use it
|
||||
objj_eval("("+swapAnimation+")")(self, aFromIndex, aToIndex, _columnDragClipView, _columnDragView);
|
||||
|
||||
// var animatedColumn = [[_tableView tableColumns] objectAtIndex:aToIndex],
|
||||
// animatedHeader = [animatedColumn headerView],
|
||||
// animatedHeaderOrigin = [animatedHeader frameOrigin],
|
||||
//
|
||||
// destinationX,
|
||||
// draggedHeader = [[[_tableView tableColumns] objectAtIndex:aFromIndex] headerView],
|
||||
//
|
||||
// scrollView = [self enclosingScrollView],
|
||||
// animatedView = [_tableView _animationViewForColumn:aToIndex],
|
||||
// animatedOrigin = [animatedView frameOrigin];
|
||||
//
|
||||
// [_columnDragClipView addSubview:animatedView positioned:CPWindowBelow relativeTo:_columnDragView];
|
||||
//
|
||||
// [[animatedHeader subviews] makeObjectsPerformSelector:@selector(setHidden:) withObject:YES];
|
||||
// [animatedHeader setThemeState:CPThemeStateVertical];
|
||||
//
|
||||
// if (aFromIndex < aToIndex)
|
||||
// destinationX = CGRectGetMinX([_tableView rectOfColumn:aFromIndex]);
|
||||
// else
|
||||
// destinationX = animatedOrigin.x + CGRectGetWidth([_tableView rectOfColumn:aFromIndex]);
|
||||
//
|
||||
// [CPAnimationContext beginGrouping];
|
||||
//
|
||||
// var context = [CPAnimationContext currentContext];
|
||||
//
|
||||
// [context setDuration:0.15];
|
||||
// [context setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]];
|
||||
// [context setCompletionHandler:function() {
|
||||
// [animatedView removeFromSuperview];
|
||||
//
|
||||
// [self _finalize_moveColumn:aFromIndex toColumn:aToIndex];
|
||||
//
|
||||
// [animatedHeader unsetThemeState:CPThemeStateVertical];
|
||||
// [[animatedHeader subviews] makeObjectsPerformSelector:@selector(setHidden:) withObject:NO];
|
||||
//
|
||||
// if ([animatedView isSelected])
|
||||
// {
|
||||
// [animatedHeader setThemeState:CPThemeStateSelected];
|
||||
//
|
||||
// // We have to reselect the animated column
|
||||
// [[_tableView selectedColumnIndexes] addIndex:aFromIndex];
|
||||
// }
|
||||
//
|
||||
// // Reload animated column
|
||||
// var columnVisRect = CGRectIntersection([_tableView rectOfColumn:aFromIndex], [_tableView visibleRect]),
|
||||
// rowsIndexes = [CPIndexSet indexSetWithIndexesInRange:[_tableView rowsInRect:columnVisRect]],
|
||||
// columnsIndexes = [CPIndexSet indexSetWithIndex:aFromIndex];
|
||||
//
|
||||
// [_tableView _loadDataViewsInRows:rowsIndexes columns:columnsIndexes];
|
||||
// [_tableView _layoutViewsForRowIndexes:rowsIndexes columnIndexes:columnsIndexes];
|
||||
//
|
||||
// [_tableView._tableDrawView displayRect:columnVisRect];
|
||||
// }];
|
||||
//
|
||||
// [[animatedView animator] setFrameOrigin:CGPointMake(destinationX, animatedOrigin.y)];
|
||||
//
|
||||
// [CPAnimationContext endGrouping];
|
||||
}
|
||||
else
|
||||
[self _finalize_moveColumn:aFromIndex toColumn:aToIndex];
|
||||
}
|
||||
|
||||
- (void)_finalize_moveColumn:(CPInteger)aFromIndex toColumn:(CPInteger)aToIndex
|
||||
{
|
||||
[_tableView moveColumn:aFromIndex toColumn:aToIndex];
|
||||
_activeColumn = aToIndex;
|
||||
@@ -602,6 +745,8 @@ var CPTableHeaderViewResizeZone = 3.0,
|
||||
[_tableView _setDraggedColumn:_activeColumn];
|
||||
|
||||
[self setNeedsDisplay:YES];
|
||||
|
||||
_isAnimating = NO;
|
||||
}
|
||||
|
||||
- (BOOL)isDragging
|
||||
@@ -618,17 +763,30 @@ var CPTableHeaderViewResizeZone = 3.0,
|
||||
// Create a new clip view for the drag view that clips to the header + visible content
|
||||
var headerHeight = CGRectGetHeight([self frame]),
|
||||
scrollView = [self enclosingScrollView],
|
||||
contentFrame = [[scrollView contentView] frame];
|
||||
contentFrame = [[scrollView contentView] frame],
|
||||
contentBounds = [[scrollView contentView] bounds];
|
||||
|
||||
contentFrame.origin.y -= headerHeight;
|
||||
contentFrame.size.height += headerHeight;
|
||||
|
||||
_columnDragClipView = [[CPView alloc] initWithFrame:contentFrame];
|
||||
_columnDragScrollView = [[CPScrollView alloc] initWithFrame:contentFrame];
|
||||
|
||||
[_columnDragScrollView setHasHorizontalScroller:NO];
|
||||
[_columnDragScrollView setHasVerticalScroller:NO];
|
||||
[_columnDragScrollView setBorderType:CPNoBorder];
|
||||
|
||||
var tableFrame = [_tableView frame],
|
||||
clipFrame = CGRectMake(0, 0, tableFrame.size.width, contentFrame.size.height);
|
||||
|
||||
_columnDragClipView = [[CPView alloc] initWithFrame:clipFrame];
|
||||
|
||||
[_columnDragClipView addSubview:_columnDragView];
|
||||
|
||||
[_columnDragScrollView setDocumentView:_columnDragClipView];
|
||||
[[_columnDragScrollView contentView] setBoundsOrigin:CGPointMake(contentBounds.origin.x, 0)];
|
||||
|
||||
// Insert the clip view above the table header (and content)
|
||||
[scrollView addSubview:_columnDragClipView positioned:CPWindowAbove relativeTo:self];
|
||||
[scrollView addSubview:_columnDragScrollView positioned:CPWindowAbove relativeTo:self];
|
||||
|
||||
// Hide the underlying column header subviews, we just want to draw the chrome
|
||||
var headerView = [[[_tableView tableColumns] objectAtIndex:aColumnIndex] headerView];
|
||||
@@ -638,6 +796,9 @@ var CPTableHeaderViewResizeZone = 3.0,
|
||||
// The underlying column header shows normal state
|
||||
[headerView unsetThemeStates:[CPThemeStateHighlighted, CPThemeStateSelected]];
|
||||
|
||||
// FIXME: Just a little hack to get a special background (using an unused theme state)
|
||||
[headerView setThemeState:CPThemeStateVertical];
|
||||
|
||||
// Keep track of the location within the column header where the original mousedown occurred
|
||||
_columnDragHeaderView = [_columnDragView viewWithTag:CPTableHeaderViewDragColumnHeaderTag];
|
||||
|
||||
@@ -692,10 +853,43 @@ var CPTableHeaderViewResizeZone = 3.0,
|
||||
}
|
||||
|
||||
- (void)_stopDraggingTableColumn:(CPInteger)aColumnIndex
|
||||
{
|
||||
var returnAnimation = [self currentValueForThemeAttribute:@"return-animation"];
|
||||
|
||||
if (returnAnimation)
|
||||
{
|
||||
_isAnimating = YES;
|
||||
|
||||
// There's a theme defined animation function, just use it
|
||||
objj_eval("("+returnAnimation+")")(self, aColumnIndex, _columnDragView);
|
||||
|
||||
// var animatedColumn = [[_tableView tableColumns] objectAtIndex:aColumnIndex],
|
||||
// animatedHeader = [animatedColumn headerView],
|
||||
// animatedHeaderOrigin = [animatedHeader frameOrigin];
|
||||
//
|
||||
// [CPAnimationContext beginGrouping];
|
||||
//
|
||||
// var context = [CPAnimationContext currentContext];
|
||||
//
|
||||
// [context setDuration:0.15];
|
||||
// [context setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]];
|
||||
// [context setCompletionHandler:function() {
|
||||
//
|
||||
// [self _finalize_stopDraggingTableColumn:aColumnIndex];
|
||||
// }];
|
||||
//
|
||||
// [[_columnDragView animator] setFrameOrigin:CGPointMake(animatedHeaderOrigin.x, 0)];
|
||||
//
|
||||
// [CPAnimationContext endGrouping];
|
||||
}
|
||||
else
|
||||
[self _finalize_stopDraggingTableColumn:aColumnIndex];
|
||||
}
|
||||
|
||||
- (void)_finalize_stopDraggingTableColumn:(CPInteger)aColumnIndex
|
||||
{
|
||||
_isDragging = NO;
|
||||
|
||||
[_columnDragClipView removeFromSuperview];
|
||||
[_tableView _setDraggedColumn:-1];
|
||||
|
||||
var tableColumn = [[_tableView tableColumns] objectAtIndex:aColumnIndex],
|
||||
@@ -703,16 +897,30 @@ var CPTableHeaderViewResizeZone = 3.0,
|
||||
|
||||
[[headerView subviews] makeObjectsPerformSelector:@selector(setHidden:) withObject:NO];
|
||||
|
||||
// Restore headerView background
|
||||
[headerView unsetThemeState:CPThemeStateVertical];
|
||||
|
||||
if (_tableView._draggedColumnIsSelected)
|
||||
[headerView setThemeState:CPThemeStateSelected];
|
||||
|
||||
[_tableView _reloadDataViews];
|
||||
[[_tableView headerView] setNeedsLayout];
|
||||
// Reload animated column
|
||||
var columnVisRect = CGRectIntersection([_tableView rectOfColumn:aColumnIndex], [_tableView visibleRect]),
|
||||
rowsIndexes = [CPIndexSet indexSetWithIndexesInRange:[_tableView rowsInRect:columnVisRect]],
|
||||
columnsIndexes = [CPIndexSet indexSetWithIndex:aColumnIndex];
|
||||
|
||||
[[CPCursor arrowCursor] set];
|
||||
[_tableView _loadDataViewsInRows:rowsIndexes columns:columnsIndexes];
|
||||
[_tableView _layoutViewsForRowIndexes:rowsIndexes columnIndexes:columnsIndexes];
|
||||
[_tableView _updateDataViewsFocusState];
|
||||
[_tableView._tableDrawView displayRect:columnVisRect];
|
||||
|
||||
[[CPCursor arrowCursor] set]; // FIXME: retirer ?
|
||||
[self updateTrackingAreas];
|
||||
|
||||
[_columnDragScrollView removeFromSuperview];
|
||||
|
||||
[_tableView _sendDelegateDidDragTableColumn:tableColumn];
|
||||
|
||||
_isAnimating = NO;
|
||||
}
|
||||
|
||||
- (BOOL)_shouldResizeTableColumn:(CPInteger)aColumnIndex at:(CGPoint)aPoint
|
||||
|
||||
+459
-464
File diff suppressed because it is too large
Load Diff
+16
-12
@@ -771,33 +771,27 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
|
||||
verticalAlign = [self currentValueForThemeAttribute:"vertical-alignment"],
|
||||
left = CGRectGetMinX(contentRect);
|
||||
|
||||
// If the browser has a built in left padding, compensate for it. We need the input text to be exactly on top of the original text.
|
||||
if (CPFeatureIsCompatible(CPInput1PxLeftPadding))
|
||||
left -= 1;
|
||||
|
||||
switch (verticalAlign)
|
||||
{
|
||||
case CPTopVerticalTextAlignment:
|
||||
var topPoint = CGRectGetMinY(contentRect) + "px";
|
||||
var topPoint = CEIL(CGRectGetMinY(contentRect)) + "px";
|
||||
break;
|
||||
|
||||
case CPCenterVerticalTextAlignment:
|
||||
var topPoint = (CGRectGetMidY(contentRect) - (lineHeight / 2)) + "px";
|
||||
var topPoint = CEIL((CGRectGetMidY(contentRect) - (lineHeight / 2))) + "px";
|
||||
break;
|
||||
|
||||
case CPBottomVerticalTextAlignment:
|
||||
var topPoint = (CGRectGetMaxY(contentRect) - lineHeight) + "px";
|
||||
var topPoint = CEIL((CGRectGetMaxY(contentRect) - lineHeight)) + "px";
|
||||
break;
|
||||
|
||||
default:
|
||||
var topPoint = CGRectGetMinY(contentRect) + "px";
|
||||
var topPoint = CEIL(CGRectGetMinY(contentRect)) + "px";
|
||||
break;
|
||||
}
|
||||
|
||||
if ([self hasThemeState:CPTextFieldStatePlaceholder])
|
||||
element.style.color = [[self valueForThemeAttribute:@"text-color" inState:CPTextFieldStatePlaceholder] cssString];
|
||||
else
|
||||
element.style.color = [[self valueForThemeAttribute:@"text-color" inState:CPThemeStateEditing] cssString];
|
||||
// Use currentValueForThemeAttribute to respect all current states (HUD, Placeholder, Editing, etc.)
|
||||
element.style.color = [[self currentValueForThemeAttribute:@"text-color"] cssString];
|
||||
|
||||
switch ([self alignment])
|
||||
{
|
||||
@@ -1301,6 +1295,16 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
|
||||
[super textDidChange:note];
|
||||
}
|
||||
|
||||
- (void)validateEditing
|
||||
{
|
||||
#if PLATFORM(DOM)
|
||||
var element = [self _inputElement];
|
||||
|
||||
if (element)
|
||||
[self _setStringValue:element.value isNewValue:YES errorDescription:nil];
|
||||
#endif
|
||||
}
|
||||
|
||||
- (void)textDidBeginEditing:(CPNotification)note
|
||||
{
|
||||
//this looks to prevent false propagation of notifications for other objects
|
||||
|
||||
@@ -36,7 +36,6 @@
|
||||
@class CPLayoutManager
|
||||
@class CPTextContainer
|
||||
@class CPFontManager
|
||||
@class _CPFontPanelPreviewView
|
||||
|
||||
/*
|
||||
Collection indexes
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
CPParagraphStyleAttributeName = @"CPParagraphStyleAttributeName";
|
||||
|
||||
@typedef CPTabStopType
|
||||
// Define missing global tab stop type constants
|
||||
CPLeftTabStopType = 0;
|
||||
CPRightTabStopType = 1;
|
||||
CPCenterTabStopType = 2;
|
||||
|
||||
+151
-112
@@ -28,18 +28,17 @@
|
||||
@import "CPMenu.j"
|
||||
@import "CPMenuItem.j"
|
||||
|
||||
@typedef CPRulerOrientation
|
||||
CPHorizontalRuler = 0;
|
||||
CPVerticalRuler = 1;
|
||||
CPRulerOrientationHorizontal = 0;
|
||||
CPRulerOrientationVertical = 1;
|
||||
// Orientations matching AppKit standards
|
||||
// typedef enum CPRulerOrientation
|
||||
CPHorizontalRuler = 0,
|
||||
CPVerticalRuler = 1,
|
||||
CPRulerOrientationHorizontal = 0,
|
||||
CPRulerOrientationVertical = 1
|
||||
|
||||
@class CPRulerView;
|
||||
@class CPScrollView;
|
||||
@class CPTextTab;
|
||||
|
||||
|
||||
// MARK: - CPRulerMarker
|
||||
// MARK: - CPRulerMarker (Interactive Handles with Dynamic Alignment Icons)
|
||||
|
||||
@implementation CPRulerMarker : CPView
|
||||
{
|
||||
@@ -58,18 +57,13 @@ CPRulerOrientationVertical = 1;
|
||||
_imageValue = anImageValue;
|
||||
_representedObject = anObject;
|
||||
|
||||
// CRITICAL: Subviews must not intercept mouse events so CPRulerView receives all mouseDragged: events
|
||||
[self setHitTests:NO];
|
||||
|
||||
_label = [[CPTextField alloc] initWithFrame:CGRectMake(0, 0, 12, 12)];
|
||||
[_label setFont:[CPFont systemFontOfSize:10.0]];
|
||||
[_label setTextColor:[CPColor colorWithWhite:0.2 alpha:1.0]];
|
||||
[_label setAlignment:CPCenterTextAlignment];
|
||||
[_label setHitTests:NO];
|
||||
[self addSubview:_label];
|
||||
|
||||
_customHandleView = [[CPView alloc] initWithFrame:CGRectMakeZero()];
|
||||
[_customHandleView setHitTests:NO];
|
||||
[self addSubview:_customHandleView];
|
||||
|
||||
[self updateMarkerIcon];
|
||||
@@ -94,6 +88,8 @@ CPRulerOrientationVertical = 1;
|
||||
[self updateMarkerIcon];
|
||||
}
|
||||
|
||||
// Dynamically sets the Unicode triangle direction based on the alignment or indent type,
|
||||
// or draws custom split-height grab handles for indentation controls.
|
||||
- (void)updateMarkerIcon
|
||||
{
|
||||
var isIndentMarker = (_representedObject === @"CPFirstLineIndent" || _representedObject === @"CPHeadIndent");
|
||||
@@ -105,19 +101,28 @@ CPRulerOrientationVertical = 1;
|
||||
|
||||
var frame = [self bounds];
|
||||
[_customHandleView setFrame:CGRectMake(0, 0, frame.size.width, frame.size.height)];
|
||||
|
||||
// Remove old internal rendering to update cleanly
|
||||
[[_customHandleView subviews] makeObjectsPerformSelector:@selector(removeFromSuperview)];
|
||||
|
||||
var isFirstLine = (_representedObject === @"CPFirstLineIndent");
|
||||
[_customHandleView setBackgroundColor:[CPColor colorWithWhite:0.45 alpha:1.0]];
|
||||
|
||||
var innerView = [[CPView alloc] initWithFrame:CGRectMake(1.0, 1.0, Math.max(1.0, frame.size.width - 2.0), Math.max(1.0, frame.size.height - 2.0))];
|
||||
[innerView setHitTests:NO];
|
||||
[innerView setBackgroundColor:isFirstLine ? [CPColor colorWithWhite:0.95 alpha:1.0] : [CPColor colorWithWhite:0.80 alpha:1.0]];
|
||||
// Dark outline/border representation
|
||||
[_customHandleView setBackgroundColor:[CPColor colorWithWhite:0.5 alpha:1.0]];
|
||||
|
||||
// Inner fill (top handle is lighter, bottom is slightly darker)
|
||||
var innerView = [[CPView alloc] initWithFrame:CGRectMake(1.0, 1.0, frame.size.width - 2.0, frame.size.height - 2.0)];
|
||||
|
||||
if (isFirstLine)
|
||||
[innerView setBackgroundColor:[CPColor colorWithWhite:0.92 alpha:1.0]];
|
||||
else
|
||||
[innerView setBackgroundColor:[CPColor colorWithWhite:0.80 alpha:1.0]];
|
||||
|
||||
[_customHandleView addSubview:innerView];
|
||||
|
||||
var gripLine = [[CPView alloc] initWithFrame:CGRectMake(Math.floor(frame.size.width / 2.0) - 1.0, 1.0, 1.0, Math.max(1.0, frame.size.height - 3.0))];
|
||||
[gripLine setHitTests:NO];
|
||||
[gripLine setBackgroundColor:[CPColor colorWithWhite:0.5 alpha:1.0]];
|
||||
// Horizontal indicator line to visually guide drag interactions
|
||||
var gripLine = [[CPView alloc] initWithFrame:CGRectMake(Math.floor(frame.size.width / 2.0) - 1.0, 2.0, 1.0, frame.size.height - 4.0)];
|
||||
[gripLine setBackgroundColor:[CPColor colorWithWhite:0.6 alpha:1.0]];
|
||||
[innerView addSubview:gripLine];
|
||||
}
|
||||
else
|
||||
@@ -130,23 +135,33 @@ CPRulerOrientationVertical = 1;
|
||||
{
|
||||
var align = [_representedObject alignment];
|
||||
if (align === CPLeftTextAlignment)
|
||||
[_label setStringValue:@"▶"];
|
||||
[_label setStringValue:@"▶"]; // Left-aligned points Right
|
||||
else if (align === CPCenterTextAlignment)
|
||||
[_label setStringValue:@"▼"];
|
||||
[_label setStringValue:@"▼"]; // Center-aligned points Down
|
||||
else if (align === CPRightTextAlignment)
|
||||
[_label setStringValue:@"◀"];
|
||||
[_label setStringValue:@"◀"]; // Right-aligned points Left
|
||||
}
|
||||
else if ([_representedObject isKindOfClass:[CPString class]])
|
||||
{
|
||||
if (_representedObject === @"CPTailIndent")
|
||||
[_label setStringValue:@"⥘"]; // Solid downward triangle for tail indent
|
||||
else
|
||||
[_label setStringValue:@"⇡"]; // Fallback standard up marker
|
||||
}
|
||||
else
|
||||
{
|
||||
[_label setStringValue:@"▲"];
|
||||
[_label setStringValue:@"⇡"]; // Fallback standard up marker
|
||||
}
|
||||
}
|
||||
}
|
||||
// MARK: -
|
||||
// MARK: Context Menu Support
|
||||
|
||||
- (CPMenu)menuForEvent:(CPEvent)anEvent
|
||||
{
|
||||
var menu = [[CPMenu alloc] initWithTitle:@"Marker Context Menu"];
|
||||
|
||||
// If the marker represents a standard tab stop, allow changing its type
|
||||
if ([_representedObject isKindOfClass:[CPTextTab class]])
|
||||
{
|
||||
var itemLeft = [menu addItemWithTitle:@"Left Tab Stop" action:@selector(changeTypeToLeft:) keyEquivalent:@""],
|
||||
@@ -165,11 +180,17 @@ CPRulerOrientationVertical = 1;
|
||||
[menu addItem:[CPMenuItem separatorItem]];
|
||||
}
|
||||
|
||||
// Determine the context-specific delete title
|
||||
var deleteTitle = @"Delete Tab Stop";
|
||||
if (_representedObject === @"CPFirstLineIndent")
|
||||
deleteTitle = @"Reset 1st line indentation";
|
||||
else if (_representedObject === @"CPHeadIndent")
|
||||
deleteTitle = @"Reset head indentation";
|
||||
if ([_representedObject isKindOfClass:[CPString class]])
|
||||
{
|
||||
if (_representedObject === @"CPFirstLineIndent")
|
||||
deleteTitle = @"Delete 1st line indentation marker";
|
||||
else if (_representedObject === @"CPHeadIndent")
|
||||
deleteTitle = @"Delete head indentation marker";
|
||||
else if (_representedObject === @"CPTailIndent")
|
||||
deleteTitle = @"Delete tail indentation marker";
|
||||
}
|
||||
|
||||
var itemDelete = [menu addItemWithTitle:deleteTitle action:@selector(deleteMarker:) keyEquivalent:@""];
|
||||
[itemDelete setTarget:self];
|
||||
@@ -177,51 +198,66 @@ CPRulerOrientationVertical = 1;
|
||||
return menu;
|
||||
}
|
||||
|
||||
- (void)changeTypeToLeft:(id)sender { [self _changeAlignment:CPLeftTextAlignment]; }
|
||||
- (void)changeTypeToCenter:(id)sender { [self _changeAlignment:CPCenterTextAlignment]; }
|
||||
- (void)changeTypeToRight:(id)sender { [self _changeAlignment:CPRightTextAlignment]; }
|
||||
- (void)changeTypeToLeft:(id)sender
|
||||
{
|
||||
[self _changeAlignment:CPLeftTextAlignment];
|
||||
}
|
||||
|
||||
- (void)changeTypeToCenter:(id)sender
|
||||
{
|
||||
[self _changeAlignment:CPCenterTextAlignment];
|
||||
}
|
||||
|
||||
- (void)changeTypeToRight:(id)sender
|
||||
{
|
||||
[self _changeAlignment:CPRightTextAlignment];
|
||||
}
|
||||
|
||||
- (void)_changeAlignment:(CPTextAlignment)alignment
|
||||
{
|
||||
if (![_representedObject isKindOfClass:[CPTextTab class]])
|
||||
return;
|
||||
|
||||
var oldTab = _representedObject,
|
||||
newTab = [[CPTextTab alloc] initWithType:alignment location:_imageValue];
|
||||
var oldTab = _representedObject;
|
||||
var newTab = [[CPTextTab alloc] initWithType:alignment location:_imageValue];
|
||||
|
||||
// Using setRepresentedObject: automatically updates the marker triangle direction
|
||||
[self setRepresentedObject:newTab];
|
||||
|
||||
var client = [_rulerView clientView];
|
||||
if (client && [client respondsToSelector:@selector(rulerView:didUpdateMarker:oldTab:)])
|
||||
{
|
||||
[client rulerView:_rulerView didUpdateMarker:self oldTab:oldTab];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)deleteMarker:(id)sender
|
||||
{
|
||||
var client = [_rulerView clientView];
|
||||
if (client && [client respondsToSelector:@selector(rulerView:didRemoveMarker:)])
|
||||
{
|
||||
[client rulerView:_rulerView didRemoveMarker:self];
|
||||
|
||||
}
|
||||
[_rulerView removeMarker:self];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
// MARK: - CPRulerView
|
||||
// MARK: - CPRulerView (Pure DOM + Interactive Engine)
|
||||
|
||||
@implementation CPRulerView : CPView
|
||||
{
|
||||
CPScrollView _scrollView @accessors(property=scrollView);
|
||||
CPRulerOrientation _orientation @accessors(property=orientation);
|
||||
|
||||
CPView _clientView;
|
||||
|
||||
CPView _clientView @accessors(property=clientView);
|
||||
|
||||
float _ruleThickness @accessors(property=ruleThickness);
|
||||
float _reservedThicknessForMarkers;
|
||||
CPArray _markers;
|
||||
|
||||
CPRulerMarker _draggingMarker @accessors(getter=draggingMarker);
|
||||
// Dragger variables
|
||||
CPRulerMarker _draggingMarker;
|
||||
CGPoint _dragStartPoint;
|
||||
float _dragStartLocation;
|
||||
}
|
||||
@@ -249,16 +285,7 @@ CPRulerOrientationVertical = 1;
|
||||
[self updateRuler];
|
||||
}
|
||||
|
||||
- (CPView)clientView
|
||||
{
|
||||
return _clientView || [_scrollView documentView];
|
||||
}
|
||||
|
||||
- (void)setClientView:(CPView)aView
|
||||
{
|
||||
_clientView = aView;
|
||||
}
|
||||
|
||||
// Markers registration
|
||||
- (void)addMarker:(CPRulerMarker)aMarker
|
||||
{
|
||||
if ([_markers containsObject:aMarker])
|
||||
@@ -288,20 +315,14 @@ CPRulerOrientationVertical = 1;
|
||||
[self addSubview:marker];
|
||||
[self _positionMarker:marker];
|
||||
}
|
||||
[self updateRuler];
|
||||
}
|
||||
|
||||
- (CPRulerMarker)_markerAtPoint:(CGPoint)aPoint
|
||||
{
|
||||
// Search in reverse order so indent paddles (added last) are prioritized over overlapping 0-location tabs
|
||||
for (var i = [_markers count] - 1; i >= 0; i--)
|
||||
for (var i = 0; i < [_markers count]; i++)
|
||||
{
|
||||
var marker = [_markers objectAtIndex:i],
|
||||
frame = [marker frame];
|
||||
|
||||
// Expanded hit-box by 3px on all sides for easy grabbing
|
||||
var hitFrame = CGRectMake(frame.origin.x - 3.0, frame.origin.y - 2.0, frame.size.width + 6.0, frame.size.height + 4.0);
|
||||
if (CGRectContainsPoint(hitFrame, aPoint))
|
||||
var marker = [_markers objectAtIndex:i];
|
||||
if (CGRectContainsPoint([marker frame], aPoint))
|
||||
return marker;
|
||||
}
|
||||
return nil;
|
||||
@@ -317,48 +338,55 @@ CPRulerOrientationVertical = 1;
|
||||
isHorizontal = (_orientation === CPHorizontalRuler || _orientation === CPRulerOrientationHorizontal),
|
||||
rulerHeight = CGRectGetHeight([self bounds]),
|
||||
rulerWidth = CGRectGetWidth([self bounds]),
|
||||
markerLocation = [aMarker imageValue],
|
||||
rep = [aMarker representedObject];
|
||||
markerLocation = [aMarker imageValue];
|
||||
|
||||
if (isHorizontal)
|
||||
{
|
||||
var x = markerLocation - scrollPoint.x - 6.0,
|
||||
var x = markerLocation - scrollPoint.x - 6.0, // Center the 12px wide marker
|
||||
y = rulerHeight - 11.0,
|
||||
w = 12.0,
|
||||
h = 12.0;
|
||||
|
||||
if (rep === @"CPFirstLineIndent")
|
||||
|
||||
// Align the First Line Indent (upper half) and Head Indent (lower half) controls
|
||||
if ([aMarker representedObject] === @"CPFirstLineIndent")
|
||||
{
|
||||
y = 0.0;
|
||||
h = Math.floor(rulerHeight / 2.0);
|
||||
}
|
||||
else if (rep === @"CPHeadIndent")
|
||||
else if ([aMarker representedObject] === @"CPHeadIndent")
|
||||
{
|
||||
y = Math.floor(rulerHeight / 2.0);
|
||||
h = rulerHeight - y - 1.0;
|
||||
h = rulerHeight - y - 1.0; // Subtract 1px to stay cleanly above bottom border
|
||||
}
|
||||
else
|
||||
{
|
||||
if (x < -6.0) x = -6.0;
|
||||
else if (x + 12.0 > rulerWidth) x = rulerWidth - 12.0;
|
||||
// Keep normal horizontal markers within the bounds of the ruler to prevent clipping
|
||||
if (x < 0.0)
|
||||
x = 0.0;
|
||||
else if (x + 12.0 > rulerWidth)
|
||||
x = rulerWidth - 12.0;
|
||||
}
|
||||
|
||||
|
||||
[aMarker setFrame:CGRectMake(x, y, w, h)];
|
||||
}
|
||||
else
|
||||
{
|
||||
var x = rulerWidth - 11.0,
|
||||
y = markerLocation - scrollPoint.y - 6.0;
|
||||
|
||||
if (y < 0.0) y = 0.0;
|
||||
else if (y + 12.0 > rulerHeight) y = rulerHeight - 12.0;
|
||||
|
||||
|
||||
// Keep vertical marker within the bounds of the ruler to prevent clipping
|
||||
if (y < 0.0)
|
||||
y = 0.0;
|
||||
else if (y + 12.0 > rulerHeight)
|
||||
y = rulerHeight - 12.0;
|
||||
|
||||
[aMarker setFrame:CGRectMake(x, y, 12.0, 12.0)];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: - Interaction Handlers
|
||||
// MARK: -
|
||||
// MARK: Interaction Handlers
|
||||
|
||||
- (void)mouseDown:(CPEvent)anEvent
|
||||
{
|
||||
@@ -370,6 +398,7 @@ CPRulerOrientationVertical = 1;
|
||||
|
||||
var rulerLocation = isHorizontal ? (localPoint.x + scrollPoint.x) : (localPoint.y + scrollPoint.y);
|
||||
|
||||
// 1. Check if clicked an existing marker
|
||||
var clickedMarker = [self _markerAtPoint:localPoint];
|
||||
if (clickedMarker)
|
||||
{
|
||||
@@ -377,22 +406,20 @@ CPRulerOrientationVertical = 1;
|
||||
_dragStartPoint = localPoint;
|
||||
_dragStartLocation = [_draggingMarker imageValue];
|
||||
}
|
||||
// 2. Otherwise, create a new marker dynamically where the user clicked
|
||||
else
|
||||
{
|
||||
// Allow client view to constrain initial placement
|
||||
var client = [self clientView];
|
||||
if (client && [client respondsToSelector:@selector(rulerView:willAddMarker:atLocation:)])
|
||||
rulerLocation = [client rulerView:self willAddMarker:nil atLocation:rulerLocation];
|
||||
|
||||
var newMarker = [[CPRulerMarker alloc] initWithRulerView:self
|
||||
markerLocation:rulerLocation
|
||||
imageValue:rulerLocation
|
||||
representedObject:nil];
|
||||
[self addMarker:newMarker];
|
||||
|
||||
|
||||
// Notify the client view (e.g., CPTextView) that a new marker was added
|
||||
var client = [self clientView];
|
||||
if (client && [client respondsToSelector:@selector(rulerView:didAddMarker:)])
|
||||
[client rulerView:self didAddMarker:newMarker];
|
||||
|
||||
|
||||
_draggingMarker = newMarker;
|
||||
_dragStartPoint = localPoint;
|
||||
_dragStartLocation = rulerLocation;
|
||||
@@ -409,35 +436,34 @@ CPRulerOrientationVertical = 1;
|
||||
isHorizontal = (_orientation === CPHorizontalRuler || _orientation === CPRulerOrientationHorizontal);
|
||||
|
||||
var delta = isHorizontal ? (localPoint.x - _dragStartPoint.x) : (localPoint.y - _dragStartPoint.y),
|
||||
newLocation = Math.max(0.0, _dragStartLocation + delta);
|
||||
newLocation = _dragStartLocation + delta;
|
||||
|
||||
// Constrain marker location to last possible position
|
||||
var client = [self clientView];
|
||||
|
||||
if (client && [client respondsToSelector:@selector(rulerView:willMoveMarker:toLocation:)])
|
||||
newLocation = [client rulerView:self willMoveMarker:_draggingMarker toLocation:newLocation];
|
||||
if (newLocation < 0) newLocation = 0;
|
||||
|
||||
[_draggingMarker setImageValue:newLocation];
|
||||
[self _positionMarker:_draggingMarker];
|
||||
|
||||
var rep = [_draggingMarker representedObject],
|
||||
isIndent = (rep === @"CPFirstLineIndent" || rep === @"CPHeadIndent" || rep === @"CPTailIndent");
|
||||
|
||||
var draggedOff = !isIndent && (isHorizontal
|
||||
? (localPoint.y < -15 || localPoint.y > CGRectGetHeight([self bounds]) + 15)
|
||||
: (localPoint.x < -15 || localPoint.x > CGRectGetWidth([self bounds]) + 15));
|
||||
|
||||
// Smoothly redraw ruler and margin bounds on every drag step
|
||||
[self updateRuler];
|
||||
|
||||
// Check if dragged off the ruler (more than 15px off the boundary)
|
||||
var draggedOff = isHorizontal ? (localPoint.y < -15 || localPoint.y > CGRectGetHeight([self bounds]) + 15)
|
||||
: (localPoint.x < -15 || localPoint.x > CGRectGetWidth([self bounds]) + 15);
|
||||
|
||||
if (draggedOff)
|
||||
{
|
||||
// Visual feedback: Dim the handle to 40% and turn the triangle icon gray
|
||||
[_draggingMarker setAlphaValue:0.4];
|
||||
[[_draggingMarker label] setTextColor:[CPColor grayColor]];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Restore standard styling when dragged back into the active strip
|
||||
[_draggingMarker setAlphaValue:1.0];
|
||||
[[_draggingMarker label] setTextColor:[CPColor colorWithWhite:0.2 alpha:1.0]];
|
||||
}
|
||||
|
||||
|
||||
// Notify the CPTextView that the marker coordinates shifted
|
||||
var client = [self clientView];
|
||||
if (client && [client respondsToSelector:@selector(rulerView:didMoveMarker:)])
|
||||
[client rulerView:self didMoveMarker:_draggingMarker];
|
||||
}
|
||||
@@ -449,12 +475,10 @@ CPRulerOrientationVertical = 1;
|
||||
|
||||
var localPoint = [self convertPoint:[anEvent locationInWindow] fromView:nil],
|
||||
isHorizontal = (_orientation === CPHorizontalRuler || _orientation === CPRulerOrientationHorizontal),
|
||||
rep = [_draggingMarker representedObject],
|
||||
isIndent = (rep === @"CPFirstLineIndent" || rep === @"CPHeadIndent" || rep === @"CPTailIndent");
|
||||
|
||||
var draggedOff = !isIndent && (isHorizontal
|
||||
? (localPoint.y < -15 || localPoint.y > CGRectGetHeight([self bounds]) + 15)
|
||||
: (localPoint.x < -15 || localPoint.x > CGRectGetWidth([self bounds]) + 15));
|
||||
|
||||
// If dragged more than 15 pixels off the ruler, delete the marker
|
||||
draggedOff = isHorizontal ? (localPoint.y < -15 || localPoint.y > CGRectGetHeight([self bounds]) + 15)
|
||||
: (localPoint.x < -15 || localPoint.x > CGRectGetWidth([self bounds]) + 15);
|
||||
|
||||
if (draggedOff)
|
||||
{
|
||||
@@ -466,19 +490,22 @@ CPRulerOrientationVertical = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Ensure marker style is fully restored if not deleted
|
||||
[_draggingMarker setAlphaValue:1.0];
|
||||
[[_draggingMarker label] setTextColor:[CPColor colorWithWhite:0.2 alpha:1.0]];
|
||||
}
|
||||
|
||||
|
||||
_draggingMarker = nil;
|
||||
[self updateRuler];
|
||||
}
|
||||
|
||||
|
||||
// MARK: - Layout Builder
|
||||
// MARK: -
|
||||
// MARK: DOM Layout Builder
|
||||
|
||||
- (void)updateRuler
|
||||
{
|
||||
// Wipe subviews to redraw the dynamic visible tick lines/numbers
|
||||
[self setSubviews:@[]];
|
||||
|
||||
if (!_scrollView)
|
||||
@@ -497,11 +524,12 @@ CPRulerOrientationVertical = 1;
|
||||
rulerHeight = CGRectGetHeight([self bounds]),
|
||||
rulerWidth = CGRectGetWidth([self bounds]);
|
||||
|
||||
// Draw solid horizontal bottom border (pure, razor-sharp CSS DOM view)
|
||||
var bottomBorder = [[CPView alloc] initWithFrame:CGRectMake(0, rulerHeight - 1, rulerWidth, 1)];
|
||||
[bottomBorder setHitTests:NO];
|
||||
[bottomBorder setBackgroundColor:[CPColor colorWithWhite:0.75 alpha:1.0]];
|
||||
[self addSubview:bottomBorder];
|
||||
|
||||
// Find indent markers to determine background highlight boundaries
|
||||
var firstLineMarker = nil,
|
||||
headMarker = nil;
|
||||
for (var i = 0; i < [_markers count]; i++)
|
||||
@@ -515,30 +543,31 @@ CPRulerOrientationVertical = 1;
|
||||
|
||||
var halfHeight = Math.floor(rulerHeight / 2.0);
|
||||
|
||||
// Draw First Line Indent background - top half (lighter gray)
|
||||
if (firstLineMarker)
|
||||
{
|
||||
var firstLineX = [firstLineMarker imageValue] - scrollPoint.x;
|
||||
if (firstLineX > 0)
|
||||
{
|
||||
var firstLineBg = [[CPView alloc] initWithFrame:CGRectMake(0, 0, firstLineX, halfHeight)];
|
||||
[firstLineBg setHitTests:NO];
|
||||
[firstLineBg setBackgroundColor:[CPColor colorWithWhite:0.93 alpha:1.0]];
|
||||
[self addSubview:firstLineBg];
|
||||
}
|
||||
}
|
||||
|
||||
// Draw Head Indent background - bottom half (slightly darker gray)
|
||||
if (headMarker)
|
||||
{
|
||||
var headX = [headMarker imageValue] - scrollPoint.x;
|
||||
if (headX > 0)
|
||||
{
|
||||
var headBg = [[CPView alloc] initWithFrame:CGRectMake(0, halfHeight, headX, rulerHeight - halfHeight - 1.0)];
|
||||
[headBg setHitTests:NO];
|
||||
[headBg setBackgroundColor:[CPColor colorWithWhite:0.86 alpha:1.0]];
|
||||
[self addSubview:headBg];
|
||||
}
|
||||
}
|
||||
|
||||
// Render ruler tick lines and labels on top of shaded areas
|
||||
for (var val = start; val <= end; val += 10)
|
||||
{
|
||||
if (val < 0) continue;
|
||||
@@ -548,21 +577,30 @@ CPRulerOrientationVertical = 1;
|
||||
tickHeight = isMajor ? 8.0 : 4.0,
|
||||
tickY = rulerHeight - tickHeight - 1.0;
|
||||
|
||||
// Tick mark CSS line view
|
||||
var tick = [[CPView alloc] initWithFrame:CGRectMake(screenX, tickY, 1.0, tickHeight)];
|
||||
[tick setHitTests:NO];
|
||||
[tick setBackgroundColor:[CPColor colorWithWhite:0.65 alpha:1.0]];
|
||||
[self addSubview:tick];
|
||||
|
||||
// Unit label
|
||||
if (isMajor)
|
||||
{
|
||||
var labelX = screenX - 20.0,
|
||||
alignment = CPCenterTextAlignment;
|
||||
|
||||
if (labelX < 0.0) { labelX = Math.max(0.0, screenX); alignment = CPLeftTextAlignment; }
|
||||
else if (labelX + 40.0 > rulerWidth) { labelX = rulerWidth - 40.0; alignment = CPRightTextAlignment; }
|
||||
// Adjust label frame and alignment if it lands near left/right bounds
|
||||
if (labelX < 0.0)
|
||||
{
|
||||
labelX = Math.max(0.0, screenX);
|
||||
alignment = CPLeftTextAlignment;
|
||||
}
|
||||
else if (labelX + 40.0 > rulerWidth)
|
||||
{
|
||||
labelX = rulerWidth - 40.0;
|
||||
alignment = CPRightTextAlignment;
|
||||
}
|
||||
|
||||
var label = [[CPTextField alloc] initWithFrame:CGRectMake(labelX, 1.0, 40.0, 12.0)];
|
||||
[label setHitTests:NO];
|
||||
[label setStringValue:[CPString stringWithFormat:@"%d", val]];
|
||||
[label setFont:[CPFont systemFontOfSize:8.0]];
|
||||
[label setTextColor:[CPColor colorWithWhite:0.4 alpha:1.0]];
|
||||
@@ -619,11 +657,12 @@ CPRulerOrientationVertical = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Add back existing markers without re-creating them
|
||||
// Reposition and display active markers
|
||||
for (var i = 0; i < [_markers count]; i++)
|
||||
{
|
||||
var marker = [_markers objectAtIndex:i];
|
||||
[self addSubview:marker];
|
||||
if ([marker superview] !== self)
|
||||
[self addSubview:marker];
|
||||
[self _positionMarker:marker];
|
||||
}
|
||||
}
|
||||
|
||||
+101
-175
@@ -870,6 +870,11 @@ var kDelegateRespondsTo_textShouldBeginEditing
|
||||
- (void)drawInsertionPointInRect:(CGRect)aRect color:(CPColor)aColor turnedOn:(BOOL)flag
|
||||
{
|
||||
[_caret setRect:aRect];
|
||||
|
||||
#if PLATFORM(DOM)
|
||||
_caret._caretDOM.style.backgroundColor = [_insertionPointColor cssString] || "black";
|
||||
#endif
|
||||
|
||||
[_caret setVisibility:flag stop:NO];
|
||||
}
|
||||
|
||||
@@ -2472,10 +2477,6 @@ Sets the selection to a range of characters in response to user action.
|
||||
if (!ruler)
|
||||
return;
|
||||
|
||||
// Do not rebuild markers if user is currently dragging one
|
||||
if ([ruler draggingMarker])
|
||||
return;
|
||||
|
||||
var selectedRange = [self selectedRange],
|
||||
paragraphStyle = [CPParagraphStyle defaultParagraphStyle],
|
||||
currentAttributes = _typingAttributes;
|
||||
@@ -2484,10 +2485,10 @@ Sets the selection to a range of characters in response to user action.
|
||||
if (textLength > 0)
|
||||
{
|
||||
var charIndex = selectedRange.location;
|
||||
|
||||
|
||||
// Safety bounds checks for cursor placements
|
||||
if (charIndex >= textLength)
|
||||
charIndex = textLength - 1;
|
||||
|
||||
if (charIndex < 0)
|
||||
charIndex = 0;
|
||||
|
||||
@@ -2501,6 +2502,7 @@ Sets the selection to a range of characters in response to user action.
|
||||
tabStops = [paragraphStyle tabStops],
|
||||
count = [tabStops count];
|
||||
|
||||
// A. Load existing tab stop markers onto the ruler
|
||||
for (var i = 0; i < count; i++)
|
||||
{
|
||||
var tab = [tabStops objectAtIndex:i],
|
||||
@@ -2511,6 +2513,7 @@ Sets the selection to a range of characters in response to user action.
|
||||
[markers addObject:marker];
|
||||
}
|
||||
|
||||
// B. Add Indentation Handles (First line indent & Head indent)
|
||||
var firstLineMarker = [[CPRulerMarker alloc] initWithRulerView:ruler
|
||||
markerLocation:[paragraphStyle firstLineHeadIndent]
|
||||
imageValue:[paragraphStyle firstLineHeadIndent]
|
||||
@@ -2526,6 +2529,7 @@ Sets the selection to a range of characters in response to user action.
|
||||
[ruler setMarkers:markers];
|
||||
}
|
||||
|
||||
// Local comparison function helper for tab sorting
|
||||
var compareTabStops = function(obj1, obj2, context) {
|
||||
if ([obj1 location] < [obj2 location]) return CPOrderedAscending;
|
||||
if ([obj1 location] > [obj2 location]) return CPOrderedDescending;
|
||||
@@ -2534,10 +2538,14 @@ var compareTabStops = function(obj1, obj2, context) {
|
||||
|
||||
- (void)rulerView:(CPRulerView)rulerView didAddMarker:(CPRulerMarker)marker
|
||||
{
|
||||
if (![self _didBeginEditing] || ![self shouldChangeTextInRange:_selectionRange replacementString:nil])
|
||||
return;
|
||||
|
||||
var selectedRange = [self selectedRange],
|
||||
paragraphStyle = [CPParagraphStyle defaultParagraphStyle],
|
||||
currentAttributes = _typingAttributes;
|
||||
|
||||
// Retrieve active attributes at the cursor position if there is no selection
|
||||
var textLength = [_textStorage length],
|
||||
charIndex = selectedRange.location;
|
||||
|
||||
@@ -2545,7 +2553,6 @@ var compareTabStops = function(obj1, obj2, context) {
|
||||
{
|
||||
if (charIndex >= textLength)
|
||||
charIndex = textLength - 1;
|
||||
|
||||
if (charIndex < 0)
|
||||
charIndex = 0;
|
||||
|
||||
@@ -2555,32 +2562,48 @@ var compareTabStops = function(obj1, obj2, context) {
|
||||
if ([currentAttributes objectForKey:CPParagraphStyleAttributeName])
|
||||
paragraphStyle = [currentAttributes objectForKey:CPParagraphStyleAttributeName];
|
||||
|
||||
var mutableStyle = [paragraphStyle mutableCopy],
|
||||
newTab = [[CPTextTab alloc] initWithType:CPLeftTextAlignment location:[marker imageValue]],
|
||||
var mutableStyle = [paragraphStyle mutableCopy];
|
||||
|
||||
// Create a new Left-aligned tab stop where the user clicked
|
||||
var newTab = [[CPTextTab alloc] initWithType:CPLeftTextAlignment location:[marker imageValue]],
|
||||
tabs = [[mutableStyle tabStops] mutableCopy];
|
||||
|
||||
[tabs addObject:newTab];
|
||||
|
||||
// Sort tabs by location ascending
|
||||
[tabs sortUsingFunction:compareTabStops context:nil];
|
||||
|
||||
[mutableStyle setTabStops:tabs];
|
||||
[marker setRepresentedObject:newTab];
|
||||
|
||||
// Find the target text range to modify (selection or containing paragraph)
|
||||
var targetRange = selectedRange;
|
||||
if (targetRange.length === 0 && textLength > 0)
|
||||
if (targetRange.length === 0)
|
||||
targetRange = [self selectionRangeForProposedRange:CPMakeRange(targetRange.location, 0) granularity:CPSelectByParagraph];
|
||||
|
||||
if (targetRange.length > 0)
|
||||
{
|
||||
[_textStorage addAttribute:CPParagraphStyleAttributeName value:mutableStyle range:CPMakeRangeCopy(targetRange)];
|
||||
[_layoutManager textStorage:_textStorage edited:0 range:CPMakeRangeCopy(targetRange) changeInLength:0 invalidatedRange:CPMakeRangeCopy(targetRange)];
|
||||
|
||||
[_layoutManager textStorage:_textStorage
|
||||
edited:0
|
||||
range:CPMakeRangeCopy(targetRange)
|
||||
changeInLength:0
|
||||
invalidatedRange:CPMakeRangeCopy(targetRange)];
|
||||
}
|
||||
|
||||
[_typingAttributes setObject:mutableStyle forKey:CPParagraphStyleAttributeName];
|
||||
[[CPNotificationCenter defaultCenter] postNotificationName:CPTextViewDidChangeTypingAttributesNotification object:self];
|
||||
if (selectedRange.length === 0)
|
||||
{
|
||||
[_typingAttributes setObject:mutableStyle forKey:CPParagraphStyleAttributeName];
|
||||
[[CPNotificationCenter defaultCenter] postNotificationName:CPTextViewDidChangeTypingAttributesNotification object:self];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)rulerView:(CPRulerView)rulerView didMoveMarker:(CPRulerMarker)marker
|
||||
{
|
||||
if (![self _didBeginEditing] || ![self shouldChangeTextInRange:_selectionRange replacementString:nil])
|
||||
return;
|
||||
|
||||
var selectedRange = [self selectedRange],
|
||||
paragraphStyle = [CPParagraphStyle defaultParagraphStyle],
|
||||
currentAttributes = _typingAttributes;
|
||||
@@ -2592,7 +2615,6 @@ var compareTabStops = function(obj1, obj2, context) {
|
||||
{
|
||||
if (charIndex >= textLength)
|
||||
charIndex = textLength - 1;
|
||||
|
||||
if (charIndex < 0)
|
||||
charIndex = 0;
|
||||
|
||||
@@ -2603,45 +2625,58 @@ var compareTabStops = function(obj1, obj2, context) {
|
||||
paragraphStyle = [currentAttributes objectForKey:CPParagraphStyleAttributeName];
|
||||
|
||||
var mutableStyle = [paragraphStyle mutableCopy],
|
||||
rep = [marker representedObject];
|
||||
oldTab = [marker representedObject];
|
||||
|
||||
if (!rep)
|
||||
if (!oldTab)
|
||||
return;
|
||||
|
||||
// A. Handle standard tab stops
|
||||
if ([rep isKindOfClass:[CPTextTab class]])
|
||||
if ([oldTab isKindOfClass:[CPTextTab class]])
|
||||
{
|
||||
var newTab = [[CPTextTab alloc] initWithType:[rep alignment] location:[marker imageValue]],
|
||||
var newTab = [[CPTextTab alloc] initWithType:[oldTab alignment] location:[marker imageValue]],
|
||||
tabs = [[mutableStyle tabStops] mutableCopy];
|
||||
|
||||
[tabs removeObject:rep];
|
||||
[tabs removeObject:oldTab];
|
||||
[tabs addObject:newTab];
|
||||
|
||||
// Sort tabs by location ascending
|
||||
[tabs sortUsingFunction:compareTabStops context:nil];
|
||||
|
||||
[mutableStyle setTabStops:tabs];
|
||||
[marker setRepresentedObject:newTab];
|
||||
}
|
||||
// B. Handle Indentation Marker drags (First Line, Left, and Right indents)
|
||||
else if ([oldTab isKindOfClass:[CPString class]])
|
||||
{
|
||||
if (oldTab === @"CPFirstLineIndent")
|
||||
[mutableStyle setFirstLineHeadIndent:[marker imageValue]];
|
||||
else if (oldTab === @"CPHeadIndent")
|
||||
[mutableStyle setHeadIndent:[marker imageValue]];
|
||||
else if (oldTab === @"CPTailIndent")
|
||||
[mutableStyle setTailIndent:[marker imageValue]];
|
||||
}
|
||||
|
||||
// B. Handle Indentation Marker drags directly by string literal
|
||||
else if (rep === @"CPFirstLineIndent")
|
||||
[mutableStyle setFirstLineHeadIndent:[marker imageValue]];
|
||||
else if (rep === @"CPHeadIndent")
|
||||
[mutableStyle setHeadIndent:[marker imageValue]];
|
||||
else if (rep === @"CPTailIndent")
|
||||
[mutableStyle setTailIndent:[marker imageValue]];
|
||||
|
||||
// Find the target text range to modify (selection or containing paragraph)
|
||||
var targetRange = selectedRange;
|
||||
|
||||
if (targetRange.length === 0 && textLength > 0)
|
||||
if (targetRange.length === 0)
|
||||
targetRange = [self selectionRangeForProposedRange:CPMakeRange(targetRange.location, 0) granularity:CPSelectByParagraph];
|
||||
|
||||
if (targetRange.length > 0)
|
||||
{
|
||||
[_textStorage addAttribute:CPParagraphStyleAttributeName value:mutableStyle range:CPMakeRangeCopy(targetRange)];
|
||||
[_layoutManager textStorage:_textStorage edited:0 range:CPMakeRangeCopy(targetRange) changeInLength:0 invalidatedRange:CPMakeRangeCopy(targetRange)];
|
||||
|
||||
[_layoutManager textStorage:_textStorage
|
||||
edited:0
|
||||
range:CPMakeRangeCopy(targetRange)
|
||||
changeInLength:0
|
||||
invalidatedRange:CPMakeRangeCopy(targetRange)];
|
||||
}
|
||||
|
||||
[_typingAttributes setObject:mutableStyle forKey:CPParagraphStyleAttributeName];
|
||||
if (selectedRange.length === 0)
|
||||
{
|
||||
[_typingAttributes setObject:mutableStyle forKey:CPParagraphStyleAttributeName];
|
||||
[[CPNotificationCenter defaultCenter] postNotificationName:CPTextViewDidChangeTypingAttributesNotification object:self];
|
||||
}
|
||||
|
||||
[_layoutManager _validateLayoutAndGlyphs];
|
||||
[self sizeToFit];
|
||||
@@ -2650,6 +2685,9 @@ var compareTabStops = function(obj1, obj2, context) {
|
||||
|
||||
- (void)rulerView:(CPRulerView)rulerView didRemoveMarker:(CPRulerMarker)marker
|
||||
{
|
||||
if (![self _didBeginEditing] || ![self shouldChangeTextInRange:_selectionRange replacementString:nil])
|
||||
return;
|
||||
|
||||
var selectedRange = [self selectedRange],
|
||||
paragraphStyle = [CPParagraphStyle defaultParagraphStyle],
|
||||
currentAttributes = _typingAttributes;
|
||||
@@ -2659,8 +2697,11 @@ var compareTabStops = function(obj1, obj2, context) {
|
||||
|
||||
if (textLength > 0)
|
||||
{
|
||||
if (charIndex >= textLength) charIndex = textLength - 1;
|
||||
if (charIndex < 0) charIndex = 0;
|
||||
if (charIndex >= textLength)
|
||||
charIndex = textLength - 1;
|
||||
if (charIndex < 0)
|
||||
charIndex = 0;
|
||||
|
||||
currentAttributes = [_textStorage attributesAtIndex:charIndex effectiveRange:nil];
|
||||
}
|
||||
|
||||
@@ -2675,20 +2716,31 @@ var compareTabStops = function(obj1, obj2, context) {
|
||||
|
||||
var tabs = [[mutableStyle tabStops] mutableCopy];
|
||||
[tabs removeObject:oldTab];
|
||||
|
||||
[mutableStyle setTabStops:tabs];
|
||||
|
||||
// Find the target text range to modify (selection or containing paragraph)
|
||||
var targetRange = selectedRange;
|
||||
if (targetRange.length === 0 && textLength > 0)
|
||||
|
||||
if (targetRange.length === 0)
|
||||
targetRange = [self selectionRangeForProposedRange:CPMakeRange(targetRange.location, 0) granularity:CPSelectByParagraph];
|
||||
|
||||
if (targetRange.length > 0)
|
||||
{
|
||||
[_textStorage addAttribute:CPParagraphStyleAttributeName value:mutableStyle range:CPMakeRangeCopy(targetRange)];
|
||||
[_layoutManager textStorage:_textStorage edited:0 range:CPMakeRangeCopy(targetRange) changeInLength:0 invalidatedRange:CPMakeRangeCopy(targetRange)];
|
||||
|
||||
[_layoutManager textStorage:_textStorage
|
||||
edited:0
|
||||
range:CPMakeRangeCopy(targetRange)
|
||||
changeInLength:0
|
||||
invalidatedRange:CPMakeRangeCopy(targetRange)];
|
||||
}
|
||||
|
||||
[_typingAttributes setObject:mutableStyle forKey:CPParagraphStyleAttributeName];
|
||||
[[CPNotificationCenter defaultCenter] postNotificationName:CPTextViewDidChangeTypingAttributesNotification object:self];
|
||||
if (selectedRange.length === 0)
|
||||
{
|
||||
[_typingAttributes setObject:mutableStyle forKey:CPParagraphStyleAttributeName];
|
||||
[[CPNotificationCenter defaultCenter] postNotificationName:CPTextViewDidChangeTypingAttributesNotification object:self];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)rulerView:(CPRulerView)rulerView didUpdateMarker:(CPRulerMarker)marker oldTab:(id)oldTab
|
||||
@@ -2712,11 +2764,19 @@ var compareTabStops = function(obj1, obj2, context) {
|
||||
|
||||
[tabs removeObject:oldTab];
|
||||
[tabs addObject:newTab];
|
||||
|
||||
// Sort tabs ascending
|
||||
[tabs sortUsingFunction:compareTabStops context:nil];
|
||||
|
||||
[mutableStyle setTabStops:tabs];
|
||||
|
||||
[_textStorage addAttribute:CPParagraphStyleAttributeName value:mutableStyle range:CPMakeRangeCopy(targetRange)];
|
||||
[_layoutManager textStorage:_textStorage edited:0 range:CPMakeRangeCopy(targetRange) changeInLength:0 invalidatedRange:CPMakeRangeCopy(targetRange)];
|
||||
|
||||
[_layoutManager textStorage:_textStorage
|
||||
edited:0
|
||||
range:CPMakeRangeCopy(targetRange)
|
||||
changeInLength:0
|
||||
invalidatedRange:CPMakeRangeCopy(targetRange)];
|
||||
|
||||
if (selectedRange.length === 0)
|
||||
{
|
||||
@@ -2724,145 +2784,12 @@ var compareTabStops = function(obj1, obj2, context) {
|
||||
[[CPNotificationCenter defaultCenter] postNotificationName:CPTextViewDidChangeTypingAttributesNotification object:self];
|
||||
}
|
||||
|
||||
// Force layouts and view canvas update
|
||||
[_layoutManager _validateLayoutAndGlyphs];
|
||||
[self sizeToFit];
|
||||
[self setNeedsDisplay:YES];
|
||||
}
|
||||
|
||||
- (float)rulerView:(CPRulerView)aRulerView willMoveMarker:(CPRulerMarker)aMarker toLocation:(float)proposedLocation
|
||||
{
|
||||
var rep = [aMarker representedObject];
|
||||
|
||||
// Indent markers can be dragged anywhere >= 0
|
||||
if (rep === @"CPFirstLineIndent" || rep === @"CPHeadIndent" || rep === @"CPTailIndent")
|
||||
return Math.max(0.0, proposedLocation);
|
||||
|
||||
var textLength = [_textStorage length];
|
||||
if (textLength === 0)
|
||||
return Math.max(0.0, proposedLocation);
|
||||
|
||||
var selectedRange = [self selectedRange],
|
||||
targetRange = selectedRange;
|
||||
|
||||
if (targetRange.length === 0)
|
||||
targetRange = [self selectionRangeForProposedRange:CPMakeRange(targetRange.location, 0) granularity:CPSelectByParagraph];
|
||||
|
||||
if (targetRange.length === 0)
|
||||
return Math.max(0.0, proposedLocation);
|
||||
|
||||
[_layoutManager _validateLayoutAndGlyphs];
|
||||
|
||||
var theString = [_textStorage string],
|
||||
minLocation = 0.0,
|
||||
containerWidth = [_textContainer containerSize].width,
|
||||
maxLocation = containerWidth,
|
||||
currentParagraphStyle = [_textStorage attribute:CPParagraphStyleAttributeName atIndex:targetRange.location effectiveRange:nil] || [CPParagraphStyle defaultParagraphStyle],
|
||||
tabStops = [currentParagraphStyle tabStops] || [],
|
||||
tabCount = [tabStops count];
|
||||
|
||||
// 1. Right boundary: Tail indent (if configured)
|
||||
var tailIndent = [currentParagraphStyle tailIndent];
|
||||
if (tailIndent > 0.0)
|
||||
maxLocation = Math.min(maxLocation, tailIndent);
|
||||
else if (tailIndent < 0.0)
|
||||
maxLocation = Math.min(maxLocation, containerWidth + tailIndent);
|
||||
|
||||
// 2. Identify active tab stop index
|
||||
var targetTabIndex = -1;
|
||||
for (var i = 0; i < tabCount; i++)
|
||||
{
|
||||
var tab = [tabStops objectAtIndex:i];
|
||||
if (tab === rep || ([tab location] === [rep location] && [tab alignment] === [rep alignment]))
|
||||
{
|
||||
targetTabIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 3. Constrain to neighboring tab stops (Left and Right)
|
||||
var safetySpacer = 2.0;
|
||||
|
||||
if (targetTabIndex !== -1)
|
||||
{
|
||||
// Left neighbor constraint (previous tab stop)
|
||||
if (targetTabIndex > 0)
|
||||
{
|
||||
var prevTab = [tabStops objectAtIndex:targetTabIndex - 1];
|
||||
minLocation = Math.max(minLocation, [prevTab location] + safetySpacer);
|
||||
}
|
||||
|
||||
// Right neighbor constraint (next tab stop)
|
||||
if (targetTabIndex + 1 < tabCount)
|
||||
{
|
||||
var nextTab = [tabStops objectAtIndex:targetTabIndex + 1];
|
||||
maxLocation = Math.min(maxLocation, [nextTab location] - safetySpacer);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// For new markers being added between existing tab stops
|
||||
for (var i = 0; i < tabCount; i++)
|
||||
{
|
||||
var tabLoc = [[tabStops objectAtIndex:i] location];
|
||||
if (tabLoc < proposedLocation)
|
||||
minLocation = Math.max(minLocation, tabLoc + safetySpacer);
|
||||
else if (tabLoc > proposedLocation)
|
||||
maxLocation = Math.min(maxLocation, tabLoc - safetySpacer);
|
||||
}
|
||||
}
|
||||
|
||||
// 4. Constrain to preceding text on active lines
|
||||
var start = targetRange.location,
|
||||
end = CPMaxRange(targetRange),
|
||||
tabCountInLine = 0,
|
||||
lineStart = start;
|
||||
|
||||
for (var i = start; i < end; i++)
|
||||
{
|
||||
var charCode = theString.charCodeAt(i);
|
||||
if (charCode === 10 || charCode === 13)
|
||||
{
|
||||
tabCountInLine = 0;
|
||||
lineStart = i + 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (charCode === 9) // '\t'
|
||||
{
|
||||
if (tabCountInLine === targetTabIndex || targetTabIndex === -1)
|
||||
{
|
||||
var precedingX = 0.0;
|
||||
if (i === lineStart)
|
||||
{
|
||||
var isFirstLine = (lineStart === 0 || theString.charCodeAt(lineStart - 1) === 10 || theString.charCodeAt(lineStart - 1) === 13);
|
||||
precedingX = isFirstLine ? [currentParagraphStyle firstLineHeadIndent] : [currentParagraphStyle headIndent];
|
||||
}
|
||||
else
|
||||
{
|
||||
var glyphRect = [_layoutManager boundingRectForGlyphRange:CPMakeRange(i - 1, 1) inTextContainer:_textContainer];
|
||||
precedingX = CGRectGetMaxX(glyphRect);
|
||||
}
|
||||
|
||||
var textLimit = precedingX + safetySpacer;
|
||||
if (textLimit > minLocation)
|
||||
minLocation = textLimit;
|
||||
}
|
||||
tabCountInLine++;
|
||||
}
|
||||
}
|
||||
|
||||
if (minLocation > maxLocation)
|
||||
minLocation = maxLocation;
|
||||
|
||||
// 5. Clamp proposedLocation within [minLocation, maxLocation]
|
||||
return Math.min(maxLocation, Math.max(minLocation, proposedLocation));
|
||||
}
|
||||
|
||||
- (float)rulerView:(CPRulerView)aRulerView willAddMarker:(CPRulerMarker)aMarker atLocation:(float)proposedLocation
|
||||
{
|
||||
return [self rulerView:aRulerView willMoveMarker:aMarker toLocation:proposedLocation];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation CPTextView (CPTextViewDelegate)
|
||||
@@ -3102,7 +3029,6 @@ var CPTextViewAllowsUndoKey = @"CPTextViewAllowsUndoKey",
|
||||
style.padding = "0px";
|
||||
style.margin = "0px";
|
||||
style.whiteSpace = "pre";
|
||||
style.backgroundColor = "black";
|
||||
_caretDOM.style.width = "1px";
|
||||
_caretDOM.style.zIndex = 10001;
|
||||
_textView = aView;
|
||||
@@ -3166,8 +3092,8 @@ var CPTextViewAllowsUndoKey = @"CPTextViewAllowsUndoKey",
|
||||
{
|
||||
var rect = [_textView._layoutManager boundingRectForGlyphRange:CPMakeRange(aLoc, 1) inTextContainer:_textView._textContainer];
|
||||
|
||||
if (aLoc >= [_textView._layoutManager numberOfCharacters])
|
||||
rect.origin.x = CGRectGetMaxX(rect);
|
||||
if (aLoc >= [_textView._layoutManager numberOfCharacters])
|
||||
rect.origin.x = CGRectGetMaxX(rect);
|
||||
|
||||
[self setRect:rect];
|
||||
}
|
||||
|
||||
@@ -138,28 +138,32 @@ var CPSystemTypesetterFactory,
|
||||
return [_layoutManager textContainers];
|
||||
}
|
||||
|
||||
// Retrieves correct CPTextTab stop accounting for custom stops and default intervals
|
||||
// Retrieves correct CPTextTab stop accounting for CPArray properties
|
||||
- (CPTextTab)textTabForWidth:(double)aWidth writingDirection:(CPWritingDirection)direction
|
||||
{
|
||||
var tabStops = [_currentParagraph tabStops],
|
||||
defaultInterval = [_currentParagraph defaultTabInterval] || 28.0;
|
||||
var tabStops = [_currentParagraph tabStops];
|
||||
|
||||
var l = tabStops ? [tabStops count] : 0;
|
||||
if (!tabStops)
|
||||
tabStops = [[CPParagraphStyle defaultParagraphStyle] tabStops];
|
||||
|
||||
// 1. If custom tab stops exist ahead of current position, use the first one encountered
|
||||
if (l > 0)
|
||||
var l = [tabStops count];
|
||||
|
||||
if (l === 0)
|
||||
return nil;
|
||||
|
||||
// Find the first tab stop that is strictly greater than the current width
|
||||
for (var i = 0; i < l; i++)
|
||||
{
|
||||
for (var i = 0; i < l; i++)
|
||||
{
|
||||
var tab = [tabStops objectAtIndex:i];
|
||||
var tab = [tabStops objectAtIndex:i];
|
||||
|
||||
if ([tab location] > aWidth)
|
||||
return tab;
|
||||
}
|
||||
if ([tab location] > aWidth)
|
||||
return tab;
|
||||
}
|
||||
|
||||
// 2. Otherwise (or when all custom tab stops are behind the text), advance to the next default interval
|
||||
var nextLocation = (Math.floor(aWidth / defaultInterval) + 1) * defaultInterval;
|
||||
// If aWidth exceeds the last tab stop, dynamically calculate the next
|
||||
// tab location using the default tab interval.
|
||||
var defaultInterval = [_currentParagraph defaultTabInterval] || 28.0;
|
||||
var nextLocation = CEIL((aWidth + 1.0) / defaultInterval) * defaultInterval;
|
||||
|
||||
return [[CPTextTab alloc] initWithType:CPLeftTextAlignment location:nextLocation];
|
||||
}
|
||||
@@ -201,7 +205,7 @@ var CPSystemTypesetterFactory,
|
||||
[_layoutManager setLocation:CGPointMake(myX, _lineBase) forStartOfGlyphRange:lineRange];
|
||||
[_layoutManager _setAdvancements:advancements forGlyphRange:lineRange];
|
||||
|
||||
// fix the _lineFragments when fontsizes differ
|
||||
//fix the _lineFragments when fontsizes differ
|
||||
var l = _lineFragments.length;
|
||||
|
||||
for (var i = 0 ; i < l ; i++)
|
||||
@@ -247,7 +251,7 @@ var CPSystemTypesetterFactory,
|
||||
isTabStop = NO,
|
||||
isAttachment = NO,
|
||||
isWordWrapped = NO,
|
||||
numberOfGlyphs = [_textStorage length],
|
||||
numberOfGlyphs= [_textStorage length],
|
||||
leading,
|
||||
numLines = 0,
|
||||
theString = [_textStorage string],
|
||||
@@ -289,7 +293,7 @@ var CPSystemTypesetterFactory,
|
||||
|
||||
for (; numLines != maxNumLines && glyphIndex < numberOfGlyphs; glyphIndex++)
|
||||
{
|
||||
// check whether there is any change in the attributes from here on
|
||||
// check whether there any change in the attributes from here on
|
||||
if (!CPLocationInRange(glyphIndex, _attributesRange))
|
||||
{
|
||||
_currentAttributes = [_textStorage attributesAtIndex:glyphIndex effectiveRange:_attributesRange];
|
||||
@@ -323,6 +327,15 @@ var CPSystemTypesetterFactory,
|
||||
lineOrigin.x = isFirstLineOfParagraph ? [_currentParagraph firstLineHeadIndent] : [_currentParagraph headIndent];
|
||||
isFirstLineOfLayout = NO;
|
||||
}
|
||||
|
||||
// Calculate the right wrapping margin based on tail indent
|
||||
var tailIndent = [_currentParagraph tailIndent];
|
||||
if (tailIndent > 0.0)
|
||||
rightMargin = tailIndent;
|
||||
else if (tailIndent < 0.0)
|
||||
rightMargin = containerSizeWidth + tailIndent;
|
||||
else
|
||||
rightMargin = containerSizeWidth;
|
||||
|
||||
// Handle the layout's very first line indentation
|
||||
if (isFirstLineOfLayout)
|
||||
@@ -406,10 +419,10 @@ var CPSystemTypesetterFactory,
|
||||
// We are processing characters, so we are no longer at the start of a physical line
|
||||
isStartOfPhysicalLine = NO;
|
||||
|
||||
var currentCharCode = theString.charCodeAt(glyphIndex),
|
||||
var currentCharCode = theString.charCodeAt(glyphIndex), // use pure javascript methods for performance reasons
|
||||
rangeWidth = [theString.substr(measuringRange.location, measuringRange.length) sizeWithFont:currentFont inWidth:NULL].width + currentAnchor;
|
||||
|
||||
switch (currentCharCode)
|
||||
switch (currentCharCode) // faster than sending actionForControlCharacterAtIndex: called for each char.
|
||||
{
|
||||
case CPAttachmentCharacter:
|
||||
{
|
||||
@@ -441,8 +454,7 @@ var CPSystemTypesetterFactory,
|
||||
}
|
||||
case 9: // '\t'
|
||||
{
|
||||
// Measure against the actual text position before the tab stop
|
||||
var nextTab = [self textTabForWidth:prevRangeWidth + lineOrigin.x writingDirection:0];
|
||||
var nextTab = [self textTabForWidth:rangeWidth + lineOrigin.x writingDirection:0];
|
||||
|
||||
isTabStop = YES;
|
||||
|
||||
@@ -489,7 +501,7 @@ var CPSystemTypesetterFactory,
|
||||
}
|
||||
else
|
||||
{
|
||||
rangeWidth = prevRangeWidth + 28.0; // standard fallback spacer
|
||||
rangeWidth += 28.0; // standard fallback spacer
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -499,6 +511,10 @@ var CPSystemTypesetterFactory,
|
||||
wrapRange._height = _lineHeight;
|
||||
wrapRange._base = _lineBase;
|
||||
|
||||
// Optimization: Start measuring from the next character to avoid O(n^2)
|
||||
// string width calculation within a line since spaces do not carry ligatures or kerning.
|
||||
// Only reset the measuring range if the next character is NOT another space.
|
||||
// This prevents compounded subpixel rounding errors with contiguous spaces.
|
||||
if (theString.charCodeAt(glyphIndex + 1) !== 32)
|
||||
{
|
||||
currentAnchor = rangeWidth;
|
||||
@@ -528,7 +544,7 @@ var CPSystemTypesetterFactory,
|
||||
|
||||
isNewline = YES;
|
||||
isWordWrapped = YES;
|
||||
glyphIndex = CPMaxRange(lineRange) - 1;
|
||||
glyphIndex = CPMaxRange(lineRange) - 1; // start the line starts directly at current character
|
||||
}
|
||||
|
||||
if (isNewline || isTabStop || isAttachment)
|
||||
@@ -560,6 +576,8 @@ var CPSystemTypesetterFactory,
|
||||
containerSizeHeight = containerSize.height;
|
||||
}
|
||||
|
||||
// If this is a soft wrap (isWordWrapped), next line gets headIndent.
|
||||
// If it was a paragraph return, it gets firstLineHeadIndent.
|
||||
isFirstLineOfParagraph = !isWordWrapped;
|
||||
lineOrigin.x = isFirstLineOfParagraph ? [_currentParagraph firstLineHeadIndent] : [_currentParagraph headIndent];
|
||||
|
||||
@@ -585,7 +603,7 @@ var CPSystemTypesetterFactory,
|
||||
}
|
||||
}
|
||||
|
||||
// Flush remaining characters
|
||||
// this is to "flush" the remaining characters
|
||||
if (lineRange.length)
|
||||
[self _flushRange:lineRange lineOrigin:lineOrigin currentContainer:_currentTextContainer advancements:advancements lineCount:numLines sameLine:NO];
|
||||
|
||||
|
||||
@@ -277,7 +277,7 @@ function _points2twips(a) { return (a) * 20.0; }
|
||||
|
||||
if (!num)
|
||||
[colorDict setObject:num = [CPNumber numberWithInt:[colorDict count] + 1]
|
||||
forKey:[color cssString]];
|
||||
forKey:[color cssString]];
|
||||
|
||||
return [num intValue];
|
||||
}
|
||||
|
||||
@@ -19,8 +19,7 @@
|
||||
*/
|
||||
|
||||
@import "CPView.j"
|
||||
@class CPTextView;
|
||||
@class CPTextContainer;
|
||||
@import "CPTextView.j"
|
||||
@import "CPTextField.j"
|
||||
@import <Foundation/CPAttributedString.j>
|
||||
|
||||
|
||||
+3
-1
@@ -814,10 +814,12 @@ CPThemeStateKeyWindow = CPThemeState("keyWindow");
|
||||
CPThemeStateControlSizeRegular = CPThemeState("controlSizeRegular");
|
||||
CPThemeStateControlSizeSmall = CPThemeState("controlSizeSmall");
|
||||
CPThemeStateControlSizeMini = CPThemeState("controlSizeMini");
|
||||
CPThemeStateControlSizeLarge = CPThemeState("controlSizeLarge");
|
||||
CPThemeStateAlternateState = CPThemeState("alternate");
|
||||
CPThemeStateComposedControl = CPThemeState("composed");
|
||||
|
||||
CPThemeStateWindowsPlatform = CPThemeState("windowsPlatform");
|
||||
CPThemeStateNormalString = String(CPThemeStateNormal);
|
||||
CPThemeStateHUD = CPThemeState("hud");
|
||||
|
||||
|
||||
@implementation _CPThemeAttribute : CPObject
|
||||
|
||||
+75
-94
@@ -50,9 +50,6 @@
|
||||
|
||||
[self exposeBinding:@"contentArray"];
|
||||
[self exposeBinding:@"sortDescriptors"];
|
||||
[self exposeBinding:@"selectionIndexPaths"];
|
||||
[self exposeBinding:@"selectionIndexPath"];
|
||||
[self exposeBinding:@"selectedObjects"];
|
||||
}
|
||||
|
||||
+ (CPSet)keyPathsForValuesAffectingContentArray
|
||||
@@ -62,7 +59,7 @@
|
||||
|
||||
+ (CPSet)keyPathsForValuesAffectingArrangedObjects
|
||||
{
|
||||
return [CPSet setWithObjects:@"content", @"contentArray", @"sortDescriptors", @"childrenKeyPath"];
|
||||
return [CPSet setWithObjects:@"content", @"sortDescriptors", @"childrenKeyPath"];
|
||||
}
|
||||
|
||||
+ (CPSet)keyPathsForValuesAffectingSelectionIndexPath
|
||||
@@ -72,27 +69,27 @@
|
||||
|
||||
+ (CPSet)keyPathsForValuesAffectingSelectedObjects
|
||||
{
|
||||
return [CPSet setWithObjects:@"selectionIndexPaths", @"arrangedObjects"];
|
||||
return [CPSet setWithObjects:@"selectionIndexPaths"];
|
||||
}
|
||||
|
||||
+ (CPSet)keyPathsForValuesAffectingSelectedNodes
|
||||
{
|
||||
return [CPSet setWithObjects:@"selectionIndexPaths", @"arrangedObjects"];
|
||||
}
|
||||
|
||||
+ (CPSet)keyPathsForValuesAffectingCanInsert
|
||||
{
|
||||
return [CPSet setWithObjects:@"editable"];
|
||||
}
|
||||
|
||||
+ (CPSet)keyPathsForValuesAffectingCanInsertChild
|
||||
{
|
||||
return [CPSet setWithObjects:@"selectionIndexPaths", @"editable"];
|
||||
return [CPSet setWithObjects:@"selectionIndexPaths"];
|
||||
}
|
||||
|
||||
+ (CPSet)keyPathsForValuesAffectingCanAddChild
|
||||
{
|
||||
return [CPSet setWithObjects:@"selectionIndexPaths", @"editable"];
|
||||
return [CPSet setWithObjects:@"selectionIndexPaths"];
|
||||
}
|
||||
|
||||
+ (CPSet)keyPathsForValuesAffectingCanInsert
|
||||
{
|
||||
return [CPSet setWithObjects:@"selectionIndexPaths"];
|
||||
}
|
||||
|
||||
+ (CPSet)keyPathsForValuesAffectingCanInsertChild
|
||||
{
|
||||
return [CPSet setWithObjects:@"selectionIndexPaths"];
|
||||
}
|
||||
|
||||
- (id)init
|
||||
@@ -118,8 +115,7 @@
|
||||
}
|
||||
|
||||
- (void)prepareContent
|
||||
{
|
||||
[self _setContentArray:[CPArray arrayWithObject:[self newObject]]];
|
||||
{[self _setContentArray:[CPArray arrayWithObject:[self newObject]]];
|
||||
}
|
||||
|
||||
- (BOOL)preservesSelection { return _preservesSelection; }
|
||||
@@ -148,8 +144,7 @@
|
||||
- (void)setChildrenKeyPath:(CPString)aKeyPath
|
||||
{
|
||||
if (_childrenKeyPath === aKeyPath) return;
|
||||
_childrenKeyPath = aKeyPath;
|
||||
[self rearrangeObjects];
|
||||
_childrenKeyPath = aKeyPath;[self rearrangeObjects];
|
||||
}
|
||||
|
||||
- (CPString)countKeyPath { return _countKeyPath; }
|
||||
@@ -171,21 +166,14 @@
|
||||
if (![value isKindOfClass:[CPArray class]])
|
||||
value = [CPArray arrayWithObject:value];
|
||||
|
||||
if (_contentObject === value)
|
||||
return;
|
||||
|
||||
var oldSelectedObjects = nil,
|
||||
oldSelectionIndexPaths = nil;
|
||||
oldSelectionIndexPaths = nil;
|
||||
|
||||
if ([self preservesSelection])
|
||||
oldSelectedObjects = [self selectedObjects];
|
||||
else
|
||||
oldSelectionIndexPaths = [self selectionIndexPaths];
|
||||
|
||||
[self _selectionWillChange];
|
||||
[self willChangeValueForKey:@"content"];
|
||||
[self willChangeValueForKey:@"contentArray"];
|
||||
|
||||
_contentObject = value;
|
||||
|
||||
[self _rearrangeObjects];
|
||||
@@ -194,32 +182,23 @@
|
||||
[self __setSelectedObjects:oldSelectedObjects];
|
||||
else
|
||||
[self __setSelectionIndexPaths:oldSelectionIndexPaths avoidEmpty:_avoidsEmptySelection];
|
||||
|
||||
[self didChangeValueForKey:@"contentArray"];
|
||||
[self didChangeValueForKey:@"content"];
|
||||
[self _selectionDidChange];
|
||||
}
|
||||
|
||||
|
||||
- (void)_setContentArray:(id)anArray { [self setContent:anArray]; }
|
||||
- (void)_setContentArray:(id)anArray {[self setContent:anArray]; }
|
||||
- (id)contentArray { return _contentObject; }
|
||||
- (id)arrangedObjects { return _arrangedObjects; }
|
||||
|
||||
- (void)rearrangeObjects
|
||||
{
|
||||
[self _selectionWillChange];
|
||||
[self willChangeValueForKey:@"arrangedObjects"];
|
||||
|
||||
[self _rearrangeObjects];
|
||||
|
||||
[self didChangeValueForKey:@"arrangedObjects"];
|
||||
[self _selectionDidChange];
|
||||
}
|
||||
|
||||
- (void)_rearrangeObjects
|
||||
{
|
||||
var oldSelectedObjects = nil,
|
||||
oldSelectionIndexPaths = nil;
|
||||
oldSelectionIndexPaths = nil;
|
||||
|
||||
if ([self preservesSelection])
|
||||
oldSelectedObjects = [self selectedObjects];
|
||||
@@ -237,7 +216,7 @@
|
||||
- (void)__rebuildArrangedObjectsTree
|
||||
{
|
||||
var rootNode = [[CPTreeNode alloc] initWithRepresentedObject:nil],
|
||||
contentArray = [self contentArray];
|
||||
contentArray = [self contentArray];
|
||||
|
||||
if (contentArray && [contentArray count] > 0)
|
||||
{
|
||||
@@ -265,7 +244,7 @@
|
||||
for (var i = 0; i < count; i++)
|
||||
{
|
||||
var obj = [sortedObjects objectAtIndex:i],
|
||||
node = [[CPTreeNode alloc] initWithRepresentedObject:obj];
|
||||
node = [[CPTreeNode alloc] initWithRepresentedObject:obj];
|
||||
|
||||
if (_childrenKeyPath)
|
||||
{
|
||||
@@ -299,7 +278,11 @@
|
||||
|
||||
- (BOOL)setSelectionIndexPaths:(CPArray)indexPaths
|
||||
{
|
||||
return [self __setSelectionIndexPaths:indexPaths avoidEmpty:NO];
|
||||
[self _selectionWillChange];
|
||||
var result = [self __setSelectionIndexPaths:indexPaths avoidEmpty:NO];
|
||||
[self _selectionDidChange];
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
- (void)_ensureTreeNodesExistForIndexPaths:(CPArray)indexPaths
|
||||
@@ -351,8 +334,7 @@
|
||||
if (needsRebuild)
|
||||
{
|
||||
[childNodes removeAllObjects];
|
||||
var newNodes = [self _buildTreeNodesForObjects:expectedChildObjects];
|
||||
[childNodes addObjectsFromArray:newNodes];
|
||||
var newNodes = [self _buildTreeNodesForObjects:expectedChildObjects];[childNodes addObjectsFromArray:newNodes];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -384,13 +366,21 @@
|
||||
if ([_selectionIndexPaths isEqualToArray:newPaths])
|
||||
return NO;
|
||||
|
||||
[self _selectionWillChange];
|
||||
[self willChangeValueForKey:@"selectionIndexPaths"];
|
||||
|
||||
_selectionIndexPaths = [newPaths copy];
|
||||
|
||||
var binderClass = [[self class] _binderClassForBinding:@"selectionIndexPaths"];
|
||||
|
||||
if (binderClass)
|
||||
{
|
||||
var binding = [binderClass getBinding:@"selectionIndexPaths" forObject:self];
|
||||
|
||||
if (binding)
|
||||
[binding reverseSetValueFor:@"selectionIndexPaths"];
|
||||
}
|
||||
|
||||
[self didChangeValueForKey:@"selectionIndexPaths"];
|
||||
[self _selectionDidChange];
|
||||
|
||||
return YES;
|
||||
}
|
||||
@@ -398,7 +388,9 @@
|
||||
- (BOOL)addSelectionIndexPaths:(CPArray)indexPaths
|
||||
{
|
||||
var newPaths = [_selectionIndexPaths mutableCopy];
|
||||
|
||||
[newPaths addObjectsFromArray:indexPaths];
|
||||
|
||||
return [self setSelectionIndexPaths:newPaths];
|
||||
}
|
||||
|
||||
@@ -412,7 +404,7 @@
|
||||
- (CPArray)selectedNodes
|
||||
{
|
||||
var nodes = [CPMutableArray array],
|
||||
count = [_selectionIndexPaths count];
|
||||
count = [_selectionIndexPaths count];
|
||||
|
||||
for (var i = 0; i < count; i++)
|
||||
{
|
||||
@@ -426,17 +418,13 @@
|
||||
- (CPArray)selectedObjects
|
||||
{
|
||||
var objects = [CPMutableArray array],
|
||||
nodes = [self selectedNodes],
|
||||
count = [nodes count];
|
||||
nodes = [self selectedNodes],
|
||||
count = [nodes count];
|
||||
|
||||
for (var i = 0; i < count; i++)
|
||||
{
|
||||
var representedObject = [[nodes objectAtIndex:i] representedObject];
|
||||
if (representedObject)
|
||||
[objects addObject:representedObject];
|
||||
}
|
||||
[objects addObject:[[nodes objectAtIndex:i] representedObject]];
|
||||
|
||||
return [_CPObservableArray arrayWithArray:objects];
|
||||
return objects;
|
||||
}
|
||||
|
||||
- (BOOL)__setSelectedObjects:(CPArray)objects
|
||||
@@ -474,22 +462,22 @@
|
||||
}
|
||||
|
||||
- (BOOL)canInsert { return [self isEditable]; }
|
||||
- (BOOL)canInsertChild { return [self isEditable] && [_selectionIndexPaths count] > 0; }
|
||||
- (BOOL)canInsertChild { return [self isEditable] &&[_selectionIndexPaths count] > 0; }
|
||||
- (BOOL)canAddChild { return [self canInsertChild]; }
|
||||
|
||||
- (void)add:(id)sender
|
||||
{
|
||||
if (![self canInsert]) return;
|
||||
|
||||
var newObject = [self automaticallyPreparesContent] ? [self newObject] : [self _defaultNewObject],
|
||||
selectionPath = [self selectionIndexPath];
|
||||
var newObject = [self automaticallyPreparesContent] ? [self newObject] :[self _defaultNewObject],
|
||||
selectionPath = [self selectionIndexPath];
|
||||
|
||||
if (!selectionPath)
|
||||
selectionPath = [CPIndexPath indexPathWithIndex:[[[self arrangedObjects] childNodes] count]];
|
||||
|
||||
var length = [selectionPath length],
|
||||
lastIndex = [selectionPath indexAtPosition:length - 1],
|
||||
insertPath = [selectionPath indexPathByRemovingLastIndex];
|
||||
lastIndex = [selectionPath indexAtPosition:length - 1],
|
||||
insertPath = [selectionPath indexPathByRemovingLastIndex];
|
||||
|
||||
insertPath = [insertPath indexPathByAddingIndex:lastIndex + 1];
|
||||
|
||||
@@ -501,10 +489,10 @@
|
||||
if (![self canAddChild])
|
||||
return;
|
||||
|
||||
var newObject = [self automaticallyPreparesContent] ? [self newObject] : [self _defaultNewObject],
|
||||
parentNode = [[self arrangedObjects] descendantNodeAtIndexPath:[self selectionIndexPath]],
|
||||
childCount = [[parentNode childNodes] count],
|
||||
insertPath = [[self selectionIndexPath] indexPathByAddingIndex:childCount];
|
||||
var newObject = [self automaticallyPreparesContent] ?[self newObject] : [self _defaultNewObject],
|
||||
parentNode = [[self arrangedObjects] descendantNodeAtIndexPath:[self selectionIndexPath]],
|
||||
childCount = [[parentNode childNodes] count],
|
||||
insertPath = [[self selectionIndexPath] indexPathByAddingIndex:childCount];
|
||||
|
||||
[self insertObject:newObject atArrangedObjectIndexPath:insertPath];
|
||||
}
|
||||
@@ -513,8 +501,8 @@
|
||||
{
|
||||
if (![self canInsert]) return;
|
||||
|
||||
var newObject = [self automaticallyPreparesContent] ? [self newObject] : [self _defaultNewObject],
|
||||
indexPath = [self selectionIndexPath] || [CPIndexPath indexPathWithIndex:0];
|
||||
var newObject = [self automaticallyPreparesContent] ? [self newObject] :[self _defaultNewObject],
|
||||
indexPath = [self selectionIndexPath] || [CPIndexPath indexPathWithIndex:0];
|
||||
|
||||
[self insertObject:newObject atArrangedObjectIndexPath:indexPath];
|
||||
}
|
||||
@@ -524,7 +512,7 @@
|
||||
if (![self canInsertChild]) return;
|
||||
|
||||
var newObject = [self automaticallyPreparesContent] ? [self newObject] : [self _defaultNewObject],
|
||||
insertPath = [[self selectionIndexPath] indexPathByAddingIndex:0];
|
||||
insertPath = [[self selectionIndexPath] indexPathByAddingIndex:0];
|
||||
|
||||
[self insertObject:newObject atArrangedObjectIndexPath:insertPath];
|
||||
}
|
||||
@@ -536,7 +524,6 @@
|
||||
|
||||
- (void)insertObjects:(CPArray)objects atArrangedObjectIndexPaths:(CPArray)indexPaths
|
||||
{
|
||||
[self _selectionWillChange];
|
||||
[self willChangeValueForKey:@"content"];
|
||||
_disableSetContent = YES;
|
||||
|
||||
@@ -544,22 +531,21 @@
|
||||
for (var i = 0; i < count; i++)
|
||||
{
|
||||
var object = [objects objectAtIndex:i],
|
||||
path = [indexPaths objectAtIndex:i],
|
||||
length = [path length];
|
||||
path = [indexPaths objectAtIndex:i],
|
||||
length = [path length];
|
||||
|
||||
if (length === 1)
|
||||
{
|
||||
[_contentObject insertObject:object atIndex:[path indexAtPosition:0]];
|
||||
{[_contentObject insertObject:object atIndex:[path indexAtPosition:0]];
|
||||
}
|
||||
else
|
||||
{
|
||||
var parentPath = [path indexPathByRemovingLastIndex],
|
||||
parentNode = [[self arrangedObjects] descendantNodeAtIndexPath:parentPath];
|
||||
parentNode = [[self arrangedObjects] descendantNodeAtIndexPath:parentPath];
|
||||
|
||||
if (parentNode)
|
||||
{
|
||||
var parentObj = [parentNode representedObject],
|
||||
childIndex = [path indexAtPosition:length - 1];
|
||||
childIndex = [path indexAtPosition:length - 1];
|
||||
|
||||
var children = [parentObj valueForKeyPath:_childrenKeyPath];
|
||||
if (!children)
|
||||
@@ -582,11 +568,9 @@
|
||||
_disableSetContent = NO;
|
||||
[self _rearrangeObjects];
|
||||
|
||||
if ([self selectsInsertedObjects])
|
||||
[self setSelectionIndexPaths:indexPaths];
|
||||
if ([self selectsInsertedObjects])[self setSelectionIndexPaths:indexPaths];
|
||||
|
||||
[self didChangeValueForKey:@"content"];
|
||||
[self _selectionDidChange];
|
||||
}
|
||||
|
||||
- (void)remove:(id)sender
|
||||
@@ -601,17 +585,16 @@
|
||||
|
||||
- (void)removeObjectsAtArrangedObjectIndexPaths:(CPArray)indexPaths
|
||||
{
|
||||
[self _selectionWillChange];
|
||||
[self willChangeValueForKey:@"content"];
|
||||
_disableSetContent = YES;
|
||||
|
||||
var sortedPaths = [indexPaths sortedArrayUsingSelector:@selector(compare:)],
|
||||
count = [sortedPaths count];
|
||||
count = [sortedPaths count];
|
||||
|
||||
for (var i = count - 1; i >= 0; i--)
|
||||
{
|
||||
var path = [sortedPaths objectAtIndex:i],
|
||||
length = [path length];
|
||||
length = [path length];
|
||||
|
||||
if (length === 1)
|
||||
{
|
||||
@@ -620,15 +603,15 @@
|
||||
else
|
||||
{
|
||||
var parentPath = [path indexPathByRemovingLastIndex],
|
||||
parentNode = [[self arrangedObjects] descendantNodeAtIndexPath:parentPath];
|
||||
parentNode = [[self arrangedObjects] descendantNodeAtIndexPath:parentPath];
|
||||
|
||||
if (parentNode)
|
||||
{
|
||||
var parentObj = [parentNode representedObject],
|
||||
childIndex = [path indexAtPosition:length - 1],
|
||||
mutableChildren = [parentObj mutableArrayValueForKeyPath:_childrenKeyPath];
|
||||
childIndex = [path indexAtPosition:length - 1],
|
||||
mutableChildren = [parentObj mutableArrayValueForKeyPath:_childrenKeyPath];
|
||||
|
||||
if (mutableChildren && childIndex < [mutableChildren count])
|
||||
if (mutableChildren && childIndex <[mutableChildren count])
|
||||
[mutableChildren removeObjectAtIndex:childIndex];
|
||||
}
|
||||
}
|
||||
@@ -641,7 +624,6 @@
|
||||
_disableSetContent = NO;
|
||||
[self _rearrangeObjects];
|
||||
[self didChangeValueForKey:@"content"];
|
||||
[self _selectionDidChange];
|
||||
}
|
||||
|
||||
- (void)moveNode:(CPTreeNode)node toIndexPath:(CPIndexPath)indexPath
|
||||
@@ -650,19 +632,18 @@
|
||||
}
|
||||
|
||||
- (void)moveNodes:(CPArray)nodes toIndexPath:(CPIndexPath)startingIndexPath
|
||||
{
|
||||
[CPException raise:CPUnsupportedMethodException reason:@"moveNodes:toIndexPath: is not yet implemented in CPTreeController."];
|
||||
{[CPException raise:CPUnsupportedMethodException reason:@"moveNodes:toIndexPath: is not yet implemented in CPTreeController."];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
var CPTreeControllerAvoidsEmptySelection = @"CPTreeControllerAvoidsEmptySelection",
|
||||
CPTreeControllerPreservesSelection = @"CPTreeControllerPreservesSelection",
|
||||
CPTreeControllerSelectsInsertedObjects = @"CPTreeControllerSelectsInsertedObjects",
|
||||
CPTreeControllerAlwaysUsesMultipleValuesMarker = @"CPTreeControllerAlwaysUsesMultipleValuesMarker",
|
||||
CPTreeControllerChildrenKeyPath = @"CPTreeControllerChildrenKeyPath",
|
||||
CPTreeControllerCountKeyPath = @"CPTreeControllerCountKeyPath",
|
||||
CPTreeControllerLeafKeyPath = @"CPTreeControllerLeafKeyPath";
|
||||
CPTreeControllerPreservesSelection = @"CPTreeControllerPreservesSelection",
|
||||
CPTreeControllerSelectsInsertedObjects = @"CPTreeControllerSelectsInsertedObjects",
|
||||
CPTreeControllerAlwaysUsesMultipleValuesMarker = @"CPTreeControllerAlwaysUsesMultipleValuesMarker",
|
||||
CPTreeControllerChildrenKeyPath = @"CPTreeControllerChildrenKeyPath",
|
||||
CPTreeControllerCountKeyPath = @"CPTreeControllerCountKeyPath",
|
||||
CPTreeControllerLeafKeyPath = @"CPTreeControllerLeafKeyPath";
|
||||
|
||||
@implementation CPTreeController (CPCoding)
|
||||
|
||||
|
||||
+64
-299
@@ -17,41 +17,17 @@
|
||||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
@import <Foundation/CPObject.j>
|
||||
@import <Foundation/CPIndexPath.j>
|
||||
@import <Foundation/CPArray.j>
|
||||
|
||||
/*
|
||||
* CPTreeNode implements the NSTreeNode contract.
|
||||
* The _childNodes array contains only CPTreeNode instances.
|
||||
* The representedObject property contains the application data.
|
||||
* The _parentNode and _childNodes properties maintain a strict bidirectional relationship.
|
||||
* The KVC mutation methods are the public mechanism to change the tree structure.
|
||||
*/
|
||||
@implementation CPTreeNode : CPObject
|
||||
{
|
||||
/*
|
||||
* KVO notifications on parentNode are never delivered: there is no
|
||||
* setParentNode: for the swizzling machinery to intercept, so there is
|
||||
* no selector to instrument, in any code path.
|
||||
*
|
||||
* KVO notifications on childNodes are reliable for
|
||||
* insertObject:inChildNodesAtIndex:, including same-parent and
|
||||
* cross-parent moves: all detach paths for that method route through
|
||||
* the KVC accessors. replaceObjectInChildNodesAtIndex:withObject:
|
||||
* still detaches a same-parent replacement node by mutating
|
||||
* _childNodes directly, bypassing the KVC proxy for that step; an
|
||||
* observer of that node's former parent's childNodes can miss that
|
||||
* specific removal, or see it reported as the wrong kind of change.
|
||||
* Do not rely on childNodes observation during a same-parent replace;
|
||||
* rely only on the state after the call returns.
|
||||
*/
|
||||
id _representedObject @accessors(readonly, property=representedObject);
|
||||
CPTreeNode _parentNode @accessors(readonly, property=parentNode);
|
||||
id _representedObject @accessors(property=representedObject);
|
||||
CPTreeNode _parentNode @accessors(property=parentNode);
|
||||
CPMutableArray _childNodes;
|
||||
}
|
||||
|
||||
@@ -73,107 +49,27 @@
|
||||
return self;
|
||||
}
|
||||
|
||||
/*
|
||||
* Route plain init through the designated initializer.
|
||||
* Without this override, [[CPTreeNode alloc] init] leaves _childNodes unset.
|
||||
* The first mutation call then fails against an undefined array.
|
||||
*/
|
||||
- (id)init
|
||||
{
|
||||
return [self initWithRepresentedObject:nil];
|
||||
}
|
||||
|
||||
/*
|
||||
* Return YES if adding aTreeNode below self makes a cycle.
|
||||
* This method walks the parent chain.
|
||||
* The operation time is proportional to the tree depth.
|
||||
*/
|
||||
- (BOOL)_wouldCreateCycleWithNode:(CPTreeNode)aTreeNode
|
||||
{
|
||||
for (var node = self; node; node = node._parentNode)
|
||||
{
|
||||
if (node === aTreeNode)
|
||||
return YES;
|
||||
}
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
/*
|
||||
* Enforce the NSTreeNode abstraction boundary.
|
||||
* All children must be CPTreeNode instances.
|
||||
*/
|
||||
- (void)_validateChildNode:(id)aTreeNode
|
||||
{
|
||||
if (![aTreeNode isKindOfClass:[CPTreeNode class]])
|
||||
{
|
||||
[CPException raise:CPInvalidArgumentException
|
||||
reason:"CPTreeNode children must be CPTreeNode instances."];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove a child node by delegating to the public KVC accessor.
|
||||
* Use this method for internal structural changes across a parent
|
||||
* boundary, so an observer of this node's childNodes sees the removal.
|
||||
*/
|
||||
- (void)_removeChildNode:(CPTreeNode)aNode
|
||||
{
|
||||
var index = [_childNodes indexOfObjectIdenticalTo:aNode];
|
||||
|
||||
/*
|
||||
* A caller reaches this method only when aNode.parentNode already equals
|
||||
* self (see the two call sites below). If self._childNodes does not
|
||||
* actually contain aNode at that point, the parent/child relationship
|
||||
* is already broken. indexPath raises for this identical class of
|
||||
* inconsistency; silently returning here would hide the same problem
|
||||
* instead of surfacing it.
|
||||
*/
|
||||
if (index === CPNotFound)
|
||||
{
|
||||
[CPException raise:CPInternalInconsistencyException
|
||||
reason:"CPTreeNode parent and child relationship is inconsistent."];
|
||||
}
|
||||
|
||||
[self removeObjectFromChildNodesAtIndex:index];
|
||||
}
|
||||
|
||||
- (CPIndexPath)indexPath
|
||||
{
|
||||
if (!_parentNode)
|
||||
return [CPIndexPath indexPathWithIndexes:[]];
|
||||
|
||||
var indexes = [],
|
||||
node = self;
|
||||
|
||||
while (node._parentNode)
|
||||
// If we have a parent, calculate path based on parent's path + our index
|
||||
if (_parentNode)
|
||||
{
|
||||
var parent = node._parentNode,
|
||||
index = [parent._childNodes indexOfObjectIdenticalTo:node];
|
||||
|
||||
if (index === CPNotFound)
|
||||
{
|
||||
[CPException raise:CPInternalInconsistencyException
|
||||
reason:"CPTreeNode parent and child relationship is inconsistent."];
|
||||
}
|
||||
|
||||
[indexes addObject:index];
|
||||
node = parent;
|
||||
// Search the parent's child nodes, not our own!
|
||||
var index = [[_parentNode childNodes] indexOfObjectIdenticalTo:self];
|
||||
|
||||
// If the parent is the root (and technically has no path itself in some implementations),
|
||||
// we might get nil. Handle that gracefully.
|
||||
var parentPath = [_parentNode indexPath];
|
||||
|
||||
if (parentPath)
|
||||
return [parentPath indexPathByAddingIndex:index];
|
||||
|
||||
return [CPIndexPath indexPathWithIndex:index];
|
||||
}
|
||||
|
||||
/*
|
||||
* indexes was collected leaf-to-root. Build a second array in
|
||||
* root-to-leaf order by walking indexes backward. CPArray has no
|
||||
* -reverse selector; count/objectAtIndex:/addObject: are the verified,
|
||||
* already-used-elsewhere primitives.
|
||||
*/
|
||||
var orderedIndexes = [],
|
||||
count = [indexes count];
|
||||
|
||||
while (count--)
|
||||
[orderedIndexes addObject:[indexes objectAtIndex:count]];
|
||||
|
||||
return [CPIndexPath indexPathWithIndexes:orderedIndexes];
|
||||
|
||||
// If we are the root, we don't have an index path in the context of a tree controller usually,
|
||||
// or we are [] (empty path). Returning nil is acceptable for the absolute root.
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (BOOL)isLeaf
|
||||
@@ -183,10 +79,7 @@
|
||||
|
||||
- (CPArray)childNodes
|
||||
{
|
||||
/*
|
||||
* Return a copy.
|
||||
* This prevents external changes that bypass the KVC methods.
|
||||
*/
|
||||
// Return a copy to prevent external modification without KVC
|
||||
return [_childNodes copy];
|
||||
}
|
||||
|
||||
@@ -195,190 +88,78 @@
|
||||
return [self mutableArrayValueForKey:@"childNodes"];
|
||||
}
|
||||
|
||||
/*
|
||||
* KVC compliance methods.
|
||||
* The mutableArrayValueForKey: method uses these names.
|
||||
*/
|
||||
// MARK: - KVC Compliance Methods
|
||||
|
||||
- (void)insertObject:(CPTreeNode)aTreeNode inChildNodesAtIndex:(CPInteger)anIndex
|
||||
{
|
||||
var count = [_childNodes count];
|
||||
|
||||
if (anIndex < 0 || anIndex > count)
|
||||
// Optional: Auto-detach from old parent if strictly moving nodes
|
||||
if ([aTreeNode isKindOfClass:[CPTreeNode class]] && aTreeNode._parentNode)
|
||||
{
|
||||
[CPException raise:CPRangeException
|
||||
reason:"index (" + anIndex + ") beyond bounds (0 .. " + count + ") for insertObject:inChildNodesAtIndex:"];
|
||||
[[aTreeNode._parentNode mutableChildNodes] removeObjectIdenticalTo:aTreeNode];
|
||||
}
|
||||
|
||||
[self _validateChildNode:aTreeNode];
|
||||
// Direct ivar access is allowed here since we are inside the class implementation
|
||||
if ([aTreeNode isKindOfClass:[CPTreeNode class]])
|
||||
aTreeNode._parentNode = self;
|
||||
|
||||
if ([self _wouldCreateCycleWithNode:aTreeNode])
|
||||
{
|
||||
[CPException raise:CPInvalidArgumentException
|
||||
reason:"Inserting a CPTreeNode beneath itself or one of its descendants makes a cycle."];
|
||||
}
|
||||
|
||||
/*
|
||||
* Detach the node from its old parent first.
|
||||
* The code validated the index before this change.
|
||||
*/
|
||||
if (aTreeNode._parentNode)
|
||||
{
|
||||
if (aTreeNode._parentNode === self)
|
||||
{
|
||||
var originalIndex = [_childNodes indexOfObjectIdenticalTo:aTreeNode];
|
||||
|
||||
/*
|
||||
* Route the detach through the KVC accessor, not direct array
|
||||
* mutation, so an observer of childNodes sees the removal.
|
||||
*/
|
||||
[self removeObjectFromChildNodesAtIndex:originalIndex];
|
||||
|
||||
/*
|
||||
* No index adjustment here. anIndex is the target position in
|
||||
* the final array, per the KVC to-many contract. The array
|
||||
* above is already one element short from the removal, so
|
||||
* inserting at anIndex against it lands the node correctly.
|
||||
*/
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Detach the node from its old parent.
|
||||
* Use the internal method to bypass KVO overhead.
|
||||
*/
|
||||
[aTreeNode._parentNode _removeChildNode:aTreeNode];
|
||||
}
|
||||
}
|
||||
|
||||
aTreeNode._parentNode = self;
|
||||
[_childNodes insertObject:aTreeNode atIndex:anIndex];
|
||||
}
|
||||
|
||||
- (void)removeObjectFromChildNodesAtIndex:(CPInteger)anIndex
|
||||
{
|
||||
var node = [_childNodes objectAtIndex:anIndex];
|
||||
|
||||
if ([node isKindOfClass:[CPTreeNode class]])
|
||||
node._parentNode = nil;
|
||||
|
||||
node._parentNode = nil;
|
||||
[_childNodes removeObjectAtIndex:anIndex];
|
||||
}
|
||||
|
||||
- (void)replaceObjectInChildNodesAtIndex:(CPInteger)anIndex withObject:(CPTreeNode)aTreeNode
|
||||
- (void)replaceObjectFromChildNodesAtIndex:(CPInteger)anIndex withObject:(id)aTreeNode
|
||||
{
|
||||
var oldTreeNode = [_childNodes objectAtIndex:anIndex];
|
||||
|
||||
[self _validateChildNode:aTreeNode];
|
||||
|
||||
if (oldTreeNode === aTreeNode)
|
||||
return;
|
||||
|
||||
if ([self _wouldCreateCycleWithNode:aTreeNode])
|
||||
{
|
||||
[CPException raise:CPInvalidArgumentException
|
||||
reason:"Replacing a child with itself or one of its ancestors makes a cycle."];
|
||||
}
|
||||
|
||||
/*
|
||||
* If the replacement node is already a child of this parent, remove it first.
|
||||
* The removal shifts the array elements.
|
||||
* Adjust the target index before the replace operation.
|
||||
* This matches the Cocoa KVC mutation semantics.
|
||||
*/
|
||||
var oldParent = aTreeNode._parentNode;
|
||||
|
||||
if (oldParent === self)
|
||||
{
|
||||
var replacementIndex = [_childNodes indexOfObjectIdenticalTo:aTreeNode];
|
||||
|
||||
/*
|
||||
* aTreeNode.parentNode already equals self at this point. If
|
||||
* self._childNodes does not actually contain aTreeNode, the
|
||||
* parent/child relationship is already broken. indexPath raises
|
||||
* for this identical class of inconsistency; proceeding here would
|
||||
* silently tolerate the same problem instead of surfacing it.
|
||||
*/
|
||||
if (replacementIndex === CPNotFound)
|
||||
{
|
||||
[CPException raise:CPInternalInconsistencyException
|
||||
reason:"CPTreeNode parent and child relationship is inconsistent."];
|
||||
}
|
||||
|
||||
/*
|
||||
* Bypass KVO for this internal structural adjustment.
|
||||
*/
|
||||
aTreeNode._parentNode = nil;
|
||||
[_childNodes removeObjectAtIndex:replacementIndex];
|
||||
|
||||
/*
|
||||
* Unlike insertObject:inChildNodesAtIndex:, anIndex here cannot be
|
||||
* treated as a plain final-array position: replace requires an
|
||||
* existing slot, it cannot append past the end. The removal above
|
||||
* already took a slot out of the array ahead of the target
|
||||
* whenever the replacement's original position was before it.
|
||||
* Shift anIndex down by one in that case, to keep it pointing at
|
||||
* the same physical slot the caller named.
|
||||
*/
|
||||
if (replacementIndex < anIndex)
|
||||
--anIndex;
|
||||
}
|
||||
else if (oldParent)
|
||||
{
|
||||
/*
|
||||
* Detach the node from its old parent.
|
||||
* Use the internal method to bypass KVO overhead.
|
||||
*/
|
||||
[oldParent _removeChildNode:aTreeNode];
|
||||
}
|
||||
|
||||
oldTreeNode._parentNode = nil;
|
||||
aTreeNode._parentNode = self;
|
||||
if ([oldTreeNode isKindOfClass:[CPTreeNode class]])
|
||||
oldTreeNode._parentNode = nil;
|
||||
|
||||
if ([aTreeNode isKindOfClass:[CPTreeNode class]])
|
||||
aTreeNode._parentNode = self;
|
||||
|
||||
[_childNodes replaceObjectAtIndex:anIndex withObject:aTreeNode];
|
||||
}
|
||||
|
||||
// MARK: - Convenience Accessors
|
||||
|
||||
- (id)objectInChildNodesAtIndex:(CPInteger)anIndex
|
||||
{
|
||||
return [_childNodes objectAtIndex:anIndex];
|
||||
}
|
||||
|
||||
- (CPInteger)countOfChildNodes
|
||||
- (CPInteger)count
|
||||
{
|
||||
return [_childNodes count];
|
||||
}
|
||||
|
||||
- (id)objectAtIndex:(CPInteger)anIndex
|
||||
{
|
||||
return [_childNodes objectAtIndex:anIndex];
|
||||
}
|
||||
|
||||
// MARK: - Utility
|
||||
|
||||
- (void)sortWithSortDescriptors:(CPArray)sortDescriptors recursively:(BOOL)shouldSortRecursively
|
||||
{
|
||||
[_childNodes sortUsingDescriptors:sortDescriptors];
|
||||
|
||||
if (!shouldSortRecursively)
|
||||
{
|
||||
[_childNodes sortUsingDescriptors:sortDescriptors];
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Use an explicit stack, not recursion.
|
||||
* The recursive form is not a tail call.
|
||||
* The sibling loop continues after each child call returns.
|
||||
* Only JavaScriptCore performs tail call optimization.
|
||||
* The explicit stack prevents stack overflow on deep trees.
|
||||
*/
|
||||
var stack = [];
|
||||
|
||||
[stack addObject:self];
|
||||
|
||||
while ([stack count])
|
||||
var count = [_childNodes count];
|
||||
while (count--)
|
||||
{
|
||||
var node = [stack lastObject];
|
||||
|
||||
[stack removeLastObject];
|
||||
|
||||
[node._childNodes sortUsingDescriptors:sortDescriptors];
|
||||
|
||||
var count = [node._childNodes count];
|
||||
|
||||
while (count--)
|
||||
{
|
||||
[stack addObject:[node._childNodes objectAtIndex:count]];
|
||||
}
|
||||
var child = [_childNodes objectAtIndex:count];
|
||||
if ([child respondsToSelector:@selector(sortWithSortDescriptors:recursively:)])
|
||||
[child sortWithSortDescriptors:sortDescriptors recursively:YES];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -388,17 +169,17 @@
|
||||
return self;
|
||||
|
||||
var node = self,
|
||||
length = [indexPath length];
|
||||
length = [indexPath length];
|
||||
|
||||
for (var i = 0; i < length; i++)
|
||||
{
|
||||
var index = [indexPath indexAtPosition:i],
|
||||
count = [node countOfChildNodes];
|
||||
|
||||
if (index < 0 || index >= count)
|
||||
count = [node count];
|
||||
|
||||
if (index >= count || index < 0)
|
||||
return nil;
|
||||
|
||||
node = [node objectInChildNodesAtIndex:index];
|
||||
|
||||
node = [node objectAtIndex:index];
|
||||
}
|
||||
|
||||
return node;
|
||||
@@ -406,6 +187,7 @@
|
||||
|
||||
@end
|
||||
|
||||
// Coding implementation remains correct
|
||||
var CPTreeNodeRepresentedObjectKey = @"CPTreeNodeRepresentedObjectKey",
|
||||
CPTreeNodeParentNodeKey = @"CPTreeNodeParentNodeKey",
|
||||
CPTreeNodeChildNodesKey = @"CPTreeNodeChildNodesKey";
|
||||
@@ -421,27 +203,10 @@ var CPTreeNodeRepresentedObjectKey = @"CPTreeNodeRepresentedObjectKey",
|
||||
_representedObject = [aCoder decodeObjectForKey:CPTreeNodeRepresentedObjectKey];
|
||||
_parentNode = [aCoder decodeObjectForKey:CPTreeNodeParentNodeKey];
|
||||
_childNodes = [aCoder decodeObjectForKey:CPTreeNodeChildNodesKey];
|
||||
|
||||
|
||||
// Safety check to ensure decoding gave us a CPArray
|
||||
if (!_childNodes)
|
||||
_childNodes = [];
|
||||
|
||||
if (![_childNodes isKindOfClass:[CPMutableArray class]])
|
||||
_childNodes = [_childNodes mutableCopy];
|
||||
|
||||
/*
|
||||
* The child array is the authoritative structure.
|
||||
* Re-establish the parent links.
|
||||
* This makes the decoded tree match the tree built by the mutation methods.
|
||||
*/
|
||||
var count = [_childNodes count];
|
||||
|
||||
while (count--)
|
||||
{
|
||||
var child = [_childNodes objectAtIndex:count];
|
||||
|
||||
[self _validateChildNode:child];
|
||||
child._parentNode = self;
|
||||
}
|
||||
_childNodes = [[CPMutableArray alloc] init];
|
||||
}
|
||||
|
||||
return self;
|
||||
|
||||
+36
-21
@@ -334,8 +334,9 @@ var CPViewHighDPIDrawingEnabled = YES;
|
||||
{
|
||||
return @{
|
||||
@"css-based": NO,
|
||||
@"dynamic-set": [CPNull null],
|
||||
@"nib2cib-adjustment-frame": CGRectMakeZero()
|
||||
@"nib2cib-adjustment-frame": [CPNull null],
|
||||
@"direct-nib2cib-adjustment": NO,
|
||||
@"dynamic-set": [CPNull null]
|
||||
};
|
||||
}
|
||||
|
||||
@@ -928,6 +929,13 @@ var CPViewHighDPIDrawingEnabled = YES;
|
||||
*/
|
||||
- (void)viewDidMoveToWindow
|
||||
{
|
||||
var window = [self window];
|
||||
|
||||
// If the view is inside a window with the HUD style mask, turn on the HUD state
|
||||
if (window && ([window styleMask] & CPHUDBackgroundWindowMask))
|
||||
[self setThemeState:CPThemeStateHUD];
|
||||
else
|
||||
[self unsetThemeState:CPThemeStateHUD];
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -1474,24 +1482,6 @@ var CPViewHighDPIDrawingEnabled = YES;
|
||||
origin.y *= size.height / frameSize.height;
|
||||
}
|
||||
|
||||
var newScaleSize;
|
||||
|
||||
if (size && size.width !== 0 && size.height !== 0 && frameSize)
|
||||
newScaleSize = CGSizeMake(frameSize.width / size.width, frameSize.height / size.height);
|
||||
else
|
||||
newScaleSize = CGSizeMake(1.0, 1.0);
|
||||
|
||||
// Only update and propagate if the scale factor has actually changed
|
||||
if (!CGSizeEqualToSize(_scaleSize, newScaleSize))
|
||||
{
|
||||
[self willChangeValueForKey:@"scaleSize"];
|
||||
_scaleSize = newScaleSize;
|
||||
_isScaled = (_scaleSize.width !== 1.0 || _scaleSize.height !== 1.0);
|
||||
[self didChangeValueForKey:@"scaleSize"];
|
||||
|
||||
[self _scaleSizeUnitSquareToSize:CGSizeMake(1.0, 1.0)];
|
||||
}
|
||||
|
||||
if (_layer)
|
||||
[_layer _owningViewBoundsChanged];
|
||||
|
||||
@@ -1505,6 +1495,7 @@ var CPViewHighDPIDrawingEnabled = YES;
|
||||
[self _updateTrackingAreasWithRecursion:YES];
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
Notifies subviews that the superview changed size.
|
||||
@param aSize the size of the old superview
|
||||
@@ -2623,7 +2614,7 @@ setBoundsOrigin:
|
||||
*/
|
||||
- (void)_scaleSizeUnitSquareToSize:(CGSize)aSize
|
||||
{
|
||||
_hierarchyScaleSize = _superview ? CGSizeMakeCopy([_superview _hierarchyScaleSize]) : CGSizeMake(1.0, 1.0);
|
||||
_hierarchyScaleSize = CGSizeMakeCopy([_superview _hierarchyScaleSize]);
|
||||
|
||||
if (_isScaled)
|
||||
{
|
||||
@@ -4188,3 +4179,27 @@ var _CPViewGetTransform = function(/*CPView*/ fromView, /*CPView */ toView)
|
||||
|
||||
return transform;
|
||||
};
|
||||
|
||||
@implementation CPView (ThemingAdditions)
|
||||
|
||||
- (void)_setThemeStateRecursively:(ThemeState)aState
|
||||
{
|
||||
[_subviews makeObjectsPerformSelector:@selector(_setThemeStateRecursively:) withObject:aState];
|
||||
|
||||
[_subviews enumerateObjectsUsingBlock:function(view, idx, stop)
|
||||
{
|
||||
[view setThemeState:aState];
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)_unsetThemeStateRecursively:(ThemeState)aState
|
||||
{
|
||||
[_subviews makeObjectsPerformSelector:@selector(_unsetThemeStateRecursively:) withObject:aState];
|
||||
|
||||
[_subviews enumerateObjectsUsingBlock:function(view, idx, stop)
|
||||
{
|
||||
[view unsetThemeState:aState];
|
||||
}];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
+34
-11
@@ -28,6 +28,8 @@ CPViewAnimationTargetKey = @"CPViewAnimationTargetKey";
|
||||
CPViewAnimationStartFrameKey = @"CPViewAnimationStartFrameKey";
|
||||
CPViewAnimationEndFrameKey = @"CPViewAnimationEndFrameKey";
|
||||
CPViewAnimationEffectKey = @"CPViewAnimationEffectKey";
|
||||
CPViewAnimationStartOpacityKey = @"CPViewAnimationStartOpacityKey";
|
||||
CPViewAnimationEndOpacityKey = @"CPViewAnimationEndOpacityKey";
|
||||
|
||||
CPViewAnimationFadeInEffect = @"CPViewAnimationFadeInEffect";
|
||||
CPViewAnimationFadeOutEffect = @"CPViewAnimationFadeOutEffect";
|
||||
@@ -132,12 +134,24 @@ CPViewAnimationFadeOutEffect = @"CPViewAnimationFadeOutEffect";
|
||||
|
||||
[view setFrame:intermediateFrame];
|
||||
|
||||
// Update the view's alpha value
|
||||
var effect = [self _effect:dictionary];
|
||||
if (effect === CPViewAnimationFadeInEffect)
|
||||
[view setAlphaValue:1.0 * value];
|
||||
else if (effect === CPViewAnimationFadeOutEffect)
|
||||
[view setAlphaValue:1.0 + ( 0.0 - 1.0 ) * value];
|
||||
// Check for explicit Opacity keys first
|
||||
var startOpacity = [dictionary objectForKey:CPViewAnimationStartOpacityKey],
|
||||
endOpacity = [dictionary objectForKey:CPViewAnimationEndOpacityKey];
|
||||
|
||||
if (startOpacity != nil && endOpacity != nil)
|
||||
{
|
||||
// Interpolate alpha
|
||||
[view setAlphaValue:startOpacity + (endOpacity - startOpacity) * value];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Fallback to legacy Effect keys
|
||||
var effect = [self _effect:dictionary];
|
||||
if (effect === CPViewAnimationFadeInEffect)
|
||||
[view setAlphaValue:1.0 * value];
|
||||
else if (effect === CPViewAnimationFadeOutEffect)
|
||||
[view setAlphaValue:1.0 + ( 0.0 - 1.0 ) * value];
|
||||
}
|
||||
|
||||
if (progress === 1.0)
|
||||
[self _targetView:view setHidden:CGRectIsEmpty(endFrame) || [view alphaValue] === 0.0];
|
||||
@@ -155,11 +169,20 @@ CPViewAnimationFadeOutEffect = @"CPViewAnimationFadeOutEffect";
|
||||
|
||||
[view setFrame:endFrame];
|
||||
|
||||
var effect = [self _effect:dictionary];
|
||||
if (effect === CPViewAnimationFadeInEffect)
|
||||
[view setAlphaValue:1.0];
|
||||
else if (effect === CPViewAnimationFadeOutEffect)
|
||||
[view setAlphaValue:0.0];
|
||||
var endOpacity = [dictionary objectForKey:CPViewAnimationEndOpacityKey];
|
||||
|
||||
if (endOpacity != nil)
|
||||
{
|
||||
[view setAlphaValue:endOpacity];
|
||||
}
|
||||
else
|
||||
{
|
||||
var effect = [self _effect:dictionary];
|
||||
if (effect === CPViewAnimationFadeInEffect)
|
||||
[view setAlphaValue:1.0];
|
||||
else if (effect === CPViewAnimationFadeOutEffect)
|
||||
[view setAlphaValue:0.0];
|
||||
}
|
||||
|
||||
[self _targetView:view setHidden:CGRectIsEmpty(endFrame) || [view alphaValue] === 0.0];
|
||||
}
|
||||
|
||||
@@ -979,6 +979,9 @@ CPTexturedBackgroundWindowMask
|
||||
- (void)orderFront:(id)aSender
|
||||
{
|
||||
[self orderWindow:CPWindowAbove relativeTo:0];
|
||||
|
||||
if (_styleMask & CPHUDBackgroundWindowMask)
|
||||
[_contentView _setThemeStateRecursively:CPThemeStateHUD];
|
||||
}
|
||||
|
||||
- (void)_orderFront
|
||||
@@ -2539,6 +2542,10 @@ CPTexturedBackgroundWindowMask
|
||||
|
||||
[[CPNotificationCenter defaultCenter] postNotificationName:CPWindowWillCloseNotification object:self];
|
||||
|
||||
// Give a chance to the _windowView to do things before closing (for example, remove an observer)
|
||||
if ([_windowView respondsToSelector:@selector(_close)])
|
||||
[_windowView _close];
|
||||
|
||||
[_parentWindow removeChildWindow:self];
|
||||
[self _orderOutRecursively:NO];
|
||||
[self _detachFromChildrenClosing:!_parentWindow];
|
||||
|
||||
@@ -39,6 +39,22 @@
|
||||
};
|
||||
}
|
||||
|
||||
- (id)initWithFrame:(CGRect)aFrame styleMask:(unsigned)aStyleMask
|
||||
{
|
||||
self = [super initWithFrame:aFrame styleMask:aStyleMask];
|
||||
|
||||
if (self)
|
||||
{
|
||||
// Check if the mask contains the HUD flag
|
||||
if (aStyleMask & CPHUDBackgroundWindowMask)
|
||||
{
|
||||
[self setBackgroundColor:[CPColor blackColor]];
|
||||
}
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)setShowsResizeIndicator:(BOOL)shouldShowResizeIndicator
|
||||
{
|
||||
// We don't ever want to show the resize indicator.
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
@import "CPButton.j"
|
||||
@import "_CPTitleableWindowView.j"
|
||||
@import "CPApplication_Constants.j"
|
||||
|
||||
@class _CPDocModalWindowView
|
||||
|
||||
@@ -43,7 +44,11 @@ var _CPStandardWindowViewDividerViewHeight = 1.0;
|
||||
|
||||
+ (CPDictionary)themeAttributes
|
||||
{
|
||||
return @{};
|
||||
return @{
|
||||
@"close-active-image-button": [CPNull null],
|
||||
@"minimize-active-image-button": [CPNull null],
|
||||
@"zoom-active-image-button": [CPNull null],
|
||||
};
|
||||
}
|
||||
|
||||
- (id)initWithFrame:(CGRect)aFrame windowView:(_CPWindowView)parentView
|
||||
@@ -71,19 +76,26 @@ var _CPStandardWindowViewDividerViewHeight = 1.0;
|
||||
bounds = [self bounds],
|
||||
bezelHeadColor = [[CPTheme defaultTheme] valueForAttributeWithName:_isSheet ? @"bezel-head-sheet-color" : @"bezel-head-color" inState:[_parentView themeState] forClass:_CPStandardWindowView];
|
||||
|
||||
[_gradientView setFrame:CGRectMake(0.0, 0.0, CGRectGetWidth(bounds), gradientHeight)];
|
||||
[_gradientView setBackgroundColor:bezelHeadColor];
|
||||
// Apply the border/background color to self (the container) so borders are drawn on the outside
|
||||
[self setBackgroundColor:bezelHeadColor];
|
||||
|
||||
[_solidView setFrame:CGRectMake(0.0, gradientHeight, CGRectGetWidth(bounds), CGRectGetHeight(bounds) - gradientHeight)];
|
||||
// Set x=0.0 to avoid 1px gap. Width is reduced by 2.0 to fit inside the 1px borders on each side.
|
||||
[_gradientView setFrame:CGRectMake(0.0, 0.0, CGRectGetWidth(bounds) - 2.0, gradientHeight)];
|
||||
|
||||
// Set x=0.0 to avoid 1px gap. Width is reduced by 2.0.
|
||||
[_solidView setFrame:CGRectMake(0.0, gradientHeight, CGRectGetWidth(bounds) - 2.0, CGRectGetHeight(bounds) - gradientHeight)];
|
||||
[_solidView setBackgroundColor:[[CPTheme defaultTheme] valueForAttributeWithName:@"solid-color" forClass:_CPStandardWindowView]];
|
||||
}
|
||||
|
||||
- (void)resizeSubviewsWithOldSize:(CGSize)aSize
|
||||
{
|
||||
var bounds = [self bounds];
|
||||
var bounds = [self bounds],
|
||||
width = CGRectGetWidth(bounds) - 2.0; // Account for border inset
|
||||
|
||||
[_gradientView setFrameSize:CGSizeMake(CGRectGetWidth(bounds), [[CPTheme defaultTheme] valueForAttributeWithName:@"gradient-height" forClass:_CPStandardWindowView])];
|
||||
[_solidView setFrameSize:CGSizeMake(CGRectGetWidth(bounds), CGRectGetHeight(bounds) - [[CPTheme defaultTheme] valueForAttributeWithName:@"gradient-height" forClass:_CPStandardWindowView])];
|
||||
if (width < 0) width = 0;
|
||||
|
||||
[_gradientView setFrameSize:CGSizeMake(width, [[CPTheme defaultTheme] valueForAttributeWithName:@"gradient-height" forClass:_CPStandardWindowView])];
|
||||
[_solidView setFrameSize:CGSizeMake(width, CGRectGetHeight(bounds) - [[CPTheme defaultTheme] valueForAttributeWithName:@"gradient-height" forClass:_CPStandardWindowView])];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -97,9 +109,16 @@ var _CPStandardWindowViewDividerViewHeight = 1.0;
|
||||
|
||||
CPButton _closeButton;
|
||||
CPButton _minimizeButton;
|
||||
CPButton _zoomButton;
|
||||
|
||||
BOOL _isDocumentEdited;
|
||||
BOOL _isSheet;
|
||||
|
||||
CPTrackingArea _closeButtonTrackingArea;
|
||||
CPTrackingArea _minimizeButtonTrackingArea;
|
||||
CPTrackingArea _zoomButtonTrackingArea;
|
||||
|
||||
int _buttonsWidth;
|
||||
}
|
||||
|
||||
+ (CPString)defaultThemeClass
|
||||
@@ -123,6 +142,8 @@ var _CPStandardWindowViewDividerViewHeight = 1.0;
|
||||
@"close-image-highlighted-button": [CPNull null],
|
||||
@"unsaved-image-button": [CPNull null],
|
||||
@"unsaved-image-highlighted-button": [CPNull null],
|
||||
@"zoom-image-button": [CPNull null],
|
||||
@"zoom-image-highlighted-button": [CPNull null]
|
||||
};
|
||||
}
|
||||
|
||||
@@ -154,7 +175,7 @@ var _CPStandardWindowViewDividerViewHeight = 1.0;
|
||||
var theClass = [self class],
|
||||
bounds = [self bounds];
|
||||
|
||||
_headView = [[_CPTexturedWindowHeadView alloc] initWithFrame:CGRectMake(0.0, 0.0, CGRectGetWidth(bounds), [self valueForThemeAttribute:@"title-bar-height"]) windowView:self];
|
||||
_headView = [[_CPTexturedWindowHeadView alloc] initWithFrame:CGRectMake(0.0, 0.0, CGRectGetWidth(bounds), _titleBarHeight) windowView:self];
|
||||
|
||||
[_headView setAutoresizingMask:CPViewWidthSizable];
|
||||
[_headView setHitTests:NO];
|
||||
@@ -181,30 +202,50 @@ var _CPStandardWindowViewDividerViewHeight = 1.0;
|
||||
|
||||
if (_styleMask & CPClosableWindowMask)
|
||||
{
|
||||
_closeButton = [[CPButton alloc] initWithFrame:CGRectMake(8.0, 8.0, 16.0, 16.0)];
|
||||
_closeButton = [[CPButton alloc] initWithFrame:CGRectMakeZero()];
|
||||
|
||||
[_closeButton setButtonType:CPMomentaryChangeButton];
|
||||
[_closeButton setBordered:NO];
|
||||
[self _updateCloseButton];
|
||||
|
||||
[self addSubview:_closeButton];
|
||||
}
|
||||
|
||||
if (_styleMask & CPMiniaturizableWindowMask && ![CPPlatform isBrowser])
|
||||
if (_styleMask & CPMiniaturizableWindowMask)
|
||||
{
|
||||
_minimizeButton = [[CPButton alloc] initWithFrame:CGRectMake(27.0, 7.0, 16.0, 16.0)];
|
||||
_minimizeButton = [[CPButton alloc] initWithFrame:CGRectMakeZero()];
|
||||
|
||||
[_minimizeButton setButtonType:CPMomentaryChangeButton];
|
||||
[_minimizeButton setBordered:NO];
|
||||
|
||||
[self addSubview:_minimizeButton];
|
||||
}
|
||||
|
||||
if (_styleMask & CPResizableWindowMask)
|
||||
{
|
||||
_zoomButton = [[CPButton alloc] initWithFrame:CGRectMakeZero()];
|
||||
|
||||
[_zoomButton setButtonType:CPMomentaryChangeButton];
|
||||
[_zoomButton setBordered:NO];
|
||||
|
||||
[self addSubview:_zoomButton];
|
||||
}
|
||||
|
||||
[self _updateWindowButtons:YES];
|
||||
[self tile];
|
||||
|
||||
// Observe CPApplicationOSBehaviorDidChangeNotification
|
||||
[[CPNotificationCenter defaultCenter] addObserver:self selector:@selector(_osBehaviorDidChange:) name:CPApplicationOSBehaviorDidChangeNotification object:CPApp];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
// This will be called by CPWindow -close so the observer can be removed
|
||||
- (void)_close
|
||||
{
|
||||
[[CPNotificationCenter defaultCenter] removeObserver:self name:CPApplicationOSBehaviorDidChangeNotification object:CPApp];
|
||||
}
|
||||
|
||||
- (void)viewDidMoveToWindow
|
||||
{
|
||||
[_closeButton setTarget:[self window]];
|
||||
@@ -212,11 +253,14 @@ var _CPStandardWindowViewDividerViewHeight = 1.0;
|
||||
|
||||
[_minimizeButton setTarget:[self window]];
|
||||
[_minimizeButton setAction:@selector(performMiniaturize:)];
|
||||
|
||||
[_zoomButton setTarget:[self window]];
|
||||
[_zoomButton setAction:@selector(performZoom:)];
|
||||
}
|
||||
|
||||
- (CGSize)toolbarOffset
|
||||
{
|
||||
return CGSizeMake(0.0, [self valueForThemeAttribute:@"title-bar-height"]);
|
||||
return CGSizeMake(0.0, _titleBarHeight);
|
||||
}
|
||||
|
||||
- (void)tile
|
||||
@@ -236,6 +280,7 @@ var _CPStandardWindowViewDividerViewHeight = 1.0;
|
||||
|
||||
[_headView setFrameSize:CGSizeMake(width, headHeight)];
|
||||
|
||||
// Set divider to full width to prevent gaps/holes at the sides.
|
||||
[_dividerView setFrame:CGRectMake(0.0, headHeight, width, _CPStandardWindowViewDividerViewHeight)];
|
||||
|
||||
var dividerMinY = 0,
|
||||
@@ -246,52 +291,179 @@ var _CPStandardWindowViewDividerViewHeight = 1.0;
|
||||
|
||||
[_bodyView setFrame:CGRectMake(0.0, dividerMinY, width, CGRectGetHeight(bounds) - dividerMinY)];
|
||||
|
||||
var leftOffset = 8;
|
||||
|
||||
if (_closeButton)
|
||||
leftOffset += 19.0;
|
||||
if (_minimizeButton)
|
||||
leftOffset += 19.0;
|
||||
|
||||
[_titleField setFrame:CGRectMake(leftOffset, 0, width - leftOffset * 2.0, [self valueForThemeAttribute:@"title-bar-height"])];
|
||||
[_titleField setFrame:CGRectMake(_buttonsWidth, 0, width - _buttonsWidth * 2.0, _titleBarHeight)];
|
||||
|
||||
var contentFrame = [_bodyView frame];
|
||||
[[theWindow contentView] setFrame:CGRectInset(contentFrame, 1.0, 1.0)];
|
||||
}
|
||||
|
||||
/*
|
||||
- (void)setAnimatingToolbar:(BOOL)isAnimatingToolbar
|
||||
- (void)_updateWindowButtons:(BOOL)shouldRefreshLayout
|
||||
{
|
||||
[super setAnimatingToolbar:isAnimatingToolbar];
|
||||
|
||||
if ([self isAnimatingToolbar])
|
||||
if (shouldRefreshLayout)
|
||||
{
|
||||
[[self toolbarView] setAutoresizingMask:CPViewHeightSizable];
|
||||
var mimicWindows = [CPApp shouldMimicWindows];
|
||||
|
||||
[_headView setAutoresizingMask:CPViewHeightSizable];
|
||||
[_dividerView setAutoresizingMask:CPViewMinYMargin];
|
||||
[_bodyView setAutoresizingMask:CPViewMinYMargin];
|
||||
if (mimicWindows)
|
||||
[self setThemeState:CPThemeStateWindowsPlatform];
|
||||
else
|
||||
[self unsetThemeState:CPThemeStateWindowsPlatform];
|
||||
|
||||
[[[self window] contentView] setAutoresizingMask:CPViewNotSizable];
|
||||
// Remember that on Cappuccino, buttons are (left to right) : close - minimize - zoom
|
||||
// and that on Windows, (also left to right) : minimize - zoom - close
|
||||
|
||||
var offset,
|
||||
mask,
|
||||
closeThemeOrigin = CGPointMakeCopy([self currentValueForThemeAttribute:@"close-image-origin"] || CGPointMakeZero()),
|
||||
minimizeThemeOrigin = CGPointMakeCopy([self currentValueForThemeAttribute:@"minimize-image-origin"] || CGPointMakeZero()),
|
||||
zoomThemeOrigin = CGPointMakeCopy([self currentValueForThemeAttribute:@"zoom-image-origin"] || CGPointMakeZero()),
|
||||
closeThemeSize = CGSizeMakeZero(),
|
||||
minimizeThemeSize = CGSizeMakeZero(),
|
||||
zoomThemeSize = CGSizeMakeZero(),
|
||||
delta1,
|
||||
delta2;
|
||||
|
||||
// For retro-compatibility
|
||||
if (![self isCSSBased])
|
||||
{
|
||||
if (mimicWindows)
|
||||
{
|
||||
// There's no zoom button in Aristo2
|
||||
closeThemeOrigin = CGPointMake(-24.0, 8.0);
|
||||
minimizeThemeOrigin = CGPointMake(-43.0, 8.0);
|
||||
|
||||
// FIXME: if someone designs a zoom button in Aristo2 one day, use those values
|
||||
// closeThemeOrigin = CGPointMake(-24.0, 8.0);
|
||||
// minimizeThemeOrigin = CGPointMake(-62.0, 8.0);
|
||||
// zoomThemeOrigin = CGPointMake(-43.0, 8.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
closeThemeOrigin = CGPointMake(8.0, 8.0);
|
||||
minimizeThemeOrigin = CGPointMake(27.0, 8.0);
|
||||
zoomThemeOrigin = CGPointMake(46.0, 8.0);
|
||||
}
|
||||
}
|
||||
|
||||
if (mimicWindows)
|
||||
{
|
||||
offset = [self bounds].size.width;
|
||||
mask = CPViewMinXMargin;
|
||||
delta1 = zoomThemeOrigin.x - closeThemeOrigin.x;
|
||||
delta2 = minimizeThemeOrigin.x - zoomThemeOrigin.x;
|
||||
}
|
||||
else
|
||||
{
|
||||
offset = 0;
|
||||
mask = CPViewMaxXMargin;
|
||||
delta1 = minimizeThemeOrigin.x - closeThemeOrigin.x;
|
||||
delta2 = zoomThemeOrigin.x - minimizeThemeOrigin.x;
|
||||
}
|
||||
|
||||
_buttonsWidth = 0;
|
||||
|
||||
if (_styleMask & CPClosableWindowMask)
|
||||
{
|
||||
closeThemeSize = [self currentValueForThemeAttribute:@"close-image-size"];
|
||||
|
||||
// For retro-compatibility:
|
||||
if (!closeThemeSize)
|
||||
closeThemeSize = CGSizeMake(16.0, 16.0);
|
||||
|
||||
[_closeButton setFrame:CGRectMake(closeThemeOrigin.x + offset, closeThemeOrigin.y, closeThemeSize.width, closeThemeSize.height)];
|
||||
[_closeButton setAutoresizingMask:mask];
|
||||
|
||||
_buttonsWidth = ABS(closeThemeOrigin.x) + (mimicWindows ? 0 : closeThemeSize.width);
|
||||
}
|
||||
else
|
||||
{
|
||||
minimizeThemeOrigin.x -= delta1;
|
||||
zoomThemeOrigin.x -= delta1;
|
||||
}
|
||||
|
||||
if (mimicWindows)
|
||||
{
|
||||
if (_styleMask & CPResizableWindowMask)
|
||||
{
|
||||
zoomThemeSize = [self currentValueForThemeAttribute:@"zoom-image-size"];
|
||||
|
||||
// For retro-compatibility:
|
||||
if (!zoomThemeSize)
|
||||
zoomThemeSize = CGSizeMake(16.0, 16.0);
|
||||
|
||||
[_zoomButton setFrame:CGRectMake(zoomThemeOrigin.x + offset, zoomThemeOrigin.y, zoomThemeSize.width, zoomThemeSize.height)];
|
||||
[_zoomButton setAutoresizingMask:mask];
|
||||
|
||||
_buttonsWidth = ABS(zoomThemeOrigin.x);
|
||||
}
|
||||
else
|
||||
minimizeThemeOrigin.x -= delta2;
|
||||
|
||||
if (_styleMask & CPMiniaturizableWindowMask)
|
||||
{
|
||||
minimizeThemeSize = [self currentValueForThemeAttribute:@"minimize-image-size"];
|
||||
|
||||
// For retro-compatibility:
|
||||
if (!minimizeThemeSize)
|
||||
minimizeThemeSize = CGSizeMake(16.0, 16.0);
|
||||
|
||||
[_minimizeButton setFrame:CGRectMake(minimizeThemeOrigin.x + offset, minimizeThemeOrigin.y, minimizeThemeSize.width, minimizeThemeSize.height)];
|
||||
[_minimizeButton setAutoresizingMask:mask];
|
||||
|
||||
_buttonsWidth = ABS(minimizeThemeOrigin.x);
|
||||
}
|
||||
|
||||
if (_buttonsWidth > 0)
|
||||
_buttonsWidth += ABS(closeThemeOrigin.x) - closeThemeSize.width;
|
||||
}
|
||||
else // not win
|
||||
{
|
||||
if (_styleMask & CPMiniaturizableWindowMask)
|
||||
{
|
||||
minimizeThemeSize = [self currentValueForThemeAttribute:@"minimize-image-size"];
|
||||
|
||||
// For retro-compatibility:
|
||||
if (!minimizeThemeSize)
|
||||
minimizeThemeSize = CGSizeMake(16.0, 16.0);
|
||||
|
||||
[_minimizeButton setFrame:CGRectMake(minimizeThemeOrigin.x + offset, minimizeThemeOrigin.y, minimizeThemeSize.width, minimizeThemeSize.height)];
|
||||
[_minimizeButton setAutoresizingMask:mask];
|
||||
|
||||
_buttonsWidth = minimizeThemeOrigin.x + minimizeThemeSize.width;
|
||||
}
|
||||
else
|
||||
zoomThemeOrigin.x -= delta2;
|
||||
|
||||
if (_styleMask & CPResizableWindowMask)
|
||||
{
|
||||
zoomThemeSize = [self currentValueForThemeAttribute:@"zoom-image-size"];
|
||||
|
||||
// For retro-compatibility:
|
||||
if (!zoomThemeSize)
|
||||
zoomThemeSize = CGSizeMake(16.0, 16.0);
|
||||
|
||||
[_zoomButton setFrame:CGRectMake(zoomThemeOrigin.x + offset, zoomThemeOrigin.y, zoomThemeSize.width, zoomThemeSize.height)];
|
||||
[_zoomButton setAutoresizingMask:mask];
|
||||
|
||||
_buttonsWidth = zoomThemeOrigin.x + zoomThemeSize.width;
|
||||
}
|
||||
|
||||
if (_buttonsWidth > 0)
|
||||
_buttonsWidth += closeThemeOrigin.x;
|
||||
}
|
||||
|
||||
[self updateTrackingAreas];
|
||||
}
|
||||
else
|
||||
{
|
||||
[[self toolbarView] setAutoresizingMask:CPViewWidthSizable];
|
||||
|
||||
[_headView setAutoresizingMask:CPViewWidthSizable];
|
||||
[_dividerView setAutoresizingMask:CPViewWidthSizable];
|
||||
[_bodyView setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
|
||||
[self _updateCloseButton];
|
||||
|
||||
[[[self window] contentView] setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
|
||||
}
|
||||
[_minimizeButton setImage:[self currentValueForThemeAttribute:@"minimize-image-button"]];
|
||||
[_minimizeButton setAlternateImage:[self currentValueForThemeAttribute:@"minimize-image-highlighted-button"]];
|
||||
[_zoomButton setImage:[self currentValueForThemeAttribute:@"zoom-image-button"]];
|
||||
[_zoomButton setAlternateImage:[self currentValueForThemeAttribute:@"zoom-image-highlighted-button"]];
|
||||
}
|
||||
*/
|
||||
|
||||
- (void)_updateCloseButton
|
||||
{
|
||||
[_closeButton setFrameSize:[self valueForThemeAttribute:@"close-image-size"]];
|
||||
[_closeButton setFrameOrigin:[self valueForThemeAttribute:@"close-image-origin"]];
|
||||
|
||||
if (_isDocumentEdited)
|
||||
{
|
||||
[_closeButton setImage:[self currentValueForThemeAttribute:@"unsaved-image-button"]];
|
||||
@@ -304,9 +476,15 @@ var _CPStandardWindowViewDividerViewHeight = 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)_osBehaviorDidChange:(id)application
|
||||
{
|
||||
[self _updateWindowButtons:YES];
|
||||
}
|
||||
|
||||
- (void)setDocumentEdited:(BOOL)isEdited
|
||||
{
|
||||
_isDocumentEdited = isEdited;
|
||||
|
||||
[self _updateCloseButton];
|
||||
}
|
||||
|
||||
@@ -337,9 +515,10 @@ var _CPStandardWindowViewDividerViewHeight = 1.0;
|
||||
[_dividerView setHidden:enable];
|
||||
}
|
||||
|
||||
[_closeButton setHidden:enable];
|
||||
[_closeButton setHidden:enable];
|
||||
[_minimizeButton setHidden:enable];
|
||||
[_titleField setHidden:enable];
|
||||
[_zoomButton setHidden:enable];
|
||||
[_titleField setHidden:enable];
|
||||
|
||||
[[self window] setMovable:!enable];
|
||||
|
||||
@@ -381,28 +560,35 @@ var _CPStandardWindowViewDividerViewHeight = 1.0;
|
||||
|
||||
- (void)layoutSubviews
|
||||
{
|
||||
var bounds = [self bounds];
|
||||
var width = [self bounds].size.width,
|
||||
mimicWindows = [CPApp shouldMimicWindows];
|
||||
|
||||
[super layoutSubviews];
|
||||
[self _updateCloseButton];
|
||||
|
||||
[_minimizeButton setImage:[self valueForThemeAttribute:@"minimize-image-button"]];
|
||||
[_minimizeButton setAlternateImage:[self valueForThemeAttribute:@"minimize-image-highlighted-button"]];
|
||||
if (_closeButton || _minimizeButton || _zoomButton)
|
||||
[self _updateWindowButtons:NO];
|
||||
|
||||
[_dividerView setBackgroundColor:[self valueForThemeAttribute:@"divider-color"]];
|
||||
[_bodyView setBackgroundColor:[self valueForThemeAttribute:@"body-color"]];
|
||||
|
||||
[_headView setNeedsLayout];
|
||||
|
||||
if (width - 2 * _buttonsWidth < _minimumTitleFieldSize)
|
||||
{
|
||||
if (width - _buttonsWidth - _titleMargin < _minimumTitleFieldSize)
|
||||
[_titleField setFrame:CGRectMake((mimicWindows ? _titleMargin : _buttonsWidth), 0, width - _buttonsWidth - _titleMargin, _titleBarHeight)];
|
||||
else
|
||||
[_titleField setFrame:CGRectMake((mimicWindows ? width - _buttonsWidth - _minimumTitleFieldSize : _buttonsWidth), 0, _minimumTitleFieldSize, _titleBarHeight)];
|
||||
}
|
||||
}
|
||||
|
||||
- (CGSize)_minimumResizeSize
|
||||
{
|
||||
// The minimum width is such that the close button would always be visible.
|
||||
// We give the same margin to the right of the button as there is to the left.
|
||||
var size = [super _minimumResizeSize],
|
||||
closeSize = [self valueForThemeAttribute:@"close-image-size"],
|
||||
closeOrigin = [self valueForThemeAttribute:@"close-image-origin"];
|
||||
// The minimum width is such that the close/minimize/zoom button(s) would always be visible.
|
||||
// We give the same margin to the right of the button(s) as there is to the left.
|
||||
var size = CGSizeMakeCopy([super _minimumResizeSize]);
|
||||
|
||||
size.width = closeSize.width + (closeOrigin.x * 2);
|
||||
size.width = _buttonsWidth;
|
||||
size.height += _CPStandardWindowViewDividerViewHeight;
|
||||
|
||||
return size;
|
||||
@@ -413,4 +599,94 @@ var _CPStandardWindowViewDividerViewHeight = 1.0;
|
||||
return [_bodyView frame].origin.y;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Hover management for buttons
|
||||
|
||||
- (void)updateTrackingAreas
|
||||
{
|
||||
if (_closeButtonTrackingArea)
|
||||
[_closeButton removeTrackingArea:_closeButtonTrackingArea];
|
||||
|
||||
if (_minimizeButtonTrackingArea)
|
||||
[_minimizeButton removeTrackingArea:_minimizeButtonTrackingArea];
|
||||
|
||||
if (_zoomButtonTrackingArea)
|
||||
[_zoomButton removeTrackingArea:_zoomButtonTrackingArea];
|
||||
|
||||
if (_closeButton)
|
||||
{
|
||||
_closeButtonTrackingArea = [[CPTrackingArea alloc] initWithRect:CGRectMakeZero()
|
||||
options:CPTrackingMouseEnteredAndExited | CPTrackingActiveAlways | CPTrackingInVisibleRect
|
||||
owner:self
|
||||
userInfo:_closeButton];
|
||||
[_closeButton addTrackingArea:_closeButtonTrackingArea];
|
||||
}
|
||||
|
||||
if (_minimizeButton)
|
||||
{
|
||||
_minimizeButtonTrackingArea = [[CPTrackingArea alloc] initWithRect:CGRectMakeZero()
|
||||
options:CPTrackingMouseEnteredAndExited | CPTrackingActiveAlways | CPTrackingInVisibleRect
|
||||
owner:self
|
||||
userInfo:_minimizeButton];
|
||||
[_minimizeButton addTrackingArea:_minimizeButtonTrackingArea];
|
||||
}
|
||||
|
||||
if (_zoomButton)
|
||||
{
|
||||
_zoomButtonTrackingArea = [[CPTrackingArea alloc] initWithRect:CGRectMakeZero()
|
||||
options:CPTrackingMouseEnteredAndExited | CPTrackingActiveAlways | CPTrackingInVisibleRect
|
||||
owner:self
|
||||
userInfo:_zoomButton];
|
||||
[_zoomButton addTrackingArea:_zoomButtonTrackingArea];
|
||||
}
|
||||
|
||||
[super updateTrackingAreas];
|
||||
}
|
||||
|
||||
- (void)mouseEntered:(CPEvent)anEvent
|
||||
{
|
||||
var triggeredButton = [[anEvent trackingArea] userInfo],
|
||||
state = CPThemeStateHovered;
|
||||
|
||||
if ([CPApp shouldMimicWindows])
|
||||
state = state.and(CPThemeStateWindowsPlatform);
|
||||
|
||||
if (triggeredButton === _closeButton)
|
||||
{
|
||||
if (_isDocumentEdited)
|
||||
[_closeButton setImage:[self valueForThemeAttribute:@"unsaved-image-button" inState:state]];
|
||||
else
|
||||
[_closeButton setImage:[self valueForThemeAttribute:@"close-image-button" inState:state]];
|
||||
}
|
||||
else if (triggeredButton === _minimizeButton)
|
||||
{
|
||||
[_minimizeButton setImage:[self valueForThemeAttribute:@"minimize-image-button" inState:state]];
|
||||
}
|
||||
else if (triggeredButton === _zoomButton)
|
||||
{
|
||||
[_zoomButton setImage:[self valueForThemeAttribute:@"zoom-image-button" inState:state]];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)mouseExited:(CPEvent)anEvent
|
||||
{
|
||||
var triggeredButton = [[anEvent trackingArea] userInfo];
|
||||
|
||||
if (triggeredButton === _closeButton)
|
||||
{
|
||||
if (_isDocumentEdited)
|
||||
[_closeButton setImage:[self currentValueForThemeAttribute:@"unsaved-image-button"]];
|
||||
else
|
||||
[_closeButton setImage:[self currentValueForThemeAttribute:@"close-image-button"]];
|
||||
}
|
||||
else if (triggeredButton === _minimizeButton)
|
||||
{
|
||||
[_minimizeButton setImage:[self currentValueForThemeAttribute:@"minimize-image-button"]];
|
||||
}
|
||||
else if (triggeredButton === _zoomButton)
|
||||
{
|
||||
[_zoomButton setImage:[self currentValueForThemeAttribute:@"zoom-image-button"]];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -27,6 +27,9 @@
|
||||
@implementation _CPTitleableWindowView : _CPWindowView
|
||||
{
|
||||
CPTextField _titleField;
|
||||
int _minimumTitleFieldSize;
|
||||
int _titleBarHeight;
|
||||
int _titleMargin;
|
||||
}
|
||||
|
||||
+ (int)titleBarHeight
|
||||
@@ -47,7 +50,7 @@
|
||||
|
||||
+ (CGRect)frameRectForContentRect:(CGRect)aContentRect
|
||||
{
|
||||
var frameRect = CGRectMakeCopy(aContentRect),
|
||||
var frameRect = [super frameRectForContentRect:aContentRect],
|
||||
titleBarHeight = [self titleBarHeight];
|
||||
|
||||
frameRect.origin.y -= titleBarHeight;
|
||||
@@ -62,15 +65,19 @@
|
||||
|
||||
if (self)
|
||||
{
|
||||
// We cache some values for optimization
|
||||
_titleBarHeight = [[self class] titleBarHeight];
|
||||
_titleMargin = [self currentValueForThemeAttribute:@"title-margin"];
|
||||
|
||||
_titleField = [[CPTextField alloc] initWithFrame:CGRectMakeZero()];
|
||||
|
||||
[_titleField setHitTests:NO];
|
||||
[_titleField setStringValue:@"Untitled"];
|
||||
[_titleField sizeToFit];
|
||||
[_titleField setAutoresizingMask:CPViewWidthSizable];
|
||||
[_titleField setStringValue:@""];
|
||||
[self setTitle:@""];
|
||||
|
||||
[_titleField setFrame:CGRectMake(20.0, 3.0, CGRectGetWidth([self bounds]) - 40.0, CGRectGetHeight([_titleField frame]))];
|
||||
[_titleField setFrame:CGRectMake(_titleMargin, 3.0, CGRectGetWidth([self bounds]) - 2 * _titleMargin, CGRectGetHeight([_titleField frame]))];
|
||||
|
||||
[self addSubview:_titleField];
|
||||
|
||||
@@ -83,6 +90,8 @@
|
||||
- (void)setTitle:(CPString)aTitle
|
||||
{
|
||||
[_titleField setStringValue:aTitle];
|
||||
|
||||
_minimumTitleFieldSize = [_titleField _minimumFrameSize].width;
|
||||
}
|
||||
|
||||
- (void)tile
|
||||
@@ -95,7 +104,7 @@
|
||||
|
||||
// The vertical alignment of the title is set by the theme, so just give it all available space. By default
|
||||
// the title will vertically centre within.
|
||||
[_titleField setFrame:CGRectMake(20.0, 0, width - 40.0, [[self class] titleBarHeight])];
|
||||
[_titleField setFrame:CGRectMake(_titleMargin, 0, width - 2 * _titleMargin, _titleBarHeight)];
|
||||
}
|
||||
|
||||
- (void)layoutSubviews
|
||||
|
||||
@@ -25,8 +25,8 @@
|
||||
|
||||
@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);
|
||||
}
|
||||
|
||||
|
||||
@@ -41,21 +41,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 +73,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;
|
||||
}
|
||||
|
||||
|
||||
// MARK: -
|
||||
// MARK: drawing
|
||||
|
||||
- (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
|
||||
|
||||
@@ -61,6 +61,9 @@ task ("Theme", [$BUILD_CJS_CAPPUCCINO_APPKIT], function()
|
||||
|
||||
utilsFile.cp_r(path.join($BUILD_DIR, $CONFIGURATION, 'Aristo2.blend'), path.join($BUILD_PATH, 'Resources', 'Aristo2.blend'));
|
||||
utilsFile.cp_r(path.join($BUILD_DIR, $CONFIGURATION, 'Aristo2.blend'), path.join($BUILD_CJS_CAPPUCCINO_APPKIT, "Resources", "Aristo2.blend"));
|
||||
|
||||
utilsFile.cp_r(path.join($BUILD_DIR, $CONFIGURATION, 'Aristo3.blend'), path.join($BUILD_PATH, 'Resources', 'Aristo3.blend'));
|
||||
utilsFile.cp_r(path.join($BUILD_DIR, $CONFIGURATION, 'Aristo3.blend'), path.join($BUILD_CJS_CAPPUCCINO_APPKIT, "Resources", "Aristo3.blend"));
|
||||
});
|
||||
|
||||
task ("build", ["AppKit", $BUILD_CJS_CAPPUCCINO_APPKIT, "Theme"]);
|
||||
|
||||
@@ -481,9 +481,9 @@ _CPPlatformWindowWillCloseNotification = @"_CPPlatformWindowWillCloseNotificatio
|
||||
_DOMWindow.addEventListener("blur", onBlurEventCallback, NO);
|
||||
_DOMWindow.addEventListener("focus", onFocusEventCallback, NO);
|
||||
|
||||
_DOMWindow.addEventListener("pagehide", function()
|
||||
_DOMWindow.addEventListener("unload", function()
|
||||
{
|
||||
_DOMWindow.removeEventListener("pagehide", arguments.callee, NO);
|
||||
_DOMWindow.removeEventListener("unload", arguments.callee, NO);
|
||||
|
||||
[self blurEvent:nil];
|
||||
[self _notifyPlatformWindowWillClose];
|
||||
|
||||
@@ -0,0 +1,163 @@
|
||||
/*
|
||||
* Aristo3Colors.j
|
||||
* AppKit
|
||||
*
|
||||
* Created by Didier Korthoudt
|
||||
* Copyright 2018 <didier.korthoudt@uliege.be>
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
A3CPColorActiveText = [CPColor colorWithRed:0 green:0 blue:0 alpha:0.85];
|
||||
A3CPColorActiveTextHighlighted = [CPColor colorWithRed:255 green:255 blue:255 alpha:0.90];
|
||||
A3CPColorInactiveText = [CPColor colorWithRed:0 green:0 blue:0 alpha:0.30];
|
||||
A3CPColorInactiveWhiteText = [CPColor colorWithRed: 255 green:255 blue:255 alpha:0.6];
|
||||
A3CPColorDefaultText = [CPColor colorWithHexString:@"FFFFFF"];
|
||||
A3CPColorActiveText65 = [CPColor colorWithRed:0 green:0 blue:0 alpha:0.65];
|
||||
|
||||
A3CPColorBlack50 = [CPColor colorWithRed:0 green:0 blue:0 alpha:0.50];
|
||||
A3CPColorBlack85 = [CPColor colorWithRed:0 green:0 blue:0 alpha:0.85];
|
||||
A3CPColorBlack25 = [CPColor colorWithRed:0 green:0 blue:0 alpha:0.25];
|
||||
|
||||
A3CPColorActiveBorder = [CPColor colorWithRed:0 green:0 blue:0 alpha:0.20];
|
||||
A3ColorActiveBorder = @"rgba(0,0,0,0.20)";
|
||||
A3CPColorInactiveBorder = [CPColor colorWithRed:0 green:0 blue:0 alpha:0.10];
|
||||
A3ColorInactiveBorder = @"rgba(0,0,0,0.10)";
|
||||
A3ColorInactiveDarkBorder = @"rgba(0,0,0,0.25)";
|
||||
A3ColorNotKeyDarkBorder = @"rgba(0,0,0,0.85)";
|
||||
A3ColorTransparent = @"rgba(0,0,0,0)";
|
||||
A3ColorLightBackground = @"rgba(255,255,255,0.5)";
|
||||
|
||||
A3ColorBorderLight = @"rgb(230,230,230)";
|
||||
A3ColorBorderMedium = @"rgb(213,213,213)";
|
||||
A3ColorBorderDark = @"rgb(205,205,205)";
|
||||
A3ColorBorderBlue = @"rgb(23,128,251)";
|
||||
A3CPColorBorderBlue = [CPColor colorWithHexString:@"1780FB"];
|
||||
A3CPColorBorderBlueInactive = [CPColor colorWithHexString:@"DCDCDC"];
|
||||
A3ColorBorderBlueLight = @"rgb(150,200,250)";
|
||||
A3ColorBorderBlueHighlighted = @"rgb(0,103,216)";
|
||||
A3ColorBackground = @"rgb(236,236,236)";
|
||||
A3ColorBackgroundInactive = @"rgb(240,240,240)";
|
||||
A3ColorBackgroundHighlighted = @"rgb(231,231,231)";
|
||||
A3ColorBackgroundWhite = @"rgb(255,255,255)";
|
||||
A3ColorBackgroundDark = @"rgb(159,159,159)";
|
||||
A3ColorBackgroundDarkened = @"rgba(0,0,0,0.15)";
|
||||
A3ColorBackgroundLightlyDarkened = @"rgba(0,0,0,0.05)";
|
||||
A3ColorButtonBackgroundHighlighted = @"rgb(191,191,191)";
|
||||
A3ColorBackground90 = @"rgba(236,236,236,0.90)";
|
||||
A3ColorBackground50 = @"rgba(236,236,236,0.50)";
|
||||
A3ColorButtonBackgroundHighlighted80= @"rgba(191,191,191,0.80)";
|
||||
A3ColorButtonBackgroundHighlighted50= @"rgba(191,191,191,0.50)";
|
||||
A3ColorBackgroundDark35 = @"rgba(159,159,159,0.35)";
|
||||
A3ColorBackgroundBlack50 = @"rgba(0,0,0,0.50)";
|
||||
A3ColorBackgroundBlack35 = @"rgba(0,0,0,0.35)";
|
||||
A3ColorBackgroundBlack20 = @"rgba(0,0,0,0.20)";
|
||||
A3ColorBackgroundBlack14 = @"rgba(0,0,0,0.14)";
|
||||
|
||||
A3ColorBorderRed = @"rgb(192,26,25)";
|
||||
A3ColorBorderRedLight = @"rgb(239,102,103)";
|
||||
A3ColorBorderRedHighlighted = @"rgb(144,19,19)";
|
||||
|
||||
// Windows
|
||||
|
||||
A3ColorWindowHeadActive = @"rgb(216,216,216)";
|
||||
A3ColorWindowHeadInactive = @"rgb(246,246,246)";
|
||||
A3ColorWindowButtonClose = @"rgb(252,96,92)";
|
||||
A3ColorWindowButtonCloseDark = @"rgb(223,72,69)";
|
||||
A3ColorWindowButtonCloseLight = @"rgb(254,176,174)";
|
||||
A3ColorWindowButtonMin = @"rgb(253,188,64)";
|
||||
A3ColorWindowButtonMinDark = @"rgb(222,160,52)";
|
||||
A3ColorWindowButtonMinLight = @"rgb(254,222,160)";
|
||||
A3ColorWindowButtonZoom = @"rgb(52,200,74)";
|
||||
A3ColorWindowButtonZoomDark = @"rgb(40,171,53)";
|
||||
A3ColorWindowButtonZoomLight = @"rgb(154,227,164)";
|
||||
A3ColorWindowButtonUnsaved = @"rgba(50,50,50,0.65)";
|
||||
A3ColorWindowButtonUnsavedLight = @"rgb(100,100,100)";
|
||||
A3ColorWindowButtonBackground = @"rgb(128,128,128)";
|
||||
A3ColorWindowButtonBackgroundLight = @"rgb(192,192,192)";
|
||||
A3ColorWindowButtonBackgroundDark = @"rgb(96,96,96)";
|
||||
A3ColorWindowBorder = @"rgb(189,189,189)";
|
||||
|
||||
// Menus
|
||||
|
||||
A3ColorMenuLightBackground = @"rgb(246,246,246)";
|
||||
A3ColorMenuBackground = @"rgb(206,206,206)";
|
||||
A3ColorMenuCheckmark = @"rgba(0,0,0,0.85)";
|
||||
A3ColorMenuBorder = @"rgba(0,0,0,0.20)";
|
||||
|
||||
// Textfields
|
||||
|
||||
A3ColorTextfieldActiveBorder = @"rgba(0,0,0,0.25)";
|
||||
A3ColorTextfieldInactiveBorder = @"rgba(0,0,0,0.20)";
|
||||
|
||||
// Tables
|
||||
|
||||
A3CPColorTableRow = [CPColor whiteColor];
|
||||
A3CPColorTableAlternateRow = [CPColor colorWithRed:245.0/255.0 green:245.0/255.0 blue:245.0/255.0 alpha:1.0];
|
||||
A3CPColorTableDivider = [CPColor colorWithRed:214.0/255.0 green:214.0/255.0 blue:214.0/255.0 alpha:1.0];
|
||||
A3ColorTableDivider = @"rgb(214,214,214)";
|
||||
A3ColorTableHeaderSeparator = @"rgb(229,229,229)";
|
||||
A3CPColorTableHeaderText = [CPColor colorWithRed:0 green:0 blue:0 alpha:0.40];
|
||||
A3CPColorSelectedTableHeaderText = [CPColor colorWithRed:0 green:0 blue:0 alpha:0.70];
|
||||
A3ColorTableColumnHeaderPressed = @"rgba(0,0,0,0.10)";
|
||||
|
||||
// Scrollers
|
||||
|
||||
A3ColorScrollerDark = @"rgba(0,0,0,0.50)";
|
||||
A3ColorScrollerLight = @"rgba(255,255,255,0.5)";
|
||||
A3ColorScrollerLegacy = @"rgba(0,0,0,0.20)";
|
||||
A3ColorScrollerBackground = @"rgb(250,250,250)";
|
||||
A3ColorScrollerBorder = @"rgb(232,232,232)";
|
||||
|
||||
// Sliders
|
||||
|
||||
A3ColorCircularSliderKnob = @"rgba(0,0,0,0.5)";
|
||||
A3ColorSliderDisabledKnob = @"rgb(251,251,251)";
|
||||
A3ColorSliderDisabledTrack = @"rgb(140,140,140)";
|
||||
|
||||
// Steppers
|
||||
|
||||
A3ColorStepperArrow = @"rgba(0,0,0,0.65)";
|
||||
A3ColorHighlightedStepperArrow = @"rgba(255,255,255,1)";
|
||||
|
||||
// Split views
|
||||
|
||||
A3ColorSplitPaneDividerBackground = @"rgb(253,253,253)";
|
||||
A3ColorSplitPaneDividerBorder = @"rgb(213,213,213)";
|
||||
|
||||
// Calendar
|
||||
|
||||
A3ColorCalendarButtons = @"rgb(50,50,50)";
|
||||
A3ColorCalendarHighlightedButtons = @"rgb(165,165,165)";
|
||||
A3CPColorCalendarDark = [CPColor colorWithRed:0 green:0 blue:0 alpha:0.35];
|
||||
A3ColorCalendarDark = @"rgba(0,0,0,0.35)";
|
||||
A3ColorCalendarActive = A3ColorBorderBlue;
|
||||
A3ColorCalendarActiveNotKey = @"rgba(0,0,0,0.15)";
|
||||
A3CPColorCalendarTitle = [CPColor colorWithRed:65/255 green:65/255 blue:65/255 alpha:1];
|
||||
A3CPColorCalendarTile = A3CPColorActiveText; // [CPColor colorWithRed:40/255 green:40/255 blue:40/255 alpha:1];
|
||||
A3CPColorCalendarCurrentDayTile = A3CPColorBorderBlue;
|
||||
A3CPColorCalendarOutOfRangeTile = A3CPColorInactiveText;
|
||||
A3CPColorCalendarSelectedTile = [CPColor whiteColor];
|
||||
A3ColorCalendarBackground = @"rgb(255,255,255)";
|
||||
|
||||
// Disclosure triangle
|
||||
|
||||
A3ColorDisclosure = @"rgb(140,140,140)";
|
||||
A3ColorDisclosureDisabled = @"rgb(191,191,191)";
|
||||
A3ColorDisclosurePushed = @"rgb(115,115,115)";
|
||||
|
||||
// Square buttons
|
||||
|
||||
A3ColorSquareButtonBackground = @"rgb(248,248,248)";
|
||||
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CPSystemFontFace</key>
|
||||
<string>SFNSText, Helvetica Neue</string>
|
||||
<key>CPApplicationDelegateClass</key>
|
||||
<string>BKShowcaseController</string>
|
||||
<key>CPBundleName</key>
|
||||
<string>Aristo3</string>
|
||||
<key>BKLearnMoreURL</key>
|
||||
<string>http://cappuccino.org/aristo</string>
|
||||
<key>BKLearnMoreButtonTitle</key>
|
||||
<string>Aristo Home Page</string>
|
||||
<key>CPPrincipalClass</key>
|
||||
<string>CPApplication</string>
|
||||
<key>CPDefaultTheme</key>
|
||||
<string>Aristo3</string>
|
||||
<key>CPSystemFontSize</key>
|
||||
<string>13</string>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,40 @@
|
||||
require("../../../common.jake");
|
||||
|
||||
const path = require("path");
|
||||
|
||||
var callback;
|
||||
|
||||
function callbackFunction(blendtask) {
|
||||
callback(blendtask);
|
||||
}
|
||||
|
||||
$BUILD_CJS_BLENDTASK = path.join($BUILD_CJS_CAPPUCCINO, "lib", "cappuccino", "jake", "blendtask.j");
|
||||
|
||||
var promise = new Promise((resolve, reject) => {
|
||||
callback = function(BLEND_TASK) {
|
||||
exports.BlendTask = BLEND_TASK.BlendTask;
|
||||
exports.blend = BLEND_TASK.blend;
|
||||
defineBlendTask().then(() => {
|
||||
resolve();
|
||||
delete exports.jakePromise;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
require("../../../CommonJS/lib/cappuccino/jake.js").initilize(callbackFunction);
|
||||
|
||||
|
||||
async function defineBlendTask() {
|
||||
await exports.blend ("Aristo3.blend", function(aristoTask)
|
||||
{
|
||||
aristoTask.setBuildIntermediatesPath(path.join($BUILD_DIR, "Aristo3.build", $CONFIGURATION))
|
||||
aristoTask.setBuildPath(path.join($BUILD_DIR, $CONFIGURATION));
|
||||
|
||||
aristoTask.setThemeDescriptors(new FileList("ThemeDescriptors.j"));
|
||||
aristoTask.setIdentifier("com.280n.blend.Aristo3");
|
||||
aristoTask.setResources(new FileList("Resources/*"));
|
||||
});
|
||||
task ("build", ["Aristo3.blend"]);
|
||||
}
|
||||
|
||||
exports.jakePromise = promise;
|
||||
@@ -0,0 +1,28 @@
|
||||
Copyright (c) 2015, Alcatel-Lucent Inc.
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of monolithe nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,150 @@
|
||||
<!DOCTYPE html
|
||||
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<!--
|
||||
index-debug.html
|
||||
null
|
||||
|
||||
Created by You on December 12, 2012
|
||||
Copyright 2012, Your Company. All rights reserved.
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7, chrome=1" />
|
||||
|
||||
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
|
||||
|
||||
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
|
||||
|
||||
<link rel="apple-touch-icon" href="Resources/icon.png" />
|
||||
<link rel="apple-touch-startup-image" href="Resources/default.png" />
|
||||
|
||||
<title>Aristo 3</title>
|
||||
|
||||
<script type="text/javascript">
|
||||
OBJJ_MAIN_FILE = "main.j";
|
||||
OBJJ_INCLUDE_PATHS = ["Frameworks/Debug", "Frameworks", "SomethingElse"];
|
||||
OBJJ_COMPILER_FLAGS = ["IncludeDebugSymbols", "IncludeTypeSignatures", "SourceMap", "InlineMsgSend"];
|
||||
</script>
|
||||
|
||||
<script type="text/javascript" src="Frameworks/Debug/Objective-J/Objective-J.js" charset="UTF-8"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
objj_msgSend_reset();
|
||||
|
||||
// DEBUG OPTIONS:
|
||||
|
||||
// Uncomment to enable printing of backtraces on exceptions:
|
||||
//objj_msgSend_decorate(objj_backtrace_decorator);
|
||||
|
||||
// Uncomment to supress exceptions that take place inside a message
|
||||
//objj_msgSend_decorate(objj_supress_exceptions_decorator)
|
||||
|
||||
// Uncomment to enable runtime type checking:
|
||||
//objj_msgSend_decorate(objj_typecheck_decorator);
|
||||
|
||||
// Uncomment (along with both above) to print backtraces on type check errors:
|
||||
//objj_typecheck_prints_backtrace = true;
|
||||
|
||||
// Uncomment to disable the default logger (CPLogConsole if window.console exists, CPLogPopup otherwise):
|
||||
//CPLogUnregister(CPLogDefault);
|
||||
|
||||
// Uncomment to enable a specific logger:
|
||||
//CPLogRegister(CPLogConsole);
|
||||
//CPLogRegister(CPLogPopup);
|
||||
|
||||
// Tag view DOM elements with a "data-cappuccino-view" attribute that contains
|
||||
// the class name of the view that created them. Comment this or set to false to disable.
|
||||
appkit_tag_dom_elements = true;
|
||||
</script>
|
||||
|
||||
<style type="text/css">
|
||||
body{margin:0; padding:0;}
|
||||
#container {position: absolute; top:50%; left:50%;}
|
||||
#content {width:800px; text-align:center; margin-left: -400px; height:50px; margin-top:-25px; line-height: 50px;}
|
||||
#content {font-family: "Helvetica", "Arial", sans-serif; font-size: 18px; color: black; text-shadow: 0px 1px 0px white; }
|
||||
#loadgraphic {margin-right: 0.2em; margin-bottom:-2px;}
|
||||
|
||||
@font-face {
|
||||
font-family: 'SFNSText';
|
||||
src: local(".SFNSText-Light"), url("Resources/fonts/SFNSText-Light.woff") format("woff");
|
||||
font-weight: 300
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'SFNSText';
|
||||
src: local(".SFNSText-Medium"), url("Resources/fonts/SFNSText-Medium.woff") format("woff");
|
||||
font-weight: 500
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'SFNSDisplay';
|
||||
src: local(".SFNSDisplay-Light"), url("Resources/fonts/SFNSDisplay-Light.woff") format("woff");
|
||||
font-weight: 300
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'SFNSDisplay';
|
||||
src: local(".SFNSDisplay-Medium"), url("Resources/fonts/SFNSDisplay-Medium.woff") format("woff");
|
||||
font-weight: 500
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'SFNSText';
|
||||
src: local(".SFNSText"), url("Resources/fonts/SFNSText-Regular.woff") format("woff");
|
||||
font-weight: 400
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'SFNSText';
|
||||
src: local(".SFNSText-Bold"), url("Resources/fonts/SFNSText-Bold.woff") format("woff");
|
||||
font-weight: 600
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'SFNSDisplay';
|
||||
src: local(".SFNSDisplay"), url("Resources/fonts/SFNSDisplay-Regular.woff") format("woff");
|
||||
font-weight: 400
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'SFNSDisplay';
|
||||
src: local(".SFNSDisplay-Bold"), url("Resources/fonts/SFNSDisplay-Bold.woff") format("woff");
|
||||
font-weight: 600
|
||||
}
|
||||
</style>
|
||||
|
||||
<!--[if lt IE 7]>
|
||||
<STYLE type="text/css">
|
||||
#container { position: relative; top: 50%; }
|
||||
#content { position: relative;}
|
||||
</STYLE>
|
||||
<![endif]-->
|
||||
|
||||
</head>
|
||||
|
||||
<body style="">
|
||||
<div id="cappuccino-body">
|
||||
<div id="loadingcontainer" style="background-color: #eeeeee; overflow:hidden; width:100%; height:100%; position: absolute; top: 0; left: 0;">
|
||||
<script type="text/javascript">
|
||||
document.write("<div id='container'><p id='content'>" +
|
||||
"<img id='loadgraphic' width='16' height='16' src='Resources/spinner.gif' /> " +
|
||||
"Loading Aristo 3...</p></div>");
|
||||
</script>
|
||||
|
||||
<noscript>
|
||||
<div id="container">
|
||||
<div style="width: 440px; padding: 10px 25px 20px 25px; font-family: sans-serif; background-color: #ffffff; position: relative; left: -245px; top: -120px; text-align: center; -moz-border-radius: 20px; -webkit-border-radius: 20px; color: #555555">
|
||||
<p style="line-height: 1.4em;">JavaScript is required for this site to work correctly but is either disabled or not supported by your browser.</p>
|
||||
<p style="font-size:120%; padding:10px;"><a href="http://cappuccino.org/noscript">Show me how to enable JavaScript</a></p>
|
||||
<p style="font-size:80%;">You may want to upgrade to a newer browser while you're at it:</p>
|
||||
<ul style="margin:0;padding:0; text-align: center; font-size:80%;" >
|
||||
<li style="display: inline;"><a href="http://www.apple.com/safari/download/">Safari</a></li>
|
||||
<li style="display: inline;"><a href="http://www.mozilla.com/en-US/firefox/">Firefox</a></li>
|
||||
<li style="display: inline;"><a href="http://www.google.com/chrome/">Chrome</a></li>
|
||||
<li style="display: inline;"><a href="http://www.opera.com/download/">Opera</a></li>
|
||||
<li style="display: inline;"><a href="http://www.microsoft.com/windows/downloads/ie/getitnow.mspx">Internet Explorer</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</noscript>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
<!DOCTYPE html
|
||||
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<!--
|
||||
index.html
|
||||
null
|
||||
|
||||
Created by You on December 12, 2012
|
||||
Copyright 2012, Your Company. All rights reserved.
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7, chrome=1" />
|
||||
|
||||
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
|
||||
|
||||
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
|
||||
|
||||
<link rel="apple-touch-icon" href="Resources/icon.png" />
|
||||
<link rel="apple-touch-startup-image" href="Resources/default.png" />
|
||||
|
||||
<title>Aristo 2</title>
|
||||
|
||||
<script type="text/javascript">
|
||||
OBJJ_MAIN_FILE = "main.j";
|
||||
</script>
|
||||
|
||||
<script type="text/javascript" src="Frameworks/Objective-J/Objective-J.js" charset="UTF-8"></script>
|
||||
|
||||
<style type="text/css">
|
||||
body{margin:0; padding:0;}
|
||||
#container {position: absolute; top:50%; left:50%;}
|
||||
#content {width:800px; text-align:center; margin-left: -400px; height:50px; margin-top:-25px; line-height: 50px;}
|
||||
#content {font-family: "Helvetica", "Arial", sans-serif; font-size: 18px; color: black; text-shadow: 0px 1px 0px white; }
|
||||
#loadgraphic {margin-right: 0.2em; margin-bottom:-2px;}
|
||||
</style>
|
||||
|
||||
<!--[if lt IE 7]>
|
||||
<STYLE type="text/css">
|
||||
#container { position: relative; top: 50%; }
|
||||
#content { position: relative;}
|
||||
</STYLE>
|
||||
<![endif]-->
|
||||
|
||||
</head>
|
||||
|
||||
<body style="">
|
||||
<div id="cappuccino-body">
|
||||
<div id="loadingcontainer" style="background-color: #eeeeee; overflow:hidden; width:100%; height:100%; position: absolute; top: 0; left: 0;">
|
||||
<script type="text/javascript">
|
||||
document.write("<div id='container'><p id='content'>" +
|
||||
"<img id='loadgraphic' width='16' height='16' src='Resources/spinner.gif' /> " +
|
||||
"Loading Aristo 3...</p></div>");
|
||||
</script>
|
||||
|
||||
<noscript>
|
||||
<div id="container">
|
||||
<div style="width: 440px; padding: 10px 25px 20px 25px; font-family: sans-serif; background-color: #ffffff; position: relative; left: -245px; top: -120px; text-align: center; -moz-border-radius: 20px; -webkit-border-radius: 20px; color: #555555">
|
||||
<p style="line-height: 1.4em;">JavaScript is required for this site to work correctly but is either disabled or not supported by your browser.</p>
|
||||
<p style="font-size:120%; padding:10px;"><a href="http://cappuccino.org/noscript">Show me how to enable JavaScript</a></p>
|
||||
<p style="font-size:80%;">You may want to upgrade to a newer browser while you're at it:</p>
|
||||
<ul style="margin:0;padding:0; text-align: center; font-size:80%;" >
|
||||
<li style="display: inline;"><a href="http://www.apple.com/safari/download/">Safari</a></li>
|
||||
<li style="display: inline;"><a href="http://www.mozilla.com/en-US/firefox/">Firefox</a></li>
|
||||
<li style="display: inline;"><a href="http://www.google.com/chrome/">Chrome</a></li>
|
||||
<li style="display: inline;"><a href="http://www.opera.com/download/">Opera</a></li>
|
||||
<li style="display: inline;"><a href="http://www.microsoft.com/windows/downloads/ie/getitnow.mspx">Internet Explorer</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</noscript>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* main.j
|
||||
* null
|
||||
*
|
||||
* Created by You on December 12, 2012
|
||||
* Copyright 2012, Your Company. All rights reserved.
|
||||
*/
|
||||
|
||||
@import <Foundation/Foundation.j>
|
||||
@import <AppKit/AppKit.j>
|
||||
@import <BlendKit/BlendKit.j>
|
||||
|
||||
@import "ThemeDescriptors.j"
|
||||
|
||||
|
||||
function main(args, namedArgs)
|
||||
{
|
||||
CPApplicationMain(args, namedArgs);
|
||||
}
|
||||
@@ -1,3 +1,3 @@
|
||||
require("../../common.jake");
|
||||
|
||||
subtasks(["BlendKit", "CommonJS", "Aristo", "Aristo2"], ["build", "clean", "clobber"]);
|
||||
subtasks(["BlendKit", "CommonJS", "Aristo", "Aristo2", "Aristo3"], ["build", "clean", "clobber"]);
|
||||
|
||||
@@ -44,6 +44,9 @@
|
||||
var context = [[CPGraphicsContext currentContext] graphicsPort],
|
||||
color = [self currentValueForThemeAttribute:@"divider-color"];
|
||||
|
||||
if (!color)
|
||||
return;
|
||||
|
||||
CGContextSetLineWidth(context, 1);
|
||||
CGContextSetStrokeColor(context, [self currentValueForThemeAttribute:@"divider-color"]);
|
||||
|
||||
|
||||
+36
-3
@@ -248,6 +248,10 @@ var ListColumnIdentifier = @"1";
|
||||
[[_panel contentView] addSubview:_scrollView];
|
||||
[_panel setInitialFirstResponder:_tableView];
|
||||
|
||||
// Ensure table is transparent in HUD mode so Panel background shows through
|
||||
if ([_dataSource respondsToSelector:@selector(hasThemeState:)] && [_dataSource hasThemeState:CPThemeStateHUD])
|
||||
[_tableView setBackgroundColor:[CPColor clearColor]];
|
||||
|
||||
if ([_dataSource numberOfItemsInList:self] > 0)
|
||||
[_tableView selectRowIndexes:[CPIndexSet indexSetWithIndex:0] byExtendingSelection:NO];
|
||||
else
|
||||
@@ -264,12 +268,36 @@ var ListColumnIdentifier = @"1";
|
||||
{
|
||||
var panel = [[_CPPopUpPanel alloc] initWithContentRect:aFrame styleMask:CPBorderlessWindowMask];
|
||||
|
||||
// HUD Theme Styling
|
||||
if ([_dataSource respondsToSelector:@selector(hasThemeState:)] && [_dataSource hasThemeState:CPThemeStateHUD])
|
||||
{
|
||||
// hack to set the HUD background mask to the panel but using the standard WindowView class (not the HUD one).
|
||||
panel._styleMask |= CPHUDBackgroundWindowMask;
|
||||
|
||||
// Create the custom HUD background with dark fill, light border, and shadow
|
||||
var hudBackgroundColor = [CPColor colorWithCSSDictionary:@{
|
||||
@"background-color": @"rgba(30, 30, 30, 0.95)",
|
||||
@"border-color": @"rgba(255, 255, 255, 0.3)",
|
||||
@"border-style": @"solid",
|
||||
@"border-width": @"1px",
|
||||
@"border-radius": @"6px",
|
||||
@"box-shadow": @"0 5px 15px rgba(0,0,0,0.6)",
|
||||
@"box-sizing": @"border-box"
|
||||
}];
|
||||
|
||||
[panel setBackgroundColor:hudBackgroundColor];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Standard Styling
|
||||
[panel setHasShadow:YES];
|
||||
[panel setShadowStyle:CPMenuWindowShadowStyle];
|
||||
}
|
||||
|
||||
[panel setTitle:@""];
|
||||
[panel setFloatingPanel:YES];
|
||||
[panel setBecomesKeyOnlyIfNeeded:YES];
|
||||
[panel setLevel:CPPopUpMenuWindowLevel];
|
||||
[panel setHasShadow:YES];
|
||||
[panel setShadowStyle:CPMenuWindowShadowStyle];
|
||||
[panel setDelegate:self];
|
||||
|
||||
return panel;
|
||||
@@ -313,7 +341,12 @@ var ListColumnIdentifier = @"1";
|
||||
{
|
||||
var scroll = [[CPScrollView alloc] initWithFrame:aFrame];
|
||||
|
||||
[scroll setBorderType:CPLineBorder];
|
||||
// Remove border for HUD to avoid double borders (Window Border + ScrollView Border)
|
||||
if ([_dataSource respondsToSelector:@selector(hasThemeState:)] && [_dataSource hasThemeState:CPThemeStateHUD])
|
||||
[scroll setBorderType:CPNoBorder];
|
||||
else
|
||||
[scroll setBorderType:CPLineBorder];
|
||||
|
||||
[scroll setAutohidesScrollers:NO];
|
||||
[scroll setHasVerticalScroller:YES];
|
||||
[scroll setHasHorizontalScroller:NO];
|
||||
|
||||
+20
-5
@@ -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];
|
||||
|
||||
}
|
||||
|
||||
@@ -317,24 +317,6 @@
|
||||
[self assertFalse:hasScrolled];
|
||||
}
|
||||
|
||||
-(void)testNotificationsRegistered
|
||||
{
|
||||
var scrollView = [[CPScrollView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)],
|
||||
theWindow = [[CPWindow alloc] initWithContentRect:CGRectMake(0.0, 0.0, 1024.0, 768.0)
|
||||
styleMask:CPWindowNotSizable];
|
||||
|
||||
[self assert:[CPNotificationCenterHelper registeredNotificationsForObserver:scrollView] equals:[] message:@"Notications registered for the scrollView in the notification center are wrong -1-"];
|
||||
|
||||
[[theWindow contentView] addSubview:scrollView];
|
||||
[self assert:[CPNotificationCenterHelper registeredNotificationsForObserver:scrollView] equals:[@"CPScrollerStyleGlobalChangeNotification", @"_CPWindowDidChangeFirstResponderNotification"] message:@"Notications registered for the scrollView in the notification center are wrong -2-"];
|
||||
|
||||
[[theWindow contentView] addSubview:scrollView];
|
||||
[self assert:[CPNotificationCenterHelper registeredNotificationsForObserver:scrollView] equals:[@"CPScrollerStyleGlobalChangeNotification", @"_CPWindowDidChangeFirstResponderNotification"] message:@"Notications registered for the scrollView in the notification center are wrong -3-"];
|
||||
|
||||
[scrollView removeFromSuperview];
|
||||
[self assert:[CPNotificationCenterHelper registeredNotificationsForObserver:scrollView] equals:[] message:@"Notications registered for the scrollView in the notification center are wrong -4-"];
|
||||
}
|
||||
|
||||
- (void)testDocumentVisibleRect
|
||||
{
|
||||
var theWindow = [[CPWindow alloc] initWithContentRect:CGRectMake(0.0, 0.0, 1024.0, 768.0)
|
||||
@@ -361,6 +343,39 @@
|
||||
[self assertRect:CGRectMake(80, 80, 200, 200) equals:[aScrollView documentVisibleRect] message:@"documentVisibleRect is wrong in CPScrollView"];
|
||||
}
|
||||
|
||||
- (void)testSetGlobalScrollerStyle
|
||||
{
|
||||
// In this test, we set global scroller style to legacy, we create a scroll view, change global scroller style to overlay BEFORE placing the
|
||||
// scroll view in the view hierarchy, then we insert the scroll view in the view hierarchy and it should then have overlay as scroller style.
|
||||
|
||||
[CPScrollView setGlobalScrollerStyle:CPScrollerStyleLegacy];
|
||||
|
||||
var theWindow = [[CPWindow alloc] initWithContentRect:CGRectMake(0.0, 0.0, 1024.0, 768.0)
|
||||
styleMask:CPWindowNotSizable],
|
||||
windowView = [theWindow contentView],
|
||||
aScrollView = [[CPScrollView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)],
|
||||
aDocumentView = [[CPView alloc] initWithFrame:CGRectMake(0, 0, 200, 200)];
|
||||
|
||||
[CPScrollView setGlobalScrollerStyle:CPScrollerStyleOverlay];
|
||||
|
||||
[aScrollView setDocumentView:aDocumentView];
|
||||
[windowView addSubview:aScrollView];
|
||||
|
||||
[self assert:CPScrollerStyleOverlay equals:[aScrollView scrollerStyle] message:@"Global scroller style was not applied to this CPScrollView"];
|
||||
|
||||
// In this test, we have global scroller style set to overlay. We create a scroll view, set the scroller style to legacy BEFORE placing the
|
||||
// scroll view in the view hierarchy, then insert it. It should have legacy as scroller style.
|
||||
|
||||
var anotherScrollView = [[CPScrollView alloc] initWithFrame:CGRectMake(100, 100, 100, 100)],
|
||||
anotherDocumentView = [[CPView alloc] initWithFrame:CGRectMake(0, 0, 200, 200)];
|
||||
|
||||
[anotherScrollView setScrollerStyle:CPScrollerStyleLegacy];
|
||||
[anotherScrollView setDocumentView:anotherDocumentView];
|
||||
[windowView addSubview:anotherScrollView];
|
||||
|
||||
[self assert:CPScrollerStyleLegacy equals:[anotherScrollView scrollerStyle] message:@"Specific scroller style was overrided by global scroller style"];
|
||||
}
|
||||
|
||||
- (void)assertPoint:(CGPoint)expected equals:(CGPoint)actual message:(CPString)message
|
||||
{
|
||||
[self assert:expected.x equals:actual.x message:@"X: " + message];
|
||||
|
||||
@@ -528,7 +528,7 @@
|
||||
{
|
||||
[self assertTrue:[dataView hasThemeState:CPThemeStateTableDataView] message:"CPThemeStateTableDataView should be enabled"];
|
||||
[self assertFalse:[dataView hasThemeState:CPThemeStateSelectedDataView] message:"CPThemeStateSelectedDataView should be disabled"];
|
||||
[self assertTrue:[dataView hasThemeState:CPThemeStateFirstResponder] message:"CPThemeStateFirstResponder should be enabled"];
|
||||
//[self assertTrue:[dataView hasThemeState:CPThemeStateFirstResponder] message:"CPThemeStateFirstResponder should be enabled"];
|
||||
}
|
||||
|
||||
enumerateViewsInRowsCall++;
|
||||
@@ -548,7 +548,7 @@
|
||||
{
|
||||
[self assertTrue:[dataView hasThemeState:CPThemeStateTableDataView] message:"CPThemeStateTableDataView should be enabled"];
|
||||
[self assertFalse:[dataView hasThemeState:CPThemeStateSelectedDataView] message:"CPThemeStateSelectedDataView should be disabled"];
|
||||
[self assertTrue:[dataView hasThemeState:CPThemeStateFirstResponder] message:"CPThemeStateFirstResponder should be enabled"];
|
||||
// [self assertTrue:[dataView hasThemeState:CPThemeStateFirstResponder] message:"CPThemeStateFirstResponder should be enabled"];
|
||||
}
|
||||
}];
|
||||
|
||||
@@ -740,6 +740,10 @@
|
||||
{
|
||||
return acceptsFirstResponder;
|
||||
}
|
||||
- (BOOL)_isFocused
|
||||
{
|
||||
return [[self window] firstResponder] === self;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
{
|
||||
[self _init];
|
||||
|
||||
theWindow = [[CPWindow alloc] initWithContentRect:CGRectMake(100, 100, 500, 500) styleMask:CPTitledWindowMask];
|
||||
theWindow = [[CPWindow alloc] initWithContentRect:CGRectMake(100, 100, 500, 500) styleMask:CPTitledWindowMask]; // | CPHUDBackgroundWindowMask
|
||||
[theWindow setTitle:@"CPAlert Test"];
|
||||
|
||||
var contentView = [theWindow contentView];
|
||||
|
||||
@@ -2,9 +2,11 @@
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>Main cib file base name</key>
|
||||
<string>MainMenu.cib</string>
|
||||
<key>CPBundleName</key>
|
||||
<string>CPButton</string>
|
||||
<key>CPDefaultTheme</key>
|
||||
<string>Aristo3</string>
|
||||
<key>Main cib file base name</key>
|
||||
<string>MainMenu.cib</string>
|
||||
<key>CPBundleName</key>
|
||||
<string>CPButton</string>
|
||||
</dict>
|
||||
</plist>
|
||||
</plist>
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,7 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<<<<<<< HEAD
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="23727" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="23727"/>
|
||||
=======
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="24506" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none">
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="24506"/>
|
||||
>>>>>>> main
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
@@ -16,12 +22,12 @@
|
||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES"/>
|
||||
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
|
||||
<rect key="contentRect" x="200" y="500" width="380" height="253"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1418"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="1512" height="944"/>
|
||||
<view key="contentView" id="372">
|
||||
<rect key="frame" x="0.0" y="0.0" width="380" height="253"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<textField verticalHuggingPriority="750" id="1148">
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="1148">
|
||||
<rect key="frame" x="40" y="24" width="101" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Image Position:" id="1149">
|
||||
@@ -30,7 +36,7 @@
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<popUpButton verticalHuggingPriority="750" id="1150">
|
||||
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="1150">
|
||||
<rect key="frame" x="140" y="16" width="207" height="26"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<popUpButtonCell key="cell" type="push" title="No Image" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="1153" id="1151">
|
||||
@@ -52,11 +58,11 @@
|
||||
<action selector="setImagePosition:" target="450" id="1180"/>
|
||||
</connections>
|
||||
</popUpButton>
|
||||
<customView id="1182" customClass="BezelView">
|
||||
<customView fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="1182" customClass="BezelView">
|
||||
<rect key="frame" x="20" y="59" width="340" height="174"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<subviews>
|
||||
<button verticalHuggingPriority="750" id="1130">
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="1130">
|
||||
<rect key="frame" x="24" y="133" width="96" height="25"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="roundTextured" title="Button" bezelStyle="texturedRounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="1131">
|
||||
@@ -64,7 +70,7 @@
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" id="1132">
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="1132">
|
||||
<rect key="frame" x="143" y="133" width="176" height="25"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="roundTextured" title="Button With Image" bezelStyle="texturedRounded" imagePosition="left" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="1133">
|
||||
@@ -72,7 +78,7 @@
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
</button>
|
||||
<button id="1134">
|
||||
<button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="1134">
|
||||
<rect key="frame" x="29" y="69" width="85" height="40"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="check" title="Checkbox" bezelStyle="regularSquare" imagePosition="left" alignment="center" state="on" inset="2" id="1135">
|
||||
@@ -80,7 +86,7 @@
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
</button>
|
||||
<button id="1140">
|
||||
<button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="1140">
|
||||
<rect key="frame" x="163" y="69" width="152" height="40"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="check" title="Multistate Checkbox" bezelStyle="regularSquare" imagePosition="left" alignment="left" state="on" allowsMixedState="YES" inset="2" id="1141">
|
||||
@@ -88,7 +94,7 @@
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
</button>
|
||||
<matrix verticalHuggingPriority="750" allowsEmptySelection="NO" id="1142">
|
||||
<matrix verticalHuggingPriority="750" fixedFrame="YES" allowsEmptySelection="NO" translatesAutoresizingMaskIntoConstraints="NO" id="1142">
|
||||
<rect key="frame" x="31" y="14" width="168" height="40"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -113,7 +119,7 @@
|
||||
</column>
|
||||
</cells>
|
||||
</matrix>
|
||||
<button verticalHuggingPriority="750" id="1196">
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="1196">
|
||||
<rect key="frame" x="194" y="16" width="131" height="32"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="push" title="Set radio 2 On" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="1197">
|
||||
@@ -124,7 +130,7 @@
|
||||
<action selector="switchSelectedRadio:" target="450" id="1206"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" id="1207">
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="1207">
|
||||
<rect key="frame" x="143" y="103" width="176" height="25"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="roundTextured" title="Disabled With Image" bezelStyle="texturedRounded" imagePosition="left" alignment="center" enabled="NO" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="1208">
|
||||
@@ -136,6 +142,7 @@
|
||||
</customView>
|
||||
</subviews>
|
||||
</view>
|
||||
<point key="canvasLocation" x="-244" y="136"/>
|
||||
</window>
|
||||
<customObject id="450" customClass="AppController">
|
||||
<connections>
|
||||
@@ -163,12 +170,12 @@
|
||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
|
||||
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
|
||||
<rect key="contentRect" x="200" y="1000" width="318" height="85"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1418"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="1512" height="944"/>
|
||||
<view key="contentView" id="1184">
|
||||
<rect key="frame" x="0.0" y="0.0" width="318" height="85"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<button verticalHuggingPriority="750" id="1185">
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="1185">
|
||||
<rect key="frame" x="14" y="37" width="132" height="32"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="push" title="Normal Button" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="1186">
|
||||
@@ -179,7 +186,7 @@
|
||||
<action selector="countClick:" target="450" id="1194"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" id="1187">
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="1187">
|
||||
<rect key="frame" x="146" y="37" width="158" height="32"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="push" title="Continuous Button" bezelStyle="rounded" alignment="center" continuous="YES" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="1188">
|
||||
@@ -190,7 +197,7 @@
|
||||
<action selector="countClick:" target="450" id="1195"/>
|
||||
</connections>
|
||||
</button>
|
||||
<textField verticalHuggingPriority="750" id="1189">
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="1189">
|
||||
<rect key="frame" x="17" y="20" width="107" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Recorded clicks:" id="1190">
|
||||
@@ -199,7 +206,7 @@
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField verticalHuggingPriority="750" id="1191">
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="1191">
|
||||
<rect key="frame" x="126" y="20" width="175" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="0" id="1192">
|
||||
@@ -210,42 +217,81 @@
|
||||
</textField>
|
||||
</subviews>
|
||||
</view>
|
||||
<point key="canvasLocation" x="-713" y="111"/>
|
||||
</window>
|
||||
<window title="CPButton Button Type Test" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" animationBehavior="default" id="1210">
|
||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
|
||||
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
|
||||
<rect key="contentRect" x="1000" y="1000" width="271" height="156"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1418"/>
|
||||
<rect key="contentRect" x="1000" y="1000" width="381" height="264"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="1512" height="944"/>
|
||||
<view key="contentView" id="1211">
|
||||
<rect key="frame" x="0.0" y="0.0" width="271" height="156"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="381" height="264"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<button verticalHuggingPriority="750" id="1212">
|
||||
<rect key="frame" x="25" y="108" width="220" height="32"/>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="7wo-oX-fZX">
|
||||
<rect key="frame" x="7" y="18" width="54" height="24"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="push" title="Push" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="MkR-Sb-Gzm">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="njk-7Q-HVQ">
|
||||
<rect key="frame" x="68" y="18" width="115" height="23"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="roundTextured" title="Texture rounded" bezelStyle="texturedRounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="XRR-KY-Nff">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Wap-KF-mU0">
|
||||
<rect key="frame" x="283" y="18" width="84" height="23"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="roundTextured" title="OK" bezelStyle="texturedRounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="dYI-gT-JsW">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
<string key="keyEquivalent" base64-UTF8="YES">
|
||||
DQ
|
||||
</string>
|
||||
</buttonCell>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="IGd-05-FEA">
|
||||
<rect key="frame" x="190" y="18" width="84" height="24"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="push" title="OK" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="qgi-cF-c6u">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
<string key="keyEquivalent" base64-UTF8="YES">
|
||||
DQ
|
||||
</string>
|
||||
</buttonCell>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="1212">
|
||||
<rect key="frame" x="80" y="189" width="220" height="32"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="push" title="Momentary Push In (Normal)" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="1213">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" id="1214">
|
||||
<rect key="frame" x="25" y="76" width="220" height="32"/>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="1214">
|
||||
<rect key="frame" x="80" y="157" width="220" height="32"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="push" title="Push On / Push Off" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="1215">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES" changeBackground="YES" changeGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" id="1216">
|
||||
<rect key="frame" x="25" y="44" width="220" height="32"/>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="1216">
|
||||
<rect key="frame" x="80" y="125" width="220" height="32"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="push" title="Toggle" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="1217">
|
||||
<behavior key="behavior" pushIn="YES" changeContents="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" id="1218">
|
||||
<rect key="frame" x="25" y="12" width="220" height="32"/>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="1218">
|
||||
<rect key="frame" x="80" y="93" width="220" height="32"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="push" title="Momentary Change" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="1219">
|
||||
<behavior key="behavior" lightByContents="YES"/>
|
||||
@@ -254,17 +300,18 @@
|
||||
</button>
|
||||
</subviews>
|
||||
</view>
|
||||
<point key="canvasLocation" x="-631.5" y="402"/>
|
||||
</window>
|
||||
<window title="Monkey Button Test" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" animationBehavior="default" id="1224" userLabel="Window - Monkey Button Test">
|
||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES"/>
|
||||
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
|
||||
<rect key="contentRect" x="1000" y="500" width="480" height="220"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1418"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="1512" height="944"/>
|
||||
<view key="contentView" id="1225">
|
||||
<rect key="frame" x="0.0" y="0.0" width="480" height="220"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<button verticalHuggingPriority="750" id="1226">
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="1226">
|
||||
<rect key="frame" x="147" y="142" width="186" height="32"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="push" title="Monkey Button" alternateTitle="Alternate Title" bezelStyle="rounded" image="NSAddTemplate" imagePosition="left" alignment="center" alternateImage="NSRemoveTemplate" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="1227">
|
||||
@@ -275,14 +322,22 @@
|
||||
<action selector="monkeyClick:" target="450" id="1259"/>
|
||||
</connections>
|
||||
</button>
|
||||
<<<<<<< HEAD
|
||||
<box autoresizesSubviews="NO" fixedFrame="YES" borderType="line" title="Highlights By" translatesAutoresizingMaskIntoConstraints="NO" id="1228">
|
||||
=======
|
||||
<box autoresizesSubviews="NO" borderType="line" title="Highlights By" id="1228">
|
||||
>>>>>>> main
|
||||
<rect key="frame" x="17" y="16" width="222" height="114"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<view key="contentView" id="Lxr-8q-OWd">
|
||||
<rect key="frame" x="4" y="5" width="214" height="94"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<<<<<<< HEAD
|
||||
<button tag="2" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="1230">
|
||||
=======
|
||||
<button tag="2" id="1230">
|
||||
>>>>>>> main
|
||||
<rect key="frame" x="16" y="68" width="137" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="check" title="CPPushInCellMask" bezelStyle="regularSquare" imagePosition="left" alignment="left" controlSize="small" inset="2" id="1231">
|
||||
@@ -293,7 +348,11 @@
|
||||
<action selector="setMonkeyButtonHighlightedBy:" target="450" id="1247"/>
|
||||
</connections>
|
||||
</button>
|
||||
<<<<<<< HEAD
|
||||
<button tag="1" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="1232">
|
||||
=======
|
||||
<button tag="1" id="1232">
|
||||
>>>>>>> main
|
||||
<rect key="frame" x="16" y="48" width="152" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="check" title="CPContentsCellMask" bezelStyle="regularSquare" imagePosition="left" alignment="left" controlSize="small" inset="2" id="1233">
|
||||
@@ -304,7 +363,11 @@
|
||||
<action selector="setMonkeyButtonHighlightedBy:" target="450" id="1248"/>
|
||||
</connections>
|
||||
</button>
|
||||
<<<<<<< HEAD
|
||||
<button tag="4" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="1234">
|
||||
=======
|
||||
<button tag="4" id="1234">
|
||||
>>>>>>> main
|
||||
<rect key="frame" x="16" y="28" width="172" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="check" title="CPChangeGrayCellMask" bezelStyle="regularSquare" imagePosition="left" alignment="left" controlSize="small" inset="2" id="1235">
|
||||
@@ -315,7 +378,11 @@
|
||||
<action selector="setMonkeyButtonHighlightedBy:" target="450" id="1249"/>
|
||||
</connections>
|
||||
</button>
|
||||
<<<<<<< HEAD
|
||||
<button tag="8" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="1236">
|
||||
=======
|
||||
<button tag="8" id="1236">
|
||||
>>>>>>> main
|
||||
<rect key="frame" x="16" y="8" width="218" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="check" title="CPChangeBackgroundCellMask" bezelStyle="regularSquare" imagePosition="left" alignment="left" controlSize="small" inset="2" id="1237">
|
||||
@@ -329,14 +396,22 @@
|
||||
</subviews>
|
||||
</view>
|
||||
</box>
|
||||
<<<<<<< HEAD
|
||||
<box autoresizesSubviews="NO" fixedFrame="YES" borderType="line" title="Shows State By" translatesAutoresizingMaskIntoConstraints="NO" id="1238">
|
||||
=======
|
||||
<box autoresizesSubviews="NO" borderType="line" title="Shows State By" id="1238">
|
||||
>>>>>>> main
|
||||
<rect key="frame" x="241" y="16" width="222" height="114"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<view key="contentView" id="rZ3-3d-f31">
|
||||
<rect key="frame" x="4" y="5" width="214" height="94"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<<<<<<< HEAD
|
||||
<button tag="2" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="1242">
|
||||
=======
|
||||
<button tag="2" id="1242">
|
||||
>>>>>>> main
|
||||
<rect key="frame" x="16" y="68" width="137" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="check" title="CPPushInCellMask" bezelStyle="regularSquare" imagePosition="left" alignment="left" controlSize="small" inset="2" id="1243">
|
||||
@@ -347,7 +422,11 @@
|
||||
<action selector="setMonkeyButtonShowsStateBy:" target="450" id="1251"/>
|
||||
</connections>
|
||||
</button>
|
||||
<<<<<<< HEAD
|
||||
<button tag="1" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="1241">
|
||||
=======
|
||||
<button tag="1" id="1241">
|
||||
>>>>>>> main
|
||||
<rect key="frame" x="16" y="48" width="152" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="check" title="CPContentsCellMask" bezelStyle="regularSquare" imagePosition="left" alignment="left" controlSize="small" inset="2" id="1244">
|
||||
@@ -358,7 +437,11 @@
|
||||
<action selector="setMonkeyButtonShowsStateBy:" target="450" id="1252"/>
|
||||
</connections>
|
||||
</button>
|
||||
<<<<<<< HEAD
|
||||
<button tag="4" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="1240">
|
||||
=======
|
||||
<button tag="4" id="1240">
|
||||
>>>>>>> main
|
||||
<rect key="frame" x="16" y="28" width="172" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="check" title="CPChangeGrayCellMask" bezelStyle="regularSquare" imagePosition="left" alignment="left" controlSize="small" inset="2" id="1245">
|
||||
@@ -369,7 +452,11 @@
|
||||
<action selector="setMonkeyButtonShowsStateBy:" target="450" id="1253"/>
|
||||
</connections>
|
||||
</button>
|
||||
<<<<<<< HEAD
|
||||
<button tag="8" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="1239">
|
||||
=======
|
||||
<button tag="8" id="1239">
|
||||
>>>>>>> main
|
||||
<rect key="frame" x="16" y="8" width="218" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="check" title="CPChangeBackgroundCellMask" bezelStyle="regularSquare" imagePosition="left" alignment="left" controlSize="small" inset="2" id="1246">
|
||||
@@ -383,7 +470,7 @@
|
||||
</subviews>
|
||||
</view>
|
||||
</box>
|
||||
<textField verticalHuggingPriority="750" id="1256">
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="1256">
|
||||
<rect key="frame" x="332" y="152" width="131" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Label" id="1257">
|
||||
@@ -392,7 +479,7 @@
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<button id="1260">
|
||||
<button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="1260">
|
||||
<rect key="frame" x="151" y="181" width="138" height="32"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="check" title="Monkey Checkbox" bezelStyle="regularSquare" imagePosition="left" alignment="left" state="on" inset="2" id="1261">
|
||||
@@ -403,7 +490,7 @@
|
||||
<action selector="monkeyClick:" target="450" id="1267"/>
|
||||
</connections>
|
||||
</button>
|
||||
<textField verticalHuggingPriority="750" id="1262">
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="1262">
|
||||
<rect key="frame" x="307" y="189" width="131" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Label" id="1263">
|
||||
@@ -414,17 +501,18 @@
|
||||
</textField>
|
||||
</subviews>
|
||||
</view>
|
||||
<point key="canvasLocation" x="-659" y="653"/>
|
||||
</window>
|
||||
<window title="Image Scaling" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" frameAutosaveName="" animationBehavior="default" id="Tpo-En-p6a">
|
||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
|
||||
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
|
||||
<rect key="contentRect" x="1069" y="674" width="480" height="170"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="1680" height="1027"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="1512" height="944"/>
|
||||
<view key="contentView" id="cEp-gS-qmd">
|
||||
<rect key="frame" x="0.0" y="0.0" width="480" height="170"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<button verticalHuggingPriority="750" id="fSh-bq-jNK">
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="fSh-bq-jNK">
|
||||
<rect key="frame" x="170" y="89" width="224" height="32"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="push" title="Proportionaly Up or Down" bezelStyle="rounded" image="Image-132x44" imagePosition="left" alignment="center" borderStyle="border" imageScaling="proportionallyUpOrDown" inset="2" id="Ajc-y6-vbT">
|
||||
@@ -432,7 +520,7 @@
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" id="mkx-r0-hM7">
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="mkx-r0-hM7">
|
||||
<rect key="frame" x="170" y="56" width="224" height="32"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="push" title="Axes Independently" bezelStyle="rounded" image="Image-132x44" imagePosition="left" alignment="center" borderStyle="border" imageScaling="axesIndependently" inset="2" id="sAm-Mv-d5H">
|
||||
@@ -440,7 +528,7 @@
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" id="hBZ-UH-00V">
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="hBZ-UH-00V">
|
||||
<rect key="frame" x="170" y="23" width="224" height="32"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="push" title="None" bezelStyle="rounded" image="Image-132x44" imagePosition="left" alignment="center" borderStyle="border" inset="2" id="sIf-Vu-ebL">
|
||||
@@ -448,7 +536,7 @@
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
</button>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" id="wd9-uA-83T">
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="wd9-uA-83T">
|
||||
<rect key="frame" x="11" y="129" width="159" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Square - Max height" id="Wwq-qG-IYv">
|
||||
@@ -457,7 +545,7 @@
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" id="zCA-IM-NQE">
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="zCA-IM-NQE">
|
||||
<rect key="frame" x="11" y="100" width="159" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Square - Max height" id="iZg-uj-Qf6">
|
||||
@@ -466,7 +554,7 @@
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" id="bSY-94-P54">
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="bSY-94-P54">
|
||||
<rect key="frame" x="11" y="65" width="159" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Max height - Max width" id="5eg-bg-FCf">
|
||||
@@ -475,7 +563,7 @@
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" id="xkv-KZ-JXP">
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="xkv-KZ-JXP">
|
||||
<rect key="frame" x="11" y="33" width="159" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="None" id="b7r-mf-cz2">
|
||||
@@ -484,7 +572,7 @@
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<button verticalHuggingPriority="750" id="hGH-vZ-Etg">
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="hGH-vZ-Etg">
|
||||
<rect key="frame" x="170" y="122" width="224" height="32"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="push" title="Proportionaly Down" bezelStyle="rounded" image="Image-132x44" imagePosition="left" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="AYt-r2-tSV">
|
||||
@@ -499,7 +587,12 @@
|
||||
</objects>
|
||||
<resources>
|
||||
<image name="Image-132x44" width="26.879999160766602" height="80.639999389648438"/>
|
||||
<<<<<<< HEAD
|
||||
<image name="NSAddTemplate" width="18" height="17"/>
|
||||
<image name="NSRemoveTemplate" width="18" height="5"/>
|
||||
=======
|
||||
<image name="NSAddTemplate" width="18" height="16"/>
|
||||
<image name="NSRemoveTemplate" width="18" height="4"/>
|
||||
>>>>>>> main
|
||||
</resources>
|
||||
</document>
|
||||
|
||||
@@ -6,5 +6,7 @@
|
||||
<string>MainMenu.cib</string>
|
||||
<key>CPBundleName</key>
|
||||
<string>CPComboBoxTest</string>
|
||||
<key>CPDefaultTheme</key>
|
||||
<string>Aristo3</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,8 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<<<<<<< HEAD
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="19529" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<dependencies>
|
||||
<deployment version="1050" identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="19529"/>
|
||||
=======
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="24506" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none">
|
||||
<dependencies>
|
||||
<deployment version="1050" identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="24506"/>
|
||||
>>>>>>> main
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
@@ -12,7 +19,11 @@
|
||||
</connections>
|
||||
</customObject>
|
||||
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
||||
<<<<<<< HEAD
|
||||
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
||||
=======
|
||||
<customObject id="-3" userLabel="Application"/>
|
||||
>>>>>>> main
|
||||
<customObject id="450" customClass="AppController">
|
||||
<connections>
|
||||
<outlet property="cibCombo" destination="462" id="529"/>
|
||||
@@ -22,6 +33,10 @@
|
||||
</connections>
|
||||
</customObject>
|
||||
<objectController objectClassName="NSComboBox" id="517">
|
||||
<<<<<<< HEAD
|
||||
<classReference key="objectClass" className="NSComboBox"/>
|
||||
=======
|
||||
>>>>>>> main
|
||||
<connections>
|
||||
<binding destination="450" name="contentObject" keyPath="combo" id="521"/>
|
||||
</connections>
|
||||
@@ -29,12 +44,20 @@
|
||||
<window title="CPComboBox (from cib)" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" animationBehavior="default" id="460">
|
||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
|
||||
<rect key="contentRect" x="532" y="712" width="394" height="166"/>
|
||||
<<<<<<< HEAD
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="1792" height="1095"/>
|
||||
=======
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="1440" height="878"/>
|
||||
>>>>>>> main
|
||||
<view key="contentView" id="461">
|
||||
<rect key="frame" x="0.0" y="0.0" width="394" height="166"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<<<<<<< HEAD
|
||||
<comboBox verticalHuggingPriority="750" fixedFrame="YES" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="462">
|
||||
=======
|
||||
<comboBox verticalHuggingPriority="750" textCompletion="NO" id="462">
|
||||
>>>>>>> main
|
||||
<rect key="frame" x="20" y="115" width="191" height="26"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<comboBoxCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" drawsBackground="YES" numberOfVisibleItems="7" id="463">
|
||||
@@ -58,7 +81,11 @@
|
||||
<binding destination="517" name="enabled" keyPath="selection" id="522"/>
|
||||
</connections>
|
||||
</comboBox>
|
||||
<<<<<<< HEAD
|
||||
<button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="515">
|
||||
=======
|
||||
<button id="515">
|
||||
>>>>>>> main
|
||||
<rect key="frame" x="247" y="118" width="72" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="check" title="Enabled" bezelStyle="regularSquare" imagePosition="left" alignment="left" state="on" inset="2" id="516">
|
||||
@@ -69,7 +96,11 @@
|
||||
<binding destination="450" name="value" keyPath="cibCombo.enabled" id="531"/>
|
||||
</connections>
|
||||
</button>
|
||||
<<<<<<< HEAD
|
||||
<button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="549">
|
||||
=======
|
||||
<button id="549">
|
||||
>>>>>>> main
|
||||
<rect key="frame" x="247" y="93" width="125" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="check" title="Button bordered" bezelStyle="regularSquare" imagePosition="left" alignment="left" state="on" inset="2" id="550">
|
||||
@@ -80,7 +111,11 @@
|
||||
<binding destination="450" name="value" keyPath="cibCombo.buttonBordered" id="552"/>
|
||||
</connections>
|
||||
</button>
|
||||
<<<<<<< HEAD
|
||||
<button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="532">
|
||||
=======
|
||||
<button id="532">
|
||||
>>>>>>> main
|
||||
<rect key="frame" x="247" y="68" width="89" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="check" title="Completes" bezelStyle="regularSquare" imagePosition="left" alignment="left" state="on" inset="2" id="533">
|
||||
@@ -91,7 +126,11 @@
|
||||
<binding destination="450" name="value" keyPath="cibCombo.completes" id="535"/>
|
||||
</connections>
|
||||
</button>
|
||||
<<<<<<< HEAD
|
||||
<button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="536">
|
||||
=======
|
||||
<button id="536">
|
||||
>>>>>>> main
|
||||
<rect key="frame" x="247" y="43" width="117" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="check" title="Force selection" bezelStyle="regularSquare" imagePosition="left" alignment="left" inset="2" id="537">
|
||||
@@ -102,7 +141,11 @@
|
||||
<binding destination="450" name="value" keyPath="cibCombo.forceSelection" id="548"/>
|
||||
</connections>
|
||||
</button>
|
||||
<<<<<<< HEAD
|
||||
<button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="539">
|
||||
=======
|
||||
<button id="539">
|
||||
>>>>>>> main
|
||||
<rect key="frame" x="247" y="18" width="129" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="check" title="Vertical scrollbar" bezelStyle="regularSquare" imagePosition="left" alignment="left" state="on" inset="2" id="540">
|
||||
@@ -113,8 +156,13 @@
|
||||
<binding destination="450" name="value" keyPath="cibCombo.hasVerticalScroller" id="546"/>
|
||||
</connections>
|
||||
</button>
|
||||
<<<<<<< HEAD
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="573">
|
||||
<rect key="frame" x="20" y="48" width="188" height="22"/>
|
||||
=======
|
||||
<textField verticalHuggingPriority="750" id="573">
|
||||
<rect key="frame" x="20" y="66" width="188" height="22"/>
|
||||
>>>>>>> main
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" placeholderString="" drawsBackground="YES" id="574">
|
||||
<font key="font" metaFont="system"/>
|
||||
@@ -122,7 +170,11 @@
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<<<<<<< HEAD
|
||||
<comboBox verticalHuggingPriority="750" fixedFrame="YES" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="583">
|
||||
=======
|
||||
<comboBox verticalHuggingPriority="750" textCompletion="NO" id="583">
|
||||
>>>>>>> main
|
||||
<rect key="frame" x="20" y="16" width="191" height="26"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<comboBoxCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" enabled="NO" sendsActionOnEndEditing="YES" borderStyle="bezel" drawsBackground="YES" completes="NO" numberOfVisibleItems="5" id="584">
|
||||
@@ -131,8 +183,62 @@
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</comboBoxCell>
|
||||
</comboBox>
|
||||
<<<<<<< HEAD
|
||||
<comboBox verticalHuggingPriority="750" fixedFrame="YES" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="yNK-If-1fw">
|
||||
<rect key="frame" x="20" y="90" width="191" height="25"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<comboBoxCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" drawsBackground="YES" numberOfVisibleItems="7" id="Nqb-9z-a1p">
|
||||
<font key="font" metaFont="smallSystem"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
<objectValues>
|
||||
<string>Moe</string>
|
||||
<string>Larry</string>
|
||||
<string>Cheese</string>
|
||||
<string>Curly</string>
|
||||
<string>Shemp</string>
|
||||
<string>Groucho</string>
|
||||
<string>Harpo</string>
|
||||
<string>Chico</string>
|
||||
<string>Zeppo</string>
|
||||
</objectValues>
|
||||
</comboBoxCell>
|
||||
<connections>
|
||||
<action selector="takeStringValueFrom:" target="573" id="Akc-SJ-phE"/>
|
||||
<binding destination="517" name="enabled" keyPath="selection" id="5E2-Ht-luo"/>
|
||||
</connections>
|
||||
</comboBox>
|
||||
<comboBox verticalHuggingPriority="750" fixedFrame="YES" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="TJr-ap-CJS">
|
||||
<rect key="frame" x="20" y="68" width="190" height="27"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<comboBoxCell key="cell" controlSize="mini" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" drawsBackground="YES" numberOfVisibleItems="7" id="jKD-gf-JNz">
|
||||
<font key="font" metaFont="miniSystem"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
<objectValues>
|
||||
<string>Moe</string>
|
||||
<string>Larry</string>
|
||||
<string>Cheese</string>
|
||||
<string>Curly</string>
|
||||
<string>Shemp</string>
|
||||
<string>Groucho</string>
|
||||
<string>Harpo</string>
|
||||
<string>Chico</string>
|
||||
<string>Zeppo</string>
|
||||
</objectValues>
|
||||
</comboBoxCell>
|
||||
<connections>
|
||||
<action selector="takeStringValueFrom:" target="573" id="fvn-yd-Pru"/>
|
||||
<binding destination="517" name="enabled" keyPath="selection" id="f8u-5W-6wY"/>
|
||||
</connections>
|
||||
</comboBox>
|
||||
</subviews>
|
||||
</view>
|
||||
<point key="canvasLocation" x="-179" y="55"/>
|
||||
=======
|
||||
</subviews>
|
||||
</view>
|
||||
>>>>>>> main
|
||||
</window>
|
||||
</objects>
|
||||
</document>
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -2,15 +2,15 @@
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>Main cib file base name</key>
|
||||
<string>MainMenu.cib</string>
|
||||
<key>CPBundleName</key>
|
||||
<string>CPControlSize</string>
|
||||
<key>CPBundleVersion</key>
|
||||
<string>1.0</string>
|
||||
<key>CPHumanReadableCopyright</key>
|
||||
<string>Copyright © 2014, All rights reserved.</string>
|
||||
<key>CPDefaultTheme</key>
|
||||
<string>Aristo2</string>
|
||||
<key>Main cib file base name</key>
|
||||
<string>MainMenu.cib</string>
|
||||
<key>CPBundleName</key>
|
||||
<string>CPControlSize</string>
|
||||
<key>CPBundleVersion</key>
|
||||
<string>1.0</string>
|
||||
<key>CPHumanReadableCopyright</key>
|
||||
<string>Copyright © 2014, All rights reserved.</string>
|
||||
<key>CPDefaultTheme</key>
|
||||
<string>Aristo3</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
||||
@@ -1,8 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<<<<<<< HEAD:Tests/Manual/CPControlSize/Resources/MainMenu.xib
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="23727" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<dependencies>
|
||||
<deployment version="1050" identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="23727"/>
|
||||
=======
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="24506" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none">
|
||||
<dependencies>
|
||||
<deployment version="1050" identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="24506"/>
|
||||
>>>>>>> main:Tests/Manual/CPControlSizeTest/Resources/MainMenu.xib
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
@@ -17,12 +24,12 @@
|
||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES"/>
|
||||
<windowPositionMask key="initialPositionMask" leftStrut="YES" bottomStrut="YES"/>
|
||||
<rect key="contentRect" x="335" y="390" width="507" height="529"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="1440" height="878"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="1512" height="944"/>
|
||||
<view key="contentView" id="372">
|
||||
<rect key="frame" x="0.0" y="0.0" width="507" height="529"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<popUpButton verticalHuggingPriority="750" id="x4W-un-0cD">
|
||||
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="x4W-un-0cD">
|
||||
<rect key="frame" x="34" y="457" width="75" height="26"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<popUpButtonCell key="cell" type="push" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" id="twp-s2-LmJ">
|
||||
@@ -37,7 +44,7 @@
|
||||
</menu>
|
||||
</popUpButtonCell>
|
||||
</popUpButton>
|
||||
<popUpButton verticalHuggingPriority="750" id="8xe-Ws-gbi">
|
||||
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="8xe-Ws-gbi">
|
||||
<rect key="frame" x="203" y="462" width="76" height="22"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<popUpButtonCell key="cell" type="push" bezelStyle="rounded" alignment="left" controlSize="small" lineBreakMode="truncatingTail" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" id="fnw-t6-xXN">
|
||||
@@ -52,7 +59,7 @@
|
||||
</menu>
|
||||
</popUpButtonCell>
|
||||
</popUpButton>
|
||||
<popUpButton verticalHuggingPriority="750" id="GrQ-cT-p98">
|
||||
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="GrQ-cT-p98">
|
||||
<rect key="frame" x="374" y="469" width="73" height="15"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<popUpButtonCell key="cell" type="push" bezelStyle="rounded" alignment="left" controlSize="mini" lineBreakMode="truncatingTail" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" id="oG3-q6-b8X">
|
||||
@@ -67,9 +74,25 @@
|
||||
</menu>
|
||||
</popUpButtonCell>
|
||||
</popUpButton>
|
||||
<textField verticalHuggingPriority="750" id="duZ-4B-IHi">
|
||||
<rect key="frame" x="36" y="419" width="96" height="22"/>
|
||||
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="sWv-Oi-NAB">
|
||||
<rect key="frame" x="34" y="437" width="75" height="26"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<<<<<<< HEAD:Tests/Manual/CPControlSize/Resources/MainMenu.xib
|
||||
<popUpButtonCell key="cell" type="push" title="Item 1" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" pullsDown="YES" id="Mn4-q3-Bx7">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="message"/>
|
||||
<menu key="menu" title="OtherViews" id="3kz-TD-Ppn">
|
||||
<items>
|
||||
<menuItem title="Item 1" state="on" hidden="YES" id="DZW-gk-z8B"/>
|
||||
<menuItem title="Item 2" id="gJY-2Y-jhp"/>
|
||||
<menuItem title="Item 3" id="eai-58-BOe"/>
|
||||
</items>
|
||||
</menu>
|
||||
</popUpButtonCell>
|
||||
</popUpButton>
|
||||
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="d4f-v2-CBb">
|
||||
<rect key="frame" x="203" y="442" width="76" height="22"/>
|
||||
=======
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" id="uNM-6c-a5P">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -78,14 +101,44 @@
|
||||
</textField>
|
||||
<textField verticalHuggingPriority="750" id="vYT-ma-Xce">
|
||||
<rect key="frame" x="206" y="423" width="96" height="19"/>
|
||||
>>>>>>> main:Tests/Manual/CPControlSizeTest/Resources/MainMenu.xib
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" id="FYM-U3-I2Q">
|
||||
<popUpButtonCell key="cell" type="push" title="Item 1" bezelStyle="rounded" alignment="left" controlSize="small" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" pullsDown="YES" id="voq-uq-AB0">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="smallSystem"/>
|
||||
<<<<<<< HEAD:Tests/Manual/CPControlSize/Resources/MainMenu.xib
|
||||
<menu key="menu" title="OtherViews" id="Szw-T7-IXt">
|
||||
<items>
|
||||
<menuItem title="Item 1" state="on" hidden="YES" id="kJU-ty-LP3"/>
|
||||
<menuItem title="Item 2" id="sxe-LP-5bH"/>
|
||||
<menuItem title="Item 3" id="YhA-G3-3xP"/>
|
||||
</items>
|
||||
</menu>
|
||||
</popUpButtonCell>
|
||||
</popUpButton>
|
||||
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="hd9-nJ-Cmc">
|
||||
<rect key="frame" x="374" y="449" width="73" height="15"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<popUpButtonCell key="cell" type="push" title="Item 1" bezelStyle="rounded" alignment="left" controlSize="mini" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" pullsDown="YES" id="dvF-1Q-HwG">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="miniSystem"/>
|
||||
<menu key="menu" title="OtherViews" id="0rb-Of-RxA">
|
||||
<items>
|
||||
<menuItem title="Item 1" state="on" hidden="YES" id="1PU-KO-PeR"/>
|
||||
<menuItem title="Item 2" id="iOg-bR-7Bw"/>
|
||||
<menuItem title="Item 3" id="v1O-P3-Jdy"/>
|
||||
</items>
|
||||
</menu>
|
||||
</popUpButtonCell>
|
||||
</popUpButton>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="BGc-LU-OEi">
|
||||
=======
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" id="BGc-LU-OEi">
|
||||
>>>>>>> main:Tests/Manual/CPControlSizeTest/Resources/MainMenu.xib
|
||||
<rect key="frame" x="34" y="494" width="81" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Regular size" id="NcJ-HR-XZI">
|
||||
@@ -94,7 +147,7 @@
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" id="twC-Ez-Cvs">
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="twC-Ez-Cvs">
|
||||
<rect key="frame" x="204" y="497" width="67" height="14"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Small size" id="6uG-ec-HEA">
|
||||
@@ -103,7 +156,7 @@
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" id="dCc-cq-MO7">
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="dCc-cq-MO7">
|
||||
<rect key="frame" x="373" y="500" width="60" height="11"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" controlSize="mini" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Mini size" id="mx4-66-yGt">
|
||||
@@ -112,6 +165,9 @@
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<<<<<<< HEAD:Tests/Manual/CPControlSize/Resources/MainMenu.xib
|
||||
<datePicker verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="pNn-Yt-Kof">
|
||||
=======
|
||||
<textField verticalHuggingPriority="750" id="Baf-Et-cEO">
|
||||
<rect key="frame" x="375" y="426" width="96" height="16"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
@@ -122,6 +178,7 @@
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<datePicker verticalHuggingPriority="750" id="pNn-Yt-Kof">
|
||||
>>>>>>> main:Tests/Manual/CPControlSizeTest/Resources/MainMenu.xib
|
||||
<rect key="frame" x="36" y="328" width="113" height="27"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<datePickerCell key="cell" borderStyle="bezel" alignment="left" id="T5R-AB-cuN">
|
||||
@@ -133,7 +190,7 @@
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
</datePickerCell>
|
||||
</datePicker>
|
||||
<datePicker verticalHuggingPriority="750" id="WXE-xa-O7P">
|
||||
<datePicker verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="WXE-xa-O7P">
|
||||
<rect key="frame" x="206" y="333" width="113" height="22"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<datePickerCell key="cell" controlSize="small" borderStyle="bezel" alignment="left" id="Qb0-X9-0KQ">
|
||||
@@ -145,7 +202,7 @@
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
</datePickerCell>
|
||||
</datePicker>
|
||||
<datePicker verticalHuggingPriority="750" id="WeD-S8-Zxs">
|
||||
<datePicker verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="WeD-S8-Zxs">
|
||||
<rect key="frame" x="375" y="338" width="113" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<datePickerCell key="cell" controlSize="mini" borderStyle="bezel" alignment="left" id="635-rQ-aDe">
|
||||
@@ -157,7 +214,7 @@
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
</datePickerCell>
|
||||
</datePicker>
|
||||
<datePicker verticalHuggingPriority="750" id="ULi-zW-Q5q">
|
||||
<datePicker verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="ULi-zW-Q5q">
|
||||
<rect key="frame" x="36" y="281" width="113" height="22"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<datePickerCell key="cell" borderStyle="bezel" alignment="left" datePickerStyle="textField" id="RCm-sN-nrQ">
|
||||
@@ -169,7 +226,7 @@
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
</datePickerCell>
|
||||
</datePicker>
|
||||
<datePicker verticalHuggingPriority="750" id="fx1-CP-l9m">
|
||||
<datePicker verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="fx1-CP-l9m">
|
||||
<rect key="frame" x="206" y="285" width="113" height="19"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<datePickerCell key="cell" controlSize="small" borderStyle="bezel" alignment="left" datePickerStyle="textField" id="0fE-Wg-6b6">
|
||||
@@ -181,7 +238,7 @@
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
</datePickerCell>
|
||||
</datePicker>
|
||||
<datePicker verticalHuggingPriority="750" id="dwU-8f-1Ek">
|
||||
<datePicker verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="dwU-8f-1Ek">
|
||||
<rect key="frame" x="375" y="287" width="110" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<datePickerCell key="cell" controlSize="mini" borderStyle="bezel" alignment="left" datePickerStyle="textField" id="O65-rh-JeL">
|
||||
@@ -193,22 +250,22 @@
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
</datePickerCell>
|
||||
</datePicker>
|
||||
<stepper horizontalHuggingPriority="750" verticalHuggingPriority="750" id="Pf5-bX-XNM">
|
||||
<stepper horizontalHuggingPriority="750" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Pf5-bX-XNM">
|
||||
<rect key="frame" x="33" y="374" width="19" height="27"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<stepperCell key="cell" continuous="YES" alignment="left" maxValue="100" id="UBb-vf-dHD"/>
|
||||
</stepper>
|
||||
<stepper horizontalHuggingPriority="750" verticalHuggingPriority="750" id="fX5-Cx-kra">
|
||||
<stepper horizontalHuggingPriority="750" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="fX5-Cx-kra">
|
||||
<rect key="frame" x="204" y="381" width="15" height="22"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<stepperCell key="cell" controlSize="small" continuous="YES" alignment="left" maxValue="100" id="s3t-dy-wPz"/>
|
||||
</stepper>
|
||||
<stepper horizontalHuggingPriority="750" verticalHuggingPriority="750" id="eJ6-cs-745">
|
||||
<stepper horizontalHuggingPriority="750" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="eJ6-cs-745">
|
||||
<rect key="frame" x="373" y="388" width="13" height="15"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<stepperCell key="cell" controlSize="mini" continuous="YES" alignment="left" maxValue="100" id="RqJ-YK-TXI"/>
|
||||
</stepper>
|
||||
<button verticalHuggingPriority="750" id="qeW-JF-8PA">
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="qeW-JF-8PA">
|
||||
<rect key="frame" x="30" y="192" width="82" height="32"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="push" title="Button" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="r33-XP-TYJ">
|
||||
@@ -216,7 +273,7 @@
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" id="bUw-8W-83b">
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="bUw-8W-83b">
|
||||
<rect key="frame" x="201" y="196" width="82" height="28"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="push" title="Button" bezelStyle="rounded" alignment="center" controlSize="small" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="iFL-tR-EKi">
|
||||
@@ -224,7 +281,7 @@
|
||||
<font key="font" metaFont="smallSystem"/>
|
||||
</buttonCell>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" id="mtR-eh-GXS">
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="mtR-eh-GXS">
|
||||
<rect key="frame" x="374" y="204" width="82" height="16"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="push" title="Button" bezelStyle="rounded" alignment="center" controlSize="mini" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="Ebs-LH-Vnq">
|
||||
@@ -232,7 +289,7 @@
|
||||
<font key="font" metaFont="miniSystem"/>
|
||||
</buttonCell>
|
||||
</button>
|
||||
<button id="utt-sX-YI9">
|
||||
<button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="utt-sX-YI9">
|
||||
<rect key="frame" x="34" y="238" width="81" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="check" title="Check" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="plS-mh-316">
|
||||
@@ -240,7 +297,7 @@
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
</button>
|
||||
<button id="5tT-da-cbF">
|
||||
<button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="5tT-da-cbF">
|
||||
<rect key="frame" x="203" y="237" width="75" height="20"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="check" title="Check" bezelStyle="regularSquare" imagePosition="left" controlSize="small" state="on" inset="2" id="OGk-WN-tAu">
|
||||
@@ -248,7 +305,7 @@
|
||||
<font key="font" metaFont="smallSystem"/>
|
||||
</buttonCell>
|
||||
</button>
|
||||
<button id="wmA-RV-jeJ">
|
||||
<button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="wmA-RV-jeJ">
|
||||
<rect key="frame" x="371" y="237" width="63" height="22"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="check" title="Check" bezelStyle="regularSquare" imagePosition="left" controlSize="mini" inset="2" id="ro6-1L-HbO">
|
||||
@@ -256,7 +313,7 @@
|
||||
<font key="font" metaFont="miniSystem"/>
|
||||
</buttonCell>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" id="OuO-8D-Jv1">
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="OuO-8D-Jv1">
|
||||
<rect key="frame" x="36" y="155" width="110" height="25"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="squareTextured" title="Textured Button" bezelStyle="texturedSquare" imagePosition="overlaps" alignment="center" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="SNT-aA-bDy">
|
||||
@@ -264,7 +321,7 @@
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" id="eG9-13-wdi">
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="eG9-13-wdi">
|
||||
<rect key="frame" x="206" y="160" width="110" height="19"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="squareTextured" title="Textured Button" bezelStyle="texturedSquare" imagePosition="overlaps" alignment="center" controlSize="small" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="xJm-nS-cPR">
|
||||
@@ -272,7 +329,7 @@
|
||||
<font key="font" metaFont="smallSystem"/>
|
||||
</buttonCell>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" id="7FL-7D-m2j">
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="7FL-7D-m2j">
|
||||
<rect key="frame" x="375" y="163" width="110" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="squareTextured" title="Textured Button" bezelStyle="texturedSquare" imagePosition="overlaps" alignment="center" controlSize="mini" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="np3-qE-wIc">
|
||||
@@ -280,7 +337,7 @@
|
||||
<font key="font" metaFont="miniSystem"/>
|
||||
</buttonCell>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" id="pqa-mo-oK1">
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="pqa-mo-oK1">
|
||||
<rect key="frame" x="36" y="117" width="115" height="25"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="roundTextured" title="Round Textured" bezelStyle="texturedRounded" alignment="center" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="rpo-yw-hd8">
|
||||
@@ -288,7 +345,7 @@
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" id="Mv6-Iy-X4h">
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Mv6-Iy-X4h">
|
||||
<rect key="frame" x="206" y="122" width="115" height="19"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="roundTextured" title="Round Textured" bezelStyle="texturedRounded" alignment="center" controlSize="small" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="PQW-Lc-Dm5">
|
||||
@@ -296,7 +353,7 @@
|
||||
<font key="font" metaFont="smallSystem"/>
|
||||
</buttonCell>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" id="O3l-BH-NXK">
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="O3l-BH-NXK">
|
||||
<rect key="frame" x="375" y="125" width="115" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="roundTextured" title="Round Textured" bezelStyle="texturedRounded" alignment="center" controlSize="mini" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="fzh-RR-war">
|
||||
@@ -304,7 +361,7 @@
|
||||
<font key="font" metaFont="miniSystem"/>
|
||||
</buttonCell>
|
||||
</button>
|
||||
<matrix verticalHuggingPriority="750" allowsEmptySelection="NO" autorecalculatesCellSize="YES" id="eUQ-61-gJI">
|
||||
<matrix verticalHuggingPriority="750" fixedFrame="YES" allowsEmptySelection="NO" autorecalculatesCellSize="YES" translatesAutoresizingMaskIntoConstraints="NO" id="eUQ-61-gJI">
|
||||
<rect key="frame" x="36" y="67" width="70" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -327,7 +384,7 @@
|
||||
</column>
|
||||
</cells>
|
||||
</matrix>
|
||||
<matrix verticalHuggingPriority="750" allowsEmptySelection="NO" autorecalculatesCellSize="YES" id="IGX-cm-xbF">
|
||||
<matrix verticalHuggingPriority="750" fixedFrame="YES" allowsEmptySelection="NO" autorecalculatesCellSize="YES" translatesAutoresizingMaskIntoConstraints="NO" id="IGX-cm-xbF">
|
||||
<rect key="frame" x="206" y="73" width="63" height="38"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -350,7 +407,7 @@
|
||||
</column>
|
||||
</cells>
|
||||
</matrix>
|
||||
<matrix verticalHuggingPriority="750" allowsEmptySelection="NO" autorecalculatesCellSize="YES" id="SLm-Fm-NnP">
|
||||
<matrix verticalHuggingPriority="750" fixedFrame="YES" allowsEmptySelection="NO" autorecalculatesCellSize="YES" translatesAutoresizingMaskIntoConstraints="NO" id="SLm-Fm-NnP">
|
||||
<rect key="frame" x="375" y="73" width="57" height="38"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -373,7 +430,7 @@
|
||||
</column>
|
||||
</cells>
|
||||
</matrix>
|
||||
<comboBox verticalHuggingPriority="750" id="yfb-qa-Ypy">
|
||||
<comboBox verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="yfb-qa-Ypy">
|
||||
<rect key="frame" x="36" y="35" width="99" height="26"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<comboBoxCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" drawsBackground="YES" completes="NO" numberOfVisibleItems="5" id="7lM-32-tfT">
|
||||
@@ -382,7 +439,7 @@
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</comboBoxCell>
|
||||
</comboBox>
|
||||
<comboBox verticalHuggingPriority="750" id="aGP-Sw-SGa">
|
||||
<comboBox verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="aGP-Sw-SGa">
|
||||
<rect key="frame" x="206" y="38" width="99" height="22"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<comboBoxCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" drawsBackground="YES" completes="NO" numberOfVisibleItems="5" id="1HS-Qg-oau">
|
||||
@@ -391,7 +448,7 @@
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</comboBoxCell>
|
||||
</comboBox>
|
||||
<comboBox verticalHuggingPriority="750" id="Sub-ME-hYL">
|
||||
<comboBox verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Sub-ME-hYL">
|
||||
<rect key="frame" x="375" y="41" width="99" height="19"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<comboBoxCell key="cell" controlSize="mini" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" drawsBackground="YES" completes="NO" numberOfVisibleItems="5" id="6Ao-lo-5FY">
|
||||
@@ -400,8 +457,36 @@
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</comboBoxCell>
|
||||
</comboBox>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="duZ-4B-IHi">
|
||||
<rect key="frame" x="36" y="410" width="96" height="22"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" id="uNM-6c-a5P">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="vYT-ma-Xce">
|
||||
<rect key="frame" x="206" y="414" width="96" height="19"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" id="FYM-U3-I2Q">
|
||||
<font key="font" metaFont="smallSystem"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Baf-Et-cEO">
|
||||
<rect key="frame" x="375" y="417" width="96" height="16"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" controlSize="mini" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" id="8VU-QE-dZY">
|
||||
<font key="font" metaFont="miniSystem"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
</subviews>
|
||||
</view>
|
||||
<point key="canvasLocation" x="140" y="144"/>
|
||||
</window>
|
||||
<customObject id="450" customClass="AppController">
|
||||
<connections>
|
||||
|
||||
@@ -2,6 +2,10 @@
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CPDefaulTheme</key>
|
||||
<string>Aristo2</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string></string>
|
||||
<key>Main cib file base name</key>
|
||||
<string>MainMenu.cib</string>
|
||||
<key>CPBundleName</key>
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,13 +1,50 @@
|
||||
<<<<<<< HEAD
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="19529" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<dependencies>
|
||||
<deployment version="1050" identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="19529"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
=======
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="24506" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none">
|
||||
<dependencies>
|
||||
<deployment version="1050" identifier="macosx" />
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="24506" />
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0" />
|
||||
>>>>>>> main
|
||||
</dependencies>
|
||||
<objects>
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="NSApplication">
|
||||
<connections>
|
||||
<<<<<<< HEAD
|
||||
<outlet property="delegate" destination="450" id="451"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
||||
<customObject id="-3" userLabel="Application"/>
|
||||
<menu title="AMainMenu" systemMenu="main" id="29" userLabel="MainMenu">
|
||||
<items>
|
||||
<menuItem title="NewApplication" id="56">
|
||||
<menu key="submenu" title="NewApplication" systemMenu="apple" id="57">
|
||||
<items>
|
||||
<menuItem title="About NewApplication" id="58">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="orderFrontStandardAboutPanel:" target="-2" id="142"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="236">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Preferences…" keyEquivalent="," id="129"/>
|
||||
<menuItem isSeparatorItem="YES" id="143">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Quit NewApplication" keyEquivalent="q" id="136">
|
||||
<connections>
|
||||
<action selector="terminate:" target="-3" id="449"/>
|
||||
=======
|
||||
<outlet property="delegate" destination="450" id="451" />
|
||||
</connections>
|
||||
</customObject>
|
||||
@@ -34,6 +71,7 @@
|
||||
<menuItem title="Quit CPDatePickerTest" keyEquivalent="q" id="136">
|
||||
<connections>
|
||||
<action selector="terminate:" target="-3" id="449" />
|
||||
>>>>>>> main
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
@@ -44,12 +82,20 @@
|
||||
<items>
|
||||
<menuItem title="New" keyEquivalent="n" id="82">
|
||||
<connections>
|
||||
<<<<<<< HEAD
|
||||
<action selector="newDocument:" target="-1" id="373"/>
|
||||
=======
|
||||
<action selector="newDocument:" target="-1" id="373" />
|
||||
>>>>>>> main
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Open…" keyEquivalent="o" id="72">
|
||||
<connections>
|
||||
<<<<<<< HEAD
|
||||
<action selector="openDocument:" target="-1" id="374"/>
|
||||
=======
|
||||
<action selector="openDocument:" target="-1" id="374" />
|
||||
>>>>>>> main
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Open Recent" id="124">
|
||||
@@ -57,22 +103,49 @@
|
||||
<items>
|
||||
<menuItem title="Clear Menu" id="126">
|
||||
<connections>
|
||||
<<<<<<< HEAD
|
||||
<action selector="clearRecentDocuments:" target="-1" id="127"/>
|
||||
=======
|
||||
<action selector="clearRecentDocuments:" target="-1" id="127" />
|
||||
>>>>>>> main
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="79">
|
||||
<<<<<<< HEAD
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Close" keyEquivalent="w" id="73">
|
||||
<connections>
|
||||
<action selector="performClose:" target="-1" id="193"/>
|
||||
=======
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES" />
|
||||
</menuItem>
|
||||
<menuItem title="Close" keyEquivalent="w" id="73">
|
||||
<connections>
|
||||
<action selector="performClose:" target="-1" id="193" />
|
||||
>>>>>>> main
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Save" keyEquivalent="s" id="75">
|
||||
<connections>
|
||||
<<<<<<< HEAD
|
||||
<action selector="saveDocument:" target="-1" id="362"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Save As…" keyEquivalent="S" id="80">
|
||||
<modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="saveDocumentAs:" target="-1" id="363"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Revert to Saved" id="112">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="revertDocumentToSaved:" target="-1" id="364"/>
|
||||
=======
|
||||
<action selector="saveDocument:" target="-1" id="362" />
|
||||
</connections>
|
||||
</menuItem>
|
||||
@@ -86,6 +159,7 @@
|
||||
<modifierMask key="keyEquivalentModifierMask" />
|
||||
<connections>
|
||||
<action selector="revertDocumentToSaved:" target="-1" id="364" />
|
||||
>>>>>>> main
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
@@ -96,6 +170,23 @@
|
||||
<items>
|
||||
<menuItem title="Undo" keyEquivalent="z" id="207">
|
||||
<connections>
|
||||
<<<<<<< HEAD
|
||||
<action selector="undo:" target="-1" id="223"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Redo" keyEquivalent="Z" id="215">
|
||||
<modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="redo:" target="-1" id="231"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="206">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Cut" keyEquivalent="x" id="199">
|
||||
<connections>
|
||||
<action selector="cut:" target="-1" id="228"/>
|
||||
=======
|
||||
<action selector="undo:" target="-1" id="223" />
|
||||
</connections>
|
||||
</menuItem>
|
||||
@@ -111,36 +202,70 @@
|
||||
<menuItem title="Cut" keyEquivalent="x" id="199">
|
||||
<connections>
|
||||
<action selector="cut:" target="-1" id="228" />
|
||||
>>>>>>> main
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Copy" keyEquivalent="c" id="197">
|
||||
<connections>
|
||||
<<<<<<< HEAD
|
||||
<action selector="copy:" target="-1" id="224"/>
|
||||
=======
|
||||
<action selector="copy:" target="-1" id="224" />
|
||||
>>>>>>> main
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Paste" keyEquivalent="v" id="203">
|
||||
<connections>
|
||||
<<<<<<< HEAD
|
||||
<action selector="paste:" target="-1" id="226"/>
|
||||
=======
|
||||
<action selector="paste:" target="-1" id="226" />
|
||||
>>>>>>> main
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Delete" id="202">
|
||||
<connections>
|
||||
<<<<<<< HEAD
|
||||
<action selector="delete:" target="-1" id="235"/>
|
||||
=======
|
||||
<action selector="delete:" target="-1" id="235" />
|
||||
>>>>>>> main
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Select All" keyEquivalent="a" id="198">
|
||||
<connections>
|
||||
<<<<<<< HEAD
|
||||
<action selector="selectAll:" target="-1" id="232"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="214">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
=======
|
||||
<action selector="selectAll:" target="-1" id="232" />
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="214">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES" />
|
||||
>>>>>>> main
|
||||
</menuItem>
|
||||
<menuItem title="Find" id="218">
|
||||
<menu key="submenu" title="Find" id="220">
|
||||
<items>
|
||||
<menuItem title="Find…" tag="1" keyEquivalent="f" id="209">
|
||||
<connections>
|
||||
<<<<<<< HEAD
|
||||
<action selector="performFindPanelAction:" target="-1" id="241"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Find Next" tag="2" keyEquivalent="g" id="208"/>
|
||||
<menuItem title="Find Previous" tag="3" keyEquivalent="G" id="213">
|
||||
<modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Use Selection for Find" tag="7" keyEquivalent="e" id="221"/>
|
||||
<menuItem title="Jump to Selection" keyEquivalent="j" id="210">
|
||||
<connections>
|
||||
<action selector="centerSelectionInVisibleArea:" target="-1" id="245"/>
|
||||
=======
|
||||
<action selector="performFindPanelAction:" target="-1" id="241" />
|
||||
</connections>
|
||||
</menuItem>
|
||||
@@ -152,6 +277,7 @@
|
||||
<menuItem title="Jump to Selection" keyEquivalent="j" id="210">
|
||||
<connections>
|
||||
<action selector="centerSelectionInVisibleArea:" target="-1" id="245" />
|
||||
>>>>>>> main
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
@@ -162,22 +288,38 @@
|
||||
<items>
|
||||
<menuItem title="Show Spelling…" keyEquivalent=":" id="204">
|
||||
<connections>
|
||||
<<<<<<< HEAD
|
||||
<action selector="showGuessPanel:" target="-1" id="230"/>
|
||||
=======
|
||||
<action selector="showGuessPanel:" target="-1" id="230" />
|
||||
>>>>>>> main
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Check Spelling" keyEquivalent=";" id="201">
|
||||
<connections>
|
||||
<<<<<<< HEAD
|
||||
<action selector="checkSpelling:" target="-1" id="225"/>
|
||||
=======
|
||||
<action selector="checkSpelling:" target="-1" id="225" />
|
||||
>>>>>>> main
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Check Spelling While Typing" id="219">
|
||||
<connections>
|
||||
<<<<<<< HEAD
|
||||
<action selector="toggleContinuousSpellChecking:" target="-1" id="222"/>
|
||||
=======
|
||||
<action selector="toggleContinuousSpellChecking:" target="-1" id="222" />
|
||||
>>>>>>> main
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Check Grammar With Spelling" id="346">
|
||||
<connections>
|
||||
<<<<<<< HEAD
|
||||
<action selector="toggleGrammarChecking:" target="-1" id="347"/>
|
||||
=======
|
||||
<action selector="toggleGrammarChecking:" target="-1" id="347" />
|
||||
>>>>>>> main
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
@@ -188,11 +330,24 @@
|
||||
<items>
|
||||
<menuItem title="Smart Copy/Paste" tag="1" keyEquivalent="f" id="350">
|
||||
<connections>
|
||||
<<<<<<< HEAD
|
||||
<action selector="toggleSmartInsertDelete:" target="-1" id="355"/>
|
||||
=======
|
||||
<action selector="toggleSmartInsertDelete:" target="-1" id="355" />
|
||||
>>>>>>> main
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Smart Quotes" tag="2" keyEquivalent="g" id="351">
|
||||
<connections>
|
||||
<<<<<<< HEAD
|
||||
<action selector="toggleAutomaticQuoteSubstitution:" target="-1" id="356"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Smart Links" tag="3" keyEquivalent="G" id="354">
|
||||
<modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="toggleAutomaticLinkDetection:" target="-1" id="357"/>
|
||||
=======
|
||||
<action selector="toggleAutomaticQuoteSubstitution:" target="-1" id="356" />
|
||||
</connections>
|
||||
</menuItem>
|
||||
@@ -200,6 +355,7 @@
|
||||
<modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES" />
|
||||
<connections>
|
||||
<action selector="toggleAutomaticLinkDetection:" target="-1" id="357" />
|
||||
>>>>>>> main
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
@@ -210,12 +366,20 @@
|
||||
<items>
|
||||
<menuItem title="Start Speaking" id="196">
|
||||
<connections>
|
||||
<<<<<<< HEAD
|
||||
<action selector="startSpeaking:" target="-1" id="233"/>
|
||||
=======
|
||||
<action selector="startSpeaking:" target="-1" id="233" />
|
||||
>>>>>>> main
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Stop Speaking" id="195">
|
||||
<connections>
|
||||
<<<<<<< HEAD
|
||||
<action selector="stopSpeaking:" target="-1" id="227"/>
|
||||
=======
|
||||
<action selector="stopSpeaking:" target="-1" id="227" />
|
||||
>>>>>>> main
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
@@ -228,14 +392,24 @@
|
||||
<menu key="submenu" title="View" id="296">
|
||||
<items>
|
||||
<menuItem title="Show Toolbar" keyEquivalent="t" id="297">
|
||||
<<<<<<< HEAD
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="toggleToolbarShown:" target="-1" id="366"/>
|
||||
=======
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES" />
|
||||
<connections>
|
||||
<action selector="toggleToolbarShown:" target="-1" id="366" />
|
||||
>>>>>>> main
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Customize Toolbar…" id="298">
|
||||
<connections>
|
||||
<<<<<<< HEAD
|
||||
<action selector="runToolbarCustomizationPalette:" target="-1" id="365"/>
|
||||
=======
|
||||
<action selector="runToolbarCustomizationPalette:" target="-1" id="365" />
|
||||
>>>>>>> main
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
@@ -246,11 +420,26 @@
|
||||
<items>
|
||||
<menuItem title="Minimize" keyEquivalent="m" id="23">
|
||||
<connections>
|
||||
<<<<<<< HEAD
|
||||
<action selector="performMiniaturize:" target="-1" id="37"/>
|
||||
=======
|
||||
<action selector="performMiniaturize:" target="-1" id="37" />
|
||||
>>>>>>> main
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Zoom" id="239">
|
||||
<connections>
|
||||
<<<<<<< HEAD
|
||||
<action selector="performZoom:" target="-1" id="240"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="92">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Bring All to Front" id="5">
|
||||
<connections>
|
||||
<action selector="arrangeInFront:" target="-1" id="39"/>
|
||||
=======
|
||||
<action selector="performZoom:" target="-1" id="240" />
|
||||
</connections>
|
||||
</menuItem>
|
||||
@@ -260,6 +449,7 @@
|
||||
<menuItem title="Bring All to Front" id="5">
|
||||
<connections>
|
||||
<action selector="arrangeInFront:" target="-1" id="39" />
|
||||
>>>>>>> main
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
@@ -268,23 +458,131 @@
|
||||
<menuItem title="Help" id="103">
|
||||
<menu key="submenu" title="Help" id="106">
|
||||
<items>
|
||||
<<<<<<< HEAD
|
||||
<menuItem title="NewApplication Help" keyEquivalent="?" id="111">
|
||||
<connections>
|
||||
<action selector="showHelp:" target="-1" id="360"/>
|
||||
=======
|
||||
<menuItem title="CPDatePickerTest Help" keyEquivalent="?" id="111">
|
||||
<connections>
|
||||
<action selector="showHelp:" target="-1" id="360" />
|
||||
>>>>>>> main
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
</items>
|
||||
<<<<<<< HEAD
|
||||
<point key="canvasLocation" x="-53" y="65"/>
|
||||
</menu>
|
||||
<objectController objectClassName="NSDatePicker" id="799" userLabel="DatePickerStyleController">
|
||||
<connections>
|
||||
<outlet property="content" destination="538" id="800"/>
|
||||
=======
|
||||
</menu>
|
||||
<objectController objectClassName="NSDatePicker" id="799" userLabel="DatePickerStyleController">
|
||||
<connections>
|
||||
<outlet property="content" destination="538" id="800" />
|
||||
>>>>>>> main
|
||||
</connections>
|
||||
</objectController>
|
||||
<customObject id="450" customClass="AppController">
|
||||
<connections>
|
||||
<<<<<<< HEAD
|
||||
<outlet property="buttonElementsDate" destination="554" id="809"/>
|
||||
<outlet property="buttonElementsTime" destination="572" id="810"/>
|
||||
<outlet property="buttonStyle" destination="542" id="776"/>
|
||||
<outlet property="pickerCurrentDate" destination="594" id="757"/>
|
||||
<outlet property="pickerMaxDate" destination="590" id="756"/>
|
||||
<outlet property="pickerMinDate" destination="582" id="755"/>
|
||||
<outlet property="pickerTarget" destination="538" id="758"/>
|
||||
<outlet property="theWindow" destination="371" id="459"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
<window title="CPDatePicker Test" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" animationBehavior="default" id="371">
|
||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES"/>
|
||||
<windowPositionMask key="initialPositionMask" leftStrut="YES" bottomStrut="YES"/>
|
||||
<rect key="contentRect" x="133" y="289" width="885" height="477"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="1792" height="1095"/>
|
||||
<view key="contentView" id="372">
|
||||
<rect key="frame" x="0.0" y="0.0" width="885" height="477"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<datePicker verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="538">
|
||||
<rect key="frame" x="456" y="167" width="277" height="148"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<datePickerCell key="cell" borderStyle="bezel" alignment="left" datePickerMode="range" datePickerStyle="clockAndCalendar" id="539">
|
||||
<font key="font" metaFont="system"/>
|
||||
<date key="date" timeIntervalSinceReferenceDate="377037012">
|
||||
<!--2012-12-12 20:30:12 +0000-->
|
||||
</date>
|
||||
<date key="minDate" timeIntervalSinceReferenceDate="-63113861222">
|
||||
<!--0001-01-03 11:52:58 +0000-->
|
||||
</date>
|
||||
<date key="maxDate" timeIntervalSinceReferenceDate="63113947200">
|
||||
<!--4001-01-01 12:00:00 +0000-->
|
||||
</date>
|
||||
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<datePickerElements key="datePickerElements" era="YES" year="YES" month="YES" day="YES" timeZone="YES" hour="YES" minute="YES" second="YES"/>
|
||||
</datePickerCell>
|
||||
<connections>
|
||||
<binding destination="450" name="maxValue" keyPath="pickerMaxDate.objectValue" id="768"/>
|
||||
<binding destination="450" name="minValue" keyPath="pickerMinDate.objectValue" previousBinding="768" id="774"/>
|
||||
<binding destination="450" name="value" keyPath="pickerCurrentDate.objectValue" previousBinding="774" id="789"/>
|
||||
</connections>
|
||||
</datePicker>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="540">
|
||||
<rect key="frame" x="17" y="428" width="168" height="29"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="CPDatePicker test" id="541">
|
||||
<font key="font" metaFont="systemBold" size="17"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<box autoresizesSubviews="NO" fixedFrame="YES" borderType="line" title="Parameters" titlePosition="noTitle" translatesAutoresizingMaskIntoConstraints="NO" id="822">
|
||||
<rect key="frame" x="17" y="16" width="363" height="388"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<view key="contentView" id="43f-xl-6GJ">
|
||||
<rect key="frame" x="3" y="3" width="357" height="382"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<datePicker verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="582">
|
||||
<rect key="frame" x="104" y="163" width="230" height="27"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<datePickerCell key="cell" borderStyle="bezel" alignment="left" useCurrentDate="YES" id="583">
|
||||
<font key="font" metaFont="system"/>
|
||||
<date key="date" timeIntervalSinceReferenceDate="670077009.29153705">
|
||||
<!--2022-03-27 12:30:09 +0000-->
|
||||
</date>
|
||||
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<datePickerElements key="datePickerElements" year="YES" month="YES" day="YES" hour="YES" minute="YES" second="YES"/>
|
||||
</datePickerCell>
|
||||
<connections>
|
||||
<binding destination="450" name="value" keyPath="pickerTarget.minDate" id="832"/>
|
||||
<outlet property="nextKeyView" destination="590" id="816"/>
|
||||
</connections>
|
||||
</datePicker>
|
||||
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="542">
|
||||
<rect key="frame" x="102" y="339" width="232" height="26"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<popUpButtonCell key="cell" type="push" title="Graphical" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" tag="1" imageScaling="proportionallyDown" inset="2" selectedItem="547" id="543">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
<menu key="menu" title="OtherViews" id="544">
|
||||
<items>
|
||||
<menuItem title="Textual" tag="2" id="545">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem title="Textual with Stepper" id="546">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem title="Graphical" state="on" tag="1" id="547">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
=======
|
||||
<outlet property="buttonElementsDate" destination="554" id="809" />
|
||||
<outlet property="buttonElementsTime" destination="572" id="810" />
|
||||
<outlet property="buttonStyle" destination="542" id="776" />
|
||||
@@ -377,11 +675,30 @@
|
||||
</menuItem>
|
||||
<menuItem title="Graphical" state="on" tag="1" id="547">
|
||||
<modifierMask key="keyEquivalentModifierMask" />
|
||||
>>>>>>> main
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</popUpButtonCell>
|
||||
<connections>
|
||||
<<<<<<< HEAD
|
||||
<binding destination="799" name="selectedTag" keyPath="selection.datePickerStyle" id="806"/>
|
||||
</connections>
|
||||
</popUpButton>
|
||||
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="548">
|
||||
<rect key="frame" x="102" y="309" width="232" height="26"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<popUpButtonCell key="cell" type="push" title="Date Range" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" tag="1" imageScaling="proportionallyDown" inset="2" selectedItem="552" id="549">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
<menu key="menu" title="OtherViews" id="550">
|
||||
<items>
|
||||
<menuItem title="Single Date" id="553">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem title="Date Range" state="on" tag="1" id="552">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
=======
|
||||
<binding destination="799" name="selectedTag" keyPath="selection.datePickerStyle" id="806" />
|
||||
</connections>
|
||||
</popUpButton>
|
||||
@@ -398,11 +715,33 @@
|
||||
</menuItem>
|
||||
<menuItem title="Date Range" state="on" tag="1" id="552">
|
||||
<modifierMask key="keyEquivalentModifierMask" />
|
||||
>>>>>>> main
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</popUpButtonCell>
|
||||
<connections>
|
||||
<<<<<<< HEAD
|
||||
<binding destination="799" name="selectedTag" keyPath="selection.datePickerMode" id="808"/>
|
||||
</connections>
|
||||
</popUpButton>
|
||||
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="554">
|
||||
<rect key="frame" x="102" y="278" width="232" height="26"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<popUpButtonCell key="cell" type="push" title="Month, Day and Year" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" tag="2" imageScaling="proportionallyDown" inset="2" selectedItem="557" id="555">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
<menu key="menu" title="OtherViews" id="556">
|
||||
<items>
|
||||
<menuItem title="Month, Day and Year" state="on" tag="2" id="557">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem title="Month and Year" tag="1" id="558">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem title="None" id="559">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
=======
|
||||
<binding destination="799" name="selectedTag" keyPath="selection.datePickerMode" id="808" />
|
||||
</connections>
|
||||
</popUpButton>
|
||||
@@ -422,11 +761,33 @@
|
||||
</menuItem>
|
||||
<menuItem title="None" id="559">
|
||||
<modifierMask key="keyEquivalentModifierMask" />
|
||||
>>>>>>> main
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</popUpButtonCell>
|
||||
<connections>
|
||||
<<<<<<< HEAD
|
||||
<action selector="updateElements:" target="450" id="812"/>
|
||||
</connections>
|
||||
</popUpButton>
|
||||
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="572">
|
||||
<rect key="frame" x="102" y="247" width="232" height="26"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<popUpButtonCell key="cell" type="push" title="Hour, Minute and Second" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" tag="2" imageScaling="proportionallyDown" inset="2" selectedItem="577" id="573">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
<menu key="menu" title="OtherViews" id="574">
|
||||
<items>
|
||||
<menuItem title="Hour, Minute and Second" state="on" tag="2" id="577">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem title="Hour and Minute" tag="1" id="576">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem title="None" id="575">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
=======
|
||||
<action selector="updateElements:" target="450" id="812" />
|
||||
</connections>
|
||||
</popUpButton>
|
||||
@@ -446,11 +807,182 @@
|
||||
</menuItem>
|
||||
<menuItem title="None" id="575">
|
||||
<modifierMask key="keyEquivalentModifierMask" />
|
||||
>>>>>>> main
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</popUpButtonCell>
|
||||
<connections>
|
||||
<<<<<<< HEAD
|
||||
<action selector="updateElements:" target="450" id="811"/>
|
||||
</connections>
|
||||
</popUpButton>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="560">
|
||||
<rect key="frame" x="15" y="347" width="84" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="left" title="Style" id="561">
|
||||
<font key="font" metaFont="systemBold"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="562">
|
||||
<rect key="frame" x="15" y="315" width="84" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="left" title="Selects" id="563">
|
||||
<font key="font" metaFont="systemBold"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="586">
|
||||
<rect key="frame" x="15" y="191" width="84" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="left" title="Constraints" id="587">
|
||||
<font key="font" metaFont="systemBold"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="596">
|
||||
<rect key="frame" x="15" y="75" width="84" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="left" title="Date" id="597">
|
||||
<font key="font" metaFont="systemBold"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="602">
|
||||
<rect key="frame" x="15" y="50" width="84" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="left" title="Display" id="603">
|
||||
<font key="font" metaFont="systemBold"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="564">
|
||||
<rect key="frame" x="15" y="284" width="84" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="left" title="Elements" id="565">
|
||||
<font key="font" metaFont="systemBold"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="578">
|
||||
<rect key="frame" x="102" y="223" width="89" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="check" title="Time zone" bezelStyle="regularSquare" imagePosition="left" enabled="NO" state="on" inset="2" id="579">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
</button>
|
||||
<button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="588">
|
||||
<rect key="frame" x="102" y="191" width="113" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="check" title="Minimum date" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="589">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="updateHasMinConstraint:" target="450" id="823"/>
|
||||
</connections>
|
||||
</button>
|
||||
<datePicker verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="590">
|
||||
<rect key="frame" x="104" y="111" width="230" height="27"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<datePickerCell key="cell" borderStyle="bezel" alignment="left" useCurrentDate="YES" id="593">
|
||||
<font key="font" metaFont="system"/>
|
||||
<date key="date" timeIntervalSinceReferenceDate="670077009.333233">
|
||||
<!--2022-03-27 12:30:09 +0000-->
|
||||
</date>
|
||||
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<datePickerElements key="datePickerElements" year="YES" month="YES" day="YES" hour="YES" minute="YES" second="YES"/>
|
||||
</datePickerCell>
|
||||
<connections>
|
||||
<binding destination="450" name="value" keyPath="pickerTarget.maxDate" id="835"/>
|
||||
<outlet property="nextKeyView" destination="594" id="817"/>
|
||||
</connections>
|
||||
</datePicker>
|
||||
<datePicker verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="594">
|
||||
<rect key="frame" x="104" y="72" width="230" height="27"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<datePickerCell key="cell" borderStyle="bezel" alignment="left" useCurrentDate="YES" id="595">
|
||||
<font key="font" metaFont="system"/>
|
||||
<date key="date" timeIntervalSinceReferenceDate="670077009.33555698">
|
||||
<!--2022-03-27 12:30:09 +0000-->
|
||||
</date>
|
||||
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<datePickerElements key="datePickerElements" year="YES" month="YES" day="YES" hour="YES" minute="YES" second="YES"/>
|
||||
</datePickerCell>
|
||||
<connections>
|
||||
<binding destination="450" name="value" keyPath="pickerTarget.dateValue" id="828"/>
|
||||
<outlet property="nextKeyView" destination="582" id="821"/>
|
||||
</connections>
|
||||
</datePicker>
|
||||
<button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="591">
|
||||
<rect key="frame" x="102" y="139" width="116" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="check" title="Maximum date" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="592">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="updateHasMaxConstraint:" target="450" id="824"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="580">
|
||||
<rect key="frame" x="195" y="223" width="76" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="check" title="Era" bezelStyle="regularSquare" imagePosition="left" enabled="NO" state="on" inset="2" id="581">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
</button>
|
||||
<button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="598">
|
||||
<rect key="frame" x="102" y="48" width="97" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="check" title="Background" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="601">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<binding destination="450" name="value" keyPath="pickerTarget.drawsBackground" id="870"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="599">
|
||||
<rect key="frame" x="102" y="28" width="97" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="check" title="Border" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="600">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<binding destination="450" name="value" keyPath="pickerTarget.bordered" id="867"/>
|
||||
</connections>
|
||||
</button>
|
||||
<box autoresizesSubviews="NO" verticalHuggingPriority="750" fixedFrame="YES" boxType="separator" translatesAutoresizingMaskIntoConstraints="NO" id="837">
|
||||
<rect key="frame" x="2" y="214" width="357" height="5"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
</box>
|
||||
<box autoresizesSubviews="NO" verticalHuggingPriority="750" fixedFrame="YES" boxType="separator" translatesAutoresizingMaskIntoConstraints="NO" id="838">
|
||||
<rect key="frame" x="2" y="100" width="357" height="5"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
</box>
|
||||
<button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="854">
|
||||
<rect key="frame" x="102" y="8" width="97" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="check" title="Enabled" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="855">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<binding destination="450" name="value" keyPath="pickerTarget.enabled" id="859"/>
|
||||
=======
|
||||
<action selector="updateElements:" target="450" id="811" />
|
||||
</connections>
|
||||
</popUpButton>
|
||||
@@ -619,11 +1151,33 @@
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<binding destination="450" name="value" keyPath="pickerTarget.enabled" id="859" />
|
||||
>>>>>>> main
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
</view>
|
||||
</box>
|
||||
<<<<<<< HEAD
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="842">
|
||||
<rect key="frame" x="413" y="381" width="362" height="21"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="center" title="Label" id="843">
|
||||
<font key="font" metaFont="system" size="17"/>
|
||||
<color key="textColor" red="0.34552848339999997" green="0.34552848339999997" blue="0.34552848339999997" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
<connections>
|
||||
<binding destination="450" name="value" keyPath="pickerTarget.objectValue" id="847"/>
|
||||
</connections>
|
||||
</textField>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="848">
|
||||
<rect key="frame" x="413" y="352" width="362" height="21"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="center" title="Label" id="849">
|
||||
<font key="font" metaFont="system" size="17"/>
|
||||
<color key="textColor" red="0.34552848339999997" green="0.34552848339999997" blue="0.34552848339999997" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
=======
|
||||
<textField verticalHuggingPriority="750" id="842">
|
||||
<rect key="frame" x="413" y="381" width="362" height="21" />
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES" />
|
||||
@@ -643,18 +1197,31 @@
|
||||
<font key="font" metaFont="system" size="17" />
|
||||
<color key="textColor" red="0.34552848339999997" green="0.34552848339999997" blue="0.34552848339999997" alpha="1" colorSpace="calibratedRGB" />
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog" />
|
||||
>>>>>>> main
|
||||
</textFieldCell>
|
||||
<connections>
|
||||
<binding destination="450" name="value" keyPath="pickerTarget.timeInterval" id="860">
|
||||
<dictionary key="options">
|
||||
<<<<<<< HEAD
|
||||
<integer key="NSConditionallySetsHidden" value="1"/>
|
||||
=======
|
||||
<integer key="NSConditionallySetsHidden" value="1" />
|
||||
>>>>>>> main
|
||||
</dictionary>
|
||||
</binding>
|
||||
</connections>
|
||||
</textField>
|
||||
</subviews>
|
||||
</view>
|
||||
<<<<<<< HEAD
|
||||
<point key="canvasLocation" x="5" y="405"/>
|
||||
</window>
|
||||
<userDefaultsController representsSharedInstance="YES" id="790"/>
|
||||
</objects>
|
||||
</document>
|
||||
=======
|
||||
</window>
|
||||
<userDefaultsController representsSharedInstance="YES" id="790" />
|
||||
</objects>
|
||||
</document>
|
||||
</document>
|
||||
>>>>>>> main
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
- (void)applicationDidFinishLaunching:(CPNotification)aNotification
|
||||
{
|
||||
var theWindow = [[CPWindow alloc] initWithContentRect:CGRectMakeZero() styleMask:CPBorderlessBridgeWindowMask],
|
||||
var theWindow = [[CPWindow alloc] initWithContentRect:CGRectMakeZero() styleMask:CPBorderlessBridgeWindowMask | CPHUDBackgroundWindowMask],
|
||||
contentView = [theWindow contentView],
|
||||
popupButton = [[CPPopUpButton alloc] initWithFrame:CGRectMakeZero()];
|
||||
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CPDefaultTheme</key>
|
||||
<string>Aristo3</string>
|
||||
<key>Main cib file base name</key>
|
||||
<string>MainMenu.cib</string>
|
||||
<key>CPBundleName</key>
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CPDefaultTheme</key>
|
||||
<string>Aristo3</string>
|
||||
<key>Main cib file base name</key>
|
||||
<string>MainMenu.cib</string>
|
||||
<key>CPBundleName</key>
|
||||
|
||||
@@ -2,6 +2,10 @@
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CPDefaultTheme</key>
|
||||
<string>Aristo3</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string></string>
|
||||
<key>Main cib file base name</key>
|
||||
<string>MainMenu.cib</string>
|
||||
<key>CPBundleName</key>
|
||||
|
||||
@@ -0,0 +1,306 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="19529" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<dependencies>
|
||||
<deployment version="1050" identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="19529"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="NSApplication">
|
||||
<connections>
|
||||
<outlet property="delegate" destination="450" id="451"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
||||
<customObject id="-3" userLabel="Application"/>
|
||||
<window title="Window" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" animationBehavior="default" id="371">
|
||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES"/>
|
||||
<rect key="contentRect" x="464" y="307" width="769" height="357"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="1792" height="1095"/>
|
||||
<view key="contentView" id="372">
|
||||
<rect key="frame" x="0.0" y="0.0" width="769" height="357"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
|
||||
<subviews>
|
||||
<scrollView fixedFrame="YES" autohidesScrollers="YES" horizontalLineScroll="19" horizontalPageScroll="10" verticalLineScroll="19" verticalPageScroll="10" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="461">
|
||||
<rect key="frame" x="20" y="51" width="619" height="104"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
|
||||
<clipView key="contentView" id="EON-jB-7vG">
|
||||
<rect key="frame" x="1" y="1" width="617" height="102"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" alternatingRowBackgroundColors="YES" columnReordering="NO" columnResizing="NO" autosaveColumns="NO" typeSelect="NO" headerView="464" id="462">
|
||||
<rect key="frame" x="0.0" y="0.0" width="617" height="74"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<size key="intercellSpacing" width="3" height="2"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<color key="gridColor" name="gridColor" catalog="System" colorSpace="catalog"/>
|
||||
<tableColumns>
|
||||
<tableColumn width="180" minWidth="40" maxWidth="1000" id="466">
|
||||
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left" title="Value">
|
||||
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" white="0.33333298560000002" alpha="1" colorSpace="calibratedWhite"/>
|
||||
</tableHeaderCell>
|
||||
<textFieldCell key="dataCell" lineBreakMode="truncatingTail" selectable="YES" editable="YES" alignment="left" title="Text Cell" id="469">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
|
||||
<connections>
|
||||
<binding destination="472" name="value" keyPath="arrangedObjects.value" id="529">
|
||||
<dictionary key="options">
|
||||
<string key="NSNullPlaceholder">NULL</string>
|
||||
</dictionary>
|
||||
</binding>
|
||||
</connections>
|
||||
</tableColumn>
|
||||
<tableColumn width="211" minWidth="40" maxWidth="1000" id="467">
|
||||
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left" title="Min Value">
|
||||
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" white="0.33333298560000002" alpha="1" colorSpace="calibratedWhite"/>
|
||||
</tableHeaderCell>
|
||||
<textFieldCell key="dataCell" lineBreakMode="truncatingTail" selectable="YES" editable="YES" alignment="left" title="Text Cell" id="468">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
|
||||
<connections>
|
||||
<binding destination="472" name="value" keyPath="arrangedObjects.minValue" id="528">
|
||||
<dictionary key="options">
|
||||
<string key="NSNullPlaceholder">NULL</string>
|
||||
</dictionary>
|
||||
</binding>
|
||||
</connections>
|
||||
</tableColumn>
|
||||
<tableColumn width="208" minWidth="10" maxWidth="3.4028234663852886e+38" id="497">
|
||||
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left" title="Max Value">
|
||||
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
|
||||
</tableHeaderCell>
|
||||
<textFieldCell key="dataCell" lineBreakMode="truncatingTail" selectable="YES" editable="YES" alignment="left" title="Text Cell" id="498">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
|
||||
<connections>
|
||||
<binding destination="472" name="value" keyPath="arrangedObjects.maxValue" id="530">
|
||||
<dictionary key="options">
|
||||
<string key="NSNullPlaceholder">NULL</string>
|
||||
</dictionary>
|
||||
</binding>
|
||||
</connections>
|
||||
</tableColumn>
|
||||
</tableColumns>
|
||||
</tableView>
|
||||
</subviews>
|
||||
</clipView>
|
||||
<scroller key="horizontalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="YES" id="463">
|
||||
<rect key="frame" x="1" y="192" width="446" height="15"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</scroller>
|
||||
<scroller key="verticalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="NO" id="465">
|
||||
<rect key="frame" x="224" y="17" width="15" height="102"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</scroller>
|
||||
<tableHeaderView key="headerView" wantsLayer="YES" id="464">
|
||||
<rect key="frame" x="0.0" y="0.0" width="617" height="28"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</tableHeaderView>
|
||||
</scrollView>
|
||||
<stepper horizontalHuggingPriority="750" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="476">
|
||||
<rect key="frame" x="17" y="305" width="19" height="27"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
|
||||
<stepperCell key="cell" continuous="YES" alignment="left" minValue="40" maxValue="50" doubleValue="45" id="477"/>
|
||||
<connections>
|
||||
<binding destination="472" name="maxValue" keyPath="selection.maxValue" id="494"/>
|
||||
<binding destination="472" name="minValue" keyPath="selection.minValue" previousBinding="494" id="495"/>
|
||||
<binding destination="472" name="value" keyPath="selection.value" previousBinding="495" id="496"/>
|
||||
</connections>
|
||||
</stepper>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="478">
|
||||
<rect key="frame" x="20" y="188" width="152" height="22"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" id="479">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
<connections>
|
||||
<binding destination="472" name="value" keyPath="selection.value" id="524">
|
||||
<dictionary key="options">
|
||||
<string key="NSNullPlaceholder">NULL</string>
|
||||
</dictionary>
|
||||
</binding>
|
||||
</connections>
|
||||
</textField>
|
||||
<button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="486">
|
||||
<rect key="frame" x="20" y="19" width="30" height="25"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
|
||||
<buttonCell key="cell" type="smallSquare" title="+" bezelStyle="smallSquare" alignment="center" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="487">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" size="25" name="Symbol"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="add:" target="472" id="488"/>
|
||||
</connections>
|
||||
</button>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="502">
|
||||
<rect key="frame" x="339" y="315" width="96" height="22"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" id="503">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
<connections>
|
||||
<binding destination="513" name="value" keyPath="selection.objectValue" id="521"/>
|
||||
</connections>
|
||||
</textField>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="505">
|
||||
<rect key="frame" x="339" y="283" width="96" height="22"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" id="506">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
<connections>
|
||||
<binding destination="513" name="value" keyPath="selection.minValue" id="522">
|
||||
<dictionary key="options">
|
||||
<string key="NSNullPlaceholder">NULL</string>
|
||||
</dictionary>
|
||||
</binding>
|
||||
</connections>
|
||||
</textField>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="508">
|
||||
<rect key="frame" x="339" y="251" width="96" height="22"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" id="509">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
<connections>
|
||||
<binding destination="513" name="value" keyPath="selection.maxValue" id="523">
|
||||
<dictionary key="options">
|
||||
<string key="NSNullPlaceholder">NULL</string>
|
||||
</dictionary>
|
||||
</binding>
|
||||
</connections>
|
||||
</textField>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="535">
|
||||
<rect key="frame" x="17" y="166" width="172" height="14"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="ac.arrangedObjects.value" id="536">
|
||||
<font key="font" size="11" name="Courier"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="537">
|
||||
<rect key="frame" x="206" y="166" width="193" height="14"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="ac.arrangedObjects.minValue" id="538">
|
||||
<font key="font" size="11" name="Courier"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="539">
|
||||
<rect key="frame" x="417" y="166" width="193" height="14"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="ac.arrangedObjects.maxValue" id="540">
|
||||
<font key="font" size="11" name="Courier"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="541">
|
||||
<rect key="frame" x="46" y="309" width="235" height="14"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="CPValueBinding ac.selection.value" id="542">
|
||||
<font key="font" size="11" name="Courier"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="543">
|
||||
<rect key="frame" x="46" y="289" width="277" height="14"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="CPMinValueBinding ac.selection.minValue" id="544">
|
||||
<font key="font" size="11" name="Courier"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="545">
|
||||
<rect key="frame" x="46" y="269" width="277" height="14"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="CPMaxValueBinding ac.selection.maxValue" id="546">
|
||||
<font key="font" size="11" name="Courier"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="547">
|
||||
<rect key="frame" x="447" y="321" width="305" height="14"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="stepper.doubleValue (via object controller)" id="548">
|
||||
<font key="font" size="11" name="Courier"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="549">
|
||||
<rect key="frame" x="447" y="289" width="284" height="14"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="stepper.minValue (via object controller)" id="550">
|
||||
<font key="font" size="11" name="Courier"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="551">
|
||||
<rect key="frame" x="447" y="257" width="284" height="14"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="stepper.maxValue (via object controller)" id="552">
|
||||
<font key="font" size="11" name="Courier"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="555">
|
||||
<rect key="frame" x="177" y="188" width="235" height="14"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="CPValueBinding ac.selection.value" id="556">
|
||||
<font key="font" size="11" name="Courier"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
</subviews>
|
||||
</view>
|
||||
<point key="canvasLocation" x="-53" y="55"/>
|
||||
</window>
|
||||
<customObject id="450" customClass="AppController">
|
||||
<connections>
|
||||
<outlet property="stepper" destination="476" id="501"/>
|
||||
<outlet property="theWindow" destination="371" id="459"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
<arrayController automaticallyPreparesContent="YES" avoidsEmptySelection="NO" id="472">
|
||||
<declaredKeys>
|
||||
<string>value</string>
|
||||
<string>minValue</string>
|
||||
<string>maxvalue</string>
|
||||
</declaredKeys>
|
||||
</arrayController>
|
||||
<objectController id="513">
|
||||
<connections>
|
||||
<binding destination="450" name="contentObject" keyPath="stepper" id="514"/>
|
||||
</connections>
|
||||
</objectController>
|
||||
</objects>
|
||||
</document>
|
||||
@@ -1,8 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<<<<<<< HEAD
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="19529" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<dependencies>
|
||||
<deployment version="1050" identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="19529"/>
|
||||
=======
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="24506" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none">
|
||||
<dependencies>
|
||||
<deployment version="1050" identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="24506"/>
|
||||
>>>>>>> main
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
@@ -17,12 +24,20 @@
|
||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES"/>
|
||||
<windowPositionMask key="initialPositionMask" leftStrut="YES" bottomStrut="YES"/>
|
||||
<rect key="contentRect" x="630" y="330" width="480" height="360"/>
|
||||
<<<<<<< HEAD
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="1792" height="1095"/>
|
||||
=======
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="1680" height="1028"/>
|
||||
>>>>>>> main
|
||||
<view key="contentView" id="372">
|
||||
<rect key="frame" x="0.0" y="0.0" width="480" height="360"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<subviews>
|
||||
<<<<<<< HEAD
|
||||
<stepper horizontalHuggingPriority="750" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="460">
|
||||
=======
|
||||
<stepper horizontalHuggingPriority="750" verticalHuggingPriority="750" id="460">
|
||||
>>>>>>> main
|
||||
<rect key="frame" x="283" y="166" width="19" height="27"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
|
||||
<stepperCell key="cell" alignment="left" increment="2" minValue="1" maxValue="100" doubleValue="3" autorepeat="NO" valueWraps="YES" id="461"/>
|
||||
@@ -30,7 +45,11 @@
|
||||
<action selector="takeDoubleValueFrom:" target="463" id="465"/>
|
||||
</connections>
|
||||
</stepper>
|
||||
<<<<<<< HEAD
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" tag="1004" translatesAutoresizingMaskIntoConstraints="NO" id="463">
|
||||
=======
|
||||
<textField verticalHuggingPriority="750" tag="1004" id="463">
|
||||
>>>>>>> main
|
||||
<rect key="frame" x="182" y="169" width="96" height="22"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" id="464">
|
||||
@@ -39,7 +58,11 @@
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<<<<<<< HEAD
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" tag="1000" translatesAutoresizingMaskIntoConstraints="NO" id="466">
|
||||
=======
|
||||
<textField verticalHuggingPriority="750" tag="1000" id="466">
|
||||
>>>>>>> main
|
||||
<rect key="frame" x="364" y="318" width="96" height="22"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" id="467">
|
||||
@@ -51,7 +74,11 @@
|
||||
<action selector="setIncrement:" target="450" id="485"/>
|
||||
</connections>
|
||||
</textField>
|
||||
<<<<<<< HEAD
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="468">
|
||||
=======
|
||||
<textField verticalHuggingPriority="750" id="468">
|
||||
>>>>>>> main
|
||||
<rect key="frame" x="282" y="321" width="72" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Increment:" id="469">
|
||||
@@ -60,7 +87,11 @@
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<<<<<<< HEAD
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" tag="1001" translatesAutoresizingMaskIntoConstraints="NO" id="470">
|
||||
=======
|
||||
<textField verticalHuggingPriority="750" tag="1001" id="470">
|
||||
>>>>>>> main
|
||||
<rect key="frame" x="364" y="288" width="96" height="22"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" id="473">
|
||||
@@ -72,7 +103,11 @@
|
||||
<action selector="setMin:" target="450" id="484"/>
|
||||
</connections>
|
||||
</textField>
|
||||
<<<<<<< HEAD
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="471">
|
||||
=======
|
||||
<textField verticalHuggingPriority="750" id="471">
|
||||
>>>>>>> main
|
||||
<rect key="frame" x="284" y="291" width="70" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Min Value:" id="472">
|
||||
@@ -81,7 +116,11 @@
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<<<<<<< HEAD
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" tag="1002" translatesAutoresizingMaskIntoConstraints="NO" id="474">
|
||||
=======
|
||||
<textField verticalHuggingPriority="750" tag="1002" id="474">
|
||||
>>>>>>> main
|
||||
<rect key="frame" x="364" y="261" width="96" height="22"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" id="477">
|
||||
@@ -93,7 +132,11 @@
|
||||
<action selector="setMax:" target="450" id="483"/>
|
||||
</connections>
|
||||
</textField>
|
||||
<<<<<<< HEAD
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="475">
|
||||
=======
|
||||
<textField verticalHuggingPriority="750" id="475">
|
||||
>>>>>>> main
|
||||
<rect key="frame" x="280" y="264" width="74" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Max Value:" id="476">
|
||||
@@ -102,7 +145,11 @@
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<<<<<<< HEAD
|
||||
<button fixedFrame="YES" tag="1003" imageHugsTitle="YES" translatesAutoresizingMaskIntoConstraints="NO" id="480">
|
||||
=======
|
||||
<button tag="1003" imageHugsTitle="YES" id="480">
|
||||
>>>>>>> main
|
||||
<rect key="frame" x="272" y="237" width="109" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="check" title="wraps value:" bezelStyle="regularSquare" imagePosition="trailing" alignment="left" state="on" inset="2" id="481">
|
||||
@@ -113,7 +160,11 @@
|
||||
<action selector="setWraps:" target="450" id="482"/>
|
||||
</connections>
|
||||
</button>
|
||||
<<<<<<< HEAD
|
||||
<button fixedFrame="YES" tag="1005" imageHugsTitle="YES" translatesAutoresizingMaskIntoConstraints="NO" id="486">
|
||||
=======
|
||||
<button tag="1005" imageHugsTitle="YES" id="486">
|
||||
>>>>>>> main
|
||||
<rect key="frame" x="281" y="213" width="100" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="check" title="autorepeat:" bezelStyle="regularSquare" imagePosition="trailing" alignment="left" state="on" inset="2" id="487">
|
||||
@@ -126,6 +177,10 @@
|
||||
</button>
|
||||
</subviews>
|
||||
</view>
|
||||
<<<<<<< HEAD
|
||||
<point key="canvasLocation" x="-52" y="55"/>
|
||||
=======
|
||||
>>>>>>> main
|
||||
</window>
|
||||
<customObject id="450" customClass="AppController">
|
||||
<connections>
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
<dict>
|
||||
<key>CPApplicationDelegateClass</key>
|
||||
<string>AppController</string>
|
||||
<key>CPDefaultTheme</key>
|
||||
<string>Aristo2</string>
|
||||
<key>CPDefaultTheme</key>
|
||||
<string>Aristo3</string>
|
||||
<key>CPBundleName</key>
|
||||
<string>CPTokenFieldTest</string>
|
||||
<key>CPPrincipalClass</key>
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CPDefaultTheme</key>
|
||||
<string>Aristo2</string>
|
||||
<key>CPApplicationDelegateClass</key>
|
||||
<string>AppController</string>
|
||||
<key>CPBundleName</key>
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CPDefaultTheme</key>
|
||||
<string>Aristo3</string>
|
||||
<key>Main cib file base name</key>
|
||||
<string>MainMenu.cib</string>
|
||||
<key>CPBundleName</key>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CPDefaultTheme</key>
|
||||
<string>Aristo3</string>
|
||||
<key>CPApplicationDelegateClass</key>
|
||||
<string>AppController</string>
|
||||
<key>CPBundleName</key>
|
||||
<string>KitchenSink Aristo3</string>
|
||||
<key>CPPrincipalClass</key>
|
||||
<string>CPApplication</string>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,182 @@
|
||||
/*
|
||||
* Jakefile
|
||||
* ThemeKitchenSinkA3
|
||||
*
|
||||
*/
|
||||
|
||||
var ENV = require("system").env,
|
||||
FILE = require("file"),
|
||||
JAKE = require("jake"),
|
||||
task = JAKE.task,
|
||||
FileList = JAKE.FileList,
|
||||
app = require("cappuccino/jake").app,
|
||||
configuration = ENV["CONFIG"] || ENV["CONFIGURATION"] || ENV["c"] || "Debug",
|
||||
OS = require("os"),
|
||||
projectName = "ThemeKitchenSinkA3";
|
||||
|
||||
app (projectName, function(task)
|
||||
{
|
||||
ENV["OBJJ_INCLUDE_PATHS"] = "Frameworks";
|
||||
|
||||
if (configuration === "Debug")
|
||||
ENV["OBJJ_INCLUDE_PATHS"] = FILE.join(ENV["OBJJ_INCLUDE_PATHS"], configuration);
|
||||
|
||||
task.setBuildIntermediatesPath(FILE.join("Build", "ThemeKitchenSinkA3.build", configuration));
|
||||
task.setBuildPath(FILE.join("Build", configuration));
|
||||
|
||||
task.setProductName("ThemeKitchenSinkA3");
|
||||
task.setIdentifier("com.yourcompany.ThemeKitchenSinkA3");
|
||||
task.setVersion("1.0");
|
||||
task.setAuthor("SlevenBits, Ltd.");
|
||||
task.setEmail("feedback @nospam@ yourcompany.com");
|
||||
task.setSummary("ThemeKitchenSinkA3");
|
||||
task.setSources(new FileList("**/*.j").exclude(FILE.join("Build", "**")).exclude(FILE.join("Frameworks", "Source", "**")));
|
||||
task.setResources(new FileList("Resources/**"));
|
||||
task.setIndexFilePath("index.html");
|
||||
task.setInfoPlistPath("Info.plist");
|
||||
|
||||
if (configuration === "Debug")
|
||||
task.setCompilerFlags("-DDEBUG -g");
|
||||
else
|
||||
task.setCompilerFlags("-O");
|
||||
});
|
||||
|
||||
task ("default", [projectName], function()
|
||||
{
|
||||
printResults(configuration);
|
||||
});
|
||||
|
||||
task ("build", ["default"], function()
|
||||
{
|
||||
updateApplicationSize();
|
||||
});
|
||||
|
||||
task ("debug", function()
|
||||
{
|
||||
ENV["CONFIGURATION"] = "Debug";
|
||||
JAKE.subjake(["."], "build", ENV);
|
||||
});
|
||||
|
||||
task ("release", function()
|
||||
{
|
||||
ENV["CONFIGURATION"] = "Release";
|
||||
JAKE.subjake(["."], "build", ENV);
|
||||
});
|
||||
|
||||
task ("run", ["debug"], function()
|
||||
{
|
||||
OS.system(["open", FILE.join("Build", "Debug", projectName, "index.html")]);
|
||||
});
|
||||
|
||||
task ("run-release", ["release"], function()
|
||||
{
|
||||
OS.system(["open", FILE.join("Build", "Release", projectName, "index.html")]);
|
||||
});
|
||||
|
||||
task ("deploy", ["release"], function()
|
||||
{
|
||||
FILE.mkdirs(FILE.join("Build", "Deployment", projectName));
|
||||
OS.system(["press", "-f", FILE.join("Build", "Release", projectName), FILE.join("Build", "Deployment", projectName)]);
|
||||
printResults("Deployment")
|
||||
});
|
||||
|
||||
task ("desktop", ["release"], function()
|
||||
{
|
||||
FILE.mkdirs(FILE.join("Build", "Desktop", projectName));
|
||||
require("cappuccino/nativehost").buildNativeHost(FILE.join("Build", "Release", projectName), FILE.join("Build", "Desktop", projectName, "ThemeKitchenSinkA3.app"));
|
||||
printResults("Desktop")
|
||||
});
|
||||
|
||||
task ("run-desktop", ["desktop"], function()
|
||||
{
|
||||
OS.system([FILE.join("Build", "Desktop", projectName, "ThemeKitchenSinkA3.app", "Contents", "MacOS", "NativeHost"), "-i"]);
|
||||
});
|
||||
|
||||
function printResults(configuration)
|
||||
{
|
||||
print("----------------------------");
|
||||
print(configuration+" app built at path: "+FILE.join("Build", configuration, projectName));
|
||||
print("----------------------------");
|
||||
}
|
||||
|
||||
function updateApplicationSize()
|
||||
{
|
||||
print("Calculating application file sizes...");
|
||||
|
||||
var contents = FILE.read(FILE.join("Build", ENV["CONFIGURATION"], projectName, "Info.plist"), { charset:"UTF-8" }),
|
||||
format = CFPropertyList.sniffedFormatOfString(contents),
|
||||
plist = CFPropertyList.propertyListFromString(contents),
|
||||
totalBytes = {executable:0, data:0, mhtml:0};
|
||||
|
||||
// Get the size of all framework executables and sprite data
|
||||
var frameworksDir = "Frameworks";
|
||||
|
||||
if (ENV["CONFIGURATION"] === "Debug")
|
||||
frameworksDir = FILE.join(frameworksDir, "Debug");
|
||||
|
||||
var frameworks = FILE.list(frameworksDir);
|
||||
|
||||
frameworks.forEach(function(framework)
|
||||
{
|
||||
if (framework !== "Source")
|
||||
addBundleFileSizes(FILE.join(frameworksDir, framework), totalBytes);
|
||||
});
|
||||
|
||||
// Read in the default theme name, and attempt to get its size
|
||||
var themeName = plist.valueForKey("CPDefaultTheme") || "Aristo2",
|
||||
themePath = nil;
|
||||
|
||||
if (themeName === "Aristo" || themeName === "Aristo2")
|
||||
themePath = FILE.join(frameworksDir, "AppKit", "Resources", themeName + ".blend");
|
||||
else
|
||||
themePath = FILE.join("Frameworks", "Resources", themeName + ".blend");
|
||||
|
||||
if (FILE.isDirectory(themePath))
|
||||
addBundleFileSizes(themePath, totalBytes);
|
||||
|
||||
// Add sizes for the app
|
||||
addBundleFileSizes(FILE.join("Build", ENV["CONFIGURATION"], projectName), totalBytes);
|
||||
|
||||
print("Executables: " + totalBytes.executable + ", sprite data: " + totalBytes.data + ", total: " + (totalBytes.executable + totalBytes.data));
|
||||
|
||||
var dict = new CFMutableDictionary();
|
||||
|
||||
dict.setValueForKey("executable", totalBytes.executable);
|
||||
dict.setValueForKey("data", totalBytes.data);
|
||||
dict.setValueForKey("mhtml", totalBytes.mhtml);
|
||||
|
||||
plist.setValueForKey("CPApplicationSize", dict);
|
||||
|
||||
FILE.write(FILE.join("Build", ENV["CONFIGURATION"], projectName, "Info.plist"), CFPropertyList.stringFromPropertyList(plist, format), { charset:"UTF-8" });
|
||||
}
|
||||
|
||||
function addBundleFileSizes(bundlePath, totalBytes)
|
||||
{
|
||||
var bundleName = FILE.basename(bundlePath),
|
||||
environment = bundleName === "Foundation" ? "Objj" : "Browser",
|
||||
bundlePath = FILE.join(bundlePath, environment + ".environment");
|
||||
|
||||
if (FILE.isDirectory(bundlePath))
|
||||
{
|
||||
var filename = bundleName + ".sj",
|
||||
filePath = new FILE.Path(FILE.join(bundlePath, filename));
|
||||
|
||||
if (filePath.exists())
|
||||
totalBytes.executable += filePath.size();
|
||||
|
||||
filePath = new FILE.Path(FILE.join(bundlePath, "dataURLs.txt"));
|
||||
|
||||
if (filePath.exists())
|
||||
totalBytes.data += filePath.size();
|
||||
|
||||
filePath = new FILE.Path(FILE.join(bundlePath, "MHTMLData.txt"));
|
||||
|
||||
if (filePath.exists())
|
||||
totalBytes.mhtml += filePath.size();
|
||||
|
||||
filePath = new FILE.Path(FILE.join(bundlePath, "MHTMLPaths.txt"));
|
||||
|
||||
if (filePath.exists())
|
||||
totalBytes.mhtml += filePath.size();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,204 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<!--
|
||||
index-debug.html
|
||||
__project.name__
|
||||
|
||||
Created by __user.name__ on __project.date__.
|
||||
Copyright __project.year__, __organization.name__ All rights reserved.
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
||||
<!--[if lte IE 8]>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7, chrome=1">
|
||||
<![endif]-->
|
||||
<!--[if gte IE 9]>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge, chrome=1">
|
||||
<![endif]-->
|
||||
|
||||
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
|
||||
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black">
|
||||
|
||||
<link rel="apple-touch-icon" href="Resources/icon.png">
|
||||
<link rel="apple-touch-startup-image" href="Resources/default.png">
|
||||
|
||||
<title>__project.name__</title>
|
||||
|
||||
<!-- Custom javascript goes here -->
|
||||
<!-- End custom javascript -->
|
||||
|
||||
<script type="text/javascript">
|
||||
OBJJ_MAIN_FILE = "main.j";
|
||||
OBJJ_INCLUDE_PATHS = ["Frameworks/Debug", "Frameworks"];
|
||||
// The below will tell the compiler to generate debug symbols, type signatures and not inline objj_msgSend functions.
|
||||
// This will affect only Objective-J code that is compiled when loading the application. It will not affect precompiled
|
||||
// code like the Cappuccino frameworks.
|
||||
//
|
||||
// Debug symbols will give each Objective-J method a Javascript function name. Without a name it will be very hard to find
|
||||
// the methods in the debugger.
|
||||
// Type Signatures will give type information to the Objective-J runtime for instance variables and methods.
|
||||
// Inline objj_msgSend will give a speed increase but decorators will not work. Check below on debug options for
|
||||
// more information on decorators.
|
||||
//
|
||||
// Uncomment or comment on the line below to change the flags
|
||||
OBJJ_COMPILER_FLAGS = ["IncludeDebugSymbols", "IncludeTypeSignatures", "SourceMap", "InlineMsgSend"];
|
||||
|
||||
var progressBar = null;
|
||||
|
||||
OBJJ_PROGRESS_CALLBACK = function(percent, appSize, path)
|
||||
{
|
||||
percent = percent * 100;
|
||||
|
||||
if (!progressBar)
|
||||
progressBar = document.getElementById("progress-bar");
|
||||
|
||||
if (progressBar)
|
||||
progressBar.style.width = Math.min(percent, 100) + "%";
|
||||
}
|
||||
|
||||
var loadingHTML =
|
||||
'<div id="loading">' +
|
||||
' <div id="loading-text">Loading...</div>' +
|
||||
' <div id="progress-indicator">' +
|
||||
' <span id="progress-bar" style="width:0%"></span>' +
|
||||
' </div>' +
|
||||
'</div>';
|
||||
</script>
|
||||
|
||||
<script type="text/javascript" src="Frameworks/Debug/Objective-J/Objective-J.js" charset="UTF-8"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
objj_msgSend_reset();
|
||||
|
||||
// DEBUG OPTIONS:
|
||||
// Decorators will only work when the code is compiled without the compiler option 'InlineMsgSend'. Check above.
|
||||
|
||||
// Uncomment to enable printing of backtraces on exceptions:
|
||||
//objj_msgSend_decorate(objj_backtrace_decorator);
|
||||
|
||||
// Uncomment to supress exceptions that take place inside a message
|
||||
//objj_msgSend_decorate(objj_supress_exceptions_decorator)
|
||||
|
||||
// Uncomment to enable runtime type checking:
|
||||
//objj_msgSend_decorate(objj_typecheck_decorator);
|
||||
|
||||
// Uncomment (along with both above) to print backtraces on type check errors:
|
||||
//objj_typecheck_prints_backtrace = true;
|
||||
|
||||
// Uncomment to disable the default logger (CPLogConsole if window.console exists, CPLogPopup otherwise):
|
||||
//CPLogUnregister(CPLogDefault);
|
||||
|
||||
// Uncomment to enable a specific logger:
|
||||
//CPLogRegister(CPLogConsole);
|
||||
//CPLogRegister(CPLogPopup);
|
||||
|
||||
// Tag view DOM elements with a "data-cappuccino-view" attribute that contains
|
||||
// the class name of the view that created them. Comment this or set to false to disable.
|
||||
appkit_tag_dom_elements = true;
|
||||
</script>
|
||||
|
||||
<style type="text/css">
|
||||
html, body, h1, p {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/* We need a body wrapper because Cappuccino is unhappy if we change the body element */
|
||||
#cappuccino-body {
|
||||
/* Position it absolutely so it will fill the height without content */
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
|
||||
/* Put it at the bottom of the stack so it doesn't interfere with UI */
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
#cappuccino-body .container {
|
||||
display: table;
|
||||
margin: 0 auto;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
#cappuccino-body .content {
|
||||
display: table-cell;
|
||||
height: 100%;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
#loading {
|
||||
position: relative;
|
||||
top: 35%;
|
||||
}
|
||||
|
||||
#loading-text {
|
||||
height: 1.5em;
|
||||
color: #555;
|
||||
font: normal bold 36px/36px Arial, sans-serif;
|
||||
}
|
||||
|
||||
#progress-indicator {
|
||||
padding: 0px;
|
||||
height: 16px;
|
||||
border: 5px solid #555;
|
||||
border-radius: 18px;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
#progress-bar {
|
||||
position: relative;
|
||||
top: -1px;
|
||||
left: -1px;
|
||||
display: block;
|
||||
height: 18px;
|
||||
|
||||
/* Compensate for moving the bar left 1px to overlap the indicator border */
|
||||
border-right: 1px solid #555;
|
||||
background-color: #555;
|
||||
}
|
||||
|
||||
#noscript {
|
||||
position: relative;
|
||||
top: 35%;
|
||||
padding: 1em 1.5em;
|
||||
border: 5px solid #555;
|
||||
border-radius: 16px;
|
||||
background-color: white;
|
||||
color: #555;
|
||||
text-align: center;
|
||||
font: bold 24px Arial, sans-serif;
|
||||
}
|
||||
|
||||
#noscript a {
|
||||
color: #98c0ff;
|
||||
text-decoration: none;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="cappuccino-body">
|
||||
<div class="container">
|
||||
<div class="content">
|
||||
<script type="text/javascript">
|
||||
document.write(loadingHTML);
|
||||
</script>
|
||||
</div>
|
||||
</div>
|
||||
<noscript style="position:absolute; top:0; left:0; width:100%; height:100%">
|
||||
<div class="container">
|
||||
<div class="content">
|
||||
<div id="noscript">
|
||||
<p style="font-size:120%; margin-bottom:.75em">JavaScript is required for this application.</p>
|
||||
<p><a href="http://www.enable-javascript.com" target="_blank">Enable JavaScript</a></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</noscript>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,166 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<!--
|
||||
index.html
|
||||
__project.name__
|
||||
|
||||
Created by __user.name__ on __project.date__.
|
||||
Copyright __project.year__, __organization.name__ All rights reserved.
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
||||
<!--[if lte IE 8]>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7, chrome=1">
|
||||
<![endif]-->
|
||||
<!--[if gte IE 9]>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge, chrome=1">
|
||||
<![endif]-->
|
||||
|
||||
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
|
||||
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black">
|
||||
|
||||
<link rel="apple-touch-icon" href="Resources/icon.png">
|
||||
<link rel="apple-touch-startup-image" href="Resources/default.png">
|
||||
|
||||
<title>__project.name__</title>
|
||||
|
||||
<!-- Custom javascript goes here -->
|
||||
<!-- End custom javascript -->
|
||||
|
||||
<script type="text/javascript">
|
||||
OBJJ_MAIN_FILE = "main.j";
|
||||
// The below will tell the compiler to not generate debug symbols but will generate type signatures and inline objj_msgSend functions.
|
||||
// This will affect only Objective-J code that is compiled when loading the application. It will not affect precompiled
|
||||
// code like the Cappuccino frameworks.
|
||||
// Uncomment or comment on the line below to change the flags
|
||||
OBJJ_COMPILER_FLAGS = [/*"IncludeDebugSymbols"*/, "IncludeTypeSignatures"/*, "SourceMap"*/, "InlineMsgSend"];
|
||||
|
||||
var progressBar = null;
|
||||
|
||||
OBJJ_PROGRESS_CALLBACK = function(percent, appSize, path)
|
||||
{
|
||||
percent = percent * 100;
|
||||
|
||||
if (!progressBar)
|
||||
progressBar = document.getElementById("progress-bar");
|
||||
|
||||
if (progressBar)
|
||||
progressBar.style.width = Math.min(percent, 100) + "%";
|
||||
}
|
||||
|
||||
var loadingHTML =
|
||||
'<div id="loading">' +
|
||||
' <div id="loading-text">Loading...</div>' +
|
||||
' <div id="progress-indicator">' +
|
||||
' <span id="progress-bar" style="width:0%"></span>' +
|
||||
' </div>' +
|
||||
'</div>';
|
||||
</script>
|
||||
|
||||
<script type="text/javascript" src="Frameworks/Objective-J/Objective-J.js" charset="UTF-8"></script>
|
||||
|
||||
<style type="text/css">
|
||||
html, body, h1, p {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/* We need a body wrapper because Cappuccino is unhappy if we change the body element */
|
||||
#cappuccino-body {
|
||||
/* Position it absolutely so it will fill the height without content */
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
|
||||
/* Put it at the bottom of the stack so it doesn't interfere with UI */
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
#cappuccino-body .container {
|
||||
display: table;
|
||||
margin: 0 auto;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
#cappuccino-body .content {
|
||||
display: table-cell;
|
||||
height: 100%;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
#loading {
|
||||
position: relative;
|
||||
top: 35%;
|
||||
}
|
||||
|
||||
#loading-text {
|
||||
height: 1.5em;
|
||||
color: #555;
|
||||
font: normal bold 36px/36px Arial, sans-serif;
|
||||
}
|
||||
|
||||
#progress-indicator {
|
||||
padding: 0px;
|
||||
height: 16px;
|
||||
border: 5px solid #555;
|
||||
border-radius: 18px;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
#progress-bar {
|
||||
position: relative;
|
||||
top: -1px;
|
||||
left: -1px;
|
||||
display: block;
|
||||
height: 18px;
|
||||
|
||||
/* Compensate for moving the bar left 1px to overlap the indicator border */
|
||||
border-right: 1px solid #555;
|
||||
background-color: #555;
|
||||
}
|
||||
|
||||
#noscript {
|
||||
position: relative;
|
||||
top: 35%;
|
||||
padding: 1em 1.5em;
|
||||
border: 5px solid #555;
|
||||
border-radius: 16px;
|
||||
background-color: white;
|
||||
color: #555;
|
||||
text-align: center;
|
||||
font: bold 24px Arial, sans-serif;
|
||||
}
|
||||
|
||||
#noscript a {
|
||||
color: #98c0ff;
|
||||
text-decoration: none;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="cappuccino-body">
|
||||
<div class="container">
|
||||
<div class="content">
|
||||
<script type="text/javascript">
|
||||
document.write(loadingHTML);
|
||||
</script>
|
||||
</div>
|
||||
</div>
|
||||
<noscript style="position:absolute; top:0; left:0; width:100%; height:100%">
|
||||
<div class="container">
|
||||
<div class="content">
|
||||
<div id="noscript">
|
||||
<p style="font-size:120%; margin-bottom:.75em">JavaScript is required for this application.</p>
|
||||
<p><a href="http://www.enable-javascript.com" target="_blank">Enable JavaScript</a></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</noscript>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* AppController.j
|
||||
* ThemeKitchenSink
|
||||
*
|
||||
* Created by Alexander Ljungberg on May 11, 2014.
|
||||
* Copyright 2014, SlevenBits, Ltd. All rights reserved.
|
||||
*/
|
||||
|
||||
@import <Foundation/Foundation.j>
|
||||
@import <AppKit/AppKit.j>
|
||||
|
||||
@import "AppController.j"
|
||||
|
||||
|
||||
function main(args, namedArgs)
|
||||
{
|
||||
CPApplicationMain(args, namedArgs);
|
||||
}
|
||||
@@ -6,11 +6,11 @@
|
||||
<string>MainMenu.cib</string>
|
||||
<key>CPBundleName</key>
|
||||
<string>ThemeKitchenSink</string>
|
||||
<key>CPDefaultTheme</key>
|
||||
<string>Aristo2</string>
|
||||
<key>CPBundleVersion</key>
|
||||
<string>1.0</string>
|
||||
<key>CPHumanReadableCopyright</key>
|
||||
<string>Copyright © 2014, SlevenBits, Ltd. All rights reserved.</string>
|
||||
<key>CPDefaultTheme</key>
|
||||
<string>Aristo3</string>
|
||||
<key>CPBundleVersion</key>
|
||||
<string>1.0</string>
|
||||
<key>CPHumanReadableCopyright</key>
|
||||
<string>Copyright © 2014, SlevenBits, Ltd. All rights reserved.</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
||||
@@ -211,8 +211,8 @@ var NSButtonIsBorderedMask = 0x00800000,
|
||||
}
|
||||
}
|
||||
|
||||
_keyEquivalent = [cell keyEquivalent];
|
||||
_keyEquivalentModifierMask = [cell keyEquivalentModifierMask];
|
||||
[self setKeyEquivalent:[cell keyEquivalent]];
|
||||
[self setKeyEquivalentModifierMask:[cell keyEquivalentModifierMask]];
|
||||
_imageDimsWhenDisabled = YES;
|
||||
|
||||
_allowsMixedState = [cell allowsMixedState];
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user