From 8fc465b63a9e5244575248472df551a5962d4ccf Mon Sep 17 00:00:00 2001 From: Antoine Mercadal Date: Wed, 13 Oct 2010 13:37:28 +0200 Subject: [PATCH 1/7] fix: CPTabView not resizable fix: delegate problem with uninitialized variable --- AppKit/CPTabView.j | 47 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/AppKit/CPTabView.j b/AppKit/CPTabView.j index 7a9f86697..2d8265411 100644 --- a/AppKit/CPTabView.j +++ b/AppKit/CPTabView.j @@ -77,6 +77,46 @@ var HEIGHT_OF_SEGMENTED_CONTROL = 24; return self; } +/*! + Override CPView message to allow to set the autoresizing mask + of the tabview and it's subview + + @param unsigned aMask the autoresizing mask +*/ +- (void)setAutoresizingMask:(unsigned)aMask +{ + [box setAutoresizingMask:aMask]; + + [super setAutoresizingMask:aMask]; +} + + +/*! + Override the CPView method in order + to allow to reposition the segmented control + + @param aFrame the new frame +*/ +- (void)setFrame:(CGRect)aFrame +{ + [super setFrame:aFrame]; + + [self _repositionTabs]; +} + +/*! + Override the CPView method in order + to allow to reposition the segmented control + + @param someBounds the new bounds +*/ +- (void)setBounds:(CGRect)someBounds +{ + [super setBounds:someBounds]; + + [self _repositionTabs]; +} + // Adding and Removing Tabs /*! Adds a CPTabViewItem to the tab view. @@ -251,9 +291,11 @@ var HEIGHT_OF_SEGMENTED_CONTROL = 24; if (anIndex === selectedIndex) return; + var aTabViewItem = [self tabViewItemAtIndex:anIndex]; + if ((delegateSelectors & CPTabViewShouldSelectTabViewItemSelector) && ![delegate tabView:self shouldSelectTabViewItem:aTabViewItem]) return; - + if (delegateSelectors & CPTabViewWillSelectTabViewItemSelector) [delegate tabView:self willSelectTabViewItem:aTabViewItem]; @@ -292,7 +334,8 @@ var HEIGHT_OF_SEGMENTED_CONTROL = 24; type = aTabViewType; - switch (type) { + switch (type) + { case CPTopTabsBezelBorder: case CPBottomTabsBezelBorder: case CPNoTabsBezelBorder: From 560c971aeb12a5d293c877785b4bf02feef9f275 Mon Sep 17 00:00:00 2001 From: Antoine Mercadal Date: Wed, 13 Oct 2010 13:41:35 +0200 Subject: [PATCH 2/7] capp_lint --- AppKit/CPTabView.j | 79 +++++++++++++++++++++++----------------------- 1 file changed, 40 insertions(+), 39 deletions(-) diff --git a/AppKit/CPTabView.j b/AppKit/CPTabView.j index 2d8265411..46cf5b4cd 100644 --- a/AppKit/CPTabView.j +++ b/AppKit/CPTabView.j @@ -48,7 +48,7 @@ var HEIGHT_OF_SEGMENTED_CONTROL = 24; CPNumber selectedIndex; CPTabViewType type; - + id delegate; unsigned delegateSelectors; } @@ -59,61 +59,61 @@ var HEIGHT_OF_SEGMENTED_CONTROL = 24; if (self) { items = [CPArray array]; - + tabs = [[CPSegmentedControl alloc] initWithFrame:CGRectMake(0, 0, 0, HEIGHT_OF_SEGMENTED_CONTROL)]; [tabs setHitTests:NO]; - + box = [[CPBox alloc] initWithFrame:CGRectMake(0, HEIGHT_OF_SEGMENTED_CONTROL / 2, CGRectGetWidth(aFrame), CGRectGetHeight(aFrame) - HEIGHT_OF_SEGMENTED_CONTROL)]; - + selectedIndex = CPNotFound; - + [self setTabViewType:CPTopTabsBezelBorder]; [self setBackgroundColor:[CPColor colorWithCalibratedWhite:0.95 alpha:1.0]]; - + [self addSubview:box]; [self addSubview:tabs]; } return self; } -/*! - Override CPView message to allow to set the autoresizing mask +/*! + Override CPView message to allow to set the autoresizing mask of the tabview and it's subview - + @param unsigned aMask the autoresizing mask */ - (void)setAutoresizingMask:(unsigned)aMask { [box setAutoresizingMask:aMask]; - + [super setAutoresizingMask:aMask]; } -/*! +/*! Override the CPView method in order to allow to reposition the segmented control - + @param aFrame the new frame */ - (void)setFrame:(CGRect)aFrame { [super setFrame:aFrame]; - + [self _repositionTabs]; } -/*! +/*! Override the CPView method in order to allow to reposition the segmented control - + @param someBounds the new bounds */ - (void)setBounds:(CGRect)someBounds { [super setBounds:someBounds]; - + [self _repositionTabs]; } @@ -136,7 +136,7 @@ var HEIGHT_OF_SEGMENTED_CONTROL = 24; - (void)insertTabViewItem:(CPTabViewItem)aTabViewItem atIndex:(unsigned)anIndex { [items insertObject:aTabViewItem atIndex:anIndex]; - + [self _updateItems]; [self _repositionTabs]; @@ -160,7 +160,7 @@ var HEIGHT_OF_SEGMENTED_CONTROL = 24; [self _updateItems]; [self _repositionTabs]; - + if (delegateSelectors & CPTabViewDidChangeNumberOfTabViewItemsSelector) [delegate tabViewDidChangeNumberOfTabViewItems:self]; } @@ -221,7 +221,7 @@ var HEIGHT_OF_SEGMENTED_CONTROL = 24; { if ([items count] === 0) return; // throw? - + [self selectTabViewItemAtIndex:0]; } @@ -233,7 +233,7 @@ var HEIGHT_OF_SEGMENTED_CONTROL = 24; { if ([items count] === 0) return; // throw? - + [self selectTabViewItemAtIndex:[items count] - 1]; } @@ -245,12 +245,13 @@ var HEIGHT_OF_SEGMENTED_CONTROL = 24; { if (selectedIndex === CPNotFound) return; - + var nextIndex = selectedIndex + 1; - + if (nextIndex === [items count]) - return; // does nothing. According to spec at (http://developer.apple.com/mac/library/DOCUMENTATION/Cocoa/Reference/ApplicationKit/Classes/NSTabView_Class/Reference/Reference.html#//apple_ref/occ/instm/NSTabView/selectNextTabViewItem:) - + // does nothing. According to spec at (http://developer.apple.com/mac/library/DOCUMENTATION/Cocoa/Reference/ApplicationKit/Classes/NSTabView_Class/Reference/Reference.html#//apple_ref/occ/instm/NSTabView/selectNextTabViewItem:) + return; + [self selectTabViewItemAtIndex:nextIndex]; } @@ -262,12 +263,12 @@ var HEIGHT_OF_SEGMENTED_CONTROL = 24; { if (selectedIndex === CPNotFound) return; - + var previousIndex = selectedIndex - 1; if (previousIndex < 0) return; // does nothing. See above. - + [self selectTabViewItemAtIndex:previousIndex]; } @@ -290,18 +291,18 @@ var HEIGHT_OF_SEGMENTED_CONTROL = 24; if (anIndex === selectedIndex) return; - + var aTabViewItem = [self tabViewItemAtIndex:anIndex]; - + if ((delegateSelectors & CPTabViewShouldSelectTabViewItemSelector) && ![delegate tabView:self shouldSelectTabViewItem:aTabViewItem]) return; - + if (delegateSelectors & CPTabViewWillSelectTabViewItemSelector) [delegate tabView:self willSelectTabViewItem:aTabViewItem]; - + [tabs selectSegmentWithTag:anIndex]; [self _setSelectedIndex:anIndex]; - + if (delegateSelectors & CPTabViewDidSelectTabViewItemSelector) [delegate tabView:self didSelectTabViewItem:aTabViewItem]; } @@ -323,17 +324,17 @@ var HEIGHT_OF_SEGMENTED_CONTROL = 24; { if (type === aTabViewType) return; - + if ((type === CPTopTabsBezelBorder || type === CPBottomTabsBezelBorder) && (aTabViewType !== CPTopTabsBezelBorder && aTabViewType !== CPBottomTabsBezelBorder)) [tabs removeFromSuperview]; - + if ((type === CPNoTabsBezelBorder || type === CPNoTabsLineBorder || type === CPNoTabsNoBorder) && (aTabViewType !== CPNoTabsBezelBorder && aTabViewType !== CPNoTabsBezelBorder && aTabViewType !== CPNoTabsNoBorder)) [self addSubview:tabs]; - + type = aTabViewType; - + switch (type) { case CPTopTabsBezelBorder: @@ -400,7 +401,7 @@ var HEIGHT_OF_SEGMENTED_CONTROL = 24; - (void)mouseDown:(CPEvent)anEvent { var segmentIndex = [tabs testSegment:[tabs convertPoint:[anEvent locationInWindow] fromView:nil]]; - + if (segmentIndex != CPNotFound) { [self selectTabViewItemAtIndex:segmentIndex]; @@ -412,7 +413,7 @@ var HEIGHT_OF_SEGMENTED_CONTROL = 24; { var horizontalCenterOfSelf = CGRectGetWidth([self bounds]) / 2, verticalCenterOfTabs = CGRectGetHeight([tabs bounds]) / 2; - + if (type === CPBottomTabsBezelBorder) [tabs setCenter:CGPointMake(horizontalCenterOfSelf, CGRectGetHeight([self bounds]) - verticalCenterOfTabs)]; else @@ -422,7 +423,7 @@ var HEIGHT_OF_SEGMENTED_CONTROL = 24; - (void)_setSelectedIndex:(CPNumber)index { selectedIndex = index; - + [box setContentView:[[items objectAtIndex:selectedIndex] view]]; } @@ -475,7 +476,7 @@ var CPTabViewItemsKey = "CPTabViewItemsKey", - (void)encodeWithCoder:(CPCoder)aCoder { [super encodeWithCoder:aCoder]; - + [aCoder encodeObject:items forKey:CPTabViewItemsKey];; [aCoder encodeObject:[self selectedTabViewItem] forKey:CPTabViewSelectedItemKey]; From 3d82203893b3eaa2b196101a4ba6f1a144f62cd7 Mon Sep 17 00:00:00 2001 From: Antoine Mercadal Date: Tue, 19 Oct 2010 22:53:52 +0200 Subject: [PATCH 3/7] remove 'drunk' code and simply use resizing masks --- AppKit/CPTabView.j | 43 +++---------------------------------------- 1 file changed, 3 insertions(+), 40 deletions(-) diff --git a/AppKit/CPTabView.j b/AppKit/CPTabView.j index 46cf5b4cd..31c6d1c51 100644 --- a/AppKit/CPTabView.j +++ b/AppKit/CPTabView.j @@ -73,50 +73,13 @@ var HEIGHT_OF_SEGMENTED_CONTROL = 24; [self addSubview:box]; [self addSubview:tabs]; + + [box setAutoresizingMask:CPViewWidthSizable]; + [tabs setAutoresizingMask:CPViewMinXMargin | CPViewMaxXMargin]; } return self; } -/*! - Override CPView message to allow to set the autoresizing mask - of the tabview and it's subview - - @param unsigned aMask the autoresizing mask -*/ -- (void)setAutoresizingMask:(unsigned)aMask -{ - [box setAutoresizingMask:aMask]; - - [super setAutoresizingMask:aMask]; -} - - -/*! - Override the CPView method in order - to allow to reposition the segmented control - - @param aFrame the new frame -*/ -- (void)setFrame:(CGRect)aFrame -{ - [super setFrame:aFrame]; - - [self _repositionTabs]; -} - -/*! - Override the CPView method in order - to allow to reposition the segmented control - - @param someBounds the new bounds -*/ -- (void)setBounds:(CGRect)someBounds -{ - [super setBounds:someBounds]; - - [self _repositionTabs]; -} - // Adding and Removing Tabs /*! Adds a CPTabViewItem to the tab view. From 48ebd2e954e79c142ff203c70d6c01dda3ea065b Mon Sep 17 00:00:00 2001 From: Antoine Mercadal Date: Tue, 19 Oct 2010 23:46:03 +0200 Subject: [PATCH 4/7] add tests for CPTabView --- Tests/AppKit/CPTabViewTest.j | 65 ++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 Tests/AppKit/CPTabViewTest.j diff --git a/Tests/AppKit/CPTabViewTest.j b/Tests/AppKit/CPTabViewTest.j new file mode 100644 index 000000000..3496bf6c0 --- /dev/null +++ b/Tests/AppKit/CPTabViewTest.j @@ -0,0 +1,65 @@ +@import +@import + + + +@implementation CPTabView (TEST) + +- (CPSegmentedControl)tabs +{ + return tabs; +} + +@end + + +@implementation CPTabViewTest : OJTestCase +{ + CPTabView _tableView; + CPTabViewItem _tabItem1; + CPTabViewItem _tabItem2; +} + +- (void)setUp +{ + _tabView = [[CPTabView alloc] initWithFrame:CGRectMake(0, 0, 800, 600)]; + + _tabItem1 = [[CPTabViewItem alloc] initWithIdentifier:@"id1"]; + [_tabItem1 setLabel:@"Item A"]; + [_tabItem1 setView:[[CPView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)]] + + _tabItem2 = [[CPTabViewItem alloc] initWithIdentifier:@"id2"]; + [_tabItem2 setLabel:@"Item B"]; + [_tabItem2 setView:[[CPView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)]] + + [_tabView addTabViewItem:_tabItem1]; + [_tabView addTabViewItem:_tabItem2]; +} + +- (void)testCreate +{ + [self assertNotNull:_tabView]; + +} + +- (void)testMiddle +{ + var tabs = [_tabView tabs]; + [self assert:([_tabView frameSize].width / 2) equals:CPRectGetMidX([tabs frame])]; +} + +- (void)testMiddleAfterMoveFrame +{ + var tabs = [_tabView tabs]; + [_tabView setFrame:CPRectMake(10, 100, 1000, 200)]; + [self assert:([_tabView frameSize].width / 2) equals:CPRectGetMidX([tabs frame])]; +} + +- (void)testMiddleAfterMoveBound +{ + var tabs = [_tabView tabs]; + [_tabView setBounds:CPRectMake(12, 13, 20, 300)]; + [self assert:([_tabView boundsSize].width / 2) equals:CPRectGetMidX([tabs frame])]; +} + +@end \ No newline at end of file From 8ead5f63dadd135fc8818845a3d2f57b31febd99 Mon Sep 17 00:00:00 2001 From: Antoine Mercadal Date: Thu, 28 Oct 2010 11:01:38 +0200 Subject: [PATCH 5/7] fix CPtabViewTest --- Tests/AppKit/CPTabViewTest.j | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Tests/AppKit/CPTabViewTest.j b/Tests/AppKit/CPTabViewTest.j index 3496bf6c0..9bba62b40 100644 --- a/Tests/AppKit/CPTabViewTest.j +++ b/Tests/AppKit/CPTabViewTest.j @@ -58,8 +58,8 @@ - (void)testMiddleAfterMoveBound { var tabs = [_tabView tabs]; - [_tabView setBounds:CPRectMake(12, 13, 20, 300)]; - [self assert:([_tabView boundsSize].width / 2) equals:CPRectGetMidX([tabs frame])]; + [_tabView setBounds:CPRectMake(100, 100, 20, 300)]; + [self assert:([tabs boundsSize].width / 2) equals:CPRectGetMidX([tabs bounds])]; } @end \ No newline at end of file From 0867ccdc7316e31cdda6a6c5379b68128fa57852 Mon Sep 17 00:00:00 2001 From: Alexander Ljungberg Date: Fri, 29 Oct 2010 14:21:20 -0300 Subject: [PATCH 6/7] Reduced token height by 1 pixel to put some more whitespace underneath it in a standard height token field. --- .../Themes/Aristo/Resources/token-center.png | Bin 150 -> 151 bytes .../Resources/token-close-highlighted.png | Bin 245 -> 242 bytes .../Resources/token-highlighted-center.png | Bin 158 -> 151 bytes .../Resources/token-highlighted-left.png | Bin 530 -> 532 bytes .../Resources/token-highlighted-right.png | Bin 537 -> 524 bytes AppKit/Themes/Aristo/Resources/token-left.png | Bin 512 -> 522 bytes .../Themes/Aristo/Resources/token-right.png | Bin 524 -> 520 bytes AppKit/Themes/Aristo/ThemeDescriptors.j | 24 +++++++++--------- 8 files changed, 12 insertions(+), 12 deletions(-) diff --git a/AppKit/Themes/Aristo/Resources/token-center.png b/AppKit/Themes/Aristo/Resources/token-center.png index 3ea58da30d10d2ad6144c822a7e609a32e54c640..9ec12f972f996aea15d5f80b1fbf3bad5d81b9a2 100644 GIT binary patch delta 99 zcmV-p0G$7p0ha-g7YY&x1^@s6npd>Eks&BfIY~r8RCwBAT6yB;f5y8Xe*b6s^6fhV z)4%`!K?DPo_zUO$1&aZhP!_5zlmK!Mp1;lj0wMqb1^|WOD_!@&%oqRw002ovPDHLk FV1lTkChq_M delta 98 zcmV-o0G|{L_t(|+FXxK3c@fDg%hdhqTLHFa*bReC-!gUR`3vk1e!qT zRui!1(+0$W58k{t%rH_2v94?@ugXJwi+7Y8Do_9{z?F7JhE=NDWsGin*ObRnx=axWp>V;0FBp93@R8Qgp1aC4`@6x`S<2? f*}7?Oz6BTnvfE<7`hZv{00000NkvXXu0mjf-p5hD delta 180 zcmV;l089V!0rdfpNq?6~L_t(|+Dwnl3IZV%g|#LcYGxm_@HKn|pSZtO+n|RK6jTtm zrI6hdcOc=z!*?#qT?-*L#GdaDu_AWFNOVHXwbmX&I4h+NAfEks&BfIY~r8RCwBA$eXkEKf}T+pZ+r)fBKDq z>F>XPK;kcu`1AKKG7CcdL1Tdx|3%iO@b(M?2#5d#7yw~?FXWtl@ z{{H<3B>w$_vHt#LVETi^f^q-+`3qG77DMRx2V%*;J@~ M07*qoM6N<$g8zdnlK=n! diff --git a/AppKit/Themes/Aristo/Resources/token-highlighted-left.png b/AppKit/Themes/Aristo/Resources/token-highlighted-left.png index 30f2cc1b95774886c609b2603471aeb8e81e5525..60bc6b4b28492248865539189755e0a5bd9f533d 100644 GIT binary patch delta 460 zcmV;-0Wl>vU)NyF>A2E zRRA@C6{h+y0V(Fx{$;@&+`JRTC8fpq1%((mIJp_%ivRup$1o+$52TPKZPJQLaVfb5 zVR0#jAFR9#Pk;Pl`1bxE10&2CKma0G61(O{ODn0*=aEogc=VN#;rGA)aLWr zRAj~A5CFPe>&t&OhW~&6;#CX|*Z=?j3H<&KWD-ye*6{D|-w*$O{}lbl#7a={|KGoU z++g_mMf49FA6CUoFomFa`S$6r0D0t%bUnZ#9!K68kI(*`^Q z(9;GGa{w{7dumCru#{ZWXHE&BZ>;R zGArQ7!pf!wR~%V45p31+rhG{%vyr0000V)NPZ0sDtjLgi2EN~S- zO<;woK43*LjnmWxB&25u2#VMU3X3ps@$fRRAk_Y2n4IPZR+!K+*MV11WR;AfiXexu z6vNx^e;J;A`^Ufta|X=Xu&Q27Fc6H zIf^qd5)u%De8*+t8LF*hXxaOlTg3Pqn;^qaW-f%{$ofeP%Nz5MHGsm8(=jH?SwLLM zFpGtqLkFR_ZX(z{%bW6H8d#v3*nyZ8#0Lm40Ps}I|ILy78UO$Q07*qoM6N<$f{u9R Au>b%7 diff --git a/AppKit/Themes/Aristo/Resources/token-highlighted-right.png b/AppKit/Themes/Aristo/Resources/token-highlighted-right.png index 13fc317d658930ba24cfe9030b6d058af1846c50..2aabf627c627d0cf5fa1f735829554f9a0b07087 100644 GIT binary patch delta 475 zcmV<10VMvJ1dIfb7YY&x1^@s6jddh-ks&C5u1Q2eRCwBSk~>QSK@^40u1n%05k(>f z6cs^Gu(Yx8AK2Ikf{2Zsh(AEVLPQV?K@d`C-V5 zB9E^bD>WJz>)#Y{Dw7Ik{n%u9bShx@8qw0$QCrv0v^qS$HZJ0Zkgn2on^44Uf@?F2 zi?kaae=}l)KfXr)jL?N(shSY{MJKGyiil; zZ|&?JQ0YI&suG$9hRfX}YyU7CdD4G>$Koz{HLYEe^QEw&W^hfki&aUZBs>3`bwPuA{|3IX>O^b7i9Lw=q4$+Q<3O?D7dbU-Jrk9C=s=mS8Bn~8$HT+MASOl^p(tR#P$L9%dB8|5Skul<~eKiy46gaWhq zt+R!Qx_L%@{4nN_+=ZQb+uaKVSDvm;W77D83faRNnN4MVj`At4?(@3<0|4Xa{y`-A R;g$dZ002ovPDHLkV1n!X+Nb~k delta 488 zcmVU;hx($GFxt=P^bzMk{M`>4o zFKAHzD9EeIul(KZWPEPwLTIX(x460z<G~ eXOI6;fB^tgX!VrHU4)GQ0000R&X*MvWcd5GVVL57e?a_q_tF_FAHRC{`u&%0;1EH_$R_`} zd}!zU=l5?nK6~??;m5B(I86pA21VJ=*(GtSZ{EDocjxI#hWDSpp(w^k8$iqf#N4s1 zvx6m-G@7KvgoT9oco?`i*%69MmLFm0iL_yYYG4OqPDKL?5r>$ZC|)5^M;0~?HMruU sC}oGi?&*uNWrW2jR3i(N%>)o&0GssJf9{T@WdHyG07*qoM6N<$f)jAurT_o{ delta 440 zcmV;p0Z0Cd1b_sP7YY*y1^@s6Mk)8uks&AnqLE4)e}ORboE<0JIJmfinV4A&SzrqO z{fE$zmSBa<-OIMBOUfzE5aQ#p5#-}$;O1awKqv;Pj<(hSE1a}$zk`sN#3}_z5kWBl zK88Pk|1$jj_m6=Q<_ws%O>!Ml{~7E-e{2|8@t;}c$p>D(esk){>-Pjr{tLuE zFC5%aeCNrF&#&Hp!s}*`;$Pclc3!`I{zTHX`%gYTdG!uOF-AfHVm2V=a!D-I)^+sh z6%!FQ7UAb*;NjvxC@xukgrO(W23Z3q2!~YmIg84vc(HME>A)2iEjtW$PhXTROalv4 i9uqqdvx4{l0R{kNv(+~%V|2#=0000QSK@i91HYJABGI50qNlke=jC;|$L_j^ zdt{?#V6NEv&7Yb7jIwnZd!>}dZQDAyy*giAm>4qvfbwJ@1!D}9m}WB5vf(RVgpag; zp3G;Bv60@MUH+elqB4A^<`_Zn%wJQxv5!Es&i)B{L? zj@BTA+uJ4=_fGpc6X2=%>WK2r{3QHiI|PD_4badOoa-AMZ}FIaVLvg(&=zV6cSoWF zvN|HXm;bV^wia+*eUvlUhcT@%s2nwaT%Dmnr%?7t;18|VSZ(NaECuxLiqFVx;i0kU&1rdy$9pLQivGorOZQ*l$TUZvtAB))pHmhaS?eR^h z-3cTEO%iZHx5)rzi)BU)>qSY^p~f(O8VsP*8^)9mnPl*{xro{II0X&WPxD?$1_cC3M0IpZ6LuMBm+vogc)(T`N=;mYU2%c}Z)Xy8O93ooCkLM-H8^looN@D`_mOH2i5h6SpCGg9A1{@}%l z>uhf`jL$0S2sQZbF%sq~OehnNdJo+z=L%G5b_J!`PQ`&&GIGlL&*T3QU;x@X`A00s RF~|S_002ovPDHLkV1lgT-5US^ diff --git a/AppKit/Themes/Aristo/ThemeDescriptors.j b/AppKit/Themes/Aristo/ThemeDescriptors.j index 70a4b2413..606fc40ae 100755 --- a/AppKit/Themes/Aristo/ThemeDescriptors.j +++ b/AppKit/Themes/Aristo/ThemeDescriptors.j @@ -824,8 +824,8 @@ var themedButtonValues = nil, [@"content-inset", CGInsetMake(7.0, 0.0, 4.0, 0.0)], // Placeholder is displayed as regular text, not tokens; requires a different inset. [@"content-inset", CGInsetMake(9.0, 0.0, 5.0, 2.0), CPTextFieldStatePlaceholder], - [@"content-inset", CGInsetMake(7.0, 5.0, 4.0, 6.0), CPThemeStateBezeled], - [@"content-inset", CGInsetMake(9.0, 7.0, 5.0, 8.0), CPThemeStateBezeled | CPTextFieldStatePlaceholder], + [@"content-inset", CGInsetMake(7.0, 5.0, 5.0, 6.0), CPThemeStateBezeled], + [@"content-inset", CGInsetMake(9.0, 7.0, 6.0, 8.0), CPThemeStateBezeled | CPTextFieldStatePlaceholder], ]; [self registerThemeValues:overrides forView:tokenfield inherit:themedTextFieldValues]; @@ -835,21 +835,21 @@ var themedButtonValues = nil, + (_CPTokenFieldToken)themedTokenFieldToken { - var token = [[_CPTokenFieldToken alloc] initWithFrame:CGRectMake(0.0, 0.0, 60.0, 19.0)], + var token = [[_CPTokenFieldToken alloc] initWithFrame:CGRectMake(0.0, 0.0, 60.0, 18.0)], bezelColor = PatternColor( [ - ["token-left.png", 11.0, 19.0], - ["token-center.png", 1.0, 19.0], - ["token-right.png", 11.0, 19.0] + ["token-left.png", 11.0, 18.0], + ["token-center.png", 1.0, 18.0], + ["token-right.png", 11.0, 18.0] ], PatternIsHorizontal), bezelHighlightedColor = PatternColor( [ - ["token-highlighted-left.png", 11.0, 19.0], - ["token-highlighted-center.png", 1.0, 19.0], - ["token-highlighted-right.png", 11.0, 19.0] + ["token-highlighted-left.png", 11.0, 18.0], + ["token-highlighted-center.png", 1.0, 18.0], + ["token-highlighted-right.png", 11.0, 18.0] ], PatternIsHorizontal), @@ -865,11 +865,11 @@ var themedButtonValues = nil, [@"text-color", textHighlightedColor, CPThemeStateHighlighted], [@"bezel-inset", CGInsetMake(0.0, 0.0, 0.0, 0.0), CPThemeStateBezeled], - [@"content-inset", CGInsetMake(1.0, 24.0, 2.0, 16.0), CPThemeStateBezeled], + [@"content-inset", CGInsetMake(2.0, 24.0, 2.0, 16.0), CPThemeStateBezeled], // Minimum height == maximum height since tokens are fixed height. - [@"min-size", CGSizeMake(0.0, 19.0)], - [@"max-size", CGSizeMake(-1.0, 19.0)], + [@"min-size", CGSizeMake(0.0, 18.0)], + [@"max-size", CGSizeMake(-1.0, 18.0)], [@"vertical-alignment", CPCenterTextAlignment], ]; From eb39e2e81aca5096c5525a10865a0a48c008130e Mon Sep 17 00:00:00 2001 From: Alexander Ljungberg Date: Fri, 29 Oct 2010 14:40:46 -0300 Subject: [PATCH 7/7] Optimise token field redraws when adding or deleting tokens by recycling token fields. This eliminates the flicker of all previous tokens whenever a new token was added. --- AppKit/CPTokenField.j | 47 +++++++++++++++++++++++++++++-------------- 1 file changed, 32 insertions(+), 15 deletions(-) diff --git a/AppKit/CPTokenField.j b/AppKit/CPTokenField.j index 85379894d..70e70c2c0 100755 --- a/AppKit/CPTokenField.j +++ b/AppKit/CPTokenField.j @@ -491,31 +491,48 @@ var CPThemeStateAutoCompleting = @"CPThemeStateAutoCompleting", if (aValue === superValue || [aValue isEqualToArray:superValue]) return; - var objectValue = [aValue copy], - contentView = [_tokenScrollView documentView]; + var contentView = [_tokenScrollView documentView]; - // Because we do not know for sure which tokens are removed we remove them all - for (var i = 0, count = [[self _tokens] count]; i < count; i++) - [[[self _tokens] objectAtIndex:i] removeFromSuperview]; - - objectValue = []; + // Preserve as many existing tokens as possible to reduce redraw flickering. + var oldTokens = [self _tokens], + newTokens = []; if (aValue !== nil) { - // Re-add all tokens for (var i = 0, count = [aValue count]; i < count; i++) { - var token = [aValue objectAtIndex:i], - tokenView = [[_CPTokenFieldToken alloc] init]; + // Do we have this token among the old ones? + var tokenValue = aValue[i], + newToken = nil; - [tokenView setTokenField:self]; - [tokenView setStringValue:token]; - [objectValue addObject:tokenView]; + for (var j = 0, oldCount = [oldTokens count]; j < oldCount; j++) + { + var oldToken = oldTokens[j]; + if ([oldToken stringValue] == tokenValue) + { + // Yep. Reuse it. + [oldTokens removeObjectAtIndex:j]; + newToken = oldToken; + break; + } + } - [contentView addSubview:tokenView]; + if (newToken === nil) + { + newToken = [[_CPTokenFieldToken alloc] init]; + [newToken setTokenField:self]; + [newToken setStringValue:tokenValue]; + [contentView addSubview:newToken]; + } + + newTokens.push(newToken); } } + // Remove any now unused tokens. + for (var j = 0, oldCount = [oldTokens count]; j < oldCount; j++) + [oldTokens[j] removeFromSuperview]; + /* [CPTextField setObjectValue] will try to set the _inputElement.value to the new objectValue, if the _inputElement exists. This is wrong for us @@ -524,7 +541,7 @@ var CPThemeStateAutoCompleting = @"CPThemeStateAutoCompleting", Instead do what CPControl setObjectValue would. */ - _value = objectValue; + _value = newTokens; // Reset the selection. [self _selectToken:nil byExtendingSelection:NO];