From 9ed9a9f1052e8eb02da3804c9e0fe431cb3c1de6 Mon Sep 17 00:00:00 2001 From: Bjorn Winckler Date: Wed, 25 Jul 2007 07:09:26 +0000 Subject: [PATCH] Initial import git-svn-id: http://macvim.googlecode.com/svn/trunk@5 96c4425d-ca35-0410-94e5-3396d5c13a8f --- Colors.plist | 1326 ++++++++++++ Credits.rtf | 25 + English.lproj/InfoPlist.strings | Bin 0 -> 194 bytes English.lproj/MainMenu.nib/classes.nib | 23 + English.lproj/MainMenu.nib/info.nib | 21 + English.lproj/MainMenu.nib/keyedobjects.nib | Bin 0 -> 7901 bytes English.lproj/VimWindow.nib/classes.nib | 35 + English.lproj/VimWindow.nib/info.nib | 20 + English.lproj/VimWindow.nib/keyedobjects.nib | Bin 0 -> 5460 bytes Info.plist | 550 +++++ MMAppController.h | 25 + MMAppController.m | 182 ++ MMBackend.h | 81 + MMBackend.m | 1046 +++++++++ MMTextStorage.h | 60 + MMTextStorage.m | 554 +++++ MMTextView.h | 28 + MMTextView.m | 401 ++++ MMVimController.h | 34 + MMVimController.m | 819 +++++++ MMWindowController.h | 54 + MMWindowController.m | 987 +++++++++ MacVim.h | 102 + MacVim.m | 86 + MacVim.xcodeproj/project.pbxproj | 651 ++++++ MacVim.xcodeproj/winckler.mode1 | 1348 ++++++++++++ MacVim.xcodeproj/winckler.pbxuser | 247 +++ MacVim_Prefix.pch | 7 + .../English.lproj/InfoPlist.strings | Bin 0 -> 208 bytes .../English.lproj/MainMenu.nib/classes.nib | 24 + .../English.lproj/MainMenu.nib/info.nib | 21 + .../MainMenu.nib/keyedobjects.nib | Bin 0 -> 11566 bytes .../English.lproj/MainMenu.nib/objects.nib | Bin 0 -> 4740 bytes .../PSMTabBarControlInspector.nib/classes.nib | 22 + .../PSMTabBarControlInspector.nib/info.nib | 16 + .../keyedobjects.nib | Bin 0 -> 11273 bytes .../PSMTabBarControlInspector.nib/objects.nib | Bin 0 -> 4291 bytes .../PSMTabBarControlPalette.nib/classes.nib | 28 + .../PSMTabBarControlPalette.nib/info.nib | 16 + .../keyedobjects.nib | Bin 0 -> 3036 bytes .../PSMTabBarControlPalette.nib/objects.nib | Bin 0 -> 1004 bytes .../English.lproj/Window.nib/classes.nib | 38 + .../English.lproj/Window.nib/info.nib | 25 + .../English.lproj/Window.nib/keyedobjects.nib | Bin 0 -> 16340 bytes PSMTabBarControl/Info.plist | 24 + .../PSMTabBarControl.ibclassdescription | 7 + .../PSMTabBarControl.xcodeproj/johnp.mode1 | 1551 +++++++++++++ .../PSMTabBarControl.xcodeproj/johnp.pbxuser | 1920 +++++++++++++++++ .../project.pbxproj | 677 ++++++ .../PSMTabBarControl.xcodeproj/winckler.mode1 | 1330 ++++++++++++ .../winckler.pbxuser | 178 ++ .../PSMTabBarControlFramework-Info.plist | 22 + PSMTabBarControl/PSMTabBarControl_Prefix.pch | 8 + PSMTabBarControl/ReadMe.rtfd/TXT.rtf | 186 ++ PSMTabBarControl/ReadMe.rtfd/startpage.gif | Bin 0 -> 11246 bytes PSMTabBarControl/TabBarControlDemo-Info.plist | 24 + .../documentation/PSMTabBarControlDoc.html | 301 +++ .../documentation/frameset_styles.css | 943 ++++++++ PSMTabBarControl/images/32x32_log.tiff | Bin 0 -> 20328 bytes PSMTabBarControl/images/32x32cancel.png | Bin 0 -> 1447 bytes .../images/AquaTabClose_Front.tif | Bin 0 -> 15388 bytes .../images/AquaTabClose_Front_Pressed.tif | Bin 0 -> 15416 bytes .../images/AquaTabClose_Front_Rollover.tif | Bin 0 -> 15444 bytes PSMTabBarControl/images/AquaTabNew.png | Bin 0 -> 3139 bytes PSMTabBarControl/images/AquaTabNewPressed.png | Bin 0 -> 3157 bytes .../images/AquaTabNewRollover.png | Bin 0 -> 3147 bytes .../images/AquaTabsBackground.png | Bin 0 -> 3091 bytes PSMTabBarControl/images/AquaTabsDown.png | Bin 0 -> 2901 bytes .../images/AquaTabsDownGraphite.png | Bin 0 -> 843 bytes .../images/AquaTabsDownNonKey.png | Bin 0 -> 787 bytes PSMTabBarControl/images/AquaTabsSeparator.png | Bin 0 -> 257 bytes .../images/AquaTabsSeparatorDown.png | Bin 0 -> 264 bytes PSMTabBarControl/images/Folder.tif | Bin 0 -> 926 bytes PSMTabBarControl/images/Globe.tiff | Bin 0 -> 17104 bytes PSMTabBarControl/images/TabClose_Front.tif | Bin 0 -> 518 bytes .../images/TabClose_Front_Pressed.tif | Bin 0 -> 520 bytes .../images/TabClose_Front_Rollover.tif | Bin 0 -> 514 bytes PSMTabBarControl/images/TabControlRep.tif | Bin 0 -> 29768 bytes PSMTabBarControl/images/TabIcon.tif | Bin 0 -> 21160 bytes PSMTabBarControl/images/TabNewMetal.png | Bin 0 -> 3137 bytes .../images/TabNewMetalPressed.png | Bin 0 -> 3160 bytes .../images/TabNewMetalRollover.png | Bin 0 -> 3146 bytes PSMTabBarControl/images/Warning.png | Bin 0 -> 3412 bytes PSMTabBarControl/images/overflowImage.tiff | Bin 0 -> 1018 bytes .../images/overflowImagePressed.tif | Bin 0 -> 1018 bytes PSMTabBarControl/images/pi.png | Bin 0 -> 3396 bytes PSMTabBarControl/palette.table | 42 + PSMTabBarControl/source/AppController.h | 17 + PSMTabBarControl/source/AppController.m | 30 + PSMTabBarControl/source/FakeModel.h | 34 + PSMTabBarControl/source/FakeModel.m | 77 + .../source/NSBezierPath_AMShading.h | 23 + .../source/NSBezierPath_AMShading.m | 169 ++ PSMTabBarControl/source/PSMAquaTabStyle.h | 32 + PSMTabBarControl/source/PSMAquaTabStyle.m | 516 +++++ PSMTabBarControl/source/PSMMetalTabStyle.h | 26 + PSMTabBarControl/source/PSMMetalTabStyle.m | 524 +++++ .../source/PSMOverflowPopUpButton.h | 21 + .../source/PSMOverflowPopUpButton.m | 89 + .../source/PSMProgressIndicator.h | 23 + .../source/PSMProgressIndicator.m | 20 + PSMTabBarControl/source/PSMRolloverButton.h | 29 + PSMTabBarControl/source/PSMRolloverButton.m | 107 + PSMTabBarControl/source/PSMTabBarCell.h | 102 + PSMTabBarControl/source/PSMTabBarCell.m | 397 ++++ PSMTabBarControl/source/PSMTabBarControl.h | 124 ++ PSMTabBarControl/source/PSMTabBarControl.m | 1398 ++++++++++++ .../source/PSMTabBarControlInspector.h | 23 + .../source/PSMTabBarControlInspector.m | 99 + .../source/PSMTabBarControlPalette.h | 21 + .../source/PSMTabBarControlPalette.m | 35 + .../source/PSMTabBarControl_Prefix.pch | 8 + PSMTabBarControl/source/PSMTabDragAssistant.h | 84 + PSMTabBarControl/source/PSMTabDragAssistant.m | 439 ++++ PSMTabBarControl/source/PSMTabStyle.h | 52 + PSMTabBarControl/source/PSMUnifiedTabStyle.h | 24 + PSMTabBarControl/source/PSMUnifiedTabStyle.m | 529 +++++ PSMTabBarControl/source/WindowController.h | 58 + PSMTabBarControl/source/WindowController.m | 280 +++ PSMTabBarControl/source/main.m | 14 + PSMTabBarControl/version.plist | 16 + README | 145 ++ SpecialKeys.plist | 62 + TODO | 114 + Toolbar/Attention.png | Bin 0 -> 1931 bytes Toolbar/Copy.png | Bin 0 -> 1075 bytes Toolbar/Cut.png | Bin 0 -> 1379 bytes Toolbar/FindHelp.png | Bin 0 -> 1983 bytes Toolbar/FindNext.png | Bin 0 -> 1596 bytes Toolbar/FindPrev.png | Bin 0 -> 1595 bytes Toolbar/Help.png | Bin 0 -> 2461 bytes Toolbar/LoadSesn.png | Bin 0 -> 1757 bytes Toolbar/Make.png | Bin 0 -> 2113 bytes Toolbar/Open.png | Bin 0 -> 1365 bytes Toolbar/Paste.png | Bin 0 -> 1550 bytes Toolbar/Print.png | Bin 0 -> 1482 bytes Toolbar/Redo.png | Bin 0 -> 1236 bytes Toolbar/Replace.png | Bin 0 -> 1777 bytes Toolbar/RunCtags.png | Bin 0 -> 1225 bytes Toolbar/RunScript.png | Bin 0 -> 2166 bytes Toolbar/Save.png | Bin 0 -> 1440 bytes Toolbar/SaveAll.png | Bin 0 -> 2002 bytes Toolbar/SaveSesn.png | Bin 0 -> 2039 bytes Toolbar/TagJump.png | Bin 0 -> 1154 bytes Toolbar/Undo.png | Bin 0 -> 1178 bytes VimColorList.clr | 803 +++++++ doc-bm-c.icns | Bin 0 -> 39682 bytes doc-bm-h.icns | Bin 0 -> 39691 bytes doc-bm-html.icns | Bin 0 -> 40619 bytes doc-bm-java.icns | Bin 0 -> 40589 bytes doc-bm-php.icns | Bin 0 -> 40303 bytes doc-bm-pl.icns | Bin 0 -> 39845 bytes doc-bm-sh.icns | Bin 0 -> 39997 bytes doc-bm-tex.icns | Bin 0 -> 40095 bytes doc-bm-txt.icns | Bin 0 -> 40106 bytes doc-bm-xml.icns | Bin 0 -> 40446 bytes doc-bm.icns | Bin 0 -> 42287 bytes gui_macvim.m | 1200 +++++++++++ main.m | 16 + vim_gloss.icns | Bin 0 -> 55320 bytes 160 files changed, 23895 insertions(+) create mode 100644 Colors.plist create mode 100644 Credits.rtf create mode 100644 English.lproj/InfoPlist.strings create mode 100644 English.lproj/MainMenu.nib/classes.nib create mode 100644 English.lproj/MainMenu.nib/info.nib create mode 100644 English.lproj/MainMenu.nib/keyedobjects.nib create mode 100644 English.lproj/VimWindow.nib/classes.nib create mode 100644 English.lproj/VimWindow.nib/info.nib create mode 100644 English.lproj/VimWindow.nib/keyedobjects.nib create mode 100644 Info.plist create mode 100644 MMAppController.h create mode 100644 MMAppController.m create mode 100644 MMBackend.h create mode 100644 MMBackend.m create mode 100644 MMTextStorage.h create mode 100644 MMTextStorage.m create mode 100644 MMTextView.h create mode 100644 MMTextView.m create mode 100644 MMVimController.h create mode 100644 MMVimController.m create mode 100644 MMWindowController.h create mode 100644 MMWindowController.m create mode 100644 MacVim.h create mode 100644 MacVim.m create mode 100644 MacVim.xcodeproj/project.pbxproj create mode 100644 MacVim.xcodeproj/winckler.mode1 create mode 100644 MacVim.xcodeproj/winckler.pbxuser create mode 100644 MacVim_Prefix.pch create mode 100644 PSMTabBarControl/English.lproj/InfoPlist.strings create mode 100644 PSMTabBarControl/English.lproj/MainMenu.nib/classes.nib create mode 100644 PSMTabBarControl/English.lproj/MainMenu.nib/info.nib create mode 100644 PSMTabBarControl/English.lproj/MainMenu.nib/keyedobjects.nib create mode 100644 PSMTabBarControl/English.lproj/MainMenu.nib/objects.nib create mode 100644 PSMTabBarControl/English.lproj/PSMTabBarControlInspector.nib/classes.nib create mode 100644 PSMTabBarControl/English.lproj/PSMTabBarControlInspector.nib/info.nib create mode 100644 PSMTabBarControl/English.lproj/PSMTabBarControlInspector.nib/keyedobjects.nib create mode 100644 PSMTabBarControl/English.lproj/PSMTabBarControlInspector.nib/objects.nib create mode 100644 PSMTabBarControl/English.lproj/PSMTabBarControlPalette.nib/classes.nib create mode 100644 PSMTabBarControl/English.lproj/PSMTabBarControlPalette.nib/info.nib create mode 100644 PSMTabBarControl/English.lproj/PSMTabBarControlPalette.nib/keyedobjects.nib create mode 100644 PSMTabBarControl/English.lproj/PSMTabBarControlPalette.nib/objects.nib create mode 100644 PSMTabBarControl/English.lproj/Window.nib/classes.nib create mode 100644 PSMTabBarControl/English.lproj/Window.nib/info.nib create mode 100644 PSMTabBarControl/English.lproj/Window.nib/keyedobjects.nib create mode 100644 PSMTabBarControl/Info.plist create mode 100755 PSMTabBarControl/PSMTabBarControl.ibclassdescription create mode 100644 PSMTabBarControl/PSMTabBarControl.xcodeproj/johnp.mode1 create mode 100644 PSMTabBarControl/PSMTabBarControl.xcodeproj/johnp.pbxuser create mode 100644 PSMTabBarControl/PSMTabBarControl.xcodeproj/project.pbxproj create mode 100644 PSMTabBarControl/PSMTabBarControl.xcodeproj/winckler.mode1 create mode 100644 PSMTabBarControl/PSMTabBarControl.xcodeproj/winckler.pbxuser create mode 100644 PSMTabBarControl/PSMTabBarControlFramework-Info.plist create mode 100644 PSMTabBarControl/PSMTabBarControl_Prefix.pch create mode 100644 PSMTabBarControl/ReadMe.rtfd/TXT.rtf create mode 100644 PSMTabBarControl/ReadMe.rtfd/startpage.gif create mode 100644 PSMTabBarControl/TabBarControlDemo-Info.plist create mode 100644 PSMTabBarControl/documentation/PSMTabBarControlDoc.html create mode 100644 PSMTabBarControl/documentation/frameset_styles.css create mode 100644 PSMTabBarControl/images/32x32_log.tiff create mode 100644 PSMTabBarControl/images/32x32cancel.png create mode 100644 PSMTabBarControl/images/AquaTabClose_Front.tif create mode 100644 PSMTabBarControl/images/AquaTabClose_Front_Pressed.tif create mode 100644 PSMTabBarControl/images/AquaTabClose_Front_Rollover.tif create mode 100644 PSMTabBarControl/images/AquaTabNew.png create mode 100644 PSMTabBarControl/images/AquaTabNewPressed.png create mode 100644 PSMTabBarControl/images/AquaTabNewRollover.png create mode 100644 PSMTabBarControl/images/AquaTabsBackground.png create mode 100644 PSMTabBarControl/images/AquaTabsDown.png create mode 100644 PSMTabBarControl/images/AquaTabsDownGraphite.png create mode 100644 PSMTabBarControl/images/AquaTabsDownNonKey.png create mode 100644 PSMTabBarControl/images/AquaTabsSeparator.png create mode 100644 PSMTabBarControl/images/AquaTabsSeparatorDown.png create mode 100644 PSMTabBarControl/images/Folder.tif create mode 100644 PSMTabBarControl/images/Globe.tiff create mode 100644 PSMTabBarControl/images/TabClose_Front.tif create mode 100644 PSMTabBarControl/images/TabClose_Front_Pressed.tif create mode 100644 PSMTabBarControl/images/TabClose_Front_Rollover.tif create mode 100644 PSMTabBarControl/images/TabControlRep.tif create mode 100644 PSMTabBarControl/images/TabIcon.tif create mode 100644 PSMTabBarControl/images/TabNewMetal.png create mode 100644 PSMTabBarControl/images/TabNewMetalPressed.png create mode 100644 PSMTabBarControl/images/TabNewMetalRollover.png create mode 100644 PSMTabBarControl/images/Warning.png create mode 100755 PSMTabBarControl/images/overflowImage.tiff create mode 100755 PSMTabBarControl/images/overflowImagePressed.tif create mode 100644 PSMTabBarControl/images/pi.png create mode 100644 PSMTabBarControl/palette.table create mode 100644 PSMTabBarControl/source/AppController.h create mode 100644 PSMTabBarControl/source/AppController.m create mode 100644 PSMTabBarControl/source/FakeModel.h create mode 100644 PSMTabBarControl/source/FakeModel.m create mode 100755 PSMTabBarControl/source/NSBezierPath_AMShading.h create mode 100755 PSMTabBarControl/source/NSBezierPath_AMShading.m create mode 100644 PSMTabBarControl/source/PSMAquaTabStyle.h create mode 100644 PSMTabBarControl/source/PSMAquaTabStyle.m create mode 100644 PSMTabBarControl/source/PSMMetalTabStyle.h create mode 100644 PSMTabBarControl/source/PSMMetalTabStyle.m create mode 100644 PSMTabBarControl/source/PSMOverflowPopUpButton.h create mode 100644 PSMTabBarControl/source/PSMOverflowPopUpButton.m create mode 100644 PSMTabBarControl/source/PSMProgressIndicator.h create mode 100644 PSMTabBarControl/source/PSMProgressIndicator.m create mode 100644 PSMTabBarControl/source/PSMRolloverButton.h create mode 100644 PSMTabBarControl/source/PSMRolloverButton.m create mode 100644 PSMTabBarControl/source/PSMTabBarCell.h create mode 100644 PSMTabBarControl/source/PSMTabBarCell.m create mode 100644 PSMTabBarControl/source/PSMTabBarControl.h create mode 100644 PSMTabBarControl/source/PSMTabBarControl.m create mode 100644 PSMTabBarControl/source/PSMTabBarControlInspector.h create mode 100644 PSMTabBarControl/source/PSMTabBarControlInspector.m create mode 100644 PSMTabBarControl/source/PSMTabBarControlPalette.h create mode 100644 PSMTabBarControl/source/PSMTabBarControlPalette.m create mode 100644 PSMTabBarControl/source/PSMTabBarControl_Prefix.pch create mode 100644 PSMTabBarControl/source/PSMTabDragAssistant.h create mode 100644 PSMTabBarControl/source/PSMTabDragAssistant.m create mode 100644 PSMTabBarControl/source/PSMTabStyle.h create mode 100644 PSMTabBarControl/source/PSMUnifiedTabStyle.h create mode 100644 PSMTabBarControl/source/PSMUnifiedTabStyle.m create mode 100644 PSMTabBarControl/source/WindowController.h create mode 100644 PSMTabBarControl/source/WindowController.m create mode 100644 PSMTabBarControl/source/main.m create mode 100644 PSMTabBarControl/version.plist create mode 100644 README create mode 100644 SpecialKeys.plist create mode 100644 TODO create mode 100644 Toolbar/Attention.png create mode 100644 Toolbar/Copy.png create mode 100644 Toolbar/Cut.png create mode 100644 Toolbar/FindHelp.png create mode 100644 Toolbar/FindNext.png create mode 100644 Toolbar/FindPrev.png create mode 100644 Toolbar/Help.png create mode 100644 Toolbar/LoadSesn.png create mode 100644 Toolbar/Make.png create mode 100644 Toolbar/Open.png create mode 100644 Toolbar/Paste.png create mode 100644 Toolbar/Print.png create mode 100644 Toolbar/Redo.png create mode 100644 Toolbar/Replace.png create mode 100644 Toolbar/RunCtags.png create mode 100644 Toolbar/RunScript.png create mode 100644 Toolbar/Save.png create mode 100644 Toolbar/SaveAll.png create mode 100644 Toolbar/SaveSesn.png create mode 100644 Toolbar/TagJump.png create mode 100644 Toolbar/Undo.png create mode 100644 VimColorList.clr create mode 100644 doc-bm-c.icns create mode 100644 doc-bm-h.icns create mode 100644 doc-bm-html.icns create mode 100644 doc-bm-java.icns create mode 100644 doc-bm-php.icns create mode 100644 doc-bm-pl.icns create mode 100644 doc-bm-sh.icns create mode 100644 doc-bm-tex.icns create mode 100644 doc-bm-txt.icns create mode 100644 doc-bm-xml.icns create mode 100644 doc-bm.icns create mode 100644 gui_macvim.m create mode 100644 main.m create mode 100644 vim_gloss.icns diff --git a/Colors.plist b/Colors.plist new file mode 100644 index 0000000000..8cd93b13f8 --- /dev/null +++ b/Colors.plist @@ -0,0 +1,1326 @@ + + + + + aliceblue + 15792127 + antiquewhite + 16444374 + antiquewhite1 + 16773082 + antiquewhite2 + 15589068 + antiquewhite3 + 13418416 + antiquewhite4 + 9142904 + aquamarine + 8323028 + aquamarine1 + 8323028 + aquamarine2 + 7728582 + aquamarine3 + 6737066 + aquamarine4 + 4557683 + azure + 15794175 + azure1 + 15794175 + azure2 + 14675437 + azure3 + 12700876 + azure4 + 8555403 + beige + 16119259 + bisque + 16769987 + bisque1 + 16769987 + bisque2 + 15586742 + bisque3 + 13416093 + bisque4 + 9141610 + black + 0 + blanchedalmond + 16772044 + blue + 212 + blue1 + 255 + blue2 + 237 + blue3 + 204 + blue4 + 139 + blueviolet + 9054946 + brown + 8405056 + brown1 + 16728128 + brown2 + 15547195 + brown3 + 13382451 + brown4 + 9118499 + burlywood + 14596230 + burlywood1 + 16765850 + burlywood2 + 15582352 + burlywood3 + 13412989 + burlywood4 + 9139028 + cadetblue + 6200736 + cadetblue1 + 10024447 + cadetblue2 + 9364717 + cadetblue3 + 7980236 + cadetblue4 + 5473931 + chartreuse + 8322816 + chartreuse1 + 8322816 + chartreuse2 + 7728384 + chartreuse3 + 6736896 + chartreuse4 + 4557568 + chocolate + 13723933 + chocolate1 + 16743972 + chocolate2 + 15562016 + chocolate3 + 13395484 + chocolate4 + 9127186 + coral + 16744015 + coral1 + 16740950 + coral2 + 15559247 + coral3 + 13392709 + coral4 + 9125166 + cornflowerblue + 6591724 + cornsilk + 16775131 + cornsilk1 + 16775131 + cornsilk2 + 15591372 + cornsilk3 + 13420464 + cornsilk4 + 9144184 + cyan + 109545 + cyan1 + 65535 + cyan2 + 60909 + cyan3 + 52428 + cyan4 + 35723 + darkblue + 128 + darkcyan + 32896 + darkgoldenrod + 12092938 + darkgoldenrod1 + 16759054 + darkgoldenrod2 + 15576077 + darkgoldenrod3 + 13407244 + darkgoldenrod4 + 9135368 + darkgray + 8421504 + darkgreen + 32768 + darkgrey + 8421504 + darkkhaki + 12433002 + darkmagenta + 8388736 + darkolivegreen + 5532206 + darkolivegreen1 + 13303663 + darkolivegreen2 + 12381543 + darkolivegreen3 + 10669145 + darkolivegreen4 + 7244604 + darkorange + 16747264 + darkorange1 + 16743936 + darkorange2 + 15561984 + darkorange3 + 13395456 + darkorange4 + 9127168 + darkorchid + 10040012 + darkorchid1 + 12467711 + darkorchid2 + 11614957 + darkorchid3 + 10040012 + darkorchid4 + 6758795 + darkred + 8388608 + darksalmon + 15242617 + darkseagreen + 9419919 + darkseagreen1 + 12713921 + darkseagreen2 + 11857332 + darkseagreen3 + 10144922 + darkseagreen4 + 6916969 + darkslateblue + 4734091 + darkslategray + 3034702 + darkslategray1 + 9961471 + darkslategray2 + 9235949 + darkslategray3 + 7916748 + darkslategray4 + 5409675 + darkslategrey + 3034702 + darkturquoise + 52688 + darkviolet + 9699539 + darkyellow + 12237312 + deeppink + 16716691 + deeppink1 + 16716691 + deeppink2 + 15536777 + deeppink3 + 13373301 + deeppink4 + 9111887 + deepskyblue + 48895 + deepskyblue1 + 48895 + deepskyblue2 + 45549 + deepskyblue3 + 39372 + deepskyblue4 + 26507 + dimgray + 6908265 + dimgrey + 6908265 + dodgerblue + 1937407 + dodgerblue1 + 1937407 + dodgerblue2 + 1804013 + dodgerblue3 + 1536972 + dodgerblue4 + 1003147 + firebrick + 11608353 + firebrick1 + 16723759 + firebrick2 + 15543083 + firebrick3 + 13378853 + firebrick4 + 9116186 + floralwhite + 16775920 + forestgreen + 2198305 + gainsboro + 14408667 + ghostwhite + 16250879 + gold + 16766464 + gold1 + 16766464 + gold2 + 15583232 + gold3 + 13413376 + gold4 + 9139200 + goldenrod + 14263584 + goldenrod1 + 16761125 + goldenrod2 + 15578145 + goldenrod3 + 13408796 + goldenrod4 + 9136403 + gray + 12566463 + gray0 + 0 + gray1 + 197379 + gray10 + 1710618 + gray100 + 16777215 + gray11 + 1776411 + gray12 + 2039583 + gray13 + 2105376 + gray14 + 2368548 + gray15 + 2434341 + gray16 + 2697513 + gray17 + 2763306 + gray18 + 3026478 + gray19 + 3092271 + gray2 + 263172 + gray20 + 3355443 + gray21 + 3552822 + gray22 + 3618615 + gray23 + 3881787 + gray24 + 3947580 + gray25 + 4210752 + gray26 + 4276545 + gray27 + 4539717 + gray28 + 4605510 + gray29 + 4868682 + gray3 + 526344 + gray30 + 5066061 + gray31 + 5131854 + gray32 + 5395026 + gray33 + 5460819 + gray34 + 5723991 + gray35 + 5789784 + gray36 + 6052956 + gray37 + 6118749 + gray38 + 6381921 + gray39 + 6447714 + gray4 + 592137 + gray40 + 6710886 + gray41 + 6908265 + gray42 + 6974058 + gray43 + 7237230 + gray44 + 7303023 + gray45 + 7566195 + gray46 + 7631988 + gray47 + 7895160 + gray48 + 7960953 + gray49 + 8224125 + gray5 + 855309 + gray50 + 8289918 + gray51 + 8487297 + gray52 + 8750469 + gray53 + 8816262 + gray54 + 9079434 + gray55 + 9145227 + gray56 + 9408399 + gray57 + 9474192 + gray58 + 9737364 + gray59 + 9803157 + gray6 + 921102 + gray60 + 10066329 + gray61 + 10263708 + gray62 + 10329501 + gray63 + 10592673 + gray64 + 10658466 + gray65 + 10921638 + gray66 + 10987431 + gray67 + 11250603 + gray68 + 11316396 + gray69 + 11579568 + gray7 + 1184274 + gray70 + 11776947 + gray71 + 11842740 + gray72 + 12105912 + gray73 + 12171705 + gray74 + 12434877 + gray75 + 12500670 + gray76 + 12763842 + gray77 + 12829635 + gray78 + 13092807 + gray79 + 13158600 + gray8 + 1250067 + gray80 + 13421772 + gray81 + 13619151 + gray82 + 13684944 + gray83 + 13948116 + gray84 + 14013909 + gray85 + 14277081 + gray86 + 14342874 + gray87 + 14606046 + gray88 + 14671839 + gray89 + 14935011 + gray9 + 1513239 + gray90 + 15000804 + gray91 + 15198183 + gray92 + 15461355 + gray93 + 15527148 + gray94 + 15790320 + gray95 + 15856113 + gray96 + 16119285 + gray97 + 16185078 + gray98 + 16448250 + gray99 + 16514043 + green + 25617 + green1 + 65280 + green2 + 60672 + green3 + 52224 + green4 + 35584 + greenyellow + 11337518 + grey + 12566463 + grey0 + 0 + grey1 + 197379 + grey10 + 1710618 + grey100 + 16777215 + grey11 + 1776411 + grey12 + 2039583 + grey13 + 2105376 + grey14 + 2368548 + grey15 + 2434341 + grey16 + 2697513 + grey17 + 2763306 + grey18 + 3026478 + grey19 + 3092271 + grey2 + 263172 + grey20 + 3355443 + grey21 + 3552822 + grey22 + 3618615 + grey23 + 3881787 + grey24 + 3947580 + grey25 + 4210752 + grey26 + 4276545 + grey27 + 4539717 + grey28 + 4605510 + grey29 + 4868682 + grey3 + 526344 + grey30 + 5066061 + grey31 + 5131854 + grey32 + 5395026 + grey33 + 5460819 + grey34 + 5723991 + grey35 + 5789784 + grey36 + 6052956 + grey37 + 6118749 + grey38 + 6381921 + grey39 + 6447714 + grey4 + 592137 + grey40 + 6710886 + grey41 + 6908265 + grey42 + 6974058 + grey43 + 7237230 + grey44 + 7303023 + grey45 + 7566195 + grey46 + 7631988 + grey47 + 7895160 + grey48 + 7960953 + grey49 + 8224125 + grey5 + 855309 + grey50 + 8289918 + grey51 + 8487297 + grey52 + 8750469 + grey53 + 8816262 + grey54 + 9079434 + grey55 + 9145227 + grey56 + 9408399 + grey57 + 9474192 + grey58 + 9737364 + grey59 + 9803157 + grey6 + 921102 + grey60 + 10066329 + grey61 + 10263708 + grey62 + 10329501 + grey63 + 10592673 + grey64 + 10658466 + grey65 + 10921638 + grey66 + 10987431 + grey67 + 11250603 + grey68 + 11316396 + grey69 + 11579568 + grey7 + 1184274 + grey70 + 11776947 + grey71 + 11842740 + grey72 + 12105912 + grey73 + 12171705 + grey74 + 12434877 + grey75 + 12500670 + grey76 + 12763842 + grey77 + 12829635 + grey78 + 13092807 + grey79 + 13158600 + grey8 + 1250067 + grey80 + 13421772 + grey81 + 13619151 + grey82 + 13684944 + grey83 + 13948116 + grey84 + 14013909 + grey85 + 14277081 + grey86 + 14342874 + grey87 + 14606046 + grey88 + 14671839 + grey89 + 14935011 + grey9 + 1513239 + grey90 + 15000804 + grey91 + 15198183 + grey92 + 15461355 + grey93 + 15527148 + grey94 + 15790320 + grey95 + 15856113 + grey96 + 16119285 + grey97 + 16185078 + grey98 + 16448250 + grey99 + 16514043 + honeydew + 15794160 + honeydew1 + 15794160 + honeydew2 + 14675423 + honeydew3 + 12700865 + honeydew4 + 8555394 + hotpink + 16738740 + hotpink1 + 16740020 + hotpink2 + 15559334 + hotpink3 + 13394063 + hotpink4 + 9124449 + indianred + 13392988 + indianred1 + 16738922 + indianred2 + 15557218 + indianred3 + 13390932 + indianred4 + 9124410 + ivory + 16777200 + ivory1 + 16777200 + ivory2 + 15592927 + ivory3 + 13421761 + ivory4 + 9145218 + khaki + 15787659 + khaki1 + 16774543 + khaki2 + 15591045 + khaki3 + 13420147 + khaki4 + 9143886 + lavender + 15132410 + lavenderblush + 16773365 + lavenderblush1 + 16773365 + lavenderblush2 + 15589348 + lavenderblush3 + 13418948 + lavenderblush4 + 9142918 + lawngreen + 8190720 + lemonchiffon + 16775884 + lemonchiffon1 + 16775884 + lemonchiffon2 + 15591614 + lemonchiffon3 + 13420709 + lemonchiffon4 + 9144687 + lightblue + 10526975 + lightblue1 + 12513279 + lightblue2 + 11656941 + lightblue3 + 10076108 + lightblue4 + 6783627 + lightcoral + 15761536 + lightcyan + 10551295 + lightcyan1 + 14680063 + lightcyan2 + 13692397 + lightcyan3 + 11848908 + lightcyan4 + 7965579 + lightgoldenrod + 15588737 + lightgoldenrod1 + 16772235 + lightgoldenrod2 + 15588225 + lightgoldenrod3 + 13418095 + lightgoldenrod4 + 9142603 + lightgoldenrodyellow + 16448209 + lightgray + 14671839 + lightgreen + 10551200 + lightgrey + 14671839 + lightmagenta + 15769840 + lightpink + 16758209 + lightpink1 + 16756409 + lightpink2 + 15573676 + lightpink3 + 13405076 + lightpink4 + 9133669 + lightred + 16752800 + lightsalmon + 16752761 + lightsalmon1 + 16752761 + lightsalmon2 + 15570034 + lightsalmon3 + 13402465 + lightsalmon4 + 9131841 + lightseagreen + 2142634 + lightskyblue + 8834554 + lightskyblue1 + 11592447 + lightskyblue2 + 10736621 + lightskyblue3 + 9221580 + lightskyblue4 + 6323083 + lightslateblue + 8613887 + lightslategray + 7833497 + lightslategrey + 7833497 + lightsteelblue + 11584478 + lightsteelblue1 + 13296127 + lightsteelblue2 + 12374509 + lightsteelblue3 + 10663116 + lightsteelblue4 + 7240587 + lightyellow + 16777120 + lightyellow1 + 16777183 + lightyellow2 + 15592912 + lightyellow3 + 13421748 + lightyellow4 + 9145209 + limegreen + 3329074 + linen + 16445670 + magenta + 15796355 + magenta1 + 16711935 + magenta2 + 15532269 + magenta3 + 13369548 + magenta4 + 9109643 + maroon + 11546464 + maroon1 + 16724915 + maroon2 + 15544230 + maroon3 + 13379983 + maroon4 + 9116513 + mediumaquamarine + 6737066 + mediumblue + 204 + mediumorchid + 12145875 + mediumorchid1 + 14640895 + mediumorchid2 + 13655789 + mediumorchid3 + 11817676 + mediumorchid4 + 7944075 + mediumpurple + 9662426 + mediumpurple1 + 11239935 + mediumpurple2 + 10385645 + mediumpurple3 + 9005004 + mediumpurple4 + 6047371 + mediumseagreen + 3978096 + mediumslateblue + 8087533 + mediumspringgreen + 64153 + mediumturquoise + 4772044 + mediumvioletred + 13047173 + midnightblue + 1579119 + mintcream + 16121850 + mistyrose + 16770017 + mistyrose1 + 16770017 + mistyrose2 + 15586769 + mistyrose3 + 13416116 + mistyrose4 + 9141627 + moccasin + 16769972 + navajowhite + 16768684 + navajowhite1 + 16768684 + navajowhite2 + 15585185 + navajowhite3 + 13415307 + navajowhite4 + 9140317 + navy + 128 + navyblue + 128 + oldlace + 16643558 + olivedrab + 6983203 + olivedrab1 + 12582717 + olivedrab2 + 11791674 + olivedrab3 + 10079282 + olivedrab4 + 6916897 + orange + 16482304 + orange1 + 16753920 + orange2 + 15571200 + orange3 + 13403392 + orange4 + 9132288 + orangered + 16729344 + orangered1 + 16729344 + orangered2 + 15548416 + orangered3 + 13383424 + orangered4 + 9118976 + orchid + 14249941 + orchid1 + 16745210 + orchid2 + 15563240 + orchid3 + 13396424 + orchid4 + 9127561 + palegoldenrod + 15591338 + palegreen + 10025624 + palegreen1 + 10092441 + palegreen2 + 9432463 + palegreen3 + 8178812 + palegreen4 + 5475155 + paleturquoise + 11529709 + paleturquoise1 + 12255231 + paleturquoise2 + 11464173 + paleturquoise3 + 9817292 + paleturquoise4 + 6720395 + palevioletred + 14315411 + palevioletred1 + 16744875 + palevioletred2 + 15562910 + palevioletred3 + 13395849 + palevioletred4 + 9127516 + papayawhip + 16773077 + peachpuff + 16767417 + peachpuff1 + 16767417 + peachpuff2 + 15584172 + peachpuff3 + 13414292 + peachpuff4 + 9140069 + peru + 13403455 + pink + 16760779 + pink1 + 16757956 + pink2 + 15575224 + pink3 + 13406365 + pink4 + 9134699 + plum + 14524637 + plum1 + 16759551 + plum2 + 15576813 + plum3 + 13407692 + plum4 + 9135755 + powderblue + 11591654 + purple + 10494192 + purple1 + 10104831 + purple2 + 9448429 + purple3 + 8201676 + purple4 + 5511819 + red + 14485509 + red1 + 16711680 + red2 + 15532032 + red3 + 13369344 + red4 + 9109504 + rosybrown + 12357519 + rosybrown1 + 16761281 + rosybrown2 + 15578292 + rosybrown3 + 13408922 + rosybrown4 + 9136489 + royalblue + 4221409 + royalblue1 + 4748799 + royalblue2 + 4353773 + royalblue3 + 3825356 + royalblue4 + 2506891 + saddlebrown + 9127186 + salmon + 16416882 + salmon1 + 16747369 + salmon2 + 15565153 + salmon3 + 13397843 + salmon4 + 9128760 + sandybrown + 16032608 + seagreen + 3050327 + seagreen1 + 5504926 + seagreen2 + 5172628 + seagreen3 + 4377728 + seagreen4 + 3050327 + seashell + 16774637 + seashell1 + 16774637 + seashell2 + 15590622 + seashell3 + 13419710 + seashell4 + 9143937 + sienna + 10506797 + sienna1 + 16744774 + sienna2 + 15562817 + sienna3 + 13395768 + sienna4 + 9127461 + skyblue + 8834539 + skyblue1 + 8834559 + skyblue2 + 8241133 + skyblue3 + 7055052 + skyblue4 + 4878219 + slateblue + 6969804 + slateblue1 + 8548351 + slateblue2 + 7956205 + slateblue3 + 6904012 + slateblue4 + 4603019 + slategray + 7307407 + slategray1 + 13034239 + slategray2 + 12178413 + slategray3 + 10401228 + slategray4 + 7043979 + slategrey + 7307407 + snow + 16775930 + snow1 + 16775930 + snow2 + 15591656 + snow3 + 13420744 + snow4 + 9144713 + springgreen + 65406 + springgreen1 + 65406 + springgreen2 + 60789 + springgreen3 + 52326 + springgreen4 + 35653 + steelblue + 4555188 + steelblue1 + 6469887 + steelblue2 + 6073325 + steelblue3 + 5149900 + steelblue4 + 3564683 + tan + 13743243 + tan1 + 16753998 + tan2 + 15571273 + tan3 + 13403455 + tan4 + 9132330 + thistle + 14204632 + thistle1 + 16769535 + thistle2 + 15585773 + thistle3 + 13415628 + thistle4 + 9141131 + tomato + 16736838 + tomato1 + 16736838 + tomato2 + 15555649 + tomato3 + 13389368 + tomato4 + 9123365 + turquoise + 4251600 + turquoise1 + 62975 + turquoise2 + 58605 + turquoise3 + 50380 + turquoise4 + 34443 + violet + 9189320 + violetred + 13639823 + violetred1 + 16727445 + violetred2 + 15547019 + violetred3 + 13382264 + violetred4 + 9118034 + wheat + 16113331 + wheat1 + 16771001 + wheat2 + 15587502 + wheat3 + 13416853 + wheat4 + 9141606 + white + 16777215 + whitesmoke + 16119285 + yellow + 16511492 + yellow1 + 16776960 + yellow2 + 15592704 + yellow3 + 13421568 + yellow4 + 9145088 + yellowgreen + 10079282 + + diff --git a/Credits.rtf b/Credits.rtf new file mode 100644 index 0000000000..5823bbbce5 --- /dev/null +++ b/Credits.rtf @@ -0,0 +1,25 @@ +{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf410 +{\fonttbl\f0\fswiss\fcharset77 Helvetica-Bold;\f1\fswiss\fcharset77 Helvetica;\f2\fswiss\fcharset77 Helvetica-Oblique; +} +{\colortbl;\red255\green255\blue255;} +\paperw11900\paperh16840\margl1440\margr1440\vieww9360\viewh8400\viewkind0 +\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\ql\qnatural\pardirnatural + +\f0\b\fs24 \cf0 VIM - Vi IMproved +\f1\b0 \ +by: +\f2\i Bram Moolenaar +\f1\i0 \ +\ + +\f0\b MacVim GUI\ + +\f1\b0 by: +\f2\i Bj\'9arn Winckler +\f1\i0 \ +\ +Thank you to {\field{\*\fldinst{HYPERLINK "http://www.positivespinmedia.com"}}{\fldrslt Positive Spin Media}} for the PSMTabBarControl Framework.\ +\ +Toolbar icons borrowed from the {\field{\*\fldinst{HYPERLINK "http://www.everaldo.com/crystal/"}}{\fldrslt Crystal Project}}.\ +\ +Vim icons made by {\field{\*\fldinst{HYPERLINK "http://www.cs.princeton.edu/~mtwebb/vim_icon/vim_icons.html"}}{\fldrslt Matthew Webb}}.} \ No newline at end of file diff --git a/English.lproj/InfoPlist.strings b/English.lproj/InfoPlist.strings new file mode 100644 index 0000000000000000000000000000000000000000..f2e5194d14248b8b3ba9a52774bb638a0f6a624e GIT binary patch literal 194 zcmW-b!4APd6h+V4S2UK5AT}0afendRu&^##n$k8c68^|f;$-qN@6OzJ-^qM`42X$X zQ*k8WO3s^1J#@%h5!Hn literal 0 HcmV?d00001 diff --git a/English.lproj/MainMenu.nib/classes.nib b/English.lproj/MainMenu.nib/classes.nib new file mode 100644 index 0000000000..cc058adef0 --- /dev/null +++ b/English.lproj/MainMenu.nib/classes.nib @@ -0,0 +1,23 @@ +{ + IBClasses = ( + { + ACTIONS = {newVimWindow = id; }; + CLASS = AppController; + LANGUAGE = ObjC; + SUPERCLASS = NSObject; + }, + { + ACTIONS = {addNewTab = id; }; + CLASS = FirstResponder; + LANGUAGE = ObjC; + SUPERCLASS = NSObject; + }, + { + ACTIONS = {newVimWindow = id; }; + CLASS = MMAppController; + LANGUAGE = ObjC; + SUPERCLASS = NSObject; + } + ); + IBVersion = 1; +} \ No newline at end of file diff --git a/English.lproj/MainMenu.nib/info.nib b/English.lproj/MainMenu.nib/info.nib new file mode 100644 index 0000000000..3879585f32 --- /dev/null +++ b/English.lproj/MainMenu.nib/info.nib @@ -0,0 +1,21 @@ + + + + + IBDocumentLocation + 68 69 356 240 0 0 1024 746 + IBEditorPositions + + 29 + 130 475 458 44 0 0 1024 746 + + IBFramework Version + 446.1 + IBOpenObjects + + 29 + + IBSystem Version + 8R218 + + diff --git a/English.lproj/MainMenu.nib/keyedobjects.nib b/English.lproj/MainMenu.nib/keyedobjects.nib new file mode 100644 index 0000000000000000000000000000000000000000..f0b2eac405714621560847aace435767a35f75b9 GIT binary patch literal 7901 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 + + + + IBDocumentLocation + 12 50 356 240 0 0 1024 746 + IBFramework Version + 446.1 + IBLockedTabItems + + 10 + + IBOpenObjects + + 28 + + IBSystem Version + 8R218 + + diff --git a/English.lproj/VimWindow.nib/keyedobjects.nib b/English.lproj/VimWindow.nib/keyedobjects.nib new file mode 100644 index 0000000000000000000000000000000000000000..ff924b86caca5a11881e053d123e1d3dbc10f7ce GIT binary patch literal 5460 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 YvOVl~>@Vzjus@V`Ujxqd+%MbvA9G_tsQ>@~ literal 0 HcmV?d00001 diff --git a/Info.plist b/Info.plist new file mode 100644 index 0000000000..95dd126b70 --- /dev/null +++ b/Info.plist @@ -0,0 +1,550 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleDocumentTypes + + + CFBundleTypeExtensions + + vim + + CFBundleTypeIconFile + doc-bm + CFBundleTypeName + Vim Script File + CFBundleTypeRole + Editor + LSIsAppleDefaultForType + + + + CFBundleTypeExtensions + + txt + text + + CFBundleTypeIconFile + doc-bm-txt + CFBundleTypeMIMETypes + + text/plain + + CFBundleTypeName + Plain Text File + CFBundleTypeRole + Editor + LSIsAppleDefaultForType + + + + CFBundleTypeExtensions + + tex + + CFBundleTypeIconFile + doc-bm-tex + CFBundleTypeName + TeX File + CFBundleTypeRole + Editor + LSIsAppleDefaultForType + + + + CFBundleTypeExtensions + + h + + CFBundleTypeIconFile + doc-bm-h + CFBundleTypeName + C Header Source File + CFBundleTypeRole + Editor + LSIsAppleDefaultForType + + LSItemContentTypes + + public.c-header + + + + CFBundleTypeExtensions + + pch + + CFBundleTypeName + C Precompiled Header Source File + CFBundleTypeRole + Editor + LSIsAppleDefaultForType + + LSItemContentTypes + + public.precompiled-c-header + + + + CFBundleTypeExtensions + + hh + hp + hpp + hxx + h++ + + CFBundleTypeName + C++ Header Source File + CFBundleTypeRole + Editor + LSIsAppleDefaultForType + + + + CFBundleTypeExtensions + + pch++ + + CFBundleTypeName + C++ Precompiled Header Source File + CFBundleTypeRole + Editor + LSIsAppleDefaultForType + + LSItemContentTypes + + public.precompiled-c-plus-plus-header + + + + CFBundleTypeExtensions + + c + + CFBundleTypeIconFile + doc-bm-c + CFBundleTypeName + C Source File + CFBundleTypeRole + Editor + LSIsAppleDefaultForType + + LSItemContentTypes + + public.c-source + + + + CFBundleTypeExtensions + + m + + CFBundleTypeName + Objective-C Source File + CFBundleTypeRole + Editor + LSIsAppleDefaultForType + + LSItemContentTypes + + public.objective-c-source + + + + CFBundleTypeExtensions + + mm + + CFBundleTypeName + Objective-C++ Source File + CFBundleTypeRole + Editor + LSIsAppleDefaultForType + + LSItemContentTypes + + public.objective-c-plus-plus-source + + + + CFBundleTypeExtensions + + cc + cp + cpp + cxx + c++ + + CFBundleTypeName + C++ Source File + CFBundleTypeRole + Editor + LSIsAppleDefaultForType + + LSItemContentTypes + + public.c-plus-plus-source + + + + CFBundleTypeExtensions + + s + asm + + CFBundleTypeName + Assembly Source File + CFBundleTypeRole + Editor + LSIsAppleDefaultForType + + LSItemContentTypes + + public.assembler-source + + + + CFBundleTypeExtensions + + r + + CFBundleTypeName + Rez Source File + CFBundleTypeRole + Editor + LSIsAppleDefaultForType + + LSItemContentTypes + + public.rez-source + + + + CFBundleTypeExtensions + + java + jav + + CFBundleTypeIconFile + doc-bm-java + CFBundleTypeName + Java Source File + CFBundleTypeRole + Editor + LSIsAppleDefaultForType + + LSItemContentTypes + + com.sun.java-source + + + + CFBundleTypeExtensions + + l + lm + lmm + lpp + lxx + + CFBundleTypeName + Lex Source File + CFBundleTypeRole + Editor + LSIsAppleDefaultForType + + LSItemContentTypes + + public.lex-source + + + + CFBundleTypeExtensions + + y + ym + ymm + ypp + yxx + + CFBundleTypeName + Yacc Source File + CFBundleTypeRole + Editor + LSIsAppleDefaultForType + + LSItemContentTypes + + public.yacc-source + + + + CFBundleTypeExtensions + + defs + + CFBundleTypeName + Mig Definition File + CFBundleTypeRole + Editor + LSIsAppleDefaultForType + + + + CFBundleTypeExtensions + + exp + + CFBundleTypeName + Symbol Export File + CFBundleTypeRole + Editor + LSIsAppleDefaultForType + + LSItemContentTypes + + public.symbol-export + + + + CFBundleTypeExtensions + + f + for + f77 + f95 + + CFBundleTypeName + Fortran Source File + CFBundleTypeRole + Editor + LSIsAppleDefaultForType + + LSItemContentTypes + + public.fortran-source + + + + CFBundleTypeExtensions + + pas + + CFBundleTypeName + Pascal Source file + CFBundleTypeRole + Editor + LSIsAppleDefaultForType + + LSItemContentTypes + + public.pascal-source + + + + CFBundleTypeExtensions + + ada + adb + ads + + CFBundleTypeName + Ada Source File + CFBundleTypeRole + Editor + LSIsAppleDefaultForType + + LSItemContentTypes + + public.ada-source + + + + CFBundleTypeExtensions + + html + htm + + CFBundleTypeIconFile + doc-bm-html + CFBundleTypeMIMETypes + + text/html + + CFBundleTypeName + HTML Source File + CFBundleTypeRole + Editor + LSIsAppleDefaultForType + + LSItemContentTypes + + public.html + + + + CFBundleTypeExtensions + + xml + + CFBundleTypeIconFile + doc-bm-xml + CFBundleTypeMIMETypes + + text/xml + + CFBundleTypeName + XML Source File + CFBundleTypeRole + Editor + LSIsAppleDefaultForType + + LSItemContentTypes + + public.xml + + + + CFBundleTypeExtensions + + js + jscript + javascript + + CFBundleTypeMIMETypes + + text/javascript + + CFBundleTypeName + JavaScript Source File + CFBundleTypeRole + Editor + LSIsAppleDefaultForType + + LSItemContentTypes + + com.netscape.javascript-source + + + + CFBundleTypeExtensions + + sh + command + csh + pl + pm + py + rb + rbw + php + php3 + php4 + ph3 + ph4 + phtml + applescript + + CFBundleTypeIconFile + doc-bm-sh + CFBundleTypeMIMETypes + + text/x-perl-script + text/x-python-script + text/ruby-script + text/php + + CFBundleTypeName + Script File + CFBundleTypeRole + Editor + LSIsAppleDefaultForType + + LSItemContentTypes + + public.script + + + + CFBundleTypeExtensions + + class + + CFBundleTypeName + Java Class File + CFBundleTypeRole + Viewer + LSIsAppleDefaultForType + + LSItemContentTypes + + com.sun.java-class + + + + CFBundleTypeExtensions + + strings + + CFBundleTypeName + Strings File + CFBundleTypeRole + Editor + LSItemContentTypes + + public.strings-text + + + + CFBundleTypeExtensions + + plist + dict + + CFBundleTypeName + Propery List File + CFBundleTypeRole + Editor + LSIsAppleDefaultForType + + + + CFBundleTypeExtensions + + * + + CFBundleTypeName + Text File + CFBundleTypeOSTypes + + **** + + CFBundleTypeRole + Editor + + + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFile + vim_gloss + CFBundleIdentifier + org.vim.MacVim + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + VIMM + CFBundleVersion + (first snapshot) + NSMainNibFile + MainMenu + NSPrincipalClass + NSApplication + + diff --git a/MMAppController.h b/MMAppController.h new file mode 100644 index 0000000000..5bcbf1ea48 --- /dev/null +++ b/MMAppController.h @@ -0,0 +1,25 @@ +/* vi:set ts=8 sts=4 sw=4 ft=objc: + * + * VIM - Vi IMproved by Bram Moolenaar + * MacVim GUI port by Bjorn Winckler + * + * Do ":help uganda" in Vim to read copying and usage conditions. + * Do ":help credits" in Vim to see a list of people who contributed. + * See README.txt for an overview of the Vim source code. + */ + +#import + + + +@interface MMAppController : NSObject { + NSPort *receivePort; + NSMutableArray *vimControllers; + unsigned terminateNowCount; + BOOL abortTermination; +} + +- (void)removeVimController:(id)controller; +- (IBAction)newVimWindow:(id)sender; + +@end diff --git a/MMAppController.m b/MMAppController.m new file mode 100644 index 0000000000..08c1e9c199 --- /dev/null +++ b/MMAppController.m @@ -0,0 +1,182 @@ +/* vi:set ts=8 sts=4 sw=4 ft=objc: + * + * VIM - Vi IMproved by Bram Moolenaar + * MacVim GUI port by Bjorn Winckler + * + * Do ":help uganda" in Vim to read copying and usage conditions. + * Do ":help credits" in Vim to see a list of people who contributed. + * See README.txt for an overview of the Vim source code. + */ + +#import "MMAppController.h" +#import "MMVimController.h" +#import "MacVim.h" + + + +@implementation MMAppController + +- (id)init +{ + if ((self = [super init])) { + vimControllers = [NSMutableArray new]; + + // Init named port for VimTasks to connect to + receivePort = [NSMachPort new]; + [receivePort setDelegate:self]; + + [[NSRunLoop currentRunLoop] addPort:receivePort + forMode:NSDefaultRunLoopMode]; + + // NOTE! If the name of the port changes here it must also be updated + // in MMBackend.m. + NSString *portName = [NSString stringWithFormat:@"%@-taskport", + [[NSBundle mainBundle] bundleIdentifier]]; + //NSLog(@"Starting mach bootstrap server: %@", portName); + if (![[NSMachBootstrapServer sharedInstance] registerPort:receivePort + name:portName]) { + NSLog(@"WARNING: Failed to start mach bootstrap server"); + } + } + + return self; +} + +- (void)dealloc +{ + //NSLog(@"MMAppController dealloc"); + + [receivePort release]; + [vimControllers release]; + + [super dealloc]; +} + +- (BOOL)applicationShouldOpenUntitledFile:(NSApplication *)sender +{ + // NOTE! This way it possible to start the app with the command-line + // argument '-nowindow yes' and no window will be opened by default. + return ![[NSUserDefaults standardUserDefaults] boolForKey:@"nowindow"]; +} + +- (BOOL)applicationOpenUntitledFile:(NSApplication *)sender +{ + //NSLog(@"%s NSapp=%@ theApp=%@", _cmd, NSApp, sender); + + [self newVimWindow:self]; + return YES; +} + +- (void)application:(NSApplication *)sender openFiles:(NSArray *)filenames +{ + NSMutableArray *args = [NSMutableArray arrayWithObjects:@"-g", @"-p", nil]; + [args addObjectsFromArray:filenames]; + + NSString *path = [[NSBundle mainBundle] + pathForAuxiliaryExecutable:@"Vim"]; + + [NSTask launchedTaskWithLaunchPath:path arguments:args]; + + [NSApp replyToOpenOrPrint:NSApplicationDelegateReplySuccess]; + // NSApplicationDelegateReplySuccess = 0, + // NSApplicationDelegateReplyCancel = 1, + // NSApplicationDelegateReplyFailure = 2 +} + +- (NSApplicationTerminateReply)applicationShouldTerminate: + (NSApplication *)sender +{ + int reply = NSTerminateNow; + + // HACK! Send message to all vim tasks asking if they have modified + // buffers, then hang around for a while waiting for responses to come + // back. If any task has at least one modified buffer an alert dialog is + // displayed telling the user that there are modified buffers. The user + // can then choose whether to quit anyway, or cancel the termination. + // (NSTerminateLater is not supported.) + terminateNowCount = 0; + abortTermination = NO; + + unsigned i, count = [vimControllers count]; + for (i = 0; i < count; ++i) { + MMVimController *controller = [vimControllers objectAtIndex:i]; + [NSPortMessage sendMessage:TaskShouldTerminateMsgID + withSendPort:[controller sendPort] + receivePort:receivePort + wait:NO]; + } + + NSDate *timeOutDate = [NSDate dateWithTimeIntervalSinceNow:15]; + while (terminateNowCount < count && !abortTermination && + NSOrderedDescending == [timeOutDate compare:[NSDate date]]) { + [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode + beforeDate:timeOutDate]; + } + + //NSLog(@"%s terminateNowCount=%d abortTermination=%s", _cmd, + // terminateNowCount, abortTermination ? "YES" : "NO"); + + if (abortTermination) { + NSAlert *alert = [[NSAlert alloc] init]; + [alert addButtonWithTitle:@"Quit"]; + [alert addButtonWithTitle:@"Cancel"]; + [alert setMessageText:@"Quit without saving?"]; + [alert setInformativeText:@"There are modified buffers, " + " if you quit now all changes will be lost. Quit anyway?"]; + [alert setAlertStyle:NSWarningAlertStyle]; + + if ([alert runModal] != NSAlertFirstButtonReturn) { + reply = NSTerminateCancel; + } + + [alert release]; + } else if (terminateNowCount < count) { + NSLog(@"WARNING: Not all tasks replied to TaskShouldTerminateMsgID," + " quitting anyway."); + } + + return reply; +} + +- (void)applicationWillTerminate:(NSNotification *)aNotification +{ + // NOTE! Is this a correct way of releasing the MMAppController? + [NSApp setDelegate:nil]; + [self autorelease]; +} + +- (void)handlePortMessage:(NSPortMessage *)portMessage +{ + unsigned msgid = [portMessage msgid]; + + if (msgid == CheckinMsgID) { + //NSLog(@"Received checkin message from VimTask."); + MMVimController *wc = [[MMVimController alloc] + initWithPort:[portMessage sendPort]]; + [vimControllers addObject:wc]; + [wc release]; + } else if (msgid == TerminateReplyYesMsgID) { + ++terminateNowCount; + } else if (msgid == TerminateReplyNoMsgID) { + abortTermination = YES; + } else { + NSLog(@"WARNING: Unknown message received (msgid=%d)", msgid); + } +} + +- (void)removeVimController:(id)controller +{ + [vimControllers removeObject:controller]; +} + +- (IBAction)newVimWindow:(id)sender +{ + NSMutableArray *args = [NSMutableArray arrayWithObject:@"-g"]; + NSString *path = [[NSBundle mainBundle] + pathForAuxiliaryExecutable:@"Vim"]; + + //NSLog(@"Launching a new VimTask..."); + [NSTask launchedTaskWithLaunchPath:path arguments:args]; +} + +@end diff --git a/MMBackend.h b/MMBackend.h new file mode 100644 index 0000000000..5f2aa7265d --- /dev/null +++ b/MMBackend.h @@ -0,0 +1,81 @@ +/* vi:set ts=8 sts=4 sw=4 ft=objc: + * + * VIM - Vi IMproved by Bram Moolenaar + * MacVim GUI port by Bjorn Winckler + * + * Do ":help uganda" in Vim to read copying and usage conditions. + * Do ":help credits" in Vim to see a list of people who contributed. + * See README.txt for an overview of the Vim source code. + */ + +#import + + + +@interface MMBackend : NSObject { + NSMutableArray *queue; + NSMutableData *drawData; + NSData *replyData; + NSPort *sendPort; + NSPort *receivePort; + NSDictionary *colorDict; + BOOL inputReceived; + BOOL receivedKillTaskMsg; + BOOL tabBarVisible; + int backgroundColor; + int foregroundColor; + int defaultBackgroundColor; + int defaultForegroundColor; +} + ++ (MMBackend *)sharedInstance; + +- (void)setBackgroundColor:(int)color; +- (void)setForegroundColor:(int)color; +- (void)setDefaultColorsBackground:(int)bg foreground:(int)fg; + +- (BOOL)checkin; +- (BOOL)openVimWindowWithRows:(int)rows columns:(int)cols; +- (void)clearAll; +- (void)clearBlockFromRow:(int)row1 column:(int)col1 + toRow:(int)row2 column:(int)col2; +- (void)deleteLinesFromRow:(int)row count:(int)count + scrollBottom:(int)bottom left:(int)left right:(int)right; +- (void)replaceString:(char*)s length:(int)len row:(int)row column:(int)col + flags:(int)flags; +- (void)insertLinesFromRow:(int)row count:(int)count + scrollBottom:(int)bottom left:(int)left right:(int)right; +- (void)flush; +- (void)flushQueue; +- (BOOL)waitForInput:(int)milliseconds; +- (void)exit; +- (void)selectTab:(int)index; +- (void)updateTabBar; +- (BOOL)tabBarVisible; +- (void)showTabBar:(BOOL)enable; +- (void)setRows:(int)rows columns:(int)cols; +- (void)setVimWindowTitle:(char *)title; +- (char *)browseForFileInDirectory:(char *)dir title:(char *)title + saving:(int)saving; +- (void)updateInsertionPoint; +- (void)addMenuWithTag:(int)tag parent:(int)parentTag name:(char *)name + atIndex:(int)index; +- (void)addMenuItemWithTag:(int)tag parent:(int)parentTag name:(char *)name + tip:(char *)tip icon:(char *)icon atIndex:(int)index; +- (void)removeMenuItemWithTag:(int)tag; +- (void)enableMenuItemWithTag:(int)tag state:(int)enabled; +- (void)showToolbar:(int)enable flags:(int)flags; +- (void)createScrollbarWithIdentifier:(long)ident type:(int)type; +- (void)destroyScrollbarWithIdentifier:(long)ident; +- (void)showScrollbarWithIdentifier:(long)ident state:(int)visible; +- (void)setScrollbarPosition:(int)pos length:(int)len identifier:(long)ident; +- (void)setScrollbarThumbValue:(long)val size:(long)size max:(long)max + identifier:(long)ident; +- (BOOL)setFontWithName:(char *)name; + +- (int)lookupColorWithKey:(NSString *)key; + +@end + + +// vim: set ft=objc: diff --git a/MMBackend.m b/MMBackend.m new file mode 100644 index 0000000000..50c809f39b --- /dev/null +++ b/MMBackend.m @@ -0,0 +1,1046 @@ +/* vi:set ts=8 sts=4 sw=4 ft=objc: + * + * VIM - Vi IMproved by Bram Moolenaar + * MacVim GUI port by Bjorn Winckler + * + * Do ":help uganda" in Vim to read copying and usage conditions. + * Do ":help credits" in Vim to see a list of people who contributed. + * See README.txt for an overview of the Vim source code. + */ + +#import "MMBackend.h" +#import "MacVim.h" +#import "vim.h" + + + +// TODO: Move to separate file. +static int eventModifierFlagsToVimModMask(int modifierFlags); +static int eventModifierFlagsToVimMouseModMask(int modifierFlags); +static int eventButtonNumberToVimMouseButton(int buttonNumber); + + +@interface MMBackend (Private) ++ (NSDictionary *)specialKeys; +- (void)handleKeyDown:(NSString *)key modifiers:(int)mods; +- (void)queueMessage:(int)msgid data:(NSData *)data; +@end + + + +@implementation MMBackend + ++ (MMBackend *)sharedInstance +{ + static MMBackend *singleton = nil; + return singleton ? singleton : (singleton = [MMBackend new]); +} + +- (id)init +{ + if ((self = [super init])) { + queue = [[NSMutableArray alloc] init]; + drawData = [[NSMutableData alloc] initWithCapacity:1024]; + NSString *path = [[NSBundle mainBundle] pathForResource:@"Colors" + ofType:@"plist"]; + colorDict = [[NSDictionary dictionaryWithContentsOfFile:path] retain]; + } + + return self; +} + +- (void)dealloc +{ + [queue release]; + [drawData release]; + [sendPort release]; + [receivePort release]; + [colorDict release]; + + [super dealloc]; +} + +- (void)setBackgroundColor:(int)color +{ + backgroundColor = color; +} + +- (void)setForegroundColor:(int)color +{ + foregroundColor = color; +} + +- (void)setDefaultColorsBackground:(int)bg foreground:(int)fg +{ + defaultBackgroundColor = bg; + defaultForegroundColor = fg; +} + +- (BOOL)checkin +{ + // NOTE! If the name of the port changes here it must also be updated in + // MMAppController.m. + NSString *portName = [NSString stringWithFormat:@"%@-taskport", + [[NSBundle mainBundle] bundleIdentifier]]; + + NSPort *port = [[[NSMachBootstrapServer sharedInstance] + portForName:portName host:nil] retain]; + if (!port) { +#if 0 + NSString *path = [[NSBundle mainBundle] bundlePath]; + if (![[NSWorkspace sharedWorkspace] launchApplication:path]) { + NSLog(@"WARNING: Failed to launch GUI with path %@", path); + return NO; + } +#else + // HACK! It would be preferable to launch the GUI using NSWorkspace, + // however I have not managed to figure out how to pass arguments using + // NSWorkspace. + // + // NOTE! Using NSTask to launch the GUI has the negative side-effect + // that the GUI won't be activated (or raised) so there is a hack in + // MMWindowController which always raises the app when a new window is + // opened. + NSMutableArray *args = [NSMutableArray arrayWithObjects:@"-nowindow", + @"yes", nil]; + NSString *path = [[NSBundle mainBundle] + pathForAuxiliaryExecutable:@"MacVim"]; + [NSTask launchedTaskWithLaunchPath:path arguments:args]; +#endif + + // HACK! The NSWorkspaceDidLaunchApplicationNotification does not work + // for tasks like this, so poll the mach bootstrap server until it + // returns a valid port. Also set a time-out date so that we don't get + // stuck doing this forever. + NSDate *timeOutDate = [NSDate dateWithTimeIntervalSinceNow:15]; + while (!port && + NSOrderedDescending == [timeOutDate compare:[NSDate date]]) { + [[NSRunLoop currentRunLoop] + runMode:NSDefaultRunLoopMode + beforeDate:[NSDate dateWithTimeIntervalSinceNow:1]]; + port = [[NSMachBootstrapServer sharedInstance] portForName:portName]; + } + + if (!port) { + NSLog(@"WARNING: Timed-out waiting for GUI to launch."); + return NO; + } + } + + receivePort = [NSMachPort new]; + [receivePort setDelegate:self]; + + [[NSRunLoop currentRunLoop] addPort:receivePort + forMode:NSDefaultRunLoopMode]; + + [NSPortMessage sendMessage:CheckinMsgID withSendPort:port + receivePort:receivePort wait:YES]; + + return YES; +} + +- (BOOL)openVimWindowWithRows:(int)rows columns:(int)cols +{ + if (!sendPort) { +#if 0 + // TODO: Wait until connected---maybe time out at some point? + // Note that if we return 'NO' Vim will be started in terminal mode + // (i.e. output goes to stdout). + NSLog(@"WARNING: Trying to open VimWindow but sendPort==nil;" + " waiting for connected message."); + + [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode + beforeDate:[NSDate distantFuture]]; + if (!sendPort) + return NO; +#else + // Wait until the sendPort has actually been set. + // + // TODO: Come up with a more elegant solution to this problem---this + // message should not be called before the sendPort has been + // initialized. + while (!sendPort) { + [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode + beforeDate:[NSDate distantFuture]]; + } +#endif + } + + NSMutableData *data = [NSMutableData data]; + + [data appendBytes:&rows length:sizeof(int)]; + [data appendBytes:&cols length:sizeof(int)]; + + [self queueMessage:OpenVimWindowMsgID data:data]; + + return YES; +} + +- (void)clearAll +{ + int type = ClearAllDrawType; + + // Any draw commands in queue are effectively obsolete since this clearAll + // will negate any effect they have, therefore we may as well clear the + // draw queue. + [drawData setLength:0]; + + [drawData appendBytes:&type length:sizeof(int)]; + [drawData appendBytes:&Rows length:sizeof(int)]; + [drawData appendBytes:&Columns length:sizeof(int)]; + + [drawData appendBytes:&defaultBackgroundColor length:sizeof(int)]; +} + +- (void)clearBlockFromRow:(int)row1 column:(int)col1 + toRow:(int)row2 column:(int)col2 +{ + int type = ClearBlockDrawType; + + [drawData appendBytes:&type length:sizeof(int)]; + [drawData appendBytes:&Rows length:sizeof(int)]; + [drawData appendBytes:&Columns length:sizeof(int)]; + + [drawData appendBytes:&defaultBackgroundColor length:sizeof(int)]; + [drawData appendBytes:&row1 length:sizeof(int)]; + [drawData appendBytes:&col1 length:sizeof(int)]; + [drawData appendBytes:&row2 length:sizeof(int)]; + [drawData appendBytes:&col2 length:sizeof(int)]; +} + +- (void)deleteLinesFromRow:(int)row count:(int)count + scrollBottom:(int)bottom left:(int)left right:(int)right +{ + int type = DeleteLinesDrawType; + + [drawData appendBytes:&type length:sizeof(int)]; + [drawData appendBytes:&Rows length:sizeof(int)]; + [drawData appendBytes:&Columns length:sizeof(int)]; + + [drawData appendBytes:&defaultBackgroundColor length:sizeof(int)]; + [drawData appendBytes:&row length:sizeof(int)]; + [drawData appendBytes:&count length:sizeof(int)]; + [drawData appendBytes:&bottom length:sizeof(int)]; + [drawData appendBytes:&left length:sizeof(int)]; + [drawData appendBytes:&right length:sizeof(int)]; +} + +- (void)replaceString:(char*)s length:(int)len row:(int)row column:(int)col + flags:(int)flags +{ + int type = ReplaceStringDrawType; + + [drawData appendBytes:&type length:sizeof(int)]; + [drawData appendBytes:&Rows length:sizeof(int)]; + [drawData appendBytes:&Columns length:sizeof(int)]; + + [drawData appendBytes:&backgroundColor length:sizeof(int)]; + [drawData appendBytes:&foregroundColor length:sizeof(int)]; + [drawData appendBytes:&row length:sizeof(int)]; + [drawData appendBytes:&col length:sizeof(int)]; + [drawData appendBytes:&flags length:sizeof(int)]; + [drawData appendBytes:&len length:sizeof(int)]; + [drawData appendBytes:s length:len]; +} + +- (void)insertLinesFromRow:(int)row count:(int)count + scrollBottom:(int)bottom left:(int)left right:(int)right +{ + int type = InsertLinesDrawType; + + [drawData appendBytes:&type length:sizeof(int)]; + [drawData appendBytes:&Rows length:sizeof(int)]; + [drawData appendBytes:&Columns length:sizeof(int)]; + + [drawData appendBytes:&defaultBackgroundColor length:sizeof(int)]; + [drawData appendBytes:&row length:sizeof(int)]; + [drawData appendBytes:&count length:sizeof(int)]; + [drawData appendBytes:&bottom length:sizeof(int)]; + [drawData appendBytes:&left length:sizeof(int)]; + [drawData appendBytes:&right length:sizeof(int)]; +} + +- (void)flush +{ + if ([drawData length] > 0) { + [self queueMessage:BatchDrawMsgID data:[drawData copy]]; + [drawData setLength:0]; + } +} + +- (void)flushQueue +{ + [self flush]; + + if ([drawData length] > 0 || [queue count] > 0) { + // TODO: Come up with a better way to handle the insertion point. + [self updateInsertionPoint]; + + [NSPortMessage sendMessage:FlushQueueMsgID withSendPort:sendPort + components:queue wait:YES]; + [queue removeAllObjects]; + } +} + +- (BOOL)waitForInput:(int)milliseconds +{ + if (![receivePort isValid]) { + // This should only happen if the GUI crashes. + NSLog(@"ERROR: The receive port is no longer valid, quitting..."); + getout(0); + } + + NSDate *date = milliseconds > 0 ? + [NSDate dateWithTimeIntervalSinceNow:.001*milliseconds] : + [NSDate distantFuture]; + + [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:date]; + + // I know of no way to figure out if the run loop exited because input was + // found or because of a time out, so I need to manually indicate when + // input was received in handlePortMessage and then reset it every time + // here. + BOOL yn = inputReceived; + inputReceived = NO; + + return yn; +} + +- (void)exit +{ + if (!receivedKillTaskMsg) { + [NSPortMessage sendMessage:TaskExitedMsgID withSendPort:sendPort + receivePort:receivePort wait:YES]; + } +} + +- (void)selectTab:(int)index +{ + //NSLog(@"%s%d", _cmd, index); + + index -= 1; + NSData *data = [NSData dataWithBytes:&index length:sizeof(int)]; + [self queueMessage:SelectTabMsgID data:data]; +} + +- (void)updateTabBar +{ + //NSLog(@"%s", _cmd); + + NSMutableData *data = [NSMutableData data]; + + int idx = tabpage_index(curtab) - 1; + [data appendBytes:&idx length:sizeof(int)]; + + tabpage_T *tp; + for (tp = first_tabpage; tp != NULL; tp = tp->tp_next) { + // This function puts the label of the tab in the global 'NameBuff'. + get_tabline_label(tp, FALSE); + int len = strlen((char*)NameBuff); + + // Count the number of windows in the tabpage. + //win_T *wp = tp->tp_firstwin; + //int wincount; + //for (wincount = 0; wp != NULL; wp = wp->w_next, ++wincount); + + //[data appendBytes:&wincount length:sizeof(int)]; + [data appendBytes:&len length:sizeof(int)]; + [data appendBytes:NameBuff length:len]; + } + + [self queueMessage:UpdateTabBarMsgID data:data]; +} + +- (BOOL)tabBarVisible +{ + return tabBarVisible; +} + +- (void)showTabBar:(BOOL)enable +{ + tabBarVisible = enable; + + int msgid = enable ? ShowTabBarMsgID : HideTabBarMsgID; + [self queueMessage:msgid data:nil]; +} + +- (void)setRows:(int)rows columns:(int)cols +{ + //NSLog(@"[VimTask] setRows:%d columns:%d", rows, cols); + + int dim[] = { rows, cols }; + NSData *data = [NSData dataWithBytes:&dim length:2*sizeof(int)]; + + [self queueMessage:SetTextDimensionsMsgID data:data]; +} + +- (void)setVimWindowTitle:(char *)title +{ + NSMutableData *data = [NSMutableData data]; + int len = strlen(title); + + [data appendBytes:&len length:sizeof(int)]; + [data appendBytes:title length:len]; + + [self queueMessage:SetVimWindowTitleMsgID data:data]; +} + +- (char *)browseForFileInDirectory:(char *)dir title:(char *)title + saving:(int)saving +{ + //NSLog(@"browseForFileInDirectory:%s title:%s saving:%d", dir, title, + // saving); + + NSMutableData *data = [NSMutableData data]; + + [data appendBytes:&saving length:sizeof(int)]; + + int len = dir ? strlen(dir) : 0; + [data appendBytes:&len length:sizeof(int)]; + if (len > 0) + [data appendBytes:dir length:len]; + + len = title ? strlen(title) : 0; + [data appendBytes:&len length:sizeof(int)]; + if (len > 0) + [data appendBytes:title length:len]; + + if (![NSPortMessage sendMessage:BrowseForFileMsgID withSendPort:sendPort + data:data wait:YES]) + return nil; + + // Wait until a reply is sent from MMVimController. + [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode + beforeDate:[NSDate distantFuture]]; + + // Something went wrong if replyData is nil. + if (!replyData) + return nil; + + const void *bytes = [replyData bytes]; + int ok = *((int*)bytes); bytes += sizeof(int); + len = *((int*)bytes); bytes += sizeof(int); + + char_u *s = NULL; + if (ok && len > 0) { + NSString *name = [[NSString alloc] initWithBytes:(void*)bytes + length:len encoding:NSUTF8StringEncoding]; + s = vim_strsave((char_u*)[name UTF8String]); + } + + [replyData release]; replyData = nil; + return (char*)s; +} + +- (void)updateInsertionPoint +{ + NSMutableData *data = [NSMutableData data]; + + int state = get_shape_idx(FALSE); + state = (state == SHAPE_IDX_I) || (state == SHAPE_IDX_CI); + + [data appendBytes:&defaultForegroundColor length:sizeof(int)]; + [data appendBytes:&gui.row length:sizeof(int)]; + [data appendBytes:&gui.col length:sizeof(int)]; + [data appendBytes:&state length:sizeof(int)]; + + [self queueMessage:UpdateInsertionPointMsgID data:data]; +} + +- (void)addMenuWithTag:(int)tag parent:(int)parentTag name:(char *)name + atIndex:(int)index +{ + //NSLog(@"addMenuWithTag:%d parent:%d name:%s atIndex:%d", tag, parentTag, + // name, index); + + int namelen = name ? strlen(name) : 0; + NSMutableData *data = [NSMutableData data]; + + [data appendBytes:&tag length:sizeof(int)]; + [data appendBytes:&parentTag length:sizeof(int)]; + [data appendBytes:&namelen length:sizeof(int)]; + if (namelen > 0) [data appendBytes:name length:namelen]; + [data appendBytes:&index length:sizeof(int)]; + + [self queueMessage:AddMenuMsgID data:data]; +} + +- (void)addMenuItemWithTag:(int)tag parent:(int)parentTag name:(char *)name + tip:(char *)tip icon:(char *)icon atIndex:(int)index +{ + //NSLog(@"addMenuItemWithTag:%d parent:%d name:%s tip:%s atIndex:%d", tag, + // parentTag, name, tip, index); + + int namelen = name ? strlen(name) : 0; + int tiplen = tip ? strlen(tip) : 0; + int iconlen = icon ? strlen(icon) : 0; + NSMutableData *data = [NSMutableData data]; + + [data appendBytes:&tag length:sizeof(int)]; + [data appendBytes:&parentTag length:sizeof(int)]; + [data appendBytes:&namelen length:sizeof(int)]; + if (namelen > 0) [data appendBytes:name length:namelen]; + [data appendBytes:&tiplen length:sizeof(int)]; + if (tiplen > 0) [data appendBytes:tip length:tiplen]; + [data appendBytes:&iconlen length:sizeof(int)]; + if (iconlen > 0) [data appendBytes:icon length:iconlen]; + [data appendBytes:&index length:sizeof(int)]; + + [self queueMessage:AddMenuItemMsgID data:data]; +} + +- (void)removeMenuItemWithTag:(int)tag +{ + NSMutableData *data = [NSMutableData data]; + [data appendBytes:&tag length:sizeof(int)]; + + [self queueMessage:RemoveMenuItemMsgID data:data]; +} + +- (void)enableMenuItemWithTag:(int)tag state:(int)enabled +{ + NSMutableData *data = [NSMutableData data]; + + [data appendBytes:&tag length:sizeof(int)]; + [data appendBytes:&enabled length:sizeof(int)]; + + [self queueMessage:EnableMenuItemMsgID data:data]; +} + +- (void)showToolbar:(int)enable flags:(int)flags +{ + NSMutableData *data = [NSMutableData data]; + + [data appendBytes:&enable length:sizeof(int)]; + [data appendBytes:&flags length:sizeof(int)]; + + [self queueMessage:ShowToolbarMsgID data:data]; +} + +- (void)createScrollbarWithIdentifier:(long)ident type:(int)type +{ + NSMutableData *data = [NSMutableData data]; + + [data appendBytes:&ident length:sizeof(long)]; + [data appendBytes:&type length:sizeof(int)]; + + [self queueMessage:CreateScrollbarMsgID data:data]; +} + +- (void)destroyScrollbarWithIdentifier:(long)ident +{ + NSMutableData *data = [NSMutableData data]; + [data appendBytes:&ident length:sizeof(long)]; + + [self queueMessage:DestroyScrollbarMsgID data:data]; +} + +- (void)showScrollbarWithIdentifier:(long)ident state:(int)visible +{ + NSMutableData *data = [NSMutableData data]; + + [data appendBytes:&ident length:sizeof(long)]; + [data appendBytes:&visible length:sizeof(int)]; + + [self queueMessage:ShowScrollbarMsgID data:data]; +} + +- (void)setScrollbarPosition:(int)pos length:(int)len identifier:(long)ident +{ + NSMutableData *data = [NSMutableData data]; + + [data appendBytes:&ident length:sizeof(long)]; + [data appendBytes:&pos length:sizeof(int)]; + [data appendBytes:&len length:sizeof(int)]; + + [self queueMessage:SetScrollbarPositionMsgID data:data]; +} + +- (void)setScrollbarThumbValue:(long)val size:(long)size max:(long)max + identifier:(long)ident +{ + float fval = max-size+1 > 0 ? (float)val/(max-size+1) : 0; + float prop = (float)size/(max+1); + if (fval < 0) fval = 0; + else if (fval > 1.0f) fval = 1.0f; + if (prop < 0) prop = 0; + else if (prop > 1.0f) prop = 1.0f; + + NSMutableData *data = [NSMutableData data]; + + [data appendBytes:&ident length:sizeof(long)]; + [data appendBytes:&fval length:sizeof(float)]; + [data appendBytes:&prop length:sizeof(float)]; + + [self queueMessage:SetScrollbarThumbMsgID data:data]; +} + +- (BOOL)setFontWithName:(char *)name +{ + NSString *fontName; + float size = 0.0f; + BOOL parseFailed = NO; + + if (name) { + fontName = [[[NSString alloc] initWithCString:name + encoding:NSUTF8StringEncoding] autorelease]; + NSArray *components = [fontName componentsSeparatedByString:@":"]; + if ([components count] == 2) { + NSString *sizeString = [components lastObject]; + if ([sizeString length] > 0 + && [sizeString characterAtIndex:0] == 'h') { + sizeString = [sizeString substringFromIndex:1]; + if ([sizeString length] > 0) { + size = [sizeString floatValue]; + fontName = [components objectAtIndex:0]; + } + } else { + parseFailed = YES; + } + } else if ([components count] > 2) { + parseFailed = YES; + } + } else { + fontName = [[NSFont userFixedPitchFontOfSize:0] displayName]; + } + + if (!parseFailed && [fontName length] > 0) { + if (size < 6 || size > 100) { + // Font size 0.0 tells NSFont to use the 'user default size'. + size = 0.0f; + } + + NSFont *font = [NSFont fontWithName:fontName size:size]; + if (font) { + //NSLog(@"Setting font '%@' of size %.2f", fontName, size); + NSMutableData *data = [NSMutableData data]; + int len = [fontName + lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; + + [data appendBytes:&size length:sizeof(float)]; + [data appendBytes:&len length:sizeof(int)]; + [data appendBytes:[fontName UTF8String] length:len]; + + [self queueMessage:SetFontMsgID data:data]; + return YES; + } + } + + NSLog(@"WARNING: Cannot set font with name '%@' of size %.2f", + fontName, size); + return NO; +} + +- (int)lookupColorWithKey:(NSString *)key +{ + if (!(key && [key length] > 0)) + return INVALCOLOR; + + // First of all try to lookup key in the color dictionary; note that all + // keys in this dictionary are lowercase with no whitespace. + + NSString *stripKey = [[[[key lowercaseString] + stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]] + componentsSeparatedByString:@" "] + componentsJoinedByString:@""]; + + if (stripKey && [stripKey length] > 0) { + id obj = [colorDict objectForKey:stripKey]; + if (obj) return [obj intValue]; + + // The key was not in the dictionary; is it perhaps of the form + // #rrggbb? + + if ([stripKey length] > 1 && [stripKey characterAtIndex:0] == '#') { + NSScanner *scanner = [NSScanner scannerWithString:stripKey]; + [scanner setScanLocation:1]; + unsigned hex = 0; + if ([scanner scanHexInt:&hex]) { + return (int)hex; + } + } + } + + NSLog(@"WARNING: No color with key %@ found.", stripKey); + return INVALCOLOR; +} + +- (void)handlePortMessage:(NSPortMessage *)portMessage +{ + unsigned msgid = [portMessage msgid]; + + if (ConnectedMsgID == msgid) { + sendPort = [[portMessage sendPort] retain]; + //NSLog(@"VimTask connected to MMVimController."); + } else if (KillTaskMsgID == msgid) { + //NSLog(@"VimTask received kill message; exiting now."); + // Set this flag here so that exit does not send TaskExitedMsgID back + // to MMVimController. + receivedKillTaskMsg = YES; + getout(0); + } else if (InsertTextMsgID == msgid) { + if (![[portMessage components] count]) return; + NSString *key = [[NSString alloc] + initWithData:[[portMessage components] objectAtIndex:0] + encoding:NSUTF8StringEncoding]; + //NSLog(@"insert text: %@ (hex=%x)", key, [key characterAtIndex:0]); + add_to_input_buf((char_u*)[key UTF8String], + [key lengthOfBytesUsingEncoding:NSUTF8StringEncoding]); + [key release]; + + inputReceived = YES; + } else if (KeyDownMsgID == msgid || CmdKeyMsgID == msgid) { + if (![[portMessage components] count]) return; + const void *bytes = [[[portMessage components] objectAtIndex:0] bytes]; + int mods = *((int*)bytes); bytes += sizeof(int); + int len = *((int*)bytes); bytes += sizeof(int); + NSString *key = [[NSString alloc] initWithBytes:bytes length:len + encoding:NSUTF8StringEncoding]; + mods = eventModifierFlagsToVimModMask(mods); + + [self handleKeyDown:key modifiers:mods]; + + [key release]; + inputReceived = YES; + } else if (SelectTabMsgID == msgid) { + if (![[portMessage components] count]) return; + const void *bytes = [[[portMessage components] objectAtIndex:0] bytes]; + int idx = *((int*)bytes) + 1; + //NSLog(@"Selecting tab %d", idx); + send_tabline_event(idx); + inputReceived = YES; + } else if (CloseTabMsgID == msgid) { + if (![[portMessage components] count]) return; + const void *bytes = [[[portMessage components] objectAtIndex:0] bytes]; + int idx = *((int*)bytes) + 1; + //NSLog(@"Closing tab %d", idx); + send_tabline_menu_event(idx, TABLINE_MENU_CLOSE); + inputReceived = YES; + } else if (AddNewTabMsgID == msgid) { + //NSLog(@"Adding new tab"); + send_tabline_menu_event(0, TABLINE_MENU_NEW); + inputReceived = YES; + } else if (DraggedTabMsgID == msgid) { + if (![[portMessage components] count]) return; + const void *bytes = [[[portMessage components] objectAtIndex:0] bytes]; + // NOTE! The destination index is 0 based, so do not add 1 to make it 1 + // based. + int idx = *((int*)bytes); + +#if 0 + tabpage_T *tp = find_tabpage(oldIdx); + if (tp) { + // HACK! tabpage_move(idx) moves 'curtab' to 'idx', but since it + // is also possible to drag tabs which are not selected we must + // first set 'curtab' to the tab that was actually dragged and then + // reset 'curtab' to what it used to be. + tabpage_T *oldcur = curtab; + curtab = tp; + tabpage_move(idx); + curtab = oldcur; + } +#else + tabpage_move(idx); +#endif + } else if (ScrollWheelMsgID == msgid) { + if (![[portMessage components] count]) return; + const void *bytes = [[[portMessage components] objectAtIndex:0] bytes]; + + int row = *((int*)bytes); bytes += sizeof(int); + int col = *((int*)bytes); bytes += sizeof(int); + int flags = *((int*)bytes); bytes += sizeof(int); + float dy = *((float*)bytes); bytes += sizeof(float); + + int button = MOUSE_5; + if (dy > 0) button = MOUSE_4; + + flags = eventModifierFlagsToVimMouseModMask(flags); + + gui_send_mouse_event(button, col, row, NO, flags); + inputReceived = YES; + } else if (MouseDownMsgID == msgid) { + if (![[portMessage components] count]) return; + const void *bytes = [[[portMessage components] objectAtIndex:0] bytes]; + + int row = *((int*)bytes); bytes += sizeof(int); + int col = *((int*)bytes); bytes += sizeof(int); + int button = *((int*)bytes); bytes += sizeof(int); + int flags = *((int*)bytes); bytes += sizeof(int); + int count = *((int*)bytes); bytes += sizeof(int); + + button = eventButtonNumberToVimMouseButton(button); + flags = eventModifierFlagsToVimMouseModMask(flags); + + gui_send_mouse_event(button, col, row, 0 != count, flags); + + inputReceived = YES; + } else if (MouseUpMsgID == msgid) { + if (![[portMessage components] count]) return; + const void *bytes = [[[portMessage components] objectAtIndex:0] bytes]; + + int row = *((int*)bytes); bytes += sizeof(int); + int col = *((int*)bytes); bytes += sizeof(int); + int flags = *((int*)bytes); bytes += sizeof(int); + + flags = eventModifierFlagsToVimMouseModMask(flags); + + gui_send_mouse_event(MOUSE_RELEASE, col, row, NO, flags); + inputReceived = YES; + } else if (MouseDraggedMsgID == msgid) { + if (![[portMessage components] count]) return; + const void *bytes = [[[portMessage components] objectAtIndex:0] bytes]; + + int row = *((int*)bytes); bytes += sizeof(int); + int col = *((int*)bytes); bytes += sizeof(int); + int flags = *((int*)bytes); bytes += sizeof(int); + + flags = eventModifierFlagsToVimMouseModMask(flags); + + gui_send_mouse_event(MOUSE_DRAG, col, row, NO, flags); + inputReceived = YES; + } else if (BrowseForFileReplyMsgID == msgid) { + if (![[portMessage components] count]) return; + [replyData release]; + replyData = [[[portMessage components] objectAtIndex:0] copy]; + } else if (SetTextDimensionsMsgID == msgid) { + if (![[portMessage components] count]) return; + const void *bytes = [[[portMessage components] objectAtIndex:0] bytes]; + int rows = *((int*)bytes); bytes += sizeof(int); + int cols = *((int*)bytes); bytes += sizeof(int); + + //NSLog(@"[VimTask] Resizing shell to %dx%d.", cols, rows); + gui_resize_shell(cols, rows); + } else if (ExecuteMenuMsgID == msgid) { + if (![[portMessage components] count]) return; + const void *bytes = [[[portMessage components] objectAtIndex:0] bytes]; + int tag = *((int*)bytes); bytes += sizeof(int); + + vimmenu_T *menu = (vimmenu_T*)tag; + // TODO! Make sure 'menu' is a valid menu pointer! + if (menu) { + gui_menu_cb(menu); + inputReceived = YES; + } + } else if (TaskShouldTerminateMsgID == msgid) { + int reply = TerminateReplyYesMsgID; + buf_T *buf; + for (buf = firstbuf; buf != NULL; buf = buf->b_next) { + if (bufIsChanged(buf)) { + reply = TerminateReplyNoMsgID; + break; + } + } + + //NSLog(@"TaskShouldTerminateMsgID = %s", + // reply == TerminateReplyYesMsgID ? "YES" : "NO"); + + [NSPortMessage sendMessage:reply withSendPort:[portMessage sendPort] + wait:YES]; + } else if (ScrollbarEventMsgID == msgid) { + if (![[portMessage components] count]) return; + const void *bytes = [[[portMessage components] objectAtIndex:0] bytes]; + long ident = *((long*)bytes); bytes += sizeof(long); + int hitPart = *((int*)bytes); bytes += sizeof(int); + float fval = *((float*)bytes); bytes += sizeof(float); + scrollbar_T *sb = gui_find_scrollbar(ident); + + if (sb) { + scrollbar_T *sb_info = sb->wp ? &sb->wp->w_scrollbars[0] : sb; + long value = sb_info->value; + long size = sb_info->size; + long max = sb_info->max; + BOOL isStillDragging = NO; + BOOL updateKnob = YES; + + switch (hitPart) { + case NSScrollerDecrementPage: + value -= (size > 2 ? size - 2 : 1); + break; + case NSScrollerIncrementPage: + value += (size > 2 ? size - 2 : 1); + break; + case NSScrollerDecrementLine: + --value; + break; + case NSScrollerIncrementLine: + ++value; + break; + case NSScrollerKnob: + isStillDragging = YES; + // fall through ... + case NSScrollerKnobSlot: + value = (long)(fval * (max - size + 1)); + // fall through ... + default: + updateKnob = NO; + break; + } + + //NSLog(@"value %d -> %d", sb_info->value, value); + gui_drag_scrollbar(sb, value, isStillDragging); + + if (updateKnob) { + // Dragging the knob or option+clicking automatically updates + // the knob position (on the actual NSScroller), so we only + // need to set the knob position in the other cases. + if (sb->wp) { + // Update both the left&right vertical scrollbars. + long identLeft = sb->wp->w_scrollbars[SBAR_LEFT].ident; + long identRight = sb->wp->w_scrollbars[SBAR_RIGHT].ident; + [self setScrollbarThumbValue:value size:size max:max + identifier:identLeft]; + [self setScrollbarThumbValue:value size:size max:max + identifier:identRight]; + } else { + // Update the horizontal scrollbar. + [self setScrollbarThumbValue:value size:size max:max + identifier:ident]; + } + } + + inputReceived = YES; + } + } else { + NSLog(@"WARNING: Unknown message received (msgid=%d)", msgid); + } +} + + +@end // MMBackend + + + +@implementation MMBackend (Private) + ++ (NSDictionary *)specialKeys +{ + static NSDictionary *specialKeys = nil; + + if (!specialKeys) { + NSBundle *mainBundle = [NSBundle mainBundle]; + NSString *path = [mainBundle pathForResource:@"SpecialKeys" + ofType:@"plist"]; + specialKeys = [[NSDictionary alloc] initWithContentsOfFile:path]; + } + + return specialKeys; +} + +- (void)handleKeyDown:(NSString *)key modifiers:(int)mods +{ + char_u special[3]; + char_u modChars[3]; + char_u *chars = 0; + int length = 0; + + // Special keys (arrow keys, function keys, etc.) are stored in a plist so + // that new keys can easily be added. + NSString *specialString = [[MMBackend specialKeys] + objectForKey:key]; + if (specialString && [specialString length] > 1) { + //NSLog(@"special key: %@", specialString); + int ikey = TO_SPECIAL([specialString characterAtIndex:0], + [specialString characterAtIndex:1]); + + ikey = simplify_key(ikey, &mods); + if (ikey == CSI) + ikey = K_CSI; + + special[0] = CSI; + special[1] = K_SECOND(ikey); + special[2] = K_THIRD(ikey); + + chars = special; + length = 3; + } else if ([key length] > 0) { + chars = (char_u*)[key UTF8String]; + length = [key lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; + unichar c = [key characterAtIndex:0]; + + //NSLog(@"non-special: %@ (hex=%x, mods=%d)", key, + // [key characterAtIndex:0], mods); + + // HACK! In most circumstances the Ctrl and Shift modifiers should be + // cleared since they are already added to the key by the AppKit. + // Unfortunately, the only way to deal with when to clear the modifiers + // or not seems to be to have hard-wired rules like this. + if ( !((' ' == c) || (0xa0 == c) || (mods & MOD_MASK_CMD)) ) { + mods &= ~MOD_MASK_SHIFT; + mods &= ~MOD_MASK_CTRL; + //NSLog(@"clear shift ctrl"); + } + + // HACK! All Option+key presses go via 'insert text' messages, except + // for . If the Alt flag is not cleared for it does + // not work to map to it. + if (0xa0 == c && !(mods & MOD_MASK_CMD)) { + //NSLog(@"clear alt"); + mods &= ~MOD_MASK_ALT; + } + } + + if (chars && length > 0) { + if (mods) { + //NSLog(@"adding mods: %d", mods); + modChars[0] = CSI; + modChars[1] = KS_MODIFIER; + modChars[2] = mods; + add_to_input_buf(modChars, 3); + } + + //NSLog(@"add to input buf: 0x%x", chars[0]); + add_to_input_buf(chars, length); + } +} + +- (void)queueMessage:(int)msgid data:(NSData *)data +{ + [queue addObject:[NSData dataWithBytes:&msgid length:sizeof(int)]]; + if (data) + [queue addObject:data]; + else + [queue addObject:[NSData data]]; +} + +@end // MMBackend (Private) + + + + +static int eventModifierFlagsToVimModMask(int modifierFlags) +{ + int modMask = 0; + + if (modifierFlags & NSShiftKeyMask) + modMask |= MOD_MASK_SHIFT; + if (modifierFlags & NSControlKeyMask) + modMask |= MOD_MASK_CTRL; + if (modifierFlags & NSAlternateKeyMask) + modMask |= MOD_MASK_ALT; + if (modifierFlags & NSCommandKeyMask) + modMask |= MOD_MASK_CMD; + + return modMask; +} + +static int eventModifierFlagsToVimMouseModMask(int modifierFlags) +{ + int modMask = 0; + + if (modifierFlags & NSShiftKeyMask) + modMask |= MOUSE_SHIFT; + if (modifierFlags & NSControlKeyMask) + modMask |= MOUSE_CTRL; + if (modifierFlags & NSAlternateKeyMask) + modMask |= MOUSE_ALT; + + return modMask; +} + +static int eventButtonNumberToVimMouseButton(int buttonNumber) +{ + static int mouseButton[] = { MOUSE_LEFT, MOUSE_RIGHT, MOUSE_MIDDLE, + MOUSE_X1, MOUSE_X2 }; + + return mouseButton[buttonNumber < 5 ? buttonNumber : 0]; +} diff --git a/MMTextStorage.h b/MMTextStorage.h new file mode 100644 index 0000000000..61034ccba1 --- /dev/null +++ b/MMTextStorage.h @@ -0,0 +1,60 @@ +/* vi:set ts=8 sts=4 sw=4 ft=objc: + * + * VIM - Vi IMproved by Bram Moolenaar + * MacVim GUI port by Bjorn Winckler + * + * Do ":help uganda" in Vim to read copying and usage conditions. + * Do ":help credits" in Vim to see a list of people who contributed. + * See README.txt for an overview of the Vim source code. + */ + +#import + + + +@interface MMTextStorage : NSTextStorage { + NSMutableAttributedString *attribString; + int maxRows, maxColumns; + // TODO! Rename to emptyRowString + NSAttributedString *emptyColumnString; + NSFont *font; + //NSMutableParagraphStyle *paragraphStyle; +} + +- (NSString *)string; +- (NSDictionary *)attributesAtIndex:(unsigned)index + effectiveRange:(NSRangePointer)aRange; +- (void)replaceCharactersInRange:(NSRange)aRange + withString:(NSString *)aString; +- (void)setAttributes:(NSDictionary *)attributes range:(NSRange)aRange; + +- (int)maxRows; +- (int)maxColumns; +- (void)getMaxRows:(int*)rows columns:(int*)cols; +- (void)setMaxRows:(int)rows columns:(int)cols; +- (void)replaceString:(NSString*)string atRow:(int)row column:(int)col + withFlags:(int)flags foregroundColor:(NSColor*)fg + backgroundColor:(NSColor*)bg; +- (void)deleteLinesFromRow:(int)row lineCount:(int)count + scrollBottom:(int)bottom left:(int)left right:(int)right + color:(NSColor *)color; +- (void)insertLinesAtRow:(int)row lineCount:(int)count + scrollBottom:(int)bottom left:(int)left right:(int)right + color:(NSColor *)color; +- (void)clearBlockFromRow:(int)row1 column:(int)col1 toRow:(int)row2 + column:(int)col2 color:(NSColor *)color; +- (void)clearAllWithColor:(NSColor *)color; +- (void)setFont:(NSFont*)newFont; +- (NSFont*)font; +- (float)widthOfEmptyColumn; +- (NSSize)size; +- (NSSize)calculateAverageFontSize; +- (NSRect)rectForRowsInRange:(NSRange)range; +- (NSRect)rectForColumnsInRange:(NSRange)range; +- (unsigned)offsetFromRow:(int)row column:(int)col; +- (BOOL)resizeToFitSize:(NSSize)size; +- (NSSize)fitToSize:(NSSize)size; + +@end + +/* vim: set filetype=objc: */ diff --git a/MMTextStorage.m b/MMTextStorage.m new file mode 100644 index 0000000000..4e5b4459c5 --- /dev/null +++ b/MMTextStorage.m @@ -0,0 +1,554 @@ +/* vi:set ts=8 sts=4 sw=4 ft=objc: + * + * VIM - Vi IMproved by Bram Moolenaar + * MacVim GUI port by Bjorn Winckler + * + * Do ":help uganda" in Vim to read copying and usage conditions. + * Do ":help credits" in Vim to see a list of people who contributed. + * See README.txt for an overview of the Vim source code. + */ + +#import "MMTextStorage.h" + +// If 0 DRAW_TRANSP flag will be ignored. Setting it to 1 causes the cursor +// background to be drawn in white. +#define HEED_DRAW_TRANSP 0 + +#define DRAW_TRANSP 0x01 /* draw with transparant bg */ +#define DRAW_BOLD 0x02 /* draw bold text */ +#define DRAW_UNDERL 0x04 /* draw underline text */ +#define DRAW_UNDERC 0x08 /* draw undercurl text */ +#define DRAW_ITALIC 0x10 /* draw italic text */ + + +//static float LINEHEIGHT = 30.0f; + + + +@interface MMTextStorage (Private) +- (NSSize)fitToSize:(NSSize)size rows:(int *)rows columns:(int *)columns; +@end + + + +@implementation MMTextStorage + +- (id)init +{ + if ((self = [super init])) { + attribString = [[NSMutableAttributedString alloc] initWithString:@""]; + // NOTE! It does not matter which font is set here, Vim will set its + // own font on startup anyway. + font = [[NSFont userFixedPitchFontOfSize:0] retain]; + +#if 0 + paragraphStyle = [[NSMutableParagraphStyle alloc] init]; + [paragraphStyle setMinimumLineHeight:LINEHEIGHT]; + [paragraphStyle setMaximumLineHeight:LINEHEIGHT]; + [paragraphStyle setLineSpacing:0]; +#endif + } + + return self; +} + +- (void)dealloc +{ + [emptyColumnString release]; + //[paragraphStyle release]; + [font release]; + [attribString release]; + [super dealloc]; +} + +- (NSString *)string +{ + //NSLog(@"%s : attribString=%@", _cmd, attribString); + return [attribString string]; +} + +- (NSDictionary *)attributesAtIndex:(unsigned)index + effectiveRange:(NSRangePointer)aRange +{ + //NSLog(@"%s", _cmd); + if (index>=[attribString length]) { + //NSLog(@"%sWARNING: index (%d) out of bounds", _cmd, index); + if (aRange) { + *aRange = NSMakeRange(NSNotFound, 0); + } + return [NSDictionary dictionary]; + } + + return [attribString attributesAtIndex:index effectiveRange:aRange]; +} + +- (void)replaceCharactersInRange:(NSRange)aRange + withString:(NSString *)aString +{ + //NSLog(@"replaceCharactersInRange:(%d,%d) withString:%@", aRange.location, + // aRange.length, aString); + NSLog(@"WARNING: calling %s on MMTextStorage is unsupported", _cmd); + //[attribString replaceCharactersInRange:aRange withString:aString]; +} + +- (void)setAttributes:(NSDictionary *)attributes range:(NSRange)aRange +{ + // NOTE! This method must be implemented since the text system calls it + // constantly to 'fix attributes', apply font substitution, etc. + [attribString setAttributes:attributes range:aRange]; +} + +- (int)maxRows +{ + return maxRows; +} + +- (int)maxColumns +{ + return maxColumns; +} + +- (void)getMaxRows:(int*)rows columns:(int*)cols +{ + if (rows) *rows = maxRows; + if (cols) *cols = maxColumns; +} + +- (void)setMaxRows:(int)rows columns:(int)cols +{ + // Do nothing if the dimensions are already right. + if (maxRows == rows && maxColumns == cols) + return; + + NSRange oldRange = NSMakeRange(0, maxRows*(maxColumns+1)); + + maxRows = rows; + maxColumns = cols; + //NSLog(@"setMaxRows:%d columns:%d", maxRows, maxColumns); + + NSString *fmt = [NSString stringWithFormat:@"%%%dc\%C", maxColumns, + NSLineSeparatorCharacter]; + NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys: + font, NSFontAttributeName, + nil]; + + [emptyColumnString release]; + emptyColumnString = [[NSAttributedString alloc] + initWithString:[NSString stringWithFormat:fmt, ' '] + attributes:dict]; + + [attribString release]; + attribString = [[NSMutableAttributedString alloc] init]; + int i; + for (i=0; i= maxRows || col < 0 || col >= maxColumns + || col+[string length] > maxColumns) { + //NSLog(@"[%s] WARNING : out of range, row=%d (%d) col=%d (%d) " + // "length=%d (%d)", _cmd, row, maxRows, col, maxColumns, + // [string length], [attribString length]); + return; + } + + if (!(fg && bg)) { + NSLog(@"[%s] WARNING: background or foreground color not specified", + _cmd); + return; + } + + NSRange range = NSMakeRange(col+row*(maxColumns+1), [string length]); + [attribString replaceCharactersInRange:range withString:string]; + + NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys: + font, NSFontAttributeName, + //paragraphStyle, NSParagraphStyleAttributeName, +#if !HEED_DRAW_TRANSP + bg, NSBackgroundColorAttributeName, +#endif + fg, NSForegroundColorAttributeName, nil]; + [attribString setAttributes:attributes range:range]; + +#if HEED_DRAW_TRANSP + if ( !(flags & DRAW_TRANSP) ) { + [attribString addAttribute:NSBackgroundColorAttributeName value:bg + range:range]; + } +#endif + + // TODO: cache bold font and apply in setAttributes:range: + if (flags & DRAW_BOLD) { + [attribString applyFontTraits:NSBoldFontMask range:range]; + } + + // TODO: cache italic font and apply in setAttributes:range: + if (flags & DRAW_ITALIC) { + [attribString applyFontTraits:NSItalicFontMask range:range]; + } + + if (flags & DRAW_UNDERL) { + NSNumber *value = [NSNumber numberWithInt:(NSUnderlineStyleSingle + | NSUnderlinePatternSolid)]; // | NSUnderlineByWordMask + [attribString addAttribute:NSUnderlineStyleAttributeName + value:value range:range]; + } + + // TODO: figure out how do draw proper undercurls + if (flags & DRAW_UNDERC) { + NSNumber *value = [NSNumber numberWithInt:(NSUnderlineStyleThick + | NSUnderlinePatternDot)]; // | NSUnderlineByWordMask + [attribString addAttribute:NSUnderlineStyleAttributeName + value:value range:range]; + } + +#if 0 + [attribString addAttribute:NSParagraphStyleAttributeName + value:paragraphStyle + range:NSMakeRange(0, [attribString length])]; +#endif + + [self edited:(NSTextStorageEditedCharacters|NSTextStorageEditedAttributes) + range:range changeInLength:0]; +} + +/* + * Delete 'count' lines from 'row' and insert 'count' empty lines at the bottom + * of the scroll region. + */ +- (void)deleteLinesFromRow:(int)row lineCount:(int)count + scrollBottom:(int)bottom left:(int)left right:(int)right + color:(NSColor *)color +{ + //NSLog(@"deleteLinesFromRow:%d lineCount:%d", row, count); + + if (row < 0 || row+count > maxRows) { + NSLog(@"[%s] WARNING : out of range, row=%d (%d) count=%d", _cmd, row, + maxRows, count); + return; + } + + int total = 1 + bottom - row; + int move = total - count; + int width = right - left + 1; + NSRange destRange = { row*(maxColumns+1) + left, width }; + NSRange srcRange = { (row+count)*(maxColumns+1) + left, width }; + int i; + + for (i = 0; i < move; ++i) { + NSAttributedString *srcString = [attribString + attributedSubstringFromRange:srcRange]; + [attribString replaceCharactersInRange:destRange + withAttributedString:srcString]; + [self edited:(NSTextStorageEditedCharacters + | NSTextStorageEditedAttributes) + range:destRange changeInLength:0]; + destRange.location += maxColumns+1; + srcRange.location += maxColumns+1; + } + + for (i = 0; i < count; ++i) { + NSDictionary *attribs = [NSDictionary dictionaryWithObjectsAndKeys: + font, NSFontAttributeName, + color, NSForegroundColorAttributeName, + color, NSBackgroundColorAttributeName, nil]; + [attribString setAttributes:attribs range:destRange]; + [self edited:NSTextStorageEditedAttributes range:destRange + changeInLength:0]; + destRange.location += maxColumns+1; + } +} + +/* + * Insert 'count' empty lines at 'row' and delete 'count' lines from the bottom + * of the scroll region. + */ +- (void)insertLinesAtRow:(int)row lineCount:(int)count + scrollBottom:(int)bottom left:(int)left right:(int)right + color:(NSColor *)color +{ + //NSLog(@"insertLinesAtRow:%d lineCount:%d", row, count); + + if (row < 0 || row+count > maxRows) { + NSLog(@"[%s] WARNING : out of range, row=%d (%d) count=%d", _cmd, row, + maxRows, count); + return; + } + + int total = 1 + bottom - row; + int move = total - count; + int width = right - left + 1; + NSRange destRange = { bottom*(maxColumns+1) + left, width }; + NSRange srcRange = { (row+move-1)*(maxColumns+1) + left, width }; + int i; + + for (i = 0; i < move; ++i) { + NSAttributedString *srcString = [attribString + attributedSubstringFromRange:srcRange]; + [attribString replaceCharactersInRange:destRange + withAttributedString:srcString]; + [self edited:(NSTextStorageEditedCharacters + | NSTextStorageEditedAttributes) + range:destRange changeInLength:0]; + destRange.location -= maxColumns+1; + srcRange.location -= maxColumns+1; + } + + for (i = 0; i < count; ++i) { + NSDictionary *attribs = [NSDictionary dictionaryWithObjectsAndKeys: + font, NSFontAttributeName, + color, NSForegroundColorAttributeName, + color, NSBackgroundColorAttributeName, nil]; + [attribString setAttributes:attribs range:destRange]; + [self edited:NSTextStorageEditedAttributes range:destRange + changeInLength:0]; + destRange.location -= maxColumns+1; + } +} + +- (void)clearBlockFromRow:(int)row1 column:(int)col1 toRow:(int)row2 + column:(int)col2 color:(NSColor *)color +{ + //NSLog(@"clearBlockFromRow:%d column:%d toRow:%d column:%d", row1, col1, + // row2, col2); + + if (row1 < 0 || row2 >= maxRows || col1 < 0 || col2 > maxColumns) { + NSLog(@"[%s] WARNING : out of range, row1=%d row2=%d (%d) col1=%d " + "col2=%d (%d)", _cmd, row1, row2, maxRows, col1, col2, + maxColumns); + return; + } + + NSDictionary *attribs = [NSDictionary dictionaryWithObjectsAndKeys: + font, NSFontAttributeName, + color, NSForegroundColorAttributeName, + color, NSBackgroundColorAttributeName, nil]; + + NSRange range = { row1*(maxColumns+1) + col1, col2-col1+1 }; + + int r; + for (r=row1; r<=row2; ++r) { + [attribString setAttributes:attribs range:range]; + [self edited:NSTextStorageEditedAttributes range:range + changeInLength:0]; + range.location += maxColumns+1; + } +} + +- (void)clearAllWithColor:(NSColor *)color +{ + NSRange range = { 0, [attribString length] }; + NSDictionary *attribs = [NSDictionary dictionaryWithObjectsAndKeys: + font, NSFontAttributeName, + color, NSForegroundColorAttributeName, + color, NSBackgroundColorAttributeName, nil]; + [attribString setAttributes:attribs range:range]; + [self edited:NSTextStorageEditedAttributes range:range changeInLength:0]; +} + +- (void)setFont:(NSFont*)newFont +{ +#if 0 + if (font != newFont) { + //NSLog(@"Changing font from %@ to %@", font, newFont); + [font release]; + font = [newFont retain]; + NSRange range = { 0, [attribString length] }; + [attribString addAttribute:NSFontAttributeName value:font + range:range]; + [self setDefaultFg:norm_pixel bg:gui.back_pixel]; + [self edited:NSTextStorageEditedAttributes range:range + changeInLength:0]; + } +#else + if (font != newFont) { + //NSLog(@"Setting font %@", newFont); + [font release]; + font = [newFont retain]; + // TODO! Change paragraph style to match line height of new font + } +#endif +} + +- (NSFont*)font +{ + return font; +} + +- (float)widthOfEmptyColumn +{ + return [font widthOfString:[emptyColumnString string]]; +} + +- (NSSize)size +{ + if (![[self layoutManagers] count]) return NSZeroSize; + NSLayoutManager *lm = [[self layoutManagers] objectAtIndex:0]; + + if (![[lm textContainers] count]) return NSZeroSize; + NSTextContainer *tc = [[lm textContainers] objectAtIndex:0]; + + NSRange range = [lm glyphRangeForTextContainer:tc]; + NSRect rect = [lm boundingRectForGlyphRange:range inTextContainer:tc]; + //[lm glyphRangeForTextContainer:tc]; + //NSRect rect = [lm usedRectForTextContainer:tc]; + + NSSize size = NSMakeSize([self widthOfEmptyColumn], rect.size.height); + //NSSize size = NSMakeSize([self widthOfEmptyColumn], maxRows*LINEHEIGHT); + //NSLog(@"size=(%.2f,%.2f) rows=%d cols=%d layoutManager size=(%.2f,%.2f)", + // size.width, size.height, maxRows, maxColumns, rect.size.width, + // rect.size.height); + + return size; +} + +- (NSSize)calculateAverageFontSize +{ + if (![[self layoutManagers] count]) return NSZeroSize; + + NSSize size; + NSLayoutManager *lm = [[self layoutManagers] objectAtIndex:0]; + size.height = [lm defaultLineHeightForFont:font]; + size.width = maxColumns > 0 ? [self widthOfEmptyColumn]/maxColumns : 0; + if (size.height < 1.0f) size.height = 1.0f; + if (size.width < 1.0f) size.width = 1.0f; + + return size; +} + +- (NSRect)rectForRowsInRange:(NSRange)range +{ + if (![[self layoutManagers] count]) return NSZeroRect; + + // TODO! Take range.location into account when computing height (in case + // the line height varies). + NSRect rect = { 0, 0, 0, 0 }; + NSLayoutManager *lm = [[self layoutManagers] objectAtIndex:0]; + float fontHeight = [lm defaultLineHeightForFont:font]; + + rect.origin.y = fontHeight * range.location; + rect.size.height = fontHeight * range.length; + + return rect; +} + +- (NSRect)rectForColumnsInRange:(NSRange)range +{ + NSRect rect = { 0, 0, 0, 0 }; + float fontWidth = maxColumns > 0 + ? [self widthOfEmptyColumn]/maxColumns : 0; + + rect.origin.x = fontWidth * range.location; + rect.size.width = fontWidth * range.length; + + return rect; +} + +- (unsigned)offsetFromRow:(int)row column:(int)col +{ + // Ensure the offset returned is valid. + // This code also works if maxRows and/or maxColumns is 0. + if (row >= maxRows) row = maxRows-1; + if (row < 0) row = 0; + if (col >= maxColumns) col = maxColumns-1; + if (col < 0) col = 0; + + return (unsigned)(col + row*(maxColumns+1)); +} + +- (BOOL)resizeToFitSize:(NSSize)size +{ + int rows = maxRows, cols = maxColumns; + + [self fitToSize:size rows:&rows columns:&cols]; + if (rows != maxRows || cols != maxColumns) { + [self setMaxRows:rows columns:cols]; + return YES; + } + + // Return NO only if dimensions did not change. + return NO; +} + +- (NSSize)fitToSize:(NSSize)size +{ + return [self fitToSize:size rows:NULL columns:NULL]; +} + +@end // MMTextStorage + + + + +@implementation MMTextStorage (Private) + +- (NSSize)fitToSize:(NSSize)size rows:(int *)rows columns:(int *)columns +{ + if (![[self layoutManagers] count]) return size; + NSLayoutManager *lm = [[self layoutManagers] objectAtIndex:0]; + + if (![[lm textContainers] count]) return size; + NSTextContainer *tc = [[lm textContainers] objectAtIndex:0]; + + NSSize curSize = [self size]; + NSSize fitSize = curSize; + int fitRows = maxRows; + int fitCols = maxColumns; + + if (size.height < curSize.height) { + // Remove lines until the height of the text storage fits inside + // 'size'. However, always make sure there are at least 3 lines in the + // text storage. (Why 3? It seem Vim never allows less than 3 lines.) + // + // TODO: Use binary search instead of the current linear one. + NSRange charRange = { 0, maxRows*(maxColumns+1) }; + int rowsToRemove; + for (rowsToRemove = 0; rowsToRemove < maxRows-3; ++rowsToRemove) { + NSRange glyphRange = [lm glyphRangeForCharacterRange:charRange + actualCharacterRange:nil]; + NSRect rect = [lm boundingRectForGlyphRange:glyphRange + inTextContainer:tc]; + + if (rect.size.height <= size.height) { + fitSize.height = rect.size.height; + break; + } + + charRange.length -= (maxColumns+1); + } + + fitRows -= rowsToRemove; + } else if (size.height > curSize.height) { + float fh = [lm defaultLineHeightForFont:font]; + if (fh < 1.0f) fh = 1.0f; + + fitRows = floor(size.height/fh); + fitSize.height = fh*fitRows; + } + + if (size.width != curSize.width) { + float fw = maxColumns > 0 ? [self widthOfEmptyColumn]/maxColumns : 0; + if (fw < 1.0f) fw = 1.0f; + + fitCols = floor(size.width/fw); + fitSize.width = fw*fitCols; + } + + if (rows) *rows = fitRows; + if (columns) *columns = fitCols; + + return fitSize; +} + +@end // MMTextStorage (Private) diff --git a/MMTextView.h b/MMTextView.h new file mode 100644 index 0000000000..04905f1d26 --- /dev/null +++ b/MMTextView.h @@ -0,0 +1,28 @@ +/* vi:set ts=8 sts=4 sw=4 ft=objc: + * + * VIM - Vi IMproved by Bram Moolenaar + * MacVim GUI port by Bjorn Winckler + * + * Do ":help uganda" in Vim to read copying and usage conditions. + * Do ":help credits" in Vim to see a list of people who contributed. + * See README.txt for an overview of the Vim source code. + */ + +#import + + +@interface MMTextView : NSTextView { + BOOL ownsTextStorage; + int tabpageIdx; + NSPort *sendPort; + BOOL shouldDrawInsertionPoint; +} + +- (id)initWithPort:(NSPort *)port frame:(NSRect)frame + textContainer:(NSTextContainer *)tc; +- (MMTextView *)initWithFrame:(NSRect)frame port:(NSPort *)port; +- (void)setShouldDrawInsertionPoint:(BOOL)enable; + +@end + +// vim: set ft=objc : diff --git a/MMTextView.m b/MMTextView.m new file mode 100644 index 0000000000..4c990489fa --- /dev/null +++ b/MMTextView.m @@ -0,0 +1,401 @@ +/* vi:set ts=8 sts=4 sw=4 ft=objc: + * + * VIM - Vi IMproved by Bram Moolenaar + * MacVim GUI port by Bjorn Winckler + * + * Do ":help uganda" in Vim to read copying and usage conditions. + * Do ":help credits" in Vim to see a list of people who contributed. + * See README.txt for an overview of the Vim source code. + */ + +#import "MMTextView.h" +#import "MMTextStorage.h" +#import "MacVim.h" +#import "MMWindowController.h" + + + +@interface MMTextView (Private) +- (BOOL)convertPoint:(NSPoint)point toRow:(int *)row column:(int *)column; +- (void)dispatchKeyEvent:(NSEvent *)event; +@end + + + +@implementation MMTextView + +- (id)initWithPort:(NSPort *)port frame:(NSRect)frame + textContainer:(NSTextContainer *)tc +{ + if ((self = [super initWithFrame:frame textContainer:tc])) { + sendPort = [port retain]; + } + + return self; +} + +- (MMTextView *)initWithFrame:(NSRect)frame port:(NSPort *)port +{ + MMTextStorage *ts = [[MMTextStorage alloc] init]; + NSLayoutManager *lm = [[NSLayoutManager alloc] init]; + NSTextContainer *tc = [[NSTextContainer alloc] initWithContainerSize: + NSMakeSize(1.0e7,1.0e7)]; + + [tc setWidthTracksTextView:NO]; + [tc setHeightTracksTextView:NO]; + [tc setLineFragmentPadding:0]; + + [ts addLayoutManager:lm]; + [lm addTextContainer:tc]; + + [tc release]; + [lm release]; + + // HACK! Where should i get these values from? + // TODO: get values from frame + [ts setMaxRows:24 columns:80]; + + if ((self = [super initWithFrame:frame textContainer:tc])) { + ownsTextStorage = YES; + //[self setRichText:NO]; + sendPort = [port retain]; + } else { + ownsTextStorage = NO; + [ts release]; + } + + return self; +} + + +- (void)dealloc +{ + // BUG! The reference count of the text view will never reach 0 unless + // release is explicitly called on the text storage; so this code is + // meaningless. + if (ownsTextStorage) { + [[self textContainer] setTextView:nil]; + [[self textStorage] release]; + ownsTextStorage = NO; + } + + [sendPort release]; + + [super dealloc]; +} + +- (void)setShouldDrawInsertionPoint:(BOOL)enable +{ + shouldDrawInsertionPoint = enable; +} + +- (BOOL)shouldDrawInsertionPoint +{ + return shouldDrawInsertionPoint; +} + +- (void)insertText:(id)string +{ + // NOTE! This method is called for normal key presses but also for + // Option-key presses --- even when Ctrl is held as well as Option. When + // Ctrl is held, the AppKit translates the character to a Ctrl+key stroke, + // so 'string' need not be a printable character! In this case it still + // works to pass 'string' on to Vim as a printable character (since + // modifiers are already included and should not be added to the input + // buffer using CSI, K_MODIFIER). + + //NSLog(@"%s%@ (%x)", _cmd, string, [string characterAtIndex:0]); + + NSEvent *event = [NSApp currentEvent]; + if ([event type] == NSKeyDown) { + unsigned mods = [event modifierFlags]; + unichar c = [[event charactersIgnoringModifiers] characterAtIndex:0]; + + if (mods & (NSShiftKeyMask|NSControlKeyMask|NSAlternateKeyMask) + && ' ' == c) { + // HACK! In order to be able to bind to etc. we have to + // watch for when space was pressed. + [self dispatchKeyEvent:event]; + return; + } + } + + [NSCursor setHiddenUntilMouseMoves:YES]; + + [NSPortMessage sendMessage:InsertTextMsgID withSendPort:sendPort + data:[string dataUsingEncoding:NSUTF8StringEncoding] + wait:NO]; +} + + +- (void)doCommandBySelector:(SEL)selector +{ + // By ignoring the selector we effectively disable the key binding + // mechanism of Cocoa. Hopefully this is what the user will expect + // (pressing Ctrl+P would otherwise result in moveUp: instead of previous + // match, etc.). + // + // We usually end up here if the user pressed Ctrl+key (but not + // Ctrl+Option+key). + + [self dispatchKeyEvent:[NSApp currentEvent]]; +} + +- (BOOL)performKeyEquivalent:(NSEvent *)event +{ + // Called for Cmd+key keystrokes, function keys, arrow keys, page + // up/down, home, end. + + if ([event type] != NSKeyDown) + return NO; + + // HACK! Let the main menu try to handle any key down event, before + // passing it on to vim, otherwise key equivalents for menus will + // effectively be disabled. + if ([[NSApp mainMenu] performKeyEquivalent:event]) + return YES; + + // HACK! KeyCode 50 represent the key which switches between windows + // within an application (like Cmd+Tab is used to switch between + // applications). Return NO here, else the window switching does not work. + // + // Will this hack work for all languages / keyboard layouts? + if ([event keyCode] == 50) + return NO; + + //NSLog(@"%s%@", _cmd, event); + + NSMutableData *data = [NSMutableData data]; + NSString *string = [event charactersIgnoringModifiers]; + int flags = [event modifierFlags]; + int len = [string lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; + + [data appendBytes:&flags length:sizeof(int)]; + [data appendBytes:&len length:sizeof(int)]; + [data appendBytes:[string UTF8String] length:len]; + + [NSPortMessage sendMessage:CmdKeyMsgID withSendPort:sendPort data:data + wait:NO]; + + return YES; +} + +- (void)setMarkedText:(id)text selectedRange:(NSRange)range +{ + // TODO: Figure out a way to handle marked text, at the moment the user + // has no way of knowing what has been added so far in a multi-stroke key. + // E.g. hitting Option-e and then e will result in an 'e' with acute, but + // nothing is displayed immediately after hitting Option-e. + + NSLog(@"setMarkedText:'%@' selectedRange:(%d,%d)", text, range.location, + range.length); +} + +#if 0 +- (IBAction)copy:(id)sender +{ +} + +- (IBAction)paste:(id)sender +{ +} +#endif + +- (void)scrollWheel:(NSEvent *)event +{ + if ([event deltaY] == 0) + return; + + int row, col; + NSPoint pt = [self convertPoint:[event locationInWindow] fromView:nil]; + if (![self convertPoint:pt toRow:&row column:&col]) + return; + + int flags = [event modifierFlags]; + float dy = [event deltaY]; + NSMutableData *data = [NSMutableData data]; + + [data appendBytes:&row length:sizeof(int)]; + [data appendBytes:&col length:sizeof(int)]; + [data appendBytes:&flags length:sizeof(int)]; + [data appendBytes:&dy length:sizeof(float)]; + + [NSPortMessage sendMessage:ScrollWheelMsgID withSendPort:sendPort + data:data wait:NO]; +} + +- (void)mouseDown:(NSEvent *)event +{ + int row, col; + NSPoint pt = [self convertPoint:[event locationInWindow] fromView:nil]; + if (![self convertPoint:pt toRow:&row column:&col]) + return; + + int button = [event buttonNumber]; + int flags = [event modifierFlags]; + int count = [event clickCount]; + NSMutableData *data = [NSMutableData data]; + + [data appendBytes:&row length:sizeof(int)]; + [data appendBytes:&col length:sizeof(int)]; + [data appendBytes:&button length:sizeof(int)]; + [data appendBytes:&flags length:sizeof(int)]; + [data appendBytes:&count length:sizeof(int)]; + + [NSPortMessage sendMessage:MouseDownMsgID withSendPort:sendPort + data:data wait:NO]; +} + +- (void)rightMouseDown:(NSEvent *)event +{ + [self mouseDown:event]; +} + +- (void)otherMouseDown:(NSEvent *)event +{ + [self mouseDown:event]; +} + +- (void)mouseUp:(NSEvent *)event +{ + int row, col; + NSPoint pt = [self convertPoint:[event locationInWindow] fromView:nil]; + if (![self convertPoint:pt toRow:&row column:&col]) + return; + + int flags = [event modifierFlags]; + NSMutableData *data = [NSMutableData data]; + + [data appendBytes:&row length:sizeof(int)]; + [data appendBytes:&col length:sizeof(int)]; + [data appendBytes:&flags length:sizeof(int)]; + + [NSPortMessage sendMessage:MouseUpMsgID withSendPort:sendPort + data:data wait:NO]; +} + +- (void)rightMouseUp:(NSEvent *)event +{ + [self mouseUp:event]; +} + +- (void)otherMouseUp:(NSEvent *)event +{ + [self mouseUp:event]; +} + +- (void)mouseDragged:(NSEvent *)event +{ + int row, col; + NSPoint pt = [self convertPoint:[event locationInWindow] fromView:nil]; + if (![self convertPoint:pt toRow:&row column:&col]) + return; + + int flags = [event modifierFlags]; + NSMutableData *data = [NSMutableData data]; + + [data appendBytes:&row length:sizeof(int)]; + [data appendBytes:&col length:sizeof(int)]; + [data appendBytes:&flags length:sizeof(int)]; + + [NSPortMessage sendMessage:MouseDraggedMsgID withSendPort:sendPort + data:data wait:NO]; +} + +- (void)rightMouseDragged:(NSEvent *)event +{ + [self mouseDragged:event]; +} + +- (void)otherMouseDragged:(NSEvent *)event +{ + [self mouseDragged:event]; +} + +#if 0 +- (void)menuForEvent:(NSEvent *)event +{ + // TODO: Enabling this causes a crash at the moment. Why? + // + // Called when user Ctrl-clicks in the view + [self mouseDown:event]; +} +#endif + +@end // MMTextView + + + + +@implementation MMTextView (Private) + +- (BOOL)convertPoint:(NSPoint)point toRow:(int *)row column:(int *)column +{ + NSLayoutManager *lm = [self layoutManager]; + NSTextContainer *tc = [self textContainer]; + MMTextStorage *ts = (MMTextStorage*)[self textStorage]; + + if (!(lm && tc && ts)) + return NO; + + unsigned glyphIdx = [lm glyphIndexForPoint:point inTextContainer:tc]; + unsigned charIdx = [lm characterIndexForGlyphAtIndex:glyphIdx]; + + int mod = [ts maxColumns] + 1; + + if (row) *row = (int)(charIdx / mod); + if (column) *column = (int)(charIdx % mod); + + return YES; +} + +- (void)dispatchKeyEvent:(NSEvent *)event +{ + // Only handle the command if it came from a keyDown event + if ([event type] != NSKeyDown) + return; + + //NSLog(@"%s%@", _cmd, event); + + NSString *chars = [event characters]; + NSString *imchars = [event charactersIgnoringModifiers]; + unichar c = [chars characterAtIndex:0]; + unichar imc = [imchars characterAtIndex:0]; + int len = 0; + const char *bytes = 0; + + if (' ' == imc && 0xa0 != c) { + // HACK! The AppKit turns into which is not standard + // Vim behaviour, so bypass this problem. (0xa0 is , which + // should be passed on as is.) + len = [imchars lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; + bytes = [imchars UTF8String]; + } else if (imc == c && '2' == c) { + // HACK! Translate Ctrl+2 to . + static char ctrl_at = 0; + len = 1; bytes = &ctrl_at; + } else if (imc == c && '6' == c) { + // HACK! Translate Ctrl+6 to . + static char ctrl_hat = 0x1e; + len = 1; bytes = &ctrl_hat; + } else { + len = [chars lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; + bytes = [chars UTF8String]; + } + + if (len > 0 && bytes) { + NSMutableData *data = [NSMutableData data]; + int flags = [event modifierFlags]; + + [data appendBytes:&flags length:sizeof(int)]; + [data appendBytes:&len length:sizeof(int)]; + [data appendBytes:bytes length:len]; + + [NSCursor setHiddenUntilMouseMoves:YES]; + + [NSPortMessage sendMessage:KeyDownMsgID withSendPort:sendPort data:data + wait:NO]; + } +} + +@end // MMTextView (Private) diff --git a/MMVimController.h b/MMVimController.h new file mode 100644 index 0000000000..19da37f264 --- /dev/null +++ b/MMVimController.h @@ -0,0 +1,34 @@ +/* vi:set ts=8 sts=4 sw=4 ft=objc: + * + * VIM - Vi IMproved by Bram Moolenaar + * MacVim GUI port by Bjorn Winckler + * + * Do ":help uganda" in Vim to read copying and usage conditions. + * Do ":help credits" in Vim to see a list of people who contributed. + * See README.txt for an overview of the Vim source code. + */ + +#import + +@class MMWindowController; + + + +@interface MMVimController : NSObject { + MMWindowController *windowController; + NSPort *sendPort; + NSPort *receivePort; + NSMutableArray *mainMenuItems; + BOOL shouldUpdateMainMenu; + //NSMutableArray *popupMenus; + NSToolbar *toolbar; + NSMutableDictionary *toolbarItemDict; +} + +- (id)initWithPort:(NSPort *)port; +- (void)windowWillClose:(NSNotification *)notification; +- (NSPort *)sendPort; + +@end + +// vim: set ft=objc: diff --git a/MMVimController.m b/MMVimController.m new file mode 100644 index 0000000000..cd7e44451c --- /dev/null +++ b/MMVimController.m @@ -0,0 +1,819 @@ +/* vi:set ts=8 sts=4 sw=4 ft=objc: + * + * VIM - Vi IMproved by Bram Moolenaar + * MacVim GUI port by Bjorn Winckler + * + * Do ":help uganda" in Vim to read copying and usage conditions. + * Do ":help credits" in Vim to see a list of people who contributed. + * See README.txt for an overview of the Vim source code. + */ + +#import "MMVimController.h" +#import "MMWindowController.h" +#import "MacVim.h" +#import "MMAppController.h" +#import "MMTextView.h" +#import "MMTextStorage.h" + + +//static NSString *AttentionToolbarItemID = @"Attention"; +static NSString *DefaultToolbarImageName = @"Attention"; + + +@interface MMVimController (Private) +- (void)handleMessage:(int)msgid data:(NSData *)data; +- (void)performBatchDrawWithData:(NSData *)data; +- (void)panelDidEnd:(NSSavePanel *)panel code:(int)code + context:(void *)context; +- (NSMenuItem *)menuItemForTag:(int)tag; +- (NSMenu *)menuForTag:(int)tag; +- (void)updateMainMenu; +- (NSToolbarItem *)toolbarItemForTag:(int)tag index:(int *)index; +- (IBAction)toolbarAction:(id)sender; +- (void)addToolbarItemToDictionaryWithTag:(int)tag label:(NSString *)title + toolTip:(NSString *)tip icon:(NSString *)icon; +@end + + + +// TODO: Move to separate file +@interface NSColor (MMProtocol) ++ (NSColor *)colorWithRgbInt:(int)rgb; +@end + + + +static NSMenuItem *findMenuItemWithTagInMenu(NSMenu *root, int tag) +{ + if (root) { + NSMenuItem *item = [root itemWithTag:tag]; + if (item) return item; + + NSArray *items = [root itemArray]; + unsigned i, count = [items count]; + for (i = 0; i < count; ++i) { + item = [items objectAtIndex:i]; + if ([item hasSubmenu]) { + item = findMenuItemWithTagInMenu([item submenu], tag); + if (item) return item; + } + } + } + + return nil; +} + + + +@implementation MMVimController + +- (id)initWithPort:(NSPort *)port +{ + if ((self = [super init])) { + windowController = [[MMWindowController alloc] initWithPort:port]; + + mainMenuItems = [[NSMutableArray alloc] init]; + + toolbarItemDict = [[NSMutableDictionary alloc] init]; + //[self addToolbarItemToDictionaryWithTag:0 label:@"Attention" + // toolTip:@"A toolbar item is missing" + // icon:@"Attention"]; + + [[NSNotificationCenter defaultCenter] + addObserver:self + selector:@selector(windowWillClose:) + name:NSWindowWillCloseNotification + object:[windowController window]]; + [[NSNotificationCenter defaultCenter] + addObserver:self + selector:@selector(windowDidBecomeMain:) + name:NSWindowDidBecomeMainNotification + object:[windowController window]]; + + sendPort = [port retain]; + + // Init receive port and send connected message to VimTask + receivePort = [NSMachPort new]; + [receivePort setDelegate:self]; + + // Add to the default run loop mode as well as the event tracking mode; + // the latter ensures that updates from the VimTask reaches + // MMVimController whilst the user resizes a window with the mouse. + [[NSRunLoop currentRunLoop] addPort:receivePort + forMode:NSDefaultRunLoopMode]; + [[NSRunLoop currentRunLoop] addPort:receivePort + forMode:NSEventTrackingRunLoopMode]; + + [NSPortMessage sendMessage:ConnectedMsgID withSendPort:sendPort + receivePort:receivePort wait:YES]; + } + + return self; +} + +- (void)dealloc +{ + if (sendPort) { + // Kill task immediately + [NSPortMessage sendMessage:KillTaskMsgID withSendPort:sendPort + receivePort:receivePort wait:NO]; + } + + [[NSNotificationCenter defaultCenter] removeObserver:self]; + + [toolbarItemDict release]; + [toolbar release]; + [mainMenuItems release]; + [windowController release]; + [sendPort release]; + [receivePort release]; + + [super dealloc]; +} + +- (NSPort *)sendPort +{ + return sendPort; +} + +- (void)handlePortMessage:(NSPortMessage *)portMessage +{ + NSArray *components = [portMessage components]; + unsigned msgid = [portMessage msgid]; + + //NSLog(@"%s%d", _cmd, msgid); + + if (FlushQueueMsgID == msgid) { + unsigned i, count = [components count]; + if (count % 2) { + NSLog(@"WARNING: Uneven number of components (%d) in flush queue " + "message; ignoring this message.", count); + return; + } + + for (i = 0; i < count; i += 2) { + NSData *value = [components objectAtIndex:i]; + NSData *data = [components objectAtIndex:i+1]; + + [self handleMessage:*((int*)[value bytes]) data:data]; + } + } else { + NSData *data = nil; + if ([components count] > 0) + data = [components objectAtIndex:0]; + + [self handleMessage:msgid data:data]; + } + + if (shouldUpdateMainMenu) + [self updateMainMenu]; +} + +- (void)windowWillClose:(NSNotification *)notification +{ + // NOTE! This causes the call to removeVimController: to be delayed. + [[NSApp delegate] + performSelectorOnMainThread:@selector(removeVimController:) + withObject:self waitUntilDone:NO]; +} + +- (void)windowDidBecomeMain:(NSNotification *)notification +{ + [self updateMainMenu]; +} + +- (NSToolbarItem *)toolbar:(NSToolbar *)theToolbar + itemForItemIdentifier:(NSString *)itemId + willBeInsertedIntoToolbar:(BOOL)flag +{ + //NSLog(@"%s", _cmd); + + NSToolbarItem *item = [toolbarItemDict objectForKey:itemId]; + if (!item) { + NSLog(@"WARNING: No toolbar item with id '%@'", itemId); + } + + return item; +} + +- (NSArray *)toolbarAllowedItemIdentifiers:(NSToolbar *)theToolbar +{ + //NSLog(@"%s", _cmd); + return nil; +} + +- (NSArray *)toolbarDefaultItemIdentifiers:(NSToolbar *)theToolbar +{ + //NSLog(@"%s", _cmd); + return nil; +} + +@end // MMVimController + + + +@implementation MMVimController (Private) + +- (void)handleMessage:(int)msgid data:(NSData *)data +{ + if (OpenVimWindowMsgID == msgid) { + const void *bytes = [data bytes]; + int rows = *((int*)bytes); bytes += sizeof(int); + int cols = *((int*)bytes); bytes += sizeof(int); + + //NSLog(@"Received open VimWindow (%dx%d) message from VimTask.", + // cols, rows); + + [windowController openWindowWithRows:rows columns:cols]; + } else if (TaskExitedMsgID == msgid) { + //NSLog(@"Received task exited message from VimTask; closing window."); + + // Release sendPort immediately to avoid dealloc trying to send a 'kill + // task' message to the task. + [sendPort release]; sendPort = nil; + // NOTE! This causes windowWillClose: to be called, which in turn asks + // the MMAppController to remove this MMVimController. + [windowController close]; + + // HACK! Make sure no menu updating is done, we're about to close. + shouldUpdateMainMenu = NO; + } else if (BatchDrawMsgID == msgid) { + //NSLog(@"Received batch draw message from VimTask."); + + [self performBatchDrawWithData:data]; + } else if (SelectTabMsgID == msgid) { + const void *bytes = [data bytes]; + int idx = *((int*)bytes); + //NSLog(@"Selecting tab with index %d", idx); + [windowController selectTabWithIndex:idx]; + } else if (UpdateTabBarMsgID == msgid) { + //NSLog(@"Updating tabs"); + [windowController updateTabsWithData:data]; + } else if (ShowTabBarMsgID == msgid) { + //NSLog(@"Showing tab bar"); + + // The tab bar has it's own baseline separator, so hide the one + // belonging to the toolbar whenever the tab bar is visible. + // BUG: The window auto shows the separator when clicking the show/hide + // toolbar button. + [toolbar setShowsBaselineSeparator:NO]; + + // HACK! Vim sends several draw commands etc. after the show message + // and these can mess up the display when showing the tab bar results + // in the window having to resize to fit the screen; delaying this + // message alleviates this problem. + [windowController performSelectorOnMainThread:@selector(showTabBar:) + withObject:self waitUntilDone:NO]; + //[windowController showTabBar:self]; + } else if (HideTabBarMsgID == msgid) { + //NSLog(@"Hiding tab bar"); + + // The tab bar has it's own baseline separator, so hide the one + // belonging to the toolbar whenever the tab bar is visible. + // BUG: The window auto shows the separator when clicking the show/hide + // toolbar button. + [toolbar setShowsBaselineSeparator:YES]; + + [windowController hideTabBar:self]; + } else if (SetTextDimensionsMsgID == msgid) { + const void *bytes = [data bytes]; + int rows = *((int*)bytes); bytes += sizeof(int); + int cols = *((int*)bytes); bytes += sizeof(int); + + [windowController setTextDimensionsWithRows:rows columns:cols]; + } else if (SetVimWindowTitleMsgID == msgid) { + const void *bytes = [data bytes]; + int len = *((int*)bytes); bytes += sizeof(int); + +#if 0 + // BUG! Using this call leads to ALL windows getting the same title + // and then the app crashes if you :q a window. + NSString *string = [[NSString alloc] + initWithBytesNoCopy:(void*)bytes + length:len + encoding:NSUTF8StringEncoding + freeWhenDone:NO]; +#else + NSString *string = [[NSString alloc] initWithBytes:(void*)bytes + length:len encoding:NSUTF8StringEncoding]; +#endif + + [[windowController window] setTitle:string]; + + [string release]; + } else if (BrowseForFileMsgID == msgid) { + const void *bytes = [data bytes]; + int save = *((int*)bytes); bytes += sizeof(int); + + int len = *((int*)bytes); bytes += sizeof(int); + NSString *dir = nil; + if (len > 0) { + dir = [[NSString alloc] initWithBytes:(void*)bytes + length:len + encoding:NSUTF8StringEncoding]; + bytes += len; + } + + len = *((int*)bytes); bytes += sizeof(int); + if (len > 0) { + NSString *title = [[NSString alloc] + initWithBytes:(void*)bytes length:len + encoding:NSUTF8StringEncoding]; + bytes += len; + + [windowController setStatusText:title]; + [title release]; + } + + if (save) { + [[NSSavePanel savePanel] beginSheetForDirectory:dir file:nil + modalForWindow:[windowController window] + modalDelegate:self + didEndSelector:@selector(panelDidEnd:code:context:) + contextInfo:NULL]; + } else { + NSOpenPanel *panel = [NSOpenPanel openPanel]; + [panel setAllowsMultipleSelection:NO]; + [panel beginSheetForDirectory:dir file:nil types:nil + modalForWindow:[windowController window] + modalDelegate:self + didEndSelector:@selector(panelDidEnd:code:context:) + contextInfo:NULL]; + } + + [dir release]; + } else if (UpdateInsertionPointMsgID == msgid) { + const void *bytes = [data bytes]; + int color = *((int*)bytes); bytes += sizeof(int); + int row = *((int*)bytes); bytes += sizeof(int); + int col = *((int*)bytes); bytes += sizeof(int); + int state = *((int*)bytes); bytes += sizeof(int); + + // TODO! Move to window controller. + MMTextView *textView = [windowController textView]; + if (textView) { + MMTextStorage *textStorage = (MMTextStorage*)[textView textStorage]; + unsigned off = [textStorage offsetFromRow:row column:col]; + + [textView setInsertionPointColor:[NSColor colorWithRgbInt:color]]; + [textView setSelectedRange:NSMakeRange(off, 0)]; + [textView setShouldDrawInsertionPoint:state]; + } + } else if (AddMenuMsgID == msgid) { + NSString *title = nil; + const void *bytes = [data bytes]; + int tag = *((int*)bytes); bytes += sizeof(int); + int parentTag = *((int*)bytes); bytes += sizeof(int); + int len = *((int*)bytes); bytes += sizeof(int); + if (len > 0) { + title = [[NSString alloc] initWithBytes:(void*)bytes length:len + encoding:NSUTF8StringEncoding]; + bytes += len; + } + int idx = *((int*)bytes); bytes += sizeof(int); + + if (MenuToolbarType == parentTag) { + if (!toolbar) { + NSString *ident = [NSString stringWithFormat:@"%d.%d", + (int)self, tag]; + //NSLog(@"Creating toolbar with identifier %@", ident); + toolbar = [[NSToolbar alloc] initWithIdentifier:ident]; + + [toolbar setDelegate:self]; + [toolbar setDisplayMode:NSToolbarDisplayModeIconOnly]; + [toolbar setSizeMode:NSToolbarSizeModeSmall]; + + [[windowController window] setToolbar:toolbar]; + } + } else if (MenuPopupType == parentTag) { + // TODO! + } else if (title) { + NSMenuItem *item = [[NSMenuItem alloc] init]; + NSMenu *menu = [[NSMenu alloc] initWithTitle:title]; + + [menu setAutoenablesItems:NO]; + [item setTag:tag]; + [item setTitle:title]; + [item setSubmenu:menu]; + + NSMenu *parent = [self menuForTag:parentTag]; + if (parent) { + if ([parent numberOfItems] <= idx) { + [parent addItem:item]; + } else { + [parent insertItem:item atIndex:idx]; + } + } else { + if ([mainMenuItems count] <= idx) { + [mainMenuItems addObject:item]; + } else { + [mainMenuItems insertObject:item atIndex:idx]; + } + + shouldUpdateMainMenu = YES; + } + + [item release]; + [menu release]; + } + + [title release]; + } else if (AddMenuItemMsgID == msgid) { + NSString *title = nil, *tip = nil, *icon = nil; + const void *bytes = [data bytes]; + int tag = *((int*)bytes); bytes += sizeof(int); + int parentTag = *((int*)bytes); bytes += sizeof(int); + int namelen = *((int*)bytes); bytes += sizeof(int); + if (namelen > 0) { + title = [[NSString alloc] initWithBytes:(void*)bytes length:namelen + encoding:NSUTF8StringEncoding]; + bytes += namelen; + } + int tiplen = *((int*)bytes); bytes += sizeof(int); + if (tiplen > 0) { + tip = [[NSString alloc] initWithBytes:(void*)bytes length:tiplen + encoding:NSUTF8StringEncoding]; + bytes += tiplen; + } + int iconlen = *((int*)bytes); bytes += sizeof(int); + if (iconlen > 0) { + icon = [[NSString alloc] initWithBytes:(void*)bytes length:iconlen + encoding:NSUTF8StringEncoding]; + bytes += iconlen; + } + int idx = *((int*)bytes); bytes += sizeof(int); + if (idx < 0) idx = 0; + + NSString *ident = [NSString stringWithFormat:@"%d.%d", + (int)self, parentTag]; + if (toolbar && [[toolbar identifier] isEqual:ident]) { + //NSLog(@"Toolbar add: title=%@ icon=%@ tip=%@", title, icon, tip); + [self addToolbarItemToDictionaryWithTag:tag label:title toolTip:tip + icon:icon]; + + int maxIdx = [[toolbar items] count]; + if (maxIdx < idx) idx = maxIdx; + + // If 'title' is nul, insert a separator. + if (!title) title = NSToolbarSeparatorItemIdentifier; + [toolbar insertItemWithItemIdentifier:title atIndex:idx]; + } else { + NSMenu *parent = [self menuForTag:parentTag]; + if (parent) { + NSMenuItem *item = nil; + if (title) { + item = [[[NSMenuItem alloc] init] autorelease]; + [item setTag:tag]; + [item setTitle:title]; + [item setAction:@selector(vimMenuItemAction:)]; + if (tip) [item setToolTip:tip]; + } else { + item = [NSMenuItem separatorItem]; + } + + if ([parent numberOfItems] <= idx) { + [parent addItem:item]; + } else { + [parent insertItem:item atIndex:idx]; + } + } + } + + [title release]; + [tip release]; + } else if (RemoveMenuItemMsgID == msgid) { + const void *bytes = [data bytes]; + int tag = *((int*)bytes); bytes += sizeof(int); + + // TODO: Search for tag in popup menus. + id item; + int idx; + if ((item = [self toolbarItemForTag:tag index:&idx])) { + [toolbar removeItemAtIndex:idx]; + } else if ((item = [self menuItemForTag:tag])) { + if ([item menu] == [NSApp mainMenu]) { + [mainMenuItems removeObject:item]; + } + [[item menu] removeItem:item]; + } + } else if (EnableMenuItemMsgID == msgid) { + const void *bytes = [data bytes]; + int tag = *((int*)bytes); bytes += sizeof(int); + int state = *((int*)bytes); bytes += sizeof(int); + + // TODO: Search for tag in popup menus. + id item = [self toolbarItemForTag:tag index:NULL]; + if (!item) + item = [self menuItemForTag:tag]; + + [item setEnabled:state]; + } else if (ShowToolbarMsgID == msgid) { + const void *bytes = [data bytes]; + int enable = *((int*)bytes); bytes += sizeof(int); + int flags = *((int*)bytes); bytes += sizeof(int); + + int mode = NSToolbarDisplayModeDefault; + if (flags & ToolbarLabelFlag) { + mode = flags & ToolbarIconFlag ? NSToolbarDisplayModeIconAndLabel + : NSToolbarDisplayModeLabelOnly; + } else if (flags & ToolbarIconFlag) { + mode = NSToolbarDisplayModeIconOnly; + } + + int size = flags & ToolbarSizeRegularFlag ? NSToolbarSizeModeRegular + : NSToolbarSizeModeSmall; + + [toolbar setSizeMode:size]; + [toolbar setDisplayMode:mode]; + [toolbar setVisible:enable]; + } else if (CreateScrollbarMsgID == msgid) { + const void *bytes = [data bytes]; + long ident = *((long*)bytes); bytes += sizeof(long); + int type = *((int*)bytes); bytes += sizeof(int); + + [windowController createScrollbarWithIdentifier:ident type:type]; + } else if (DestroyScrollbarMsgID == msgid) { + const void *bytes = [data bytes]; + long ident = *((long*)bytes); bytes += sizeof(long); + + [windowController destroyScrollbarWithIdentifier:ident]; + } else if (ShowScrollbarMsgID == msgid) { + const void *bytes = [data bytes]; + long ident = *((long*)bytes); bytes += sizeof(long); + int visible = *((int*)bytes); bytes += sizeof(int); + + [windowController showScrollbarWithIdentifier:ident state:visible]; + } else if (SetScrollbarPositionMsgID == msgid) { + const void *bytes = [data bytes]; + long ident = *((long*)bytes); bytes += sizeof(long); + int pos = *((int*)bytes); bytes += sizeof(int); + int len = *((int*)bytes); bytes += sizeof(int); + + [windowController setScrollbarPosition:pos length:len + identifier:ident]; + } else if (SetScrollbarThumbMsgID == msgid) { + const void *bytes = [data bytes]; + long ident = *((long*)bytes); bytes += sizeof(long); + float val = *((float*)bytes); bytes += sizeof(float); + float prop = *((float*)bytes); bytes += sizeof(float); + + [windowController setScrollbarThumbValue:val proportion:prop + identifier:ident]; + } else if (SetFontMsgID == msgid) { + const void *bytes = [data bytes]; + float size = *((float*)bytes); bytes += sizeof(float); + int len = *((int*)bytes); bytes += sizeof(int); + NSString *name = [[NSString alloc] + initWithBytes:(void*)bytes length:len + encoding:NSUTF8StringEncoding]; + NSFont *font = [NSFont fontWithName:name size:size]; + + if (font && [windowController textStorage]) { + [[windowController textStorage] setFont:font]; + } + + [name release]; + } else { + NSLog(@"WARNING: Unknown message received (msgid=%d)", msgid); + } +} + +- (void)performBatchDrawWithData:(NSData *)data +{ + // TODO! Move to window controller. + MMTextStorage *textStorage = [windowController textStorage]; + if (!textStorage) + return; + + const void *bytes = [data bytes]; + const void *end = bytes + [data length]; + + [textStorage beginEditing]; + + // TODO: + // 1. Sanity check input + // 2. Cache rgb -> NSColor lookups? + + while (bytes < end) { + int type = *((int*)bytes); bytes += sizeof(int); + int rows = *((int*)bytes); bytes += sizeof(int); + int cols = *((int*)bytes); bytes += sizeof(int); + + if (ClearAllDrawType != type) { + // All draw types except clear all rely on the text storage have + // the appropriate dimensions, so set it before attempting to + // modify the text storage. + [textStorage setMaxRows:rows columns:cols]; + } + + if (ClearAllDrawType == type) { + int color = *((int*)bytes); bytes += sizeof(int); + + [textStorage clearAllWithColor:[NSColor colorWithRgbInt:color]]; + } else if (ClearBlockDrawType == type) { + int color = *((int*)bytes); bytes += sizeof(int); + int row1 = *((int*)bytes); bytes += sizeof(int); + int col1 = *((int*)bytes); bytes += sizeof(int); + int row2 = *((int*)bytes); bytes += sizeof(int); + int col2 = *((int*)bytes); bytes += sizeof(int); + + [textStorage clearBlockFromRow:row1 column:col1 + toRow:row2 column:col2 + color:[NSColor colorWithRgbInt:color]]; + } else if (DeleteLinesDrawType == type) { + int color = *((int*)bytes); bytes += sizeof(int); + int row = *((int*)bytes); bytes += sizeof(int); + int count = *((int*)bytes); bytes += sizeof(int); + int bot = *((int*)bytes); bytes += sizeof(int); + int left = *((int*)bytes); bytes += sizeof(int); + int right = *((int*)bytes); bytes += sizeof(int); + + [textStorage deleteLinesFromRow:row lineCount:count + scrollBottom:bot left:left right:right + color:[NSColor colorWithRgbInt:color]]; + } else if (ReplaceStringDrawType == type) { + int bg = *((int*)bytes); bytes += sizeof(int); + int fg = *((int*)bytes); bytes += sizeof(int); + int row = *((int*)bytes); bytes += sizeof(int); + int col = *((int*)bytes); bytes += sizeof(int); + int flags = *((int*)bytes); bytes += sizeof(int); + int len = *((int*)bytes); bytes += sizeof(int); + NSString *string = [[NSString alloc] + initWithBytesNoCopy:(void*)bytes + length:len + encoding:NSUTF8StringEncoding + freeWhenDone:NO]; + bytes += len; + + [textStorage replaceString:string + atRow:row column:col + withFlags:flags + foregroundColor:[NSColor colorWithRgbInt:fg] + backgroundColor:[NSColor colorWithRgbInt:bg]]; + + [string release]; + } else if (InsertLinesDrawType == type) { + int color = *((int*)bytes); bytes += sizeof(int); + int row = *((int*)bytes); bytes += sizeof(int); + int count = *((int*)bytes); bytes += sizeof(int); + int bot = *((int*)bytes); bytes += sizeof(int); + int left = *((int*)bytes); bytes += sizeof(int); + int right = *((int*)bytes); bytes += sizeof(int); + + [textStorage insertLinesAtRow:row lineCount:count + scrollBottom:bot left:left right:right + color:[NSColor colorWithRgbInt:color]]; + } else { + NSLog(@"WARNING: Unknown draw type (type=%d)", type); + } + } + + [textStorage endEditing]; +} + +- (void)panelDidEnd:(NSSavePanel *)panel code:(int)code context:(void *)context +{ + NSMutableData *data = [NSMutableData data]; + int ok = (code == NSOKButton); + NSString *filename = [panel filename]; + int len = [filename lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; + + [data appendBytes:&ok length:sizeof(int)]; + [data appendBytes:&len length:sizeof(int)]; + if (len > 0) + [data appendBytes:[filename UTF8String] length:len]; + + if (![NSPortMessage sendMessage:BrowseForFileReplyMsgID + withSendPort:sendPort data:data wait:YES]) { + NSLog(@"WARNING: Failed to send browse for files reply back to " + "VimTask."); + } + + [windowController setStatusText:@""]; +} + +- (NSMenuItem *)menuItemForTag:(int)tag +{ + int i, count = [mainMenuItems count]; + for (i = 0; i < count; ++i) { + NSMenuItem *item = [mainMenuItems objectAtIndex:i]; + if ([item tag] == tag) return item; + item = findMenuItemWithTagInMenu([item submenu], tag); + if (item) return item; + } + + return nil; +} + +- (NSMenu *)menuForTag:(int)tag +{ + return [[self menuItemForTag:tag] submenu]; +} + +- (void)updateMainMenu +{ + shouldUpdateMainMenu = NO; + + // HACK! Add the vim menu named 'Window' as the submenu with index 5 of an + // already existing menu with the same name. The 'Window' menu is set up + // in Interface Builder. + NSMenu *mainMenu = [NSApp mainMenu]; + NSMenu *windowMenu = nil; + + // Remove all existing menus, except for 'Window'. + int i, count = [mainMenu numberOfItems]; + for (i = count-1; i > 0; --i) { + NSMenuItem *item = [mainMenu itemAtIndex:i]; + NSMenu *submenu = [item submenu]; + if ([[submenu title] isEqual:@"Window"]) { + windowMenu = submenu; + } else { + [mainMenu removeItem:item]; + } + } + + // Add menus from 'mainMenuItems' + count = [mainMenuItems count]; + for (i = 0; i < count; ++i) { + NSMenuItem *item = [mainMenuItems objectAtIndex:i]; + + if (windowMenu && [windowMenu numberOfItems] > 6 + && [[item title] isEqual:@"Window"]) { + // Item 5 of the Window menu is replaced with vim's Window menu. + [windowMenu removeItemAtIndex:5]; + [windowMenu insertItem:item atIndex:5]; + } else { + [mainMenu insertItem:item atIndex:i+1]; + } + } +} + +- (NSToolbarItem *)toolbarItemForTag:(int)tag index:(int *)index +{ + if (!toolbar) return nil; + + NSArray *items = [toolbar items]; + int i, count = [items count]; + for (i = 0; i < count; ++i) { + NSToolbarItem *item = [items objectAtIndex:i]; + if ([item tag] == tag) { + if (index) *index = i; + return item; + } + } + + return nil; +} + +- (IBAction)toolbarAction:(id)sender +{ + NSLog(@"%s%@", _cmd, sender); +} + +- (void)addToolbarItemToDictionaryWithTag:(int)tag label:(NSString *)title + toolTip:(NSString *)tip icon:(NSString *)icon +{ + // NOTE! 'title' is nul for separator item. Since this is already defined + // by Coca, we don't need to do anything here. + if (!title) return; + + NSToolbarItem *item = [[NSToolbarItem alloc] initWithItemIdentifier:title]; + [item setTag:tag]; + [item setLabel:title]; + [item setToolTip:tip]; + [item setAction:@selector(vimMenuItemAction:)]; + [item setAutovalidates:NO]; + + NSImage *img = [NSImage imageNamed:icon]; + if (!img) { + NSLog(@"WARNING: Could not find image with name '%@' to use as toolbar" + " image for identifier '%@';" + " using default toolbar icon '%@' instead.", + icon, title, DefaultToolbarImageName); + + img = [NSImage imageNamed:DefaultToolbarImageName]; + } + + [item setImage:img]; + + [toolbarItemDict setObject:item forKey:title]; + + [item release]; +} + +@end // MMVimController (Private) + + + +@implementation NSColor (MMProtocol) + ++ (NSColor *)colorWithRgbInt:(int)rgb +{ + float r = ((rgb>>16) & 0xff)/255.0f; + float g = ((rgb>>8) & 0xff)/255.0f; + float b = (rgb & 0xff)/255.0f; + + return [NSColor colorWithCalibratedRed:r green:g blue:b alpha:1.0f]; +} + +@end // NSColor (MMProtocol) diff --git a/MMWindowController.h b/MMWindowController.h new file mode 100644 index 0000000000..8afa6df892 --- /dev/null +++ b/MMWindowController.h @@ -0,0 +1,54 @@ +/* vi:set ts=8 sts=4 sw=4 ft=objc: + * + * VIM - Vi IMproved by Bram Moolenaar + * MacVim GUI port by Bjorn Winckler + * + * Do ":help uganda" in Vim to read copying and usage conditions. + * Do ":help credits" in Vim to see a list of people who contributed. + * See README.txt for an overview of the Vim source code. + */ + +#import + +@class PSMTabBarControl; +@class MMTextView; +@class MMTextStorage; + + +@interface MMWindowController : NSWindowController +{ + IBOutlet PSMTabBarControl *tabBarControl; + IBOutlet NSTabView *tabView; + IBOutlet NSTextField *statusTextField; + NSPort *sendPort; + BOOL vimTaskSelectedTab; + NSTimer *statusTimer; + MMTextView *textView; + MMTextStorage *textStorage; + NSMutableArray *scrollbars; + BOOL setupDone; +} + +- (id)initWithPort:(NSPort *)port; +- (MMTextView *)textView; +- (MMTextStorage *)textStorage; +- (void)openWindowWithRows:(int)rows columns:(int)cols; +- (void)updateTabsWithData:(NSData *)data; +- (void)selectTabWithIndex:(int)idx; +- (void)setTextDimensionsWithRows:(int)rows columns:(int)cols; +- (void)setStatusText:(NSString *)text; +- (void)flashStatusText:(NSString *)text; +- (void)createScrollbarWithIdentifier:(long)ident type:(int)type; +- (void)destroyScrollbarWithIdentifier:(long)ident; +- (void)showScrollbarWithIdentifier:(long)ident state:(BOOL)visible; +- (void)setScrollbarPosition:(int)pos length:(int)len identifier:(long)ident; +- (void)setScrollbarThumbValue:(float)val proportion:(float)prop + identifier:(long)ident; + +- (IBAction)addNewTab:(id)sender; +- (IBAction)showTabBar:(id)sender; +- (IBAction)hideTabBar:(id)sender; + +@end + +// vim: set ft=objc: diff --git a/MMWindowController.m b/MMWindowController.m new file mode 100644 index 0000000000..efaad4eadd --- /dev/null +++ b/MMWindowController.m @@ -0,0 +1,987 @@ +/* vi:set ts=8 sts=4 sw=4 ft=objc: + * + * VIM - Vi IMproved by Bram Moolenaar + * MacVim GUI port by Bjorn Winckler + * + * Do ":help uganda" in Vim to read copying and usage conditions. + * Do ":help credits" in Vim to see a list of people who contributed. + * See README.txt for an overview of the Vim source code. + */ + +#import "MMWindowController.h" +#import +#import "MMTextView.h" +#import "MMTextStorage.h" +#import "MacVim.h" + + +// Scroller type; these must match SBAR_* in gui.h +enum { + MMScrollerTypeLeft = 0, + MMScrollerTypeRight, + MMScrollerTypeBottom +}; + +// TODO! Implement hiding/showing of status line. +static float StatusLineHeight = 16.0f; +static BOOL statusLineIsVisible = YES; // NO is _not_ supported at the moment! + + +// TODO: Move! +@interface NSTabView (MMExtras) +- (void)removeAllTabViewItems; +@end + + +// TODO: Move! +@interface MMScroller : NSScroller { + long identifier; + int type; + NSRange range; +} +- (id)initWithIdentifier:(long)ident type:(int)type; +- (long)identifier; +- (int)type; +- (NSRange)range; +- (void)setRange:(NSRange)newRange; +@end + +@interface MMWindowController (Private) +- (NSSize)contentSizeForTextViewSize:(NSSize)textViewSize; +- (NSRect)textViewRectForContentSize:(NSSize)contentSize; +- (void)fitWindowToTextStorage; +- (NSRect)fitWindowToFrame:(NSRect)frame; +- (void)updateResizeIncrements; +- (NSTabViewItem *)addNewTabViewItem; +- (void)statusTimerFired:(NSTimer *)timer; +- (int)representedIndexOfTabViewItem:(NSTabViewItem *)tvi; +- (IBAction)vimMenuItemAction:(id)sender; +- (MMScroller *)scrollbarForIdentifier:(long)ident index:(unsigned *)idx; +- (BOOL)bottomScrollbarVisible; +- (BOOL)leftScrollbarVisible; +- (BOOL)rightScrollbarVisible; +- (void)placeScrollbars; +- (void)scroll:(id)sender; +- (void)fitWindowToScrollbars:(id)sender; +- (void)placeViews; +@end + + + +#if 0 +NSString *buildMenuItemDescriptor(NSMenu *menu, NSString *tail) +{ + return menu ? buildMenuItemDescriptor([menu supermenu], [[menu title] + stringByAppendingString:tail]) + : tail; +} + +NSMutableArray *buildMenuAddress(NSMenu *menu) +{ + NSMutableArray *addr; + if (menu) { + addr = buildMenuAddress([menu supermenu]); + [addr addObject:[menu title]]; + } else { + addr = [NSMutableArray array]; + } + + return addr; +} +#endif + + +@implementation MMWindowController + +- (id)initWithPort:(NSPort *)port +{ + if ((self = [super initWithWindowNibName:@"VimWindow"])) { + sendPort = [port retain]; + scrollbars = [[NSMutableArray alloc] init]; + textStorage = [[MMTextStorage alloc] init]; + } + + return self; +} + +- (void)dealloc +{ + // TODO: release tabBarControl and tabView? + + [tabBarControl setDelegate:nil]; + [[self window] setDelegate:nil]; + + [tabView removeAllTabViewItems]; + + [scrollbars release]; + [textView release]; + [textStorage release]; + [sendPort release]; + + [super dealloc]; +} + +- (void)windowDidLoad +{ + // Called after window nib file is loaded. + + [tabBarControl setHidden:YES]; + [tabBarControl setSizeCellsToFit:YES]; + [tabBarControl setAllowsDragBetweenWindows:NO]; + [tabBarControl setShowAddTabButton:YES]; + [[tabBarControl addTabButton] setTarget:self]; + [[tabBarControl addTabButton] setAction:@selector(addNewTab:)]; + + // HACK! remove any tabs present in the nib + [tabView removeAllTabViewItems]; +} + +- (void)createScrollbarWithIdentifier:(long)ident type:(int)type +{ + //NSLog(@"Create scroller %d of type %d", ident, type); + + MMScroller *scroller = [[MMScroller alloc] initWithIdentifier:ident + type:type]; + [scroller setTarget:self]; + [scroller setAction:@selector(scroll:)]; + + [[[self window] contentView] addSubview:scroller]; + [scrollbars addObject:scroller]; + [scroller release]; +} + +- (void)destroyScrollbarWithIdentifier:(long)ident +{ + //NSLog(@"Destroy scroller %d", ident); + + unsigned idx = 0; + MMScroller *scroller = [self scrollbarForIdentifier:ident index:&idx]; + if (scroller) { + [scroller removeFromSuperview]; + [scrollbars removeObjectAtIndex:idx]; + + if (![scroller isHidden]) { + // A visible scroller was removed, so the window must resize to + // fit. + // TODO! See comment in fitWindowToScrollbars:. + [self performSelectorOnMainThread:@selector(fitWindowToScrollbars:) + withObject:self waitUntilDone:NO]; + } + } +} + +- (void)showScrollbarWithIdentifier:(long)ident state:(BOOL)visible +{ + MMScroller *scroller = [self scrollbarForIdentifier:ident index:NULL]; + if (!scroller) return; + + BOOL wasVisible = ![scroller isHidden]; + //NSLog(@"%s scroller %d (was %svisible)", visible ? "Show" : "Hide", + // ident, wasVisible ? "" : "in"); + [scroller setHidden:!visible]; + + if (wasVisible != visible) { + // A scroller was hidden or shown, so the window must resize to fit. + //NSLog(@"%s scroller %d", visible ? "Show" : "Hide", ident); + // TODO! See comment in fitWindowToScrollbars:. + [self performSelectorOnMainThread:@selector(fitWindowToScrollbars:) + withObject:self waitUntilDone:NO]; + } +} + +- (void)setScrollbarPosition:(int)pos length:(int)len identifier:(long)ident +{ + MMScroller *scroller = [self scrollbarForIdentifier:ident index:NULL]; + NSRange range = NSMakeRange(pos, len); + if (!NSEqualRanges(range, [scroller range])) { + //NSLog(@"Set range %@ for scroller %d", + // NSStringFromRange(range), ident); + [scroller setRange:range]; + // TODO! See comment in fitWindowToScrollbars:. + [self placeScrollbars]; + } +} + +- (void)setScrollbarThumbValue:(float)val proportion:(float)prop + identifier:(long)ident +{ + MMScroller *scroller = [self scrollbarForIdentifier:ident index:NULL]; + //NSLog(@"Set thumb value %.2f proportion %.2f for scroller %d", + // val, prop, ident); + [scroller setFloatValue:val knobProportion:prop]; +} + +- (MMTextView *)textView +{ + return textView; +} + +- (MMTextStorage *)textStorage +{ + return textStorage; +} + +- (void)openWindowWithRows:(int)rows columns:(int)cols +{ +#if 0 + // Make sure window nib file is loaded. + [self window]; + + // Set up text system + textStorage = [[MMTextStorage alloc] init]; + NSLayoutManager *lm = [[NSLayoutManager alloc] init]; + NSTextContainer *tc = [[NSTextContainer alloc] initWithContainerSize: + NSMakeSize(1.0e7,1.0e7)]; + + [tc setWidthTracksTextView:NO]; + [tc setHeightTracksTextView:NO]; + [tc setLineFragmentPadding:0]; + + [textStorage setMaxRows:rows columns:cols]; + [textStorage addLayoutManager:lm]; + [lm addTextContainer:tc]; + //[[lm typesetter] setUsesFontLeading:NO]; + + textView = [[MMTextView alloc] initWithPort:sendPort frame:[tabView frame] + textContainer:tc]; + [[self window] makeFirstResponder:textView]; + + // Keep track of when the layout has changed. + [[textView layoutManager] setDelegate:self]; + + // The text storage retains the layout manager which in turn retains the + // text container. + [tc release]; + [lm release]; + + [self addNewTabViewItem]; +#else + // Setup a complete text system. + NSLayoutManager *lm = [[NSLayoutManager alloc] init]; + NSTextContainer *tc = [[NSTextContainer alloc] initWithContainerSize: + NSMakeSize(1.0e7,1.0e7)]; + + [tc setWidthTracksTextView:NO]; + [tc setHeightTracksTextView:NO]; + [tc setLineFragmentPadding:0]; + + [textStorage setMaxRows:rows columns:cols]; + [textStorage addLayoutManager:lm]; + [lm addTextContainer:tc]; + + textView = [[MMTextView alloc] initWithPort:sendPort frame:[tabView frame] + textContainer:tc]; + + [[self window] makeFirstResponder:textView]; + + // Keep track of when the layout has changed. + [[textView layoutManager] setDelegate:self]; + + // The text storage retains the layout manager which in turn retains the + // text container. + [tc release]; + [lm release]; + + [self addNewTabViewItem]; +#endif + + // NOTE! This flag is set once the entire text system is set up. + setupDone = YES; + + [self fitWindowToTextStorage]; + + // HACK! The GUI does not get activated if Vim is launched by MMBackend in + // checkin:. I have not been able to figure out any other way to get it to + // activate other than forcing it here. A better solution for launching + // the GUI would be good. + [NSApp activateIgnoringOtherApps:YES]; + + [[self window] makeKeyAndOrderFront:self]; + + [statusTextField setHidden:!statusLineIsVisible]; + [self flashStatusText:@"Welcome to MacVim!"]; +} + +- (void)updateTabsWithData:(NSData *)data +{ + const void *p = [data bytes]; + const void *end = p + [data length]; + int tabIdx = 0; + + // HACK! Current tab is first in the message. This way it is not + // necessary to guess which tab should be the selected one (this can be + // problematic for instance when new tabs are created). + int curtabIdx = *((int*)p); p += sizeof(int); + + NSArray *tabViewItems = [tabBarControl representedTabViewItems]; + + while (p < end) { + //int wincount = *((int*)p); p += sizeof(int); + int length = *((int*)p); p += sizeof(int); + + NSString *label = [[NSString alloc] + initWithBytesNoCopy:(void*)p + length:length + encoding:NSUTF8StringEncoding + freeWhenDone:NO]; + p += length; + + // Set the label of the tab; add a new tab when needed. + NSTabViewItem *tvi = [tabView numberOfTabViewItems] <= tabIdx + ? [self addNewTabViewItem] + : [tabViewItems objectAtIndex:tabIdx]; + + [tvi setLabel:label]; + + [label release]; + + ++tabIdx; + } + + // Remove unused tabs from the NSTabView. Note that when a tab is closed + // the NSTabView will automatically select another tab, but we want Vim to + // take care of which tab to select so set the vimTaskSelectedTab flag to + // prevent the tab selection message to be passed on to the VimTask. + vimTaskSelectedTab = YES; + int i, count = [tabView numberOfTabViewItems]; + for (i = count-1; i >= tabIdx; --i) { + id tvi = [tabViewItems objectAtIndex:i]; + //NSLog(@"Removing tab with index %d", i); + [tabView removeTabViewItem:tvi]; + } + vimTaskSelectedTab = NO; + + [self selectTabWithIndex:curtabIdx]; +} + +- (void)selectTabWithIndex:(int)idx +{ + //NSLog(@"%s%d", _cmd, idx); + + NSArray *tabViewItems = [tabBarControl representedTabViewItems]; + if (idx < 0 || idx >= [tabViewItems count]) { + NSLog(@"WARNING: No tab with index %d exists.", idx); + return; + } + + // Do not try to select a tab if already selected. + NSTabViewItem *tvi = [tabViewItems objectAtIndex:idx]; + if (tvi != [tabView selectedTabViewItem]) { + vimTaskSelectedTab = YES; + [tabView selectTabViewItem:tvi]; + vimTaskSelectedTab = NO; + } +} + +- (void)setTextDimensionsWithRows:(int)rows columns:(int)cols +{ + //NSLog(@"setTextDimensionsWithRows:%d columns:%d", rows, cols); + + // HACK! Dimensions are set by [MMVimController performBatchDrawWithData:]. + //[textStorage setMaxRows:rows columns:cols]; +} + +- (void)setStatusText:(NSString *)text +{ + if (text) + [statusTextField setStringValue:text]; + else + [statusTextField setStringValue:@""]; +} + +- (void)flashStatusText:(NSString *)text +{ + if (!statusLineIsVisible) return; + + [self setStatusText:text]; + + if (statusTimer) { + [statusTimer invalidate]; + [statusTimer release]; + } + + statusTimer = [[NSTimer scheduledTimerWithTimeInterval:3 + target:self + selector:@selector(statusTimerFired:) + userInfo:nil + repeats:NO] retain]; +} + +- (IBAction)addNewTab:(id)sender +{ + [NSPortMessage sendMessage:AddNewTabMsgID withSendPort:sendPort wait:NO]; +} + +- (IBAction)showTabBar:(id)sender +{ + [tabBarControl setHidden:NO]; + if (setupDone) + [self fitWindowToTextStorage]; +} + +- (IBAction)hideTabBar:(id)sender +{ + [tabBarControl setHidden:YES]; + if (setupDone) + [self fitWindowToTextStorage]; +} + + +// -- PSMTabBarControl delegate ---------------------------------------------- + + +- (void)tabView:(NSTabView *)theTabView didSelectTabViewItem: + (NSTabViewItem *)tabViewItem +{ + // HACK! There seem to be a bug in NSTextView which results in the first + // responder not being set to the view of the tab item so it is done + // manually here. + [[self window] makeFirstResponder:[tabViewItem view]]; + + // HACK! The selection message should not be propagated to the VimTask if + // the VimTask selected the tab (e.g. as opposed the user clicking the + // tab). The delegate method has no way of knowing who initiated the + // selection so a flag is set when the VimTask initiated the selection. + if (!vimTaskSelectedTab) { + // Propagate the selection message to the VimTask. + int idx = [self representedIndexOfTabViewItem:tabViewItem]; + NSData *data = [NSData dataWithBytes:&idx length:sizeof(int)]; + [NSPortMessage sendMessage:SelectTabMsgID withSendPort:sendPort + data:data wait:YES]; + } +} + +- (BOOL)tabView:(NSTabView *)theTabView shouldCloseTabViewItem: + (NSTabViewItem *)tabViewItem +{ + // HACK! This method is only called when the user clicks the close button + // on the tab. Instead of letting the tab bar close the tab, we return NO + // and pass a message on to Vim to let it handle the closing. + int idx = [self representedIndexOfTabViewItem:tabViewItem]; + //NSLog(@"Closing tab with index %d", idx); + NSData *data = [NSData dataWithBytes:&idx length:sizeof(int)]; + [NSPortMessage sendMessage:CloseTabMsgID withSendPort:sendPort + data:data wait:YES]; + + return NO; +} + +- (void)tabView:(NSTabView *)theTabView didDragTabViewItem: + (NSTabViewItem *)tabViewItem toIndex:(int)idx +{ + NSMutableData *data = [NSMutableData data]; + [data appendBytes:&idx length:sizeof(int)]; + + [NSPortMessage sendMessage:DraggedTabMsgID withSendPort:sendPort + data:data wait:YES]; +} + + +// -- NSLayoutManager delegate ----------------------------------------------- + + +- (void)layoutManager:(NSLayoutManager *)aLayoutManager + didCompleteLayoutForTextContainer:(NSTextContainer *)aTextContainer + atEnd:(BOOL)flag +{ + // HACK! Sometimes the text handling system will use fonts for some glyphs + // (e.g. digraphs) which are slightly higher than the font that the text + // storage uses (usually a fixed pitch font like Monaco). In this case the + // text might not fit in the window so the window is resized here to always + // be big enough to show all characters. This has the unpleasant visual + // side-effect of the window changing size when such glyphs are displayed. + +#if 0 + // HACK! The baseline separator keeps popping up, hide it again. This + // hack doesn't work. + if (tabBarControl) { + [[[self window] toolbar] setShowsBaselineSeparator: + [tabBarControl isHidden]]; + } +#endif + + if (flag && ![textView inLiveResize]) { + // Make sure the text storage exactly fills out the entire tab view, + // otherwise resize the window to fit the text storage. + // (This way the text storage size can change however/whenever it wants + // and the window will update to fit it.) + if (!NSEqualSizes([tabView frame].size, [textStorage size])) { + [self fitWindowToTextStorage]; + if (!NSEqualSizes([tabView frame].size, [textStorage size])) { + // NOTE! If the window is the same size after + // fitWindowToTextStorage, we place the views manually + // (normally windowDidResize: takes care of that) in case the + // text view changed size (which can happen e.g. after a ':set + // lines' command). + [self placeViews]; + } + [self updateResizeIncrements]; + } + } +} + + +// -- NSWindow delegate ------------------------------------------------------ + + +#if 0 +- (void)windowWillClose:(NSNotification *)notification +{ +} + +- (NSSize)windowWillResize:(NSWindow *)sender toSize:(NSSize)proposedFrameSize +{ + //NSLog(@"%s (%.2f,%.2f)", _cmd, proposedFrameSize.width, + // proposedFrameSize.height); + return proposedFrameSize; +} +#endif + +- (void)windowDidResize:(id)sender +{ + if (!setupDone) return; + [self placeViews]; +} + +- (NSRect)windowWillUseStandardFrame:(NSWindow *)win + defaultFrame:(NSRect)frame +{ + // HACK! For some reason 'frame' is not always constrained to fit on the + // screen (e.g. it may overlap the menu bar), so first constrain it to the + // screen; otherwise the new frame we compute may be too large and this + // will mess up the display after the window resizes. + frame = [win constrainFrameRect:frame toScreen:[win screen]]; + + // HACK! If the top of 'frame' is lower than the current window frame, + // increase 'frame' so that their tops align. Really, 'frame' should + // already have its top at least as high as the current window frame, but + // for some reason this is not always the case. + // (See fitWindowToTextStorage for a similar hack.) + NSRect cur = [win frame]; + if (NSMaxY(cur) > NSMaxY(frame)) { + frame.size.height = cur.origin.y - frame.origin.y + cur.size.height; + } + + frame = [self fitWindowToFrame:frame]; + + // Keep old width and horizontal position if the Command key is held down. + if ([[NSApp currentEvent] modifierFlags] & NSCommandKeyMask) { + NSRect currentFrame = [win frame]; + frame.size.width = currentFrame.size.width; + frame.origin.x = currentFrame.origin.x; + } + + return frame; +} + +@end // MMWindowController + + + +@implementation MMWindowController (Private) + +- (NSSize)contentSizeForTextViewSize:(NSSize)textViewSize +{ + NSSize size = textViewSize; + + if (![tabBarControl isHidden]) + size.height += [tabBarControl frame].size.height; + if (statusLineIsVisible) + size.height += StatusLineHeight; + + if ([self bottomScrollbarVisible]) + size.height += [NSScroller scrollerWidth]; + if ([self leftScrollbarVisible]) + size.width += [NSScroller scrollerWidth]; + if ([self rightScrollbarVisible]) + size.width += [NSScroller scrollerWidth]; + + return size; +} + +- (NSRect)textViewRectForContentSize:(NSSize)contentSize +{ + NSRect rect = { 0, 0, contentSize.width, contentSize.height }; + + if (![tabBarControl isHidden]) + rect.size.height -= [tabBarControl frame].size.height; + if (statusLineIsVisible) { + rect.size.height -= StatusLineHeight; + rect.origin.y += StatusLineHeight; + } + + if ([self bottomScrollbarVisible]) { + rect.size.height -= [NSScroller scrollerWidth]; + rect.origin.y += [NSScroller scrollerWidth]; + } + if ([self leftScrollbarVisible]) { + rect.size.width -= [NSScroller scrollerWidth]; + rect.origin.x += [NSScroller scrollerWidth]; + } + if ([self rightScrollbarVisible]) + rect.size.width -= [NSScroller scrollerWidth]; + + return rect; +} + +- (void)fitWindowToTextStorage +{ + if (!setupDone) return; + + NSWindow *win = [self window]; + NSRect frame = [win frame]; + NSRect contentRect = [win contentRectForFrameRect:frame]; + NSSize newSize = [self contentSizeForTextViewSize:[textStorage size]]; + + // Keep top-left corner of the window fixed when resizing. + contentRect.origin.y -= newSize.height - contentRect.size.height; + contentRect.size = newSize; + + frame = [win frameRectForContentRect:contentRect]; + NSRect maxFrame = [win constrainFrameRect:frame toScreen:[win screen]]; + + // HACK! Assuming the window frame cannot already be placed too high, + // adjust 'maxFrame' so that it at least as high up as the current frame. + // The reason for doing this is that constrainFrameRect:toScreen: does not + // always seem to utilize as much area as possible. + if (NSMaxY(frame) > NSMaxY(maxFrame)) { + maxFrame.size.height = frame.origin.y - maxFrame.origin.y + + frame.size.height; + } + + if (NSEqualRects(maxFrame, frame)) { + // The new window frame fits on the screen, so resize the window. + [win setFrame:frame display:YES]; + } else { + // The new window frame is too big to fit on the screen, so fit the + // text storage to the biggest frame which will fit on the screen. + //NSLog(@"Proposed window frame does not fit on the screen!"); + + [win setFrame:[self fitWindowToFrame:maxFrame] display:YES]; + } +} + +- (NSRect)fitWindowToFrame:(NSRect)frame +{ + if (!setupDone) return frame; + + NSWindow *win = [self window]; + NSRect contentRect = [win contentRectForFrameRect:frame]; + NSRect textViewRect = [self textViewRectForContentSize:contentRect.size]; + NSSize fitSize = [textStorage fitToSize:textViewRect.size]; + NSSize newSize = [self contentSizeForTextViewSize:fitSize]; + + // Keep top-left corner of 'frame' fixed. + contentRect.origin.y -= newSize.height - contentRect.size.height; + contentRect.size = newSize; + + return [win frameRectForContentRect:contentRect]; +} + +- (void)updateResizeIncrements +{ + if (!setupDone) return; + + NSSize size = [textStorage calculateAverageFontSize]; + [[self window] setContentResizeIncrements:size]; +} + +- (NSTabViewItem *)addNewTabViewItem +{ + // NOTE! A newly created tab is not by selected by default; the VimTask + // decides which tab should be selected at all times. However, the AppKit + // will automatically select the first tab added to a tab view. + + NSTabViewItem *tvi = [[NSTabViewItem alloc] initWithIdentifier:nil]; + [tvi setView:textView]; + + // BUG! This call seems to have no effect; see comment in + // tabView:didSelectTabViewItem:. + [tvi setInitialFirstResponder:textView]; + + [tabView addTabViewItem:tvi]; + [tvi release]; + + return tvi; +} + +- (void)statusTimerFired:(NSTimer *)timer +{ + [self setStatusText:@""]; + [statusTimer release]; + statusTimer = nil; +} + +- (int)representedIndexOfTabViewItem:(NSTabViewItem *)tvi +{ + NSArray *tabViewItems = [tabBarControl representedTabViewItems]; + return [tabViewItems indexOfObject:tvi]; +} + +- (IBAction)vimMenuItemAction:(id)sender +{ + int tag = [sender tag]; + + NSMutableData *data = [NSMutableData data]; + [data appendBytes:&tag length:sizeof(int)]; + + [NSPortMessage sendMessage:ExecuteMenuMsgID withSendPort:sendPort + data:data wait:NO]; +} + +- (MMScroller *)scrollbarForIdentifier:(long)ident index:(unsigned *)idx +{ + unsigned i, count = [scrollbars count]; + for (i = 0; i < count; ++i) { + MMScroller *scroller = [scrollbars objectAtIndex:i]; + if ([scroller identifier] == ident) { + if (idx) *idx = i; + return scroller; + } + } + + return nil; +} + +- (BOOL)bottomScrollbarVisible +{ + unsigned i, count = [scrollbars count]; + for (i = 0; i < count; ++i) { + MMScroller *scroller = [scrollbars objectAtIndex:i]; + if ([scroller type] == MMScrollerTypeBottom && ![scroller isHidden]) + return YES; + } + + return NO; +} + +- (BOOL)leftScrollbarVisible +{ + unsigned i, count = [scrollbars count]; + for (i = 0; i < count; ++i) { + MMScroller *scroller = [scrollbars objectAtIndex:i]; + if ([scroller type] == MMScrollerTypeLeft && ![scroller isHidden]) + return YES; + } + + return NO; +} + +- (BOOL)rightScrollbarVisible +{ + unsigned i, count = [scrollbars count]; + for (i = 0; i < count; ++i) { + MMScroller *scroller = [scrollbars objectAtIndex:i]; + if ([scroller type] == MMScrollerTypeRight && ![scroller isHidden]) + return YES; + } + + return NO; +} + +- (void)placeScrollbars +{ + if (!setupDone) return; + + NSRect tabViewFrame = [tabView frame]; + NSView *contentView = [[self window] contentView]; + BOOL lsbVisible = [self leftScrollbarVisible]; + + // HACK! Find the lowest left&right vertical scrollbars. This hack + // continues further down. + unsigned lowestLeftSbIdx = (unsigned)-1; + unsigned lowestRightSbIdx = (unsigned)-1; + unsigned rowMaxLeft = 0, rowMaxRight = 0; + unsigned i, count = [scrollbars count]; + for (i = 0; i < count; ++i) { + MMScroller *scroller = [scrollbars objectAtIndex:i]; + if (![scroller isHidden]) { + NSRange range = [scroller range]; + if ([scroller type] == MMScrollerTypeLeft + && range.location >= rowMaxLeft) { + rowMaxLeft = range.location; + lowestLeftSbIdx = i; + } else if ([scroller type] == MMScrollerTypeRight + && range.location >= rowMaxRight) { + rowMaxRight = range.location; + lowestRightSbIdx = i; + } + } + } + + // Place the scrollbars. + for (i = 0; i < count; ++i) { + MMScroller *scroller = [scrollbars objectAtIndex:i]; + if ([scroller isHidden]) + continue; + + NSRect rect; + if ([scroller type] == MMScrollerTypeBottom) { + rect = [textStorage rectForColumnsInRange:[scroller range]]; + rect.size.height = [NSScroller scrollerWidth]; + if (statusLineIsVisible) + rect.origin.y += StatusLineHeight; + if (lsbVisible) + rect.origin.x += [NSScroller scrollerWidth]; + } else { + rect = [textStorage rectForRowsInRange:[scroller range]]; + // Adjust for the fact that text layout is flipped. + rect.origin.y = NSMaxY(tabViewFrame) - rect.origin.y + - rect.size.height; + rect.size.width = [NSScroller scrollerWidth]; + if ([scroller type] == MMScrollerTypeRight) + rect.origin.x = NSMaxX(tabViewFrame); + + // HACK! Make sure the lowest vertical scrollbar covers the text + // view all the way to the bottom. This is done because Vim only + // makes the scrollbar cover the (vim-)window it is associated with + // and this means there is always an empty gap in the scrollbar + // region next to the command line. + // TODO! Find a nicer way to do this. + if (i == lowestLeftSbIdx || i == lowestRightSbIdx) { + float h = rect.origin.y + rect.size.height + - tabViewFrame.origin.y; + if (rect.size.height < h) { + rect.origin.y = tabViewFrame.origin.y; + rect.size.height = h; + } + } + } + + //NSLog(@"set scroller #%d frame = %@", i, NSStringFromRect(rect)); + NSRect oldRect = [scroller frame]; + if (!NSEqualRects(oldRect, rect)) { + [scroller setFrame:rect]; + // Clear behind the old scroller frame, or parts of the old + // scroller might still be visible after setFrame:. + [contentView setNeedsDisplayInRect:oldRect]; + [scroller setNeedsDisplay:YES]; + } + } +} + +- (void)scroll:(id)sender +{ + NSMutableData *data = [NSMutableData data]; + long ident = [(MMScroller*)sender identifier]; + int hitPart = [sender hitPart]; + float value = [sender floatValue]; + + [data appendBytes:&ident length:sizeof(long)]; + [data appendBytes:&hitPart length:sizeof(int)]; + [data appendBytes:&value length:sizeof(float)]; + + [NSPortMessage sendMessage:ScrollbarEventMsgID withSendPort:sendPort + data:data wait:YES]; +} + +- (void)fitWindowToScrollbars:(id)sender +{ + // TODO! Make sure this only gets called once per update (e.g. in case + // several scrollbars were hidden). Could do this by setting a flag and + // then checking for this flag at appropriate places and then calling this + // method. + [self fitWindowToTextStorage]; + [self placeScrollbars]; +} + +- (void)placeViews +{ + if (!setupDone) return; + + // NOTE! It is assumed that the window has been resized so that it will + // exactly fit the text storage (possibly after resizing it). If this is + // not the case the display might be messed up. + NSWindow *win = [self window]; + NSRect contentRect = [win contentRectForFrameRect:[win frame]]; + NSRect textViewRect = [self textViewRectForContentSize:contentRect.size]; + if ([textStorage resizeToFitSize:textViewRect.size]) { + // Text storage dimensions changed, notify the VimTask. + int dim[2]; + [textStorage getMaxRows:&dim[0] columns:&dim[1]]; + //NSLog(@"Notify Vim that text storage dimensions changed to %dx%d", + // dim[0], dim[1]); + NSData *data = [NSData dataWithBytes:dim length:2*sizeof(int)]; + [NSPortMessage sendMessage:SetTextDimensionsMsgID + withSendPort:sendPort data:data wait:YES]; + } + + [tabView setFrame:textViewRect]; + + // HACK! I manually place the tab bar here instead of setting the sizing + // options in Interface Builder because I couldn't get the automatic sizing + // to work. + if (![tabBarControl isHidden]) { + NSRect tabBarRect = { + 0, NSMaxY(textViewRect), + contentRect.size.width, [tabBarControl frame].size.height }; + + [tabBarControl setFrame:tabBarRect]; + } + + [self placeScrollbars]; +} + +@end // MMWindowController (Private) + + + +@implementation NSTabView (MMExtras) + +- (void)removeAllTabViewItems +{ + NSArray *existingItems = [self tabViewItems]; + NSEnumerator *e = [existingItems objectEnumerator]; + NSTabViewItem *item; + while (item = [e nextObject]){ + [self removeTabViewItem:item]; + } +} + +@end // NSTabView (MMExtras) + + + + +@implementation MMScroller + +- (id)initWithIdentifier:(long)ident type:(int)theType +{ + // HACK! NSScroller creates a horizontal scroller if it is init'ed with a + // frame whose with exceeds its height; so create a bogus rect and pass it + // to initWithFrame. + NSRect frame = theType == MMScrollerTypeBottom + ? NSMakeRect(0, 0, 1, 0) + : NSMakeRect(0, 0, 0, 1); + + if ((self = [super initWithFrame:frame])) { + identifier = ident; + type = theType; + [self setHidden:YES]; + [self setEnabled:YES]; + } + + return self; +} + +- (long)identifier +{ + return identifier; +} + +- (int)type +{ + return type; +} + +- (NSRange)range +{ + return range; +} + +- (void)setRange:(NSRange)newRange +{ + range = newRange; +} + +@end // MMScroller diff --git a/MacVim.h b/MacVim.h new file mode 100644 index 0000000000..cd28046690 --- /dev/null +++ b/MacVim.h @@ -0,0 +1,102 @@ +/* vi:set ts=8 sts=4 sw=4 ft=objc: + * + * VIM - Vi IMproved by Bram Moolenaar + * MacVim GUI port by Bjorn Winckler + * + * Do ":help uganda" in Vim to read copying and usage conditions. + * Do ":help credits" in Vim to see a list of people who contributed. + * See README.txt for an overview of the Vim source code. + */ + +#import + + +enum { + CheckinMsgID = 1, + ConnectedMsgID, + KillTaskMsgID, + TaskExitedMsgID, + OpenVimWindowMsgID, + InsertTextMsgID, + KeyDownMsgID, + CmdKeyMsgID, + BatchDrawMsgID, + SelectTabMsgID, + CloseTabMsgID, + AddNewTabMsgID, + DraggedTabMsgID, + UpdateTabBarMsgID, + ShowTabBarMsgID, + HideTabBarMsgID, + SetTextDimensionsMsgID, + SetVimWindowTitleMsgID, + ScrollWheelMsgID, + MouseDownMsgID, + MouseUpMsgID, + MouseDraggedMsgID, + BrowseForFileMsgID, + BrowseForFileReplyMsgID, + FlushQueueMsgID, + UpdateInsertionPointMsgID, + AddMenuMsgID, + AddMenuItemMsgID, + RemoveMenuItemMsgID, + EnableMenuItemMsgID, + ExecuteMenuMsgID, + ShowToolbarMsgID, + TaskShouldTerminateMsgID, + TerminateReplyYesMsgID, + TerminateReplyNoMsgID, + CreateScrollbarMsgID, + DestroyScrollbarMsgID, + ShowScrollbarMsgID, + SetScrollbarPositionMsgID, + SetScrollbarThumbMsgID, + ScrollbarEventMsgID, + SetFontMsgID, +}; + + +enum { + ClearAllDrawType = 1, + ClearBlockDrawType, + DeleteLinesDrawType, + ReplaceStringDrawType, + InsertLinesDrawType +}; + + +// NOTE! These values must be close to zero, or the 'add menu' message might +// fail to distinguish type from tag. +enum { + MenuMenubarType = 0, + MenuPopupType, + MenuToolbarType +}; + + +enum { + ToolbarLabelFlag = 1, + ToolbarIconFlag = 2, + ToolbarSizeRegularFlag = 4 +}; + + +@interface NSPortMessage (MacVim) + ++ (BOOL)sendMessage:(int)msgid withSendPort:(NSPort *)sendPort + receivePort:(NSPort *)receivePort components:(NSArray *)components + wait:(BOOL)wait; ++ (BOOL)sendMessage:(int)msgid withSendPort:(NSPort *)sendPort + receivePort:(NSPort *)receivePort data:(NSData *)data wait:(BOOL)wait; ++ (BOOL)sendMessage:(int)msgid withSendPort:(NSPort *)sendPort + receivePort:(NSPort *)receivePort wait:(BOOL)wait; ++ (BOOL)sendMessage:(int)msgid withSendPort:(NSPort *)sendPort + components:(NSArray *)components wait:(BOOL)wait; ++ (BOOL)sendMessage:(int)msgid withSendPort:(NSPort *)sendPort + data:(NSData *)data wait:(BOOL)wait; ++ (BOOL)sendMessage:(int)msgid withSendPort:(NSPort *)sendPort wait:(BOOL)wait; + +@end + +// vim: set ft=objc: diff --git a/MacVim.m b/MacVim.m new file mode 100644 index 0000000000..3727ea60bc --- /dev/null +++ b/MacVim.m @@ -0,0 +1,86 @@ +/* vi:set ts=8 sts=4 sw=4 ft=objc: + * + * VIM - Vi IMproved by Bram Moolenaar + * MacVim GUI port by Bjorn Winckler + * + * Do ":help uganda" in Vim to read copying and usage conditions. + * Do ":help credits" in Vim to see a list of people who contributed. + * See README.txt for an overview of the Vim source code. + */ + +#import "MacVim.h" + + +@implementation NSPortMessage (MacVim) + ++ (BOOL)sendMessage:(int)msgid withSendPort:(NSPort *)sendPort + receivePort:(NSPort *)receivePort components:(NSArray *)components + wait:(BOOL)wait +{ + NSPortMessage *msg = [[NSPortMessage alloc] + initWithSendPort:sendPort + receivePort:receivePort + components:components]; + [msg setMsgid:msgid]; + + // HACK! How long should this wait before time out? + NSDate *date = wait ? [NSDate dateWithTimeIntervalSinceNow:1] + : [NSDate date]; + BOOL ok = [msg sendBeforeDate:date]; + + [msg release]; + + return ok; +} + ++ (BOOL)sendMessage:(int)msgid withSendPort:(NSPort *)sendPort + receivePort:(NSPort *)receivePort data:(NSData *)data wait:(BOOL)wait +{ + return [NSPortMessage sendMessage:msgid + withSendPort:sendPort + receivePort:receivePort + components:[NSArray arrayWithObject:data] + wait:wait]; +} + ++ (BOOL)sendMessage:(int)msgid withSendPort:(NSPort *)sendPort + receivePort:(NSPort *)receivePort wait:(BOOL)wait +{ + return [NSPortMessage sendMessage:msgid + withSendPort:sendPort + receivePort:receivePort + components:nil + wait:wait]; +} + ++ (BOOL)sendMessage:(int)msgid withSendPort:(NSPort *)sendPort + components:(NSArray *)components wait:(BOOL)wait +{ + return [NSPortMessage sendMessage:msgid + withSendPort:sendPort + receivePort:nil + components:components + wait:wait]; +} + ++ (BOOL)sendMessage:(int)msgid withSendPort:(NSPort *)sendPort + data:(NSData *)data wait:(BOOL)wait +{ + return [NSPortMessage sendMessage:msgid + withSendPort:sendPort + receivePort:nil + components:[NSArray arrayWithObject:data] + wait:wait]; +} + ++ (BOOL)sendMessage:(int)msgid withSendPort:(NSPort *)sendPort wait:(BOOL)wait +{ + return [NSPortMessage sendMessage:msgid + withSendPort:sendPort + receivePort:nil + components:nil + wait:wait]; +} + + +@end diff --git a/MacVim.xcodeproj/project.pbxproj b/MacVim.xcodeproj/project.pbxproj new file mode 100644 index 0000000000..84316bbd38 --- /dev/null +++ b/MacVim.xcodeproj/project.pbxproj @@ -0,0 +1,651 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 42; + objects = { + +/* Begin PBXBuildFile section */ + 1D0E051C0BA5F83800B6049E /* Colors.plist in Resources */ = {isa = PBXBuildFile; fileRef = 1D0E051B0BA5F83800B6049E /* Colors.plist */; }; + 1D1474970C56703C0038FA2B /* MacVim.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 1D1474950C56703C0038FA2B /* MacVim.h */; }; + 1D1474980C56703C0038FA2B /* MacVim.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D1474960C56703C0038FA2B /* MacVim.m */; }; + 1D14749F0C5673AE0038FA2B /* MMAppController.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 1D14749D0C5673AE0038FA2B /* MMAppController.h */; }; + 1D1474A00C5673AE0038FA2B /* MMAppController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D14749E0C5673AE0038FA2B /* MMAppController.m */; }; + 1D1474A90C5677450038FA2B /* MMTextStorage.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 1D1474A70C5677450038FA2B /* MMTextStorage.h */; }; + 1D1474AA0C5677450038FA2B /* MMTextStorage.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D1474A80C5677450038FA2B /* MMTextStorage.m */; }; + 1D1474AF0C5678370038FA2B /* MMTextView.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 1D1474AD0C5678370038FA2B /* MMTextView.h */; }; + 1D1474B00C5678370038FA2B /* MMTextView.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D1474AE0C5678370038FA2B /* MMTextView.m */; }; + 1D1474B50C56796D0038FA2B /* MMVimController.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 1D1474B30C56796D0038FA2B /* MMVimController.h */; }; + 1D1474B60C56796D0038FA2B /* MMVimController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D1474B40C56796D0038FA2B /* MMVimController.m */; }; + 1D1474BB0C567A910038FA2B /* MMWindowController.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 1D1474B90C567A910038FA2B /* MMWindowController.h */; }; + 1D1474BC0C567A910038FA2B /* MMWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D1474BA0C567A910038FA2B /* MMWindowController.m */; }; + 1D16B9EB0BA33E1E00A69B33 /* VimWindow.nib in Resources */ = {isa = PBXBuildFile; fileRef = 1D16B9E90BA33E1E00A69B33 /* VimWindow.nib */; }; + 1D493D580C5247BF00AB718C /* Vim in CopyFiles */ = {isa = PBXBuildFile; fileRef = 1D493D570C5247BF00AB718C /* Vim */; }; + 1D493DBA0C52534300AB718C /* PSMTabBarControl.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 1D493DB90C52533B00AB718C /* PSMTabBarControl.framework */; }; + 1D71ACB40BC702AB002F2B60 /* doc-bm-c.icns in Resources */ = {isa = PBXBuildFile; fileRef = 1D71ACA90BC702AB002F2B60 /* doc-bm-c.icns */; }; + 1D71ACB50BC702AC002F2B60 /* doc-bm-h.icns in Resources */ = {isa = PBXBuildFile; fileRef = 1D71ACAA0BC702AB002F2B60 /* doc-bm-h.icns */; }; + 1D71ACB60BC702AC002F2B60 /* doc-bm-html.icns in Resources */ = {isa = PBXBuildFile; fileRef = 1D71ACAB0BC702AB002F2B60 /* doc-bm-html.icns */; }; + 1D71ACB70BC702AC002F2B60 /* doc-bm-java.icns in Resources */ = {isa = PBXBuildFile; fileRef = 1D71ACAC0BC702AB002F2B60 /* doc-bm-java.icns */; }; + 1D71ACB80BC702AC002F2B60 /* doc-bm-php.icns in Resources */ = {isa = PBXBuildFile; fileRef = 1D71ACAD0BC702AB002F2B60 /* doc-bm-php.icns */; }; + 1D71ACB90BC702AC002F2B60 /* doc-bm-pl.icns in Resources */ = {isa = PBXBuildFile; fileRef = 1D71ACAE0BC702AB002F2B60 /* doc-bm-pl.icns */; }; + 1D71ACBA0BC702AC002F2B60 /* doc-bm-sh.icns in Resources */ = {isa = PBXBuildFile; fileRef = 1D71ACAF0BC702AB002F2B60 /* doc-bm-sh.icns */; }; + 1D71ACBB0BC702AC002F2B60 /* doc-bm-tex.icns in Resources */ = {isa = PBXBuildFile; fileRef = 1D71ACB00BC702AB002F2B60 /* doc-bm-tex.icns */; }; + 1D71ACBC0BC702AC002F2B60 /* doc-bm-txt.icns in Resources */ = {isa = PBXBuildFile; fileRef = 1D71ACB10BC702AB002F2B60 /* doc-bm-txt.icns */; }; + 1D71ACBD0BC702AC002F2B60 /* doc-bm-xml.icns in Resources */ = {isa = PBXBuildFile; fileRef = 1D71ACB20BC702AB002F2B60 /* doc-bm-xml.icns */; }; + 1D71ACBE0BC702AC002F2B60 /* doc-bm.icns in Resources */ = {isa = PBXBuildFile; fileRef = 1D71ACB30BC702AB002F2B60 /* doc-bm.icns */; }; + 1DD04DEC0C529C5E006CDC2B /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = 1DD04DEB0C529C5E006CDC2B /* Credits.rtf */; }; + 1DD703B90BA9D15D008679E9 /* vim_gloss.icns in Resources */ = {isa = PBXBuildFile; fileRef = 1DD703B80BA9D15D008679E9 /* vim_gloss.icns */; }; + 1DD704310BA9F9C2008679E9 /* SpecialKeys.plist in Resources */ = {isa = PBXBuildFile; fileRef = 1DD704300BA9F9C2008679E9 /* SpecialKeys.plist */; }; + 1DEE0D9F0C4E150B008E82B2 /* Attention.png in Resources */ = {isa = PBXBuildFile; fileRef = 1DEE0D8A0C4E150B008E82B2 /* Attention.png */; }; + 1DEE0DA00C4E150B008E82B2 /* Copy.png in Resources */ = {isa = PBXBuildFile; fileRef = 1DEE0D8B0C4E150B008E82B2 /* Copy.png */; }; + 1DEE0DA10C4E150B008E82B2 /* Cut.png in Resources */ = {isa = PBXBuildFile; fileRef = 1DEE0D8C0C4E150B008E82B2 /* Cut.png */; }; + 1DEE0DA20C4E150B008E82B2 /* FindHelp.png in Resources */ = {isa = PBXBuildFile; fileRef = 1DEE0D8D0C4E150B008E82B2 /* FindHelp.png */; }; + 1DEE0DA30C4E150B008E82B2 /* FindNext.png in Resources */ = {isa = PBXBuildFile; fileRef = 1DEE0D8E0C4E150B008E82B2 /* FindNext.png */; }; + 1DEE0DA40C4E150B008E82B2 /* FindPrev.png in Resources */ = {isa = PBXBuildFile; fileRef = 1DEE0D8F0C4E150B008E82B2 /* FindPrev.png */; }; + 1DEE0DA50C4E150B008E82B2 /* Help.png in Resources */ = {isa = PBXBuildFile; fileRef = 1DEE0D900C4E150B008E82B2 /* Help.png */; }; + 1DEE0DA60C4E150B008E82B2 /* LoadSesn.png in Resources */ = {isa = PBXBuildFile; fileRef = 1DEE0D910C4E150B008E82B2 /* LoadSesn.png */; }; + 1DEE0DA70C4E150B008E82B2 /* Make.png in Resources */ = {isa = PBXBuildFile; fileRef = 1DEE0D920C4E150B008E82B2 /* Make.png */; }; + 1DEE0DA80C4E150B008E82B2 /* Open.png in Resources */ = {isa = PBXBuildFile; fileRef = 1DEE0D930C4E150B008E82B2 /* Open.png */; }; + 1DEE0DA90C4E150B008E82B2 /* Paste.png in Resources */ = {isa = PBXBuildFile; fileRef = 1DEE0D940C4E150B008E82B2 /* Paste.png */; }; + 1DEE0DAA0C4E150B008E82B2 /* Print.png in Resources */ = {isa = PBXBuildFile; fileRef = 1DEE0D950C4E150B008E82B2 /* Print.png */; }; + 1DEE0DAB0C4E150B008E82B2 /* Redo.png in Resources */ = {isa = PBXBuildFile; fileRef = 1DEE0D960C4E150B008E82B2 /* Redo.png */; }; + 1DEE0DAC0C4E150B008E82B2 /* Replace.png in Resources */ = {isa = PBXBuildFile; fileRef = 1DEE0D970C4E150B008E82B2 /* Replace.png */; }; + 1DEE0DAD0C4E150B008E82B2 /* RunCtags.png in Resources */ = {isa = PBXBuildFile; fileRef = 1DEE0D980C4E150B008E82B2 /* RunCtags.png */; }; + 1DEE0DAE0C4E150B008E82B2 /* RunScript.png in Resources */ = {isa = PBXBuildFile; fileRef = 1DEE0D990C4E150B008E82B2 /* RunScript.png */; }; + 1DEE0DAF0C4E150B008E82B2 /* Save.png in Resources */ = {isa = PBXBuildFile; fileRef = 1DEE0D9A0C4E150B008E82B2 /* Save.png */; }; + 1DEE0DB00C4E150B008E82B2 /* SaveAll.png in Resources */ = {isa = PBXBuildFile; fileRef = 1DEE0D9B0C4E150B008E82B2 /* SaveAll.png */; }; + 1DEE0DB10C4E150B008E82B2 /* SaveSesn.png in Resources */ = {isa = PBXBuildFile; fileRef = 1DEE0D9C0C4E150B008E82B2 /* SaveSesn.png */; }; + 1DEE0DB20C4E150B008E82B2 /* TagJump.png in Resources */ = {isa = PBXBuildFile; fileRef = 1DEE0D9D0C4E150B008E82B2 /* TagJump.png */; }; + 1DEE0DB30C4E150B008E82B2 /* Undo.png in Resources */ = {isa = PBXBuildFile; fileRef = 1DEE0D9E0C4E150B008E82B2 /* Undo.png */; }; + 1DFE25A50C527BC4003000F7 /* PSMTabBarControl.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D493DB90C52533B00AB718C /* PSMTabBarControl.framework */; }; + 8D11072A0486CEB800E47090 /* MainMenu.nib in Resources */ = {isa = PBXBuildFile; fileRef = 29B97318FDCFA39411CA2CEA /* MainMenu.nib */; }; + 8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */; }; + 8D11072D0486CEB800E47090 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; settings = {ATTRIBUTES = (); }; }; + 8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 1D493DB80C52533B00AB718C /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 1D493DB30C52533B00AB718C /* PSMTabBarControl.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 53DF68FD067E5B5A0090B5B0; + remoteInfo = PSMTabBarControlFramework; + }; + 1D493DCC0C5254A400AB718C /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 1D493DB30C52533B00AB718C /* PSMTabBarControl.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = 53DF68FC067E5B5A0090B5B0; + remoteInfo = PSMTabBarControlFramework; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 1D0DCAD80BA3604D00B6CCFA /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 6; + files = ( + 1D493D580C5247BF00AB718C /* Vim in CopyFiles */, + 1D1474970C56703C0038FA2B /* MacVim.h in CopyFiles */, + 1D14749F0C5673AE0038FA2B /* MMAppController.h in CopyFiles */, + 1D1474A90C5677450038FA2B /* MMTextStorage.h in CopyFiles */, + 1D1474AF0C5678370038FA2B /* MMTextView.h in CopyFiles */, + 1D1474B50C56796D0038FA2B /* MMVimController.h in CopyFiles */, + 1D1474BB0C567A910038FA2B /* MMWindowController.h in CopyFiles */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 1D9EB2840C366D7B0074B739 /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 1D493DBA0C52534300AB718C /* PSMTabBarControl.framework in CopyFiles */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 089C165DFE840E0CC02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = ""; }; + 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = ""; }; + 13E42FB307B3F0F600E4EEF1 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = ""; }; + 1D0E051B0BA5F83800B6049E /* Colors.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = Colors.plist; sourceTree = ""; }; + 1D1474950C56703C0038FA2B /* MacVim.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MacVim.h; sourceTree = ""; }; + 1D1474960C56703C0038FA2B /* MacVim.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = MacVim.m; sourceTree = ""; }; + 1D14749D0C5673AE0038FA2B /* MMAppController.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MMAppController.h; sourceTree = ""; }; + 1D14749E0C5673AE0038FA2B /* MMAppController.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = MMAppController.m; sourceTree = ""; }; + 1D1474A70C5677450038FA2B /* MMTextStorage.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MMTextStorage.h; sourceTree = ""; }; + 1D1474A80C5677450038FA2B /* MMTextStorage.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = MMTextStorage.m; sourceTree = ""; }; + 1D1474AD0C5678370038FA2B /* MMTextView.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MMTextView.h; sourceTree = ""; }; + 1D1474AE0C5678370038FA2B /* MMTextView.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = MMTextView.m; sourceTree = ""; }; + 1D1474B30C56796D0038FA2B /* MMVimController.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MMVimController.h; sourceTree = ""; }; + 1D1474B40C56796D0038FA2B /* MMVimController.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = MMVimController.m; sourceTree = ""; }; + 1D1474B90C567A910038FA2B /* MMWindowController.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MMWindowController.h; sourceTree = ""; }; + 1D1474BA0C567A910038FA2B /* MMWindowController.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = MMWindowController.m; sourceTree = ""; }; + 1D16B9EA0BA33E1E00A69B33 /* English */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = English; path = English.lproj/VimWindow.nib; sourceTree = ""; }; + 1D493D570C5247BF00AB718C /* Vim */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.executable"; name = Vim; path = ../Vim; sourceTree = SOURCE_ROOT; }; + 1D493DB30C52533B00AB718C /* PSMTabBarControl.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = PSMTabBarControl.xcodeproj; path = PSMTabBarControl/PSMTabBarControl.xcodeproj; sourceTree = ""; }; + 1D71ACA90BC702AB002F2B60 /* doc-bm-c.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = "doc-bm-c.icns"; sourceTree = ""; }; + 1D71ACAA0BC702AB002F2B60 /* doc-bm-h.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = "doc-bm-h.icns"; sourceTree = ""; }; + 1D71ACAB0BC702AB002F2B60 /* doc-bm-html.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = "doc-bm-html.icns"; sourceTree = ""; }; + 1D71ACAC0BC702AB002F2B60 /* doc-bm-java.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = "doc-bm-java.icns"; sourceTree = ""; }; + 1D71ACAD0BC702AB002F2B60 /* doc-bm-php.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = "doc-bm-php.icns"; sourceTree = ""; }; + 1D71ACAE0BC702AB002F2B60 /* doc-bm-pl.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = "doc-bm-pl.icns"; sourceTree = ""; }; + 1D71ACAF0BC702AB002F2B60 /* doc-bm-sh.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = "doc-bm-sh.icns"; sourceTree = ""; }; + 1D71ACB00BC702AB002F2B60 /* doc-bm-tex.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = "doc-bm-tex.icns"; sourceTree = ""; }; + 1D71ACB10BC702AB002F2B60 /* doc-bm-txt.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = "doc-bm-txt.icns"; sourceTree = ""; }; + 1D71ACB20BC702AB002F2B60 /* doc-bm-xml.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = "doc-bm-xml.icns"; sourceTree = ""; }; + 1D71ACB30BC702AB002F2B60 /* doc-bm.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = "doc-bm.icns"; sourceTree = ""; }; + 1DD04DEB0C529C5E006CDC2B /* Credits.rtf */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; path = Credits.rtf; sourceTree = ""; }; + 1DD703B80BA9D15D008679E9 /* vim_gloss.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = vim_gloss.icns; sourceTree = ""; }; + 1DD704300BA9F9C2008679E9 /* SpecialKeys.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = SpecialKeys.plist; sourceTree = ""; }; + 1DEE0D8A0C4E150B008E82B2 /* Attention.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Attention.png; path = Toolbar/Attention.png; sourceTree = ""; }; + 1DEE0D8B0C4E150B008E82B2 /* Copy.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Copy.png; path = Toolbar/Copy.png; sourceTree = ""; }; + 1DEE0D8C0C4E150B008E82B2 /* Cut.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Cut.png; path = Toolbar/Cut.png; sourceTree = ""; }; + 1DEE0D8D0C4E150B008E82B2 /* FindHelp.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = FindHelp.png; path = Toolbar/FindHelp.png; sourceTree = ""; }; + 1DEE0D8E0C4E150B008E82B2 /* FindNext.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = FindNext.png; path = Toolbar/FindNext.png; sourceTree = ""; }; + 1DEE0D8F0C4E150B008E82B2 /* FindPrev.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = FindPrev.png; path = Toolbar/FindPrev.png; sourceTree = ""; }; + 1DEE0D900C4E150B008E82B2 /* Help.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Help.png; path = Toolbar/Help.png; sourceTree = ""; }; + 1DEE0D910C4E150B008E82B2 /* LoadSesn.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = LoadSesn.png; path = Toolbar/LoadSesn.png; sourceTree = ""; }; + 1DEE0D920C4E150B008E82B2 /* Make.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Make.png; path = Toolbar/Make.png; sourceTree = ""; }; + 1DEE0D930C4E150B008E82B2 /* Open.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Open.png; path = Toolbar/Open.png; sourceTree = ""; }; + 1DEE0D940C4E150B008E82B2 /* Paste.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Paste.png; path = Toolbar/Paste.png; sourceTree = ""; }; + 1DEE0D950C4E150B008E82B2 /* Print.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Print.png; path = Toolbar/Print.png; sourceTree = ""; }; + 1DEE0D960C4E150B008E82B2 /* Redo.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Redo.png; path = Toolbar/Redo.png; sourceTree = ""; }; + 1DEE0D970C4E150B008E82B2 /* Replace.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Replace.png; path = Toolbar/Replace.png; sourceTree = ""; }; + 1DEE0D980C4E150B008E82B2 /* RunCtags.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = RunCtags.png; path = Toolbar/RunCtags.png; sourceTree = ""; }; + 1DEE0D990C4E150B008E82B2 /* RunScript.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = RunScript.png; path = Toolbar/RunScript.png; sourceTree = ""; }; + 1DEE0D9A0C4E150B008E82B2 /* Save.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Save.png; path = Toolbar/Save.png; sourceTree = ""; }; + 1DEE0D9B0C4E150B008E82B2 /* SaveAll.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = SaveAll.png; path = Toolbar/SaveAll.png; sourceTree = ""; }; + 1DEE0D9C0C4E150B008E82B2 /* SaveSesn.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = SaveSesn.png; path = Toolbar/SaveSesn.png; sourceTree = ""; }; + 1DEE0D9D0C4E150B008E82B2 /* TagJump.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = TagJump.png; path = Toolbar/TagJump.png; sourceTree = ""; }; + 1DEE0D9E0C4E150B008E82B2 /* Undo.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Undo.png; path = Toolbar/Undo.png; sourceTree = ""; }; + 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 29B97319FDCFA39411CA2CEA /* English */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = English; path = English.lproj/MainMenu.nib; sourceTree = ""; }; + 29B97324FDCFA39411CA2CEA /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = ""; }; + 29B97325FDCFA39411CA2CEA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = ""; }; + 32CA4F630368D1EE00C91783 /* MacVim_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MacVim_Prefix.pch; sourceTree = ""; }; + 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; }; + 8D1107320486CEB800E47090 /* MacVim.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MacVim.app; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 8D11072E0486CEB800E47090 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1DFE25A50C527BC4003000F7 /* PSMTabBarControl.framework in Frameworks */, + 8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 080E96DDFE201D6D7F000001 /* MacVim Source */ = { + isa = PBXGroup; + children = ( + 1D1474B90C567A910038FA2B /* MMWindowController.h */, + 1D1474BA0C567A910038FA2B /* MMWindowController.m */, + 1D1474B30C56796D0038FA2B /* MMVimController.h */, + 1D1474B40C56796D0038FA2B /* MMVimController.m */, + 1D1474AD0C5678370038FA2B /* MMTextView.h */, + 1D1474AE0C5678370038FA2B /* MMTextView.m */, + 1D1474A70C5677450038FA2B /* MMTextStorage.h */, + 1D1474A80C5677450038FA2B /* MMTextStorage.m */, + 1D14749D0C5673AE0038FA2B /* MMAppController.h */, + 1D14749E0C5673AE0038FA2B /* MMAppController.m */, + 1D1474950C56703C0038FA2B /* MacVim.h */, + 1D1474960C56703C0038FA2B /* MacVim.m */, + 32CA4F630368D1EE00C91783 /* MacVim_Prefix.pch */, + 29B97316FDCFA39411CA2CEA /* main.m */, + ); + name = "MacVim Source"; + sourceTree = ""; + }; + 1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */ = { + isa = PBXGroup; + children = ( + 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */, + ); + name = "Linked Frameworks"; + sourceTree = ""; + }; + 1058C7A2FEA54F0111CA2CBB /* Other Frameworks */ = { + isa = PBXGroup; + children = ( + 29B97324FDCFA39411CA2CEA /* AppKit.framework */, + 13E42FB307B3F0F600E4EEF1 /* CoreData.framework */, + 29B97325FDCFA39411CA2CEA /* Foundation.framework */, + ); + name = "Other Frameworks"; + sourceTree = ""; + }; + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 8D1107320486CEB800E47090 /* MacVim.app */, + ); + name = Products; + sourceTree = ""; + }; + 1D493D640C52482B00AB718C /* Executables */ = { + isa = PBXGroup; + children = ( + 1D493D570C5247BF00AB718C /* Vim */, + ); + name = Executables; + sourceTree = ""; + }; + 1D493DB40C52533B00AB718C /* Products */ = { + isa = PBXGroup; + children = ( + 1D493DB90C52533B00AB718C /* PSMTabBarControl.framework */, + ); + name = Products; + sourceTree = ""; + }; + 1DCE78490C460C6C006305A6 /* Icons */ = { + isa = PBXGroup; + children = ( + 1D71ACA90BC702AB002F2B60 /* doc-bm-c.icns */, + 1D71ACAA0BC702AB002F2B60 /* doc-bm-h.icns */, + 1D71ACAB0BC702AB002F2B60 /* doc-bm-html.icns */, + 1D71ACAC0BC702AB002F2B60 /* doc-bm-java.icns */, + 1D71ACAD0BC702AB002F2B60 /* doc-bm-php.icns */, + 1D71ACAE0BC702AB002F2B60 /* doc-bm-pl.icns */, + 1D71ACAF0BC702AB002F2B60 /* doc-bm-sh.icns */, + 1D71ACB00BC702AB002F2B60 /* doc-bm-tex.icns */, + 1D71ACB10BC702AB002F2B60 /* doc-bm-txt.icns */, + 1D71ACB20BC702AB002F2B60 /* doc-bm-xml.icns */, + 1D71ACB30BC702AB002F2B60 /* doc-bm.icns */, + 1DD703B80BA9D15D008679E9 /* vim_gloss.icns */, + ); + name = Icons; + sourceTree = ""; + }; + 1DE9726C0C48050600F96A9F /* Toolbar */ = { + isa = PBXGroup; + children = ( + 1DEE0D8A0C4E150B008E82B2 /* Attention.png */, + 1DEE0D8B0C4E150B008E82B2 /* Copy.png */, + 1DEE0D8C0C4E150B008E82B2 /* Cut.png */, + 1DEE0D8D0C4E150B008E82B2 /* FindHelp.png */, + 1DEE0D8E0C4E150B008E82B2 /* FindNext.png */, + 1DEE0D8F0C4E150B008E82B2 /* FindPrev.png */, + 1DEE0D900C4E150B008E82B2 /* Help.png */, + 1DEE0D910C4E150B008E82B2 /* LoadSesn.png */, + 1DEE0D920C4E150B008E82B2 /* Make.png */, + 1DEE0D930C4E150B008E82B2 /* Open.png */, + 1DEE0D940C4E150B008E82B2 /* Paste.png */, + 1DEE0D950C4E150B008E82B2 /* Print.png */, + 1DEE0D960C4E150B008E82B2 /* Redo.png */, + 1DEE0D970C4E150B008E82B2 /* Replace.png */, + 1DEE0D980C4E150B008E82B2 /* RunCtags.png */, + 1DEE0D990C4E150B008E82B2 /* RunScript.png */, + 1DEE0D9A0C4E150B008E82B2 /* Save.png */, + 1DEE0D9B0C4E150B008E82B2 /* SaveAll.png */, + 1DEE0D9C0C4E150B008E82B2 /* SaveSesn.png */, + 1DEE0D9D0C4E150B008E82B2 /* TagJump.png */, + 1DEE0D9E0C4E150B008E82B2 /* Undo.png */, + ); + name = Toolbar; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* MacVim */ = { + isa = PBXGroup; + children = ( + 1D493D640C52482B00AB718C /* Executables */, + 080E96DDFE201D6D7F000001 /* MacVim Source */, + 29B97317FDCFA39411CA2CEA /* Resources */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + ); + name = MacVim; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + 1DD04DEB0C529C5E006CDC2B /* Credits.rtf */, + 1DE9726C0C48050600F96A9F /* Toolbar */, + 1DCE78490C460C6C006305A6 /* Icons */, + 1DD704300BA9F9C2008679E9 /* SpecialKeys.plist */, + 1D0E051B0BA5F83800B6049E /* Colors.plist */, + 8D1107310486CEB800E47090 /* Info.plist */, + 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */, + 29B97318FDCFA39411CA2CEA /* MainMenu.nib */, + 1D16B9E90BA33E1E00A69B33 /* VimWindow.nib */, + ); + name = Resources; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 1D493DB30C52533B00AB718C /* PSMTabBarControl.xcodeproj */, + 1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */, + 1058C7A2FEA54F0111CA2CBB /* Other Frameworks */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 8D1107260486CEB800E47090 /* MacVim */ = { + isa = PBXNativeTarget; + buildConfigurationList = C01FCF4A08A954540054247B /* Build configuration list for PBXNativeTarget "MacVim" */; + buildPhases = ( + 8D1107290486CEB800E47090 /* Resources */, + 8D11072C0486CEB800E47090 /* Sources */, + 8D11072E0486CEB800E47090 /* Frameworks */, + 1D0DCAD80BA3604D00B6CCFA /* CopyFiles */, + 1D9EB2840C366D7B0074B739 /* CopyFiles */, + 1D670CC60C493AEC00E9771C /* ShellScript */, + ); + buildRules = ( + ); + dependencies = ( + 1D493DCD0C5254A400AB718C /* PBXTargetDependency */, + ); + name = MacVim; + productInstallPath = "$(HOME)/Applications"; + productName = MacVim; + productReference = 8D1107320486CEB800E47090 /* MacVim.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "MacVim" */; + hasScannedForEncodings = 1; + mainGroup = 29B97314FDCFA39411CA2CEA /* MacVim */; + projectDirPath = ""; + projectReferences = ( + { + ProductGroup = 1D493DB40C52533B00AB718C /* Products */; + ProjectRef = 1D493DB30C52533B00AB718C /* PSMTabBarControl.xcodeproj */; + }, + ); + targets = ( + 8D1107260486CEB800E47090 /* MacVim */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXReferenceProxy section */ + 1D493DB90C52533B00AB718C /* PSMTabBarControl.framework */ = { + isa = PBXReferenceProxy; + fileType = wrapper.framework; + path = PSMTabBarControl.framework; + remoteRef = 1D493DB80C52533B00AB718C /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; +/* End PBXReferenceProxy section */ + +/* Begin PBXResourcesBuildPhase section */ + 8D1107290486CEB800E47090 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 8D11072A0486CEB800E47090 /* MainMenu.nib in Resources */, + 8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */, + 1D16B9EB0BA33E1E00A69B33 /* VimWindow.nib in Resources */, + 1D0E051C0BA5F83800B6049E /* Colors.plist in Resources */, + 1DD703B90BA9D15D008679E9 /* vim_gloss.icns in Resources */, + 1DD704310BA9F9C2008679E9 /* SpecialKeys.plist in Resources */, + 1D71ACB40BC702AB002F2B60 /* doc-bm-c.icns in Resources */, + 1D71ACB50BC702AC002F2B60 /* doc-bm-h.icns in Resources */, + 1D71ACB60BC702AC002F2B60 /* doc-bm-html.icns in Resources */, + 1D71ACB70BC702AC002F2B60 /* doc-bm-java.icns in Resources */, + 1D71ACB80BC702AC002F2B60 /* doc-bm-php.icns in Resources */, + 1D71ACB90BC702AC002F2B60 /* doc-bm-pl.icns in Resources */, + 1D71ACBA0BC702AC002F2B60 /* doc-bm-sh.icns in Resources */, + 1D71ACBB0BC702AC002F2B60 /* doc-bm-tex.icns in Resources */, + 1D71ACBC0BC702AC002F2B60 /* doc-bm-txt.icns in Resources */, + 1D71ACBD0BC702AC002F2B60 /* doc-bm-xml.icns in Resources */, + 1D71ACBE0BC702AC002F2B60 /* doc-bm.icns in Resources */, + 1DEE0D9F0C4E150B008E82B2 /* Attention.png in Resources */, + 1DEE0DA00C4E150B008E82B2 /* Copy.png in Resources */, + 1DEE0DA10C4E150B008E82B2 /* Cut.png in Resources */, + 1DEE0DA20C4E150B008E82B2 /* FindHelp.png in Resources */, + 1DEE0DA30C4E150B008E82B2 /* FindNext.png in Resources */, + 1DEE0DA40C4E150B008E82B2 /* FindPrev.png in Resources */, + 1DEE0DA50C4E150B008E82B2 /* Help.png in Resources */, + 1DEE0DA60C4E150B008E82B2 /* LoadSesn.png in Resources */, + 1DEE0DA70C4E150B008E82B2 /* Make.png in Resources */, + 1DEE0DA80C4E150B008E82B2 /* Open.png in Resources */, + 1DEE0DA90C4E150B008E82B2 /* Paste.png in Resources */, + 1DEE0DAA0C4E150B008E82B2 /* Print.png in Resources */, + 1DEE0DAB0C4E150B008E82B2 /* Redo.png in Resources */, + 1DEE0DAC0C4E150B008E82B2 /* Replace.png in Resources */, + 1DEE0DAD0C4E150B008E82B2 /* RunCtags.png in Resources */, + 1DEE0DAE0C4E150B008E82B2 /* RunScript.png in Resources */, + 1DEE0DAF0C4E150B008E82B2 /* Save.png in Resources */, + 1DEE0DB00C4E150B008E82B2 /* SaveAll.png in Resources */, + 1DEE0DB10C4E150B008E82B2 /* SaveSesn.png in Resources */, + 1DEE0DB20C4E150B008E82B2 /* TagJump.png in Resources */, + 1DEE0DB30C4E150B008E82B2 /* Undo.png in Resources */, + 1DD04DEC0C529C5E006CDC2B /* Credits.rtf in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 1D670CC60C493AEC00E9771C /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 12; + files = ( + ); + inputPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "mkdir $TARGET_BUILD_DIR/MacVim.app/Contents/Resources/vim\ncp -R ../../runtime/ $TARGET_BUILD_DIR/MacVim.app/Contents/Resources/vim/runtime/"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 8D11072C0486CEB800E47090 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 8D11072D0486CEB800E47090 /* main.m in Sources */, + 1D1474980C56703C0038FA2B /* MacVim.m in Sources */, + 1D1474A00C5673AE0038FA2B /* MMAppController.m in Sources */, + 1D1474AA0C5677450038FA2B /* MMTextStorage.m in Sources */, + 1D1474B00C5678370038FA2B /* MMTextView.m in Sources */, + 1D1474B60C56796D0038FA2B /* MMVimController.m in Sources */, + 1D1474BC0C567A910038FA2B /* MMWindowController.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 1D493DCD0C5254A400AB718C /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = PSMTabBarControlFramework; + targetProxy = 1D493DCC0C5254A400AB718C /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */ = { + isa = PBXVariantGroup; + children = ( + 089C165DFE840E0CC02AAC07 /* English */, + ); + name = InfoPlist.strings; + sourceTree = ""; + }; + 1D16B9E90BA33E1E00A69B33 /* VimWindow.nib */ = { + isa = PBXVariantGroup; + children = ( + 1D16B9EA0BA33E1E00A69B33 /* English */, + ); + name = VimWindow.nib; + sourceTree = ""; + }; + 29B97318FDCFA39411CA2CEA /* MainMenu.nib */ = { + isa = PBXVariantGroup; + children = ( + 29B97319FDCFA39411CA2CEA /* English */, + ); + name = MainMenu.nib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1DF7D93A0BC05175006CF13F /* My Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + ppc, + i386, + ); + COPY_PHASE_STRIP = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(FRAMEWORK_SEARCH_PATHS_QUOTED_1)", + "$(FRAMEWORK_SEARCH_PATHS_QUOTED_2)", + "$(FRAMEWORK_SEARCH_PATHS_QUOTED_3)", + ); + FRAMEWORK_SEARCH_PATHS_QUOTED_1 = "\"$(SRCROOT)/../../../../Library/Frameworks\""; + GCC_DYNAMIC_NO_PIC = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_MODEL_TUNING = G5; + GCC_OPTIMIZATION_LEVEL = 0; + HEADER_SEARCH_PATHS = PSMTabBarControl/source/; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(HOME)/Applications"; + PRODUCT_NAME = MacVim; + WRAPPER_EXTENSION = app; + }; + name = "My Release"; + }; + 1DF7D93B0BC05175006CF13F /* My Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + PREBINDING = NO; + SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk; + }; + name = "My Release"; + }; + C01FCF4B08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + ppc, + i386, + ); + COPY_PHASE_STRIP = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(FRAMEWORK_SEARCH_PATHS_QUOTED_1)", + "$(FRAMEWORK_SEARCH_PATHS_QUOTED_2)", + "$(FRAMEWORK_SEARCH_PATHS_QUOTED_3)", + ); + FRAMEWORK_SEARCH_PATHS_QUOTED_1 = "\"$(SRCROOT)/../../../../Library/Frameworks\""; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_MODEL_TUNING = G5; + GCC_OPTIMIZATION_LEVEL = 0; + HEADER_SEARCH_PATHS = PSMTabBarControl/source/; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(HOME)/Applications"; + PRODUCT_NAME = MacVim; + WRAPPER_EXTENSION = app; + ZERO_LINK = YES; + }; + name = Debug; + }; + C01FCF4C08A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + ppc, + i386, + ); + COPY_PHASE_STRIP = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(FRAMEWORK_SEARCH_PATHS_QUOTED_1)", + "$(FRAMEWORK_SEARCH_PATHS_QUOTED_2)", + "$(FRAMEWORK_SEARCH_PATHS_QUOTED_3)", + ); + FRAMEWORK_SEARCH_PATHS_QUOTED_1 = "\"$(SRCROOT)/../../../../Library/Frameworks\""; + GCC_DYNAMIC_NO_PIC = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = G5; + GCC_OPTIMIZATION_LEVEL = s; + HEADER_SEARCH_PATHS = PSMTabBarControl/source/; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(HOME)/Applications"; + PRODUCT_NAME = MacVim; + WRAPPER_EXTENSION = app; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + PREBINDING = NO; + SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + PREBINDING = NO; + SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + C01FCF4A08A954540054247B /* Build configuration list for PBXNativeTarget "MacVim" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4B08A954540054247B /* Debug */, + C01FCF4C08A954540054247B /* Release */, + 1DF7D93A0BC05175006CF13F /* My Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "MacVim" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + 1DF7D93B0BC05175006CF13F /* My Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/MacVim.xcodeproj/winckler.mode1 b/MacVim.xcodeproj/winckler.mode1 new file mode 100644 index 0000000000..d8b9ba9ed1 --- /dev/null +++ b/MacVim.xcodeproj/winckler.mode1 @@ -0,0 +1,1348 @@ + + + + + ActivePerspectiveName + Project + AllowedModules + + + BundleLoadPath + + MaxInstances + n + Module + PBXSmartGroupTreeModule + Name + Groups and Files Outline View + + + BundleLoadPath + + MaxInstances + n + Module + PBXNavigatorGroup + Name + Editor + + + BundleLoadPath + + MaxInstances + n + Module + XCTaskListModule + Name + Task List + + + BundleLoadPath + + MaxInstances + n + Module + XCDetailModule + Name + File and Smart Group Detail Viewer + + + BundleLoadPath + + MaxInstances + 1 + Module + PBXBuildResultsModule + Name + Detailed Build Results Viewer + + + BundleLoadPath + + MaxInstances + 1 + Module + PBXProjectFindModule + Name + Project Batch Find Tool + + + BundleLoadPath + + MaxInstances + n + Module + PBXRunSessionModule + Name + Run Log + + + BundleLoadPath + + MaxInstances + n + Module + PBXBookmarksModule + Name + Bookmarks Tool + + + BundleLoadPath + + MaxInstances + n + Module + PBXClassBrowserModule + Name + Class Browser + + + BundleLoadPath + + MaxInstances + n + Module + PBXCVSModule + Name + Source Code Control Tool + + + BundleLoadPath + + MaxInstances + n + Module + PBXDebugBreakpointsModule + Name + Debug Breakpoints Tool + + + BundleLoadPath + + MaxInstances + n + Module + XCDockableInspector + Name + Inspector + + + BundleLoadPath + + MaxInstances + n + Module + PBXOpenQuicklyModule + Name + Open Quickly Tool + + + BundleLoadPath + + MaxInstances + 1 + Module + PBXDebugSessionModule + Name + Debugger + + + BundleLoadPath + + MaxInstances + 1 + Module + PBXDebugCLIModule + Name + Debug Console + + + Description + DefaultDescriptionKey + DockingSystemVisible + + Extension + mode1 + FavBarConfig + + PBXProjectModuleGUID + 1D16B9DC0BA33BB000A69B33 + XCBarModuleItemNames + + XCBarModuleItems + + + FirstTimeWindowDisplayed + + Identifier + com.apple.perspectives.project.mode1 + MajorVersion + 31 + MinorVersion + 1 + Name + Default + Notifications + + OpenEditors + + PerspectiveWidths + + -1 + -1 + + Perspectives + + + ChosenToolbarItems + + active-target-popup + active-buildstyle-popup + action + NSToolbarFlexibleSpaceItem + buildOrClean + build-and-runOrDebug + com.apple.ide.PBXToolbarStopButton + get-info + toggle-editor + NSToolbarFlexibleSpaceItem + com.apple.pbx.toolbar.searchfield + + ControllerClassBaseName + + IconName + WindowOfProjectWithEditor + Identifier + perspective.project + IsVertical + + Layout + + + BecomeActive + + ContentConfiguration + + PBXBottomSmartGroupGIDs + + 1C37FBAC04509CD000000102 + 1C37FAAC04509CD000000102 + 1C08E77C0454961000C914BD + 1C37FABC05509CD000000102 + 1C37FABC05539CD112110102 + E2644B35053B69B200211256 + 1C37FABC04509CD000100104 + 1CC0EA4004350EF90044410B + 1CC0EA4004350EF90041110B + + PBXProjectModuleGUID + 1CE0B1FE06471DED0097A5F4 + PBXProjectModuleLabel + Files + PBXProjectStructureProvided + yes + PBXSmartGroupTreeModuleColumnData + + PBXSmartGroupTreeModuleColumnWidthsKey + + 186 + + PBXSmartGroupTreeModuleColumnsKey_v4 + + MainColumn + + + PBXSmartGroupTreeModuleOutlineStateKey_v7 + + PBXSmartGroupTreeModuleOutlineStateExpansionKey + + 29B97314FDCFA39411CA2CEA + 1C37FBAC04509CD000000102 + 1C37FABC05509CD000000102 + + PBXSmartGroupTreeModuleOutlineStateSelectionKey + + + 0 + + + PBXSmartGroupTreeModuleOutlineStateVisibleRectKey + {{0, 0}, {186, 338}} + + PBXTopSmartGroupGIDs + + XCIncludePerspectivesSwitch + + XCSharingToken + com.apple.Xcode.GFSharingToken + + GeometryConfiguration + + Frame + {{0, 0}, {203, 356}} + GroupTreeTableConfiguration + + MainColumn + 186 + + RubberWindowFrame + 168 349 690 397 0 0 1024 746 + + Module + PBXSmartGroupTreeModule + Proportion + 203pt + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 1CE0B20306471E060097A5F4 + PBXProjectModuleLabel + MyNewFile14.java + PBXSplitModuleInNavigatorKey + + Split0 + + PBXProjectModuleGUID + 1CE0B20406471E060097A5F4 + PBXProjectModuleLabel + MyNewFile14.java + + SplitCount + 1 + + StatusBarVisibility + + + GeometryConfiguration + + Frame + {{0, 0}, {482, 0}} + RubberWindowFrame + 168 349 690 397 0 0 1024 746 + + Module + PBXNavigatorGroup + Proportion + 0pt + + + ContentConfiguration + + PBXProjectModuleGUID + 1CE0B20506471E060097A5F4 + PBXProjectModuleLabel + Detail + + GeometryConfiguration + + Frame + {{0, 5}, {482, 351}} + RubberWindowFrame + 168 349 690 397 0 0 1024 746 + + Module + XCDetailModule + Proportion + 351pt + + + Proportion + 482pt + + + Name + Project + ServiceClasses + + XCModuleDock + PBXSmartGroupTreeModule + XCModuleDock + PBXNavigatorGroup + XCDetailModule + + TableOfContents + + 1DDE37030C572B47007FB583 + 1CE0B1FE06471DED0097A5F4 + 1DDE37040C572B47007FB583 + 1CE0B20306471E060097A5F4 + 1CE0B20506471E060097A5F4 + + ToolbarConfiguration + xcode.toolbar.config.default + + + ControllerClassBaseName + + IconName + WindowOfProject + Identifier + perspective.morph + IsVertical + 0 + Layout + + + BecomeActive + 1 + ContentConfiguration + + PBXBottomSmartGroupGIDs + + 1C37FBAC04509CD000000102 + 1C37FAAC04509CD000000102 + 1C08E77C0454961000C914BD + 1C37FABC05509CD000000102 + 1C37FABC05539CD112110102 + E2644B35053B69B200211256 + 1C37FABC04509CD000100104 + 1CC0EA4004350EF90044410B + 1CC0EA4004350EF90041110B + + PBXProjectModuleGUID + 11E0B1FE06471DED0097A5F4 + PBXProjectModuleLabel + Files + PBXProjectStructureProvided + yes + PBXSmartGroupTreeModuleColumnData + + PBXSmartGroupTreeModuleColumnWidthsKey + + 186 + + PBXSmartGroupTreeModuleColumnsKey_v4 + + MainColumn + + + PBXSmartGroupTreeModuleOutlineStateKey_v7 + + PBXSmartGroupTreeModuleOutlineStateExpansionKey + + 29B97314FDCFA39411CA2CEA + 1C37FABC05509CD000000102 + + PBXSmartGroupTreeModuleOutlineStateSelectionKey + + + 0 + + + PBXSmartGroupTreeModuleOutlineStateVisibleRectKey + {{0, 0}, {186, 337}} + + PBXTopSmartGroupGIDs + + XCIncludePerspectivesSwitch + 1 + XCSharingToken + com.apple.Xcode.GFSharingToken + + GeometryConfiguration + + Frame + {{0, 0}, {203, 355}} + GroupTreeTableConfiguration + + MainColumn + 186 + + RubberWindowFrame + 373 269 690 397 0 0 1440 878 + + Module + PBXSmartGroupTreeModule + Proportion + 100% + + + Name + Morph + PreferredWidth + 300 + ServiceClasses + + XCModuleDock + PBXSmartGroupTreeModule + + TableOfContents + + 11E0B1FE06471DED0097A5F4 + + ToolbarConfiguration + xcode.toolbar.config.default.short + + + PerspectivesBarVisible + + ShelfIsVisible + + SourceDescription + file at '/System/Library/PrivateFrameworks/DevToolsInterface.framework/Versions/A/Resources/XCPerspectivesSpecificationMode1.xcperspec' + StatusbarIsVisible + + TimeStamp + 0.0 + ToolbarDisplayMode + 1 + ToolbarIsVisible + + ToolbarSizeMode + 1 + Type + Perspectives + UpdateMessage + The Default Workspace in this version of Xcode now includes support to hide and show the detail view (what has been referred to as the "Metro-Morph" feature). You must discard your current Default Workspace settings and update to the latest Default Workspace in order to gain this feature. Do you wish to update to the latest Workspace defaults for project '%@'? + WindowJustification + 5 + WindowOrderList + + 1D16B9EF0BA33E3800A69B33 + 1C0AD2B3069F1EA900FABCE6 + /Users/winckler/Projects/vim70/src/MacVim/MacVim.xcodeproj + + WindowString + 168 349 690 397 0 0 1024 746 + WindowTools + + + FirstTimeWindowDisplayed + + Identifier + windowTool.build + IsVertical + + Layout + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 1CD0528F0623707200166675 + PBXProjectModuleLabel + + StatusBarVisibility + + + GeometryConfiguration + + Frame + {{0, 0}, {836, 194}} + RubberWindowFrame + 188 225 836 476 0 0 1024 746 + + Module + PBXNavigatorGroup + Proportion + 194pt + + + ContentConfiguration + + PBXProjectModuleGUID + XCMainBuildResultsModuleGUID + PBXProjectModuleLabel + Build + XCBuildResultsTrigger_Collapse + 1021 + XCBuildResultsTrigger_Open + 1011 + + GeometryConfiguration + + Frame + {{0, 199}, {836, 236}} + RubberWindowFrame + 188 225 836 476 0 0 1024 746 + + Module + PBXBuildResultsModule + Proportion + 236pt + + + Proportion + 435pt + + + Name + Build Results + ServiceClasses + + PBXBuildResultsModule + + StatusbarIsVisible + + TableOfContents + + 1D16B9EF0BA33E3800A69B33 + 1DDE37050C572B47007FB583 + 1CD0528F0623707200166675 + XCMainBuildResultsModuleGUID + + ToolbarConfiguration + xcode.toolbar.config.build + WindowString + 188 225 836 476 0 0 1024 746 + WindowToolGUID + 1D16B9EF0BA33E3800A69B33 + WindowToolIsVisible + + + + FirstTimeWindowDisplayed + + Identifier + windowTool.debugger + IsVertical + + Layout + + + Dock + + + ContentConfiguration + + Debugger + + HorizontalSplitView + + _collapsingFrameDimension + 0.0 + _indexOfCollapsedView + 0 + _percentageOfCollapsedView + 0.0 + isCollapsed + yes + sizes + + {{0, 0}, {411, 339}} + {{411, 0}, {613, 339}} + + + VerticalSplitView + + _collapsingFrameDimension + 0.0 + _indexOfCollapsedView + 0 + _percentageOfCollapsedView + 0.0 + isCollapsed + yes + sizes + + {{0, 0}, {1024, 339}} + {{0, 339}, {1024, 306}} + + + + LauncherConfigVersion + 8 + PBXProjectModuleGUID + 1C162984064C10D400B95A72 + PBXProjectModuleLabel + Debug - GLUTExamples (Underwater) + + GeometryConfiguration + + DebugConsoleDrawerSize + {100, 120} + DebugConsoleVisible + None + DebugConsoleWindowFrame + {{200, 200}, {500, 300}} + DebugSTDIOWindowFrame + {{200, 200}, {500, 300}} + Frame + {{0, 0}, {1024, 645}} + RubberWindowFrame + 0 60 1024 686 0 0 1024 746 + + Module + PBXDebugSessionModule + Proportion + 645pt + + + Proportion + 645pt + + + Name + Debugger + ServiceClasses + + PBXDebugSessionModule + + StatusbarIsVisible + + TableOfContents + + 1CD10A99069EF8BA00B06720 + 1D14746A0C566C890038FA2B + 1C162984064C10D400B95A72 + 1D14746B0C566C890038FA2B + 1D14746C0C566C890038FA2B + 1D14746D0C566C890038FA2B + 1D14746E0C566C890038FA2B + 1D14746F0C566C890038FA2B + 1D1474700C566C890038FA2B + + ToolbarConfiguration + xcode.toolbar.config.debug + WindowString + 0 60 1024 686 0 0 1024 746 + WindowToolGUID + 1CD10A99069EF8BA00B06720 + WindowToolIsVisible + + + + Identifier + windowTool.find + Layout + + + Dock + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 1CDD528C0622207200134675 + PBXProjectModuleLabel + <No Editor> + PBXSplitModuleInNavigatorKey + + Split0 + + PBXProjectModuleGUID + 1CD0528D0623707200166675 + + SplitCount + 1 + + StatusBarVisibility + 1 + + GeometryConfiguration + + Frame + {{0, 0}, {781, 167}} + RubberWindowFrame + 62 385 781 470 0 0 1440 878 + + Module + PBXNavigatorGroup + Proportion + 781pt + + + Proportion + 50% + + + BecomeActive + 1 + ContentConfiguration + + PBXProjectModuleGUID + 1CD0528E0623707200166675 + PBXProjectModuleLabel + Project Find + + GeometryConfiguration + + Frame + {{8, 0}, {773, 254}} + RubberWindowFrame + 62 385 781 470 0 0 1440 878 + + Module + PBXProjectFindModule + Proportion + 50% + + + Proportion + 428pt + + + Name + Project Find + ServiceClasses + + PBXProjectFindModule + + StatusbarIsVisible + 1 + TableOfContents + + 1C530D57069F1CE1000CFCEE + 1C530D58069F1CE1000CFCEE + 1C530D59069F1CE1000CFCEE + 1CDD528C0622207200134675 + 1C530D5A069F1CE1000CFCEE + 1CE0B1FE06471DED0097A5F4 + 1CD0528E0623707200166675 + + WindowString + 62 385 781 470 0 0 1440 878 + WindowToolGUID + 1C530D57069F1CE1000CFCEE + WindowToolIsVisible + 0 + + + Identifier + MENUSEPARATOR + + + FirstTimeWindowDisplayed + + Identifier + windowTool.debuggerConsole + IsVertical + + Layout + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 1C78EAAC065D492600B07095 + PBXProjectModuleLabel + Debugger Console + + GeometryConfiguration + + Frame + {{0, 0}, {836, 380}} + RubberWindowFrame + 118 143 836 421 0 0 1024 746 + + Module + PBXDebugCLIModule + Proportion + 380pt + + + Proportion + 380pt + + + Name + Debugger Console + ServiceClasses + + PBXDebugCLIModule + + StatusbarIsVisible + + TableOfContents + + 1DE444730BA4445100C4C77A + 1D1474710C566C890038FA2B + 1C78EAAC065D492600B07095 + + WindowString + 118 143 836 421 0 0 1024 746 + WindowToolGUID + 1DE444730BA4445100C4C77A + WindowToolIsVisible + + + + FirstTimeWindowDisplayed + + Identifier + windowTool.run + IsVertical + + Layout + + + Dock + + + ContentConfiguration + + LauncherConfigVersion + 3 + PBXProjectModuleGUID + 1CD0528B0623707200166675 + PBXProjectModuleLabel + Run + Runner + + HorizontalSplitView + + _collapsingFrameDimension + 0.0 + _indexOfCollapsedView + 0 + _percentageOfCollapsedView + 0.0 + isCollapsed + yes + sizes + + {{0, 0}, {493, 167}} + {{0, 176}, {493, 267}} + + + VerticalSplitView + + _collapsingFrameDimension + 0.0 + _indexOfCollapsedView + 0 + _percentageOfCollapsedView + 0.0 + isCollapsed + yes + sizes + + {{0, 0}, {405, 443}} + {{414, 0}, {514, 443}} + + + + + GeometryConfiguration + + Frame + {{0, 0}, {897, 256}} + RubberWindowFrame + 1 65 897 297 0 0 1024 746 + + Module + PBXRunSessionModule + Proportion + 256pt + + + Proportion + 256pt + + + Name + Run Log + ServiceClasses + + PBXRunSessionModule + + StatusbarIsVisible + + TableOfContents + + 1C0AD2B3069F1EA900FABCE6 + 1DDE36F90C572B25007FB583 + 1CD0528B0623707200166675 + 1DDE36FA0C572B25007FB583 + + ToolbarConfiguration + xcode.toolbar.config.run + WindowString + 1 65 897 297 0 0 1024 746 + WindowToolGUID + 1C0AD2B3069F1EA900FABCE6 + WindowToolIsVisible + + + + Identifier + windowTool.scm + Layout + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 1C78EAB2065D492600B07095 + PBXProjectModuleLabel + <No Editor> + PBXSplitModuleInNavigatorKey + + Split0 + + PBXProjectModuleGUID + 1C78EAB3065D492600B07095 + + SplitCount + 1 + + StatusBarVisibility + 1 + + GeometryConfiguration + + Frame + {{0, 0}, {452, 0}} + RubberWindowFrame + 743 379 452 308 0 0 1280 1002 + + Module + PBXNavigatorGroup + Proportion + 0pt + + + BecomeActive + 1 + ContentConfiguration + + PBXProjectModuleGUID + 1CD052920623707200166675 + PBXProjectModuleLabel + SCM + + GeometryConfiguration + + ConsoleFrame + {{0, 259}, {452, 0}} + Frame + {{0, 7}, {452, 259}} + RubberWindowFrame + 743 379 452 308 0 0 1280 1002 + TableConfiguration + + Status + 30 + FileName + 199 + Path + 197.09500122070312 + + TableFrame + {{0, 0}, {452, 250}} + + Module + PBXCVSModule + Proportion + 262pt + + + Proportion + 266pt + + + Name + SCM + ServiceClasses + + PBXCVSModule + + StatusbarIsVisible + 1 + TableOfContents + + 1C78EAB4065D492600B07095 + 1C78EAB5065D492600B07095 + 1C78EAB2065D492600B07095 + 1CD052920623707200166675 + + ToolbarConfiguration + xcode.toolbar.config.scm + WindowString + 743 379 452 308 0 0 1280 1002 + + + FirstTimeWindowDisplayed + + Identifier + windowTool.breakpoints + IsVertical + + Layout + + + Dock + + + ContentConfiguration + + PBXBottomSmartGroupGIDs + + 1C77FABC04509CD000000102 + + PBXProjectModuleGUID + 1CE0B1FE06471DED0097A5F4 + PBXProjectModuleLabel + Files + PBXProjectStructureProvided + no + PBXSmartGroupTreeModuleColumnData + + PBXSmartGroupTreeModuleColumnWidthsKey + + 168 + + PBXSmartGroupTreeModuleColumnsKey_v4 + + MainColumn + + + PBXSmartGroupTreeModuleOutlineStateKey_v7 + + PBXSmartGroupTreeModuleOutlineStateExpansionKey + + 1C77FABC04509CD000000102 + + PBXSmartGroupTreeModuleOutlineStateSelectionKey + + + 0 + + + PBXSmartGroupTreeModuleOutlineStateVisibleRectKey + {{0, 0}, {168, 350}} + + PBXTopSmartGroupGIDs + + XCIncludePerspectivesSwitch + + + GeometryConfiguration + + Frame + {{0, 0}, {185, 368}} + GroupTreeTableConfiguration + + MainColumn + 168 + + RubberWindowFrame + 61 303 744 409 0 0 1024 746 + + Module + PBXSmartGroupTreeModule + Proportion + 185pt + + + BecomeActive + + ContentConfiguration + + PBXProjectModuleGUID + 1CA1AED706398EBD00589147 + PBXProjectModuleLabel + Detail + + GeometryConfiguration + + Frame + {{190, 0}, {554, 368}} + RubberWindowFrame + 61 303 744 409 0 0 1024 746 + + Module + XCDetailModule + Proportion + 554pt + + + Proportion + 368pt + + + MajorVersion + 2 + MinorVersion + 0 + Name + Breakpoints + ServiceClasses + + PBXSmartGroupTreeModule + XCDetailModule + + StatusbarIsVisible + + TableOfContents + + 1DDA69300C55296D00F5D112 + 1DDA69310C55296D00F5D112 + 1CE0B1FE06471DED0097A5F4 + 1CA1AED706398EBD00589147 + + ToolbarConfiguration + xcode.toolbar.config.breakpoints + WindowString + 61 303 744 409 0 0 1024 746 + WindowToolGUID + 1DDA69300C55296D00F5D112 + WindowToolIsVisible + + + + Identifier + windowTool.debugAnimator + Layout + + + Dock + + + Module + PBXNavigatorGroup + Proportion + 100% + + + Proportion + 100% + + + Name + Debug Visualizer + ServiceClasses + + PBXNavigatorGroup + + StatusbarIsVisible + 1 + ToolbarConfiguration + xcode.toolbar.config.debugAnimator + WindowString + 100 100 700 500 0 0 1280 1002 + + + Identifier + windowTool.bookmarks + Layout + + + Dock + + + Module + PBXBookmarksModule + Proportion + 100% + + + Proportion + 100% + + + Name + Bookmarks + ServiceClasses + + PBXBookmarksModule + + StatusbarIsVisible + 0 + WindowString + 538 42 401 187 0 0 1280 1002 + + + Identifier + windowTool.classBrowser + Layout + + + Dock + + + BecomeActive + 1 + ContentConfiguration + + OptionsSetName + Hierarchy, all classes + PBXProjectModuleGUID + 1CA6456E063B45B4001379D8 + PBXProjectModuleLabel + Class Browser - NSObject + + GeometryConfiguration + + ClassesFrame + {{0, 0}, {374, 96}} + ClassesTreeTableConfiguration + + PBXClassNameColumnIdentifier + 208 + PBXClassBookColumnIdentifier + 22 + + Frame + {{0, 0}, {630, 331}} + MembersFrame + {{0, 105}, {374, 395}} + MembersTreeTableConfiguration + + PBXMemberTypeIconColumnIdentifier + 22 + PBXMemberNameColumnIdentifier + 216 + PBXMemberTypeColumnIdentifier + 97 + PBXMemberBookColumnIdentifier + 22 + + PBXModuleWindowStatusBarHidden2 + 1 + RubberWindowFrame + 385 179 630 352 0 0 1440 878 + + Module + PBXClassBrowserModule + Proportion + 332pt + + + Proportion + 332pt + + + Name + Class Browser + ServiceClasses + + PBXClassBrowserModule + + StatusbarIsVisible + 0 + TableOfContents + + 1C0AD2AF069F1E9B00FABCE6 + 1C0AD2B0069F1E9B00FABCE6 + 1CA6456E063B45B4001379D8 + + ToolbarConfiguration + xcode.toolbar.config.classbrowser + WindowString + 385 179 630 352 0 0 1440 878 + WindowToolGUID + 1C0AD2AF069F1E9B00FABCE6 + WindowToolIsVisible + 0 + + + + diff --git a/MacVim.xcodeproj/winckler.pbxuser b/MacVim.xcodeproj/winckler.pbxuser new file mode 100644 index 0000000000..04c3529812 --- /dev/null +++ b/MacVim.xcodeproj/winckler.pbxuser @@ -0,0 +1,247 @@ +// !$*UTF8*$! +{ + 089C165DFE840E0CC02AAC07 /* English */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {784, 608}}"; + sepNavSelRange = "{88, 0}"; + sepNavVisRect = "{{0, 0}, {784, 608}}"; + sepNavWindowFrame = "{{15, 4}, {823, 737}}"; + }; + }; + 1D0DC9EB0BA34B3D00B6CCFA /* VimWindowController.m */ = { + isa = PBXFileReference; + fileEncoding = 30; + lastKnownFileType = sourcecode.c.objc; + name = VimWindowController.m; + path = /Users/winckler/Projects/vim70/src/MacVim/VimWindowController.m; + sourceTree = ""; + }; + 1D16B9CF0BA33BAE00A69B33 /* MacVim */ = { + isa = PBXExecutable; + activeArgIndex = 2147483647; + activeArgIndices = ( + NO, + ); + argumentStrings = ( + "-nowindow 1", + ); + autoAttachOnCrash = 1; + configStateDict = { + }; + customDataFormattersEnabled = 1; + debuggerPlugin = GDBDebugging; + disassemblyDisplayState = 0; + dylibVariantSuffix = ""; + enableDebugStr = 1; + environmentEntries = ( + ); + executableSystemSymbolLevel = 0; + executableUserSymbolLevel = 0; + libgmallocEnabled = 0; + name = MacVim; + savedGlobals = { + }; + sourceDirectories = ( + ); + variableFormatDictionary = { + }; + }; + 1D16B9DD0BA33BB000A69B33 /* Source Control */ = { + isa = PBXSourceControlManager; + fallbackIsa = XCSourceControlManager; + isSCMEnabled = 0; + scmConfiguration = { + }; + scmType = ""; + }; + 1D16B9DE0BA33BB000A69B33 /* Code sense */ = { + isa = PBXCodeSenseManager; + indexTemplatePath = ""; + }; + 1D9B9FEF0BB34E7700F878F2 /* [NSException raise] */ = { + isa = PBXSymbolicBreakpoint; + actions = ( + ); + breakpointStyle = 1; + continueAfterActions = 0; + delayBeforeContinue = 0; + hitCount = 1; + location = Foundation; + modificationTime = 206990469.69439; + state = 1; + symbolName = "[NSException raise]"; + }; + 1DD704300BA9F9C2008679E9 /* SpecialKeys.plist */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {797, 1008}}"; + sepNavSelRange = "{0, 0}"; + sepNavVisRect = "{{0, 192}, {567, 595}}"; + sepNavWindowFrame = "{{15, 17}, {606, 724}}"; + }; + }; + 1DDA694B0C552B2B00F5D112 /* VimWindowController.m:539 */ = { + isa = PBXFileBreakpoint; + actions = ( + ); + breakpointStyle = 0; + continueAfterActions = 0; + delayBeforeContinue = 0; + fileReference = 1D0DC9EB0BA34B3D00B6CCFA /* VimWindowController.m */; + functionName = "-windowDidResize:"; + hitCount = 1; + lineNumber = 539; + location = VimWindowController.ob; + modificationTime = 206990476.954509; + state = 1; + }; + 1DE445650BA493EC00C4C77A /* XCBreakpointsBucket */ = { + isa = XCBreakpointsBucket; + name = "Project Breakpoints"; + objects = ( + 1D9B9FEF0BB34E7700F878F2 /* [NSException raise] */, + 1DDA694B0C552B2B00F5D112 /* VimWindowController.m:539 */, + ); + }; + 29B97313FDCFA39411CA2CEA /* Project object */ = { + activeBuildConfigurationName = Release; + activeExecutable = 1D16B9CF0BA33BAE00A69B33 /* MacVim */; + activeTarget = 8D1107260486CEB800E47090 /* MacVim */; + addToTargets = ( + 8D1107260486CEB800E47090 /* MacVim */, + ); + breakpoints = ( + 1D9B9FEF0BB34E7700F878F2 /* [NSException raise] */, + 1DDA694B0C552B2B00F5D112 /* VimWindowController.m:539 */, + ); + breakpointsGroup = 1DE445650BA493EC00C4C77A /* XCBreakpointsBucket */; + codeSenseManager = 1D16B9DE0BA33BB000A69B33 /* Code sense */; + executables = ( + 1D16B9CF0BA33BAE00A69B33 /* MacVim */, + ); + perUserDictionary = { + "PBXConfiguration.PBXBreakpointsDataSource.v1:1CA1AED706398EBD00589147" = { + PBXFileTableDataSourceColumnSortingDirectionKey = "-1"; + PBXFileTableDataSourceColumnSortingKey = PBXBreakpointsDataSource_BreakpointID; + PBXFileTableDataSourceColumnWidthsKey = ( + 20, + 20, + 210, + 20, + 110, + 109, + 20, + ); + PBXFileTableDataSourceColumnsKey = ( + PBXBreakpointsDataSource_ActionID, + PBXBreakpointsDataSource_TypeID, + PBXBreakpointsDataSource_BreakpointID, + PBXBreakpointsDataSource_UseID, + PBXBreakpointsDataSource_LocationID, + PBXBreakpointsDataSource_ConditionID, + PBXBreakpointsDataSource_ContinueID, + ); + }; + PBXConfiguration.PBXFileTableDataSource3.PBXExecutablesDataSource = { + PBXFileTableDataSourceColumnSortingDirectionKey = "-1"; + PBXFileTableDataSourceColumnSortingKey = PBXExecutablesDataSource_NameID; + PBXFileTableDataSourceColumnWidthsKey = ( + 22, + 300, + 130, + ); + PBXFileTableDataSourceColumnsKey = ( + PBXExecutablesDataSource_ActiveFlagID, + PBXExecutablesDataSource_NameID, + PBXExecutablesDataSource_CommentsID, + ); + }; + PBXConfiguration.PBXFileTableDataSource3.PBXFileTableDataSource = { + PBXFileTableDataSourceColumnSortingDirectionKey = "-1"; + PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID; + PBXFileTableDataSourceColumnWidthsKey = ( + 20, + 243, + 20, + 48, + 43, + 43, + 20, + ); + PBXFileTableDataSourceColumnsKey = ( + PBXFileDataSource_FiletypeID, + PBXFileDataSource_Filename_ColumnID, + PBXFileDataSource_Built_ColumnID, + PBXFileDataSource_ObjectSize_ColumnID, + PBXFileDataSource_Errors_ColumnID, + PBXFileDataSource_Warnings_ColumnID, + PBXFileDataSource_Target_ColumnID, + ); + }; + PBXConfiguration.PBXFileTableDataSource3.PBXSymbolsDataSource = { + PBXFileTableDataSourceColumnSortingDirectionKey = "-1"; + PBXFileTableDataSourceColumnSortingKey = PBXSymbolsDataSource_SymbolNameID; + PBXFileTableDataSourceColumnWidthsKey = ( + 16, + 200, + 50, + 183, + ); + PBXFileTableDataSourceColumnsKey = ( + PBXSymbolsDataSource_SymbolTypeIconID, + PBXSymbolsDataSource_SymbolNameID, + PBXSymbolsDataSource_SymbolTypeID, + PBXSymbolsDataSource_ReferenceNameID, + ); + }; + PBXConfiguration.PBXTargetDataSource.PBXTargetDataSource = { + PBXFileTableDataSourceColumnSortingDirectionKey = "-1"; + PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID; + PBXFileTableDataSourceColumnWidthsKey = ( + 20, + 200, + 63, + 20, + 48, + 43, + 43, + ); + PBXFileTableDataSourceColumnsKey = ( + PBXFileDataSource_FiletypeID, + PBXFileDataSource_Filename_ColumnID, + PBXTargetDataSource_PrimaryAttribute, + PBXFileDataSource_Built_ColumnID, + PBXFileDataSource_ObjectSize_ColumnID, + PBXFileDataSource_Errors_ColumnID, + PBXFileDataSource_Warnings_ColumnID, + ); + }; + PBXPerProjectTemplateStateSaveDate = 207039262; + PBXWorkspaceStateSaveDate = 207039262; + }; + sourceControlManager = 1D16B9DD0BA33BB000A69B33 /* Source Control */; + userBuildSettings = { + }; + }; + 29B97316FDCFA39411CA2CEA /* main.m */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {784, 608}}"; + sepNavSelRange = "{0, 0}"; + sepNavVisRect = "{{0, 0}, {784, 608}}"; + sepNavWindowFrame = "{{15, 4}, {823, 737}}"; + }; + }; + 8D1107260486CEB800E47090 /* MacVim */ = { + activeExec = 0; + executables = ( + 1D16B9CF0BA33BAE00A69B33 /* MacVim */, + ); + }; + 8D1107310486CEB800E47090 /* Info.plist */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {797, 8816}}"; + sepNavSelRange = "{0, 0}"; + sepNavVisRect = "{{0, 174}, {784, 608}}"; + sepNavWindowFrame = "{{15, 4}, {823, 737}}"; + }; + }; +} diff --git a/MacVim_Prefix.pch b/MacVim_Prefix.pch new file mode 100644 index 0000000000..4b3f87e96d --- /dev/null +++ b/MacVim_Prefix.pch @@ -0,0 +1,7 @@ +// +// Prefix header for all source files of the 'MacVim' target in the 'MacVim' project +// + +#ifdef __OBJC__ + #import +#endif diff --git a/PSMTabBarControl/English.lproj/InfoPlist.strings b/PSMTabBarControl/English.lproj/InfoPlist.strings new file mode 100644 index 0000000000000000000000000000000000000000..0bf04f0d2c2a0a3273e92116975021ec5e2b6f6b GIT binary patch literal 208 zcmW-b%?`m(5Ju0sPtjO5f=H~y%7z3Ho}jcv&^B#Jcq1=~(`GU=-~63>zdwdVgsdny z5_99io0P=f(_B&8Dag&CIWsP;GWCG6+plTtUfq6mTanB_+puTBgS*_Eo%2|3%)zUa sxrEY-O8$v+$C%0K@iA_lwl6n&`;Smosm@hv>qH&Xw;D6jCf-d6{`3tbT>t<8 literal 0 HcmV?d00001 diff --git a/PSMTabBarControl/English.lproj/MainMenu.nib/classes.nib b/PSMTabBarControl/English.lproj/MainMenu.nib/classes.nib new file mode 100644 index 0000000000..2e3f46075b --- /dev/null +++ b/PSMTabBarControl/English.lproj/MainMenu.nib/classes.nib @@ -0,0 +1,24 @@ +{ + IBClasses = ( + { + ACTIONS = {newWindow = id; }; + CLASS = AppController; + LANGUAGE = ObjC; + SUPERCLASS = NSObject; + }, + {CLASS = FakeModel; LANGUAGE = ObjC; SUPERCLASS = NSObject; }, + { + ACTIONS = {addNewTab = id; closeTab = id; }; + CLASS = FirstResponder; + LANGUAGE = ObjC; + SUPERCLASS = NSObject; + }, + { + CLASS = PSMTabBarControl; + LANGUAGE = ObjC; + OUTLETS = {delegate = id; partnerView = id; style = id; tabView = NSTabView; }; + SUPERCLASS = NSControl; + } + ); + IBVersion = 1; +} \ No newline at end of file diff --git a/PSMTabBarControl/English.lproj/MainMenu.nib/info.nib b/PSMTabBarControl/English.lproj/MainMenu.nib/info.nib new file mode 100644 index 0000000000..c7f7c64d43 --- /dev/null +++ b/PSMTabBarControl/English.lproj/MainMenu.nib/info.nib @@ -0,0 +1,21 @@ + + + + + IBDocumentLocation + 135 107 356 240 0 0 1680 1028 + IBEditorPositions + + 29 + 130 357 371 44 0 0 1680 1028 + + IBFramework Version + 443.0 + IBOpenObjects + + 29 + + IBSystem Version + 8H14 + + diff --git a/PSMTabBarControl/English.lproj/MainMenu.nib/keyedobjects.nib b/PSMTabBarControl/English.lproj/MainMenu.nib/keyedobjects.nib new file mode 100644 index 0000000000000000000000000000000000000000..348142185703c0cdbdd5313a4e0fad5e742f3a77 GIT binary patch literal 11566 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 Yn$|~Ta<_Zk z+rxmWHbd8|N>P7V_6T2&#C4m5j8m}c78TWX19j`xtyN1%NJvOjR?$T$NJ04{NJ!B4 zX7}tnpU(#VVEN|z-n{qb&6}C4tg+4{X)I-#R86po4{cw_w(VedB)son&q*4!_N$i4 z$bW6SsypH$WMI&xbf#05k#ND*A$vmzrJK7WU1>}0iPMN>YI?6vD!uO^+xPjp?np;6 z8P}q!r5U<2;MhKG4+mv6D5;(fTQtEoyfuWAY;++;{yk(@YN1ew*yl$ozaG;p$92J* zs>3wZGsLz7U|W6;WoifQHwLqI9jL-#l!n?hkdKU19@S%p10TM#&N;G$kaItJ^5h8_ z0E1h)BW_HGY05~OQQA7hfe2Q^3ALA^2*U#>JNsz#)r4xk>No@TJN#W30WpqrX{Tu{ zVyPB|AxIVcb)+k!a`MB}oBVju&pibdNl*VVpo0W-R+ zvPUx&Xl+I=bxq#d;%o0nKik*x)71oJT`75`lznx5*=LJoikecsZKRbWu(L}-$(I>y zJSb4dt;z$M9xGvvEk_BPPEsI3KSsD9WdX$U(VZx9)3;pwE`Jm9m2P_4t=8TW#fFuN zI;l8h(o>p|PRVq5#LV}##;Fv8Ciu725T_+IcacP zM~{)VlvT{;8`_F(mK$AXCoGu`Lc&i_lj>2L$}jI1%0=&b^t7g{BGf#kf!(#DKM#8< zPlKQdrhoHyyCZo}rq_{O_34A!`jQr-P<;J`hYxnPzO^I6EnXwF2dzG8xOI^zcH^Sq+J zoC3Eedg8?_FAuB7oGsvO^a5O+DL4E1kvu7%pC*}~sxD2}653h!=u4FI3w?40mB$Su zQL+yCM(y&}FB8|+XZGQx3+oO$*Z~vzOCY7FJ<}s44=8qALaO+g-kPFgnMe$QXKpiM&{lR@p}6uhu9*>=Npv&HHc9Ik+xIJ~uuPZf`S+2KL7 z3=S;7$dUsS#WXN_4Uoclz^9wVB(OCPNRfBLV7wMP&$B7zV80G)$?pTFV)ye9OAF2n zc5WBj0VL4ICyPO#`v9rj4SyWo0G~zki~~^U9dKp`AGLDGf zgjbaZOe0X8l1~IM>Y-zjmWDIS112R9g~yNw%p$NEbMj)Erc#BW&EZfmich}$&D;~s z4?sveEu*(LPI2WlJq`C%Ns?D`XvH3L3YmeJeB*e~PK0W`^}{2;!*3wI&BO8HDt+-@ z9`4%ST%U4leah|iDR+>vBT99si=`WNSU;wvGfx=(^rvLFIT1`btn#(;3II) zmxH$5AWQpT+JYBeVPzk?IE-7S3e(anU(8sz)reK=wBJ3Kya|Fh!6r2pgKGkw`Lf3A z5v+>hML=TC;6Uc6y&859;H(_r;==G!A?7`ZA=FmhS+F)|^Vd&M*(?~6Dilj1BRe;4=Kf$A_aFSc(J z6O4=s!pN{#VB{?rc#V;Nib+N;h+TehpAjZ*Gx94K_$l-46`wNl3o*vXn*f|+WKQ@a zVxEz|2~?4UGI+TxaBu;uDaF$Bc0C14d@W6eGV88AdLO zlZ^aM%rWw3@vUdYEk?#fQl#3@ET5G^OgPDcKgVZQbZ8H9bbCA_cGh#KkvQ%%r* I1AjsJKZ!>(DgXcg literal 0 HcmV?d00001 diff --git a/PSMTabBarControl/English.lproj/PSMTabBarControlInspector.nib/classes.nib b/PSMTabBarControl/English.lproj/PSMTabBarControlInspector.nib/classes.nib new file mode 100644 index 0000000000..659b73a0ee --- /dev/null +++ b/PSMTabBarControl/English.lproj/PSMTabBarControlInspector.nib/classes.nib @@ -0,0 +1,22 @@ +{ + IBClasses = ( + {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; }, + { + CLASS = PSMTabBarControlInspector; + LANGUAGE = ObjC; + OUTLETS = { + "_allowsDragBetweenWindows" = NSButton; + "_canCloseOnlyTab" = NSButton; + "_cellMaxWidth" = NSTextField; + "_cellMinWidth" = NSTextField; + "_cellOptimumWidth" = NSTextField; + "_hideForSingleTab" = NSButton; + "_showAddTab" = NSButton; + "_sizeToFit" = NSButton; + "_stylePopUp" = NSPopUpButton; + }; + SUPERCLASS = IBInspector; + } + ); + IBVersion = 1; +} \ No newline at end of file diff --git a/PSMTabBarControl/English.lproj/PSMTabBarControlInspector.nib/info.nib b/PSMTabBarControl/English.lproj/PSMTabBarControlInspector.nib/info.nib new file mode 100644 index 0000000000..bf503dd361 --- /dev/null +++ b/PSMTabBarControl/English.lproj/PSMTabBarControlInspector.nib/info.nib @@ -0,0 +1,16 @@ + + + + + IBDocumentLocation + 83 72 356 240 0 0 1680 1028 + IBFramework Version + 446.1 + IBOpenObjects + + 3 + + IBSystem Version + 8I127 + + diff --git a/PSMTabBarControl/English.lproj/PSMTabBarControlInspector.nib/keyedobjects.nib b/PSMTabBarControl/English.lproj/PSMTabBarControlInspector.nib/keyedobjects.nib new file mode 100644 index 0000000000000000000000000000000000000000..2def97d1d3f7e1448ff52459ec96cb2efc22143f GIT binary patch literal 11273 zcmb7q33wC5`~S@D=4z94bEi2su^=Eq4=CjjXel=>g_csTmb6JB5R#gtv>e3=cp)H) zhzN*S3L>H+w-rUf0~HVv5K+JrLGcCw5%|5kn;t6v@8dsxHrd^odGGg~&&;&ED&UVq zQ&W#3j3`7S21$?<$xyKfvVXcST#^D`5q~IHloAb9m868qr}!$Okuo+Zzi_B; zhR>TF@2Exi{xu&VIZ{j*oYP6{=JiB91iz%golqiDqBPVMWuji_E|iV>BOjWEVrVX! zhwer9p+)FX^elQFZ9%)yJLp~X2|9tkKwqM7&`;=R^b5L({y^8zU+5;LaRSz0E$)oF z;4Iu7_riT~5gvob;xarDd$14t@f182Ps3GsI=%<)37!w%58;RLBX}8Jf$Q;F{1V=b zx8d!07jDG6@jm<(K7bG6qxcv;g-_#i_yYb7U#A#KLMbT~rKb#(jj~fIR2!-zbtl!8 z%A~TX9BLpnh#E>2P$Q@@)L5#Vs-UJ&Q>h3QrRt~{bwBk0HJ^HjT0lKYEuo&ER!~n- z>!|hAi_}ZhW_bTHwUgRKHBx)2ebfik0qP*UJ479&j#HmdC#cV;n{Z>h7?57Y(f zXZXGd*HyS~P(RQ#TynTnaA|21ZHCJZmm99z;pzxi8eExlPr4VKP3O=9=|OZJolh6i zMf4bYEL}!VqVr92!+K|=oj!rBEE>&du)E;aKASK=@A*1UzqQi z<`eEG|jD20jsB@4Acdb7Zm2jA`GEH<$}VzB2Rga zCk%o|!=b?7V5CYg;}O&iWufk)UUk$1b}jTpN97m7w>WYD z^1j5{(Lgi^4Ms!IP&5qXp?owP6`&DlBq~HjXcQ_&qfrSOgT|t9Xgr#LN>Le_h&-qq zRS*SPNuDBWNIhvF>&XVPk!&I_lFeib*+zDdU8IrhCa;q>$X@amd57#L?~?=M5IIba zknE$V5={c>CnGf?QE>C<{K8?La$f+{FAPLd!H z5UN6VqcDn~D5?e;(@_noMKjP$Gz-l}b!ZN{2az&XlV2zXQekvPz?bKVOcf$te3#>? znCcHs0P*@T6`GWBWv8CAWtAPL-T{IxznZ#!S|3Vnd zVwNIGq9Tdp36iAkTZ<4`PSjc%t&2`FFS z3Hky>Jhh|fe)Ir(5Y(IxX}bU|1ZNjkmrsW#F(>)x9qEfyg@RsR7={YrL0E#wGBQha z^ux&e3|dSyB>R*=Z3%h|Ek%z5)n(`jv>ZK&Rsj8#V7fZA8cg{#T7#ZJ^=K_>K{ce!f5e3^Tm4GUAIyz>Cub3xR=) z!X8KlPuLfX!V{k#aK|eO-E%^kR0Sf&yeMAo`KMGge3|o=+S+ospM?26?v_n;wuHOAPAu&Mui3=(uSDI zSOf3cj$C@zbl$TWsU5krjJmoLXg_)ny^lUX2Y}{5bO?Qj4x^9I5fJ4lI);u5k;=#8 zq;RM@=(SS!Ck*53>M`^!I*YzT=YaBg^ga3kT|hrVTsG+?{POg9 zL3v#Zt2`Ba>h%K{6$nid%BYh#SShg+uDEbUBp_~Htwp+wu81O$+lZUz0EIP9yxHPS46gGGa#EYnSVW*_b5h?TDzS=>N}PmQAqa0*kX+KPj5W@h)ulT`V3%%u1g3S#g!}ZmIsgq= zhYn&rHee$*VKYv~7BJu;Y()pK4ZV-;*nypx!!A^V-S{?~g4>{VxGlaNw*yAo@g2A$ z+6(x$2CM~Y2BN+&6l&k#X)uMtjFnRzjfR3ku%v@0TRnn0dA?vZL@xg`7+hJ#>RM4~ zif6%`1z}&MFC6xH`+Fye#ihU(_J_RwidD<0INoUfD z+@ZmbkbYV@1#lkf&03L`30lmTCsiAln z_$&|S<2IPZBk)LE2zJT~`lf|~{)%Ct3Zc9-*(opN+=d7;H?Re zAds6pA0gdI4(Tx}&j*SAF&+mIn2yKe3AhwO2%=q>=!NvpAYDj02q$n9oW;}VH`!M) zb($wURWw{Vu2_pJu$MO+1f__Yn#h3GkY9g)*Tk}tXGt=79>PeTwxD1WGf60a z0~92W3>3;=S{h&S;^hxuR$5kF-DzyY7ASzi91KO!fnmi2BoAUUl)yH49bS(+;tc=` zYVk(=Jl+I&@)*2-k=()VCxc0QGKlnNleL3-jkrmMkvp`oi-4f6^z#I{ia;ph<3ho} z3=San5&SYx-h#J6)C;jIMDq|bluzUuf3#wJjY=vk0OouM*x|x;9t-}G6n!kMe*;*y8&Osm+&9> zGQNVZ;y>{*A4o%B$i^A!1cqfi!-*n8h@ectRq4E^{@+lS zO2(J|#?S+b0z*&jEg5oghPMd}D|m)pfnf%~nJ$^UhF$s0{vQn6<3Ik!&M!xr81~KR9|8K%?*2MA}tu7Od->ttoTW#f}{w*W9i*DvbAgug9_79Q(NIx zsvngb$EyJ{Rm7{hD8SAZVy!VTHCTYGX#iPU5kZ%!yk^iFcce62I#R`7-FUBavR|I2>=8X|oJWN8Mcwu^0>aE#VitN!3lwV*U<%0mA z9E3UVi7vv@`M)p^;j27zAk@NqI*IVi(=t*&yG8OF(F&@X4+t>iYO0o+LCu79@Oo5B zY6Vf|klCb89#4B}4x~MG51GMlXoyQkBc$@5)V+}MHSjl+%z}wx)~s}xl>|th&gW)b zolwrH2eEvuxG)e@OXGWW7rJ$Y#Utzq6wiX+)VfcaV@+5Oi&wSOz&_d_*= z528!m)=TtHIB z@KeKRzc)JhZ^k0rzs$f-57cXMGrU2)DNG9w^Jb8f#m!=*i4`&}>;DIfQ17C~W=p*B zH%mMM+Z4iNX3Y)+V2_mZhCP$Ga$mFt_NKTRapQFCtn^fV8Q3jVv`0ETbP*gPzRv~Gn-64Vt!m0xyd3f@Rf2k0dR)u+_Sdf2%W zae92e%{Q$o0IRrSQDm{-DeClE>NItR@2Q7P2!HwTYS@;8LKWYI2CNA$n;%;?5mTwJ zU=z_#D6$H62@^`ZzJPBMkZ;}N9CaRThaRiR)1+--XsU?nsUNAI)>1!-Obt!+`IY!B z+58Gbb^wuQfJpz=)c=5nozSor8uD8=T!V&P(69~~Mz(685p^D4hK6UMp|W*@1RAbD z!*kFOYTb|k4OgMzd1#2VZb*WLYtZllG|X#h*g@;TD%)X)>m{&C+i^iC`mnm=7c4EE zcG4E;v;$z=%h0KnPP=F)H0%WQv=tg!bi!BY6f_k?50UNA&>}j%O1FoGD*#`1LPLw_ z_!`{_8m>YXzXA=dMBh$lK*KdyT)zqptwi5WX94q6Xm|}8sBvWxeiK(%D71*agYGSK z>QDCYonSFnR^bWu<01KQK;)3hEq!;=xkBH3@}}5VQ#Kg@>j2n)65#6JI`5)~2%Sfg zeR1x99054C?u0MX1wyAv@;2XTLRkf@h5$tg)uWj)SgTm*79#Jq>gK8aN4Kl=c%fT_ zyw@ZjPcM#H{?YjwT`qKCi9C>d8ZrNa=bjSxp4K^(PeXryZdc8kczqHM`!9-;aGteKP})*dmfBf=_}o=q=% ziA_cg0Bs|%E4vFvse52f1&|B#u^-mQJnX#$3$8k}4c`W9i$;7Apz?O8p&?i`Yar%& z!=zdwz~Bh%{dW?8aVbP{5^QC5hG1O;ptTsn*cTGlsa?`xOAlZ{8tfUx-$33qpIyM*$)DW`yKb$9r@;p{TVQ|gA1~7cc>Ir- zEzHu!5AX+kw@0|)H9p8B0^dd81Z)eOfNcOjS3+DJ zg7dMJ;M)>7Gphj)H-OjQhto0x#F7He&)SkT)W^$N*OfJ)( z8Ndu=1~G$~AZ4LlbFejpP9l;Wdh`Pa*mg6 zEir73VOtE_W7rYH&KTxm*cHR>7``orQ)0MH47ZKp+he$047Vr8*i1H+y^D3Q*{p@_ z&StPZ*-k9Sy4n708rz1wgLSeU*}iO7Hid1+c4qZ#2X+A4o6TZxW36lsdpkRbHL*t4 z&gQZ%wilbu8dw|KmhHy&VSBLcS+fvn%+tubhGdKP^(|4ytc%~nE*i6ed9I#$PS|)G zoFg9U=E6w_lA~leo$m<$F46;nZUh977gbX4PzT`O6x!4M>CtpK9fV4{oL)!oqW91T zA;HfxG?T>GncJC8Oe&MXbOmR32S@h?7w3R;2ZCdVf=dg)okifvGH}u~_-BO$@UI0= zfg~?5yP3C{6U>*)1?ETQXXXlXQ=*h;C00p^WUOSoq*O9dQZDgIDkYO8QzQXNP*Noc zOQMqLl3K}3$!y6S36ac|+$*_X@}T4)$wJA)l1C&iU!3N#Wuwb#V$poVz*+S;;`bB;#xOb){CBqHL?|tn8x9RAwoA zDDP7CQRXW9D+ekED~BqFDf5+OO0Tj~IaxVXIa@hLNtAPy^OOsf%aqHN&nP!28H_r`wO3uK4ymWBYt=K=v(PX?4=3r0q$^lRi&6o%BW0S4m$deVg^ycM`#8IT-ORqizQrD7Pq0_nYwUIQrUq#!4WqGZiZvyg zv6}IkQq4q7xyGxRsadIcO7pbl8BM*WL9<@7M{`B|b`uU(*Bq+O0@m$WZyw`#X* zcWPhJ9@n1Gp45J>J*7RP{Ze~Hm#nku>^i5;rMpenM%O_%P&ZgNRF|jA*A?hS>ioKg zbPIJ4>mJc9(Jj?2)2-C)(lzRK>t5IG(Y>kLr#q>;rn|1YsmFR+FVV~NtUgVjq3^2i zrq9y%(D%~!){oN9(J#?2)i2X8*RRm8(m$ntTE9X6g8pUwJNo_l_w@(#hxFg*f7M^q z|6xcps0>L4jX`Iy8+sf18gdM|hW>_uhQWrRhH}FK!y?0C!=r}B438U@8I~JX8D2B& zF}!KmXL!r-j$yyyj8Se(Fe;5|BWu(ebw-0R**L&B$T-9}%$RR1Fpe}98b=vRjUHo# z(Px})tToOw&Nj|5K4x5HTx)DJzG*yd{KEK^@f+h=<2mC6<8>2dVoXw#!elh1nA(~; zo3c#3O=TvJslwzlRhlN7rkDbzxu#c5ubK9k-Zbqqy={8e^q%RM>4I5ecAHboZO!e> z9n2lgndW}x{^m;aWb+hrz&yszncF_HYBGf zcS+7n&Pwi)+$(u-^3de+$Ft&7!oZ zEv!Xr(Ob+Gm!+MhuVsX#&@#$0+A_v6#S*XtEmfAVWuE0e%LA7AmIanomerOumU>Hr zWxHjk9BZz1fOWKWjCGuKg0;+AWer=S*6G$->wN11>muu7>!a3sYlC&Yb%S-I^;PR@ z);-oYt^2GWTEDPrM8K-a+}vy zX^YzKvpry&Z(CqnWLs(5WP8!J*|x>D&9>k6sqHh{Dcc#_m$nPG>$aPAY^UuKyU}j8 zTkJNw!`|7RX3wy9wRf`*vJbHjv*+6j>;ZeVeWQJo{YCp``xg5)`wsgqd!v1~{dM~r z_PzGE?C;q3+uyezuphD?wjZ${wI8>iu%EPlZa;1R&VIpu$PUBVab!BO z96cPp9K9WV9XXC%#{kD5#}LObN4}%LG15`wD0Y-M#yZA3N*$9N%N)xcD;%pFs~u|` z^^OL|ddCLGM#m<{i;m5XEskxD9gba&M#pZ)>y9@ZdmV2%4m$pF+;Ac%vr`(y~ zR65m8)~R*sokpkGX>r<|4kzbyJ5!u(o$Z_*oSDvC=Wu7SbD}fie9-xn^JV95=X=hN zou{4OInO!2cmD3Y=={TZldIywT$G#6)p9er+1wnCaC5nPx%;^Xxrexg+{4@>+!Agn zw~SlPt>9L1tGP8?J=egk=QeN~xlP=Q+-7bIw~gDu?cy4_-Q4Tk8{A&*E$$s|KleU& zfIGw;=8kYjx#Qdk?j-j)cbfZxJMS9n8t*D~O>~vJysk>uWY-i|z!h{=xx%iftHw3c zRp%nEd9M3i^IZ#Fi(N}xkGqz;R=QTZo^ds}o^@?>z2MsH+UnZjdd0Qdwa2yB^|ouj z>jT#z*GI0Su1{PiU8h`MxW0Csb)9!zaQ*E1&2`cBhwF;#PuE|r8*b#L+>Bf5mb(+& zO1Ik0y0vb-+vqmCEpD6J;pW_KcZ$2MyPdm(yQ904JJp@;?&8jLXSsX0d%1hN`?_=7 zx$Xh(LGB^$VeWi)fqSI8$UVVb>YnKKyQjDV?rQgRcda|-z8?u63eHIQ53^DHZTfaU F{(of|s~G?Q literal 0 HcmV?d00001 diff --git a/PSMTabBarControl/English.lproj/PSMTabBarControlInspector.nib/objects.nib b/PSMTabBarControl/English.lproj/PSMTabBarControlInspector.nib/objects.nib new file mode 100644 index 0000000000000000000000000000000000000000..9a89923a6cbc9b46f7d82325448b413fbb1551fe GIT binary patch literal 4291 zcmb7HeN0=|6~E6m1_zTtXtU8KnYU%@^3{fJ*IB_e97 z2c&9A%e1JV)Y)*vAB|m7>$6a+&E8bUWA?r+9)zm}6eL7COOnCf}}i$Qz?+y{KAR|<#GI>6toB{cBgn4fxGmHya3N|(DW z&|a&9=}n?^<#JN%RpXr1qT^#;>gnth1dBi4C2yTM|Iq`>a)KU`F)fEXsT?l^t|$+_ zj?w^X<2SqSTE=nG0-?8VahIg4!-U)hoBT0- zAR#wcbj;a1`dR$&?l!=WKBxpA+~E$G94COnKk-YD7nEF+Ho)C|>&*T;<1RXvr#i=j zU<&vM@L1qYp~18eZdEjPLF;+7r>R%hHPs*=@d$TU1IS&Q%9-5+o zR7z1W3d4r*&dWmDpAN5$f^iVgxg^S^E(WRju8GOH4fb*t8lGS9oP>Nu5;$X!`cNLB ze;(e}rgzCn%;S^=3FXb)&(IGu)3gd0A`z~&K>^O;VPE4Ly`nXmCe?(bf3~)^MoiFC z4S~e#2^0XWHz~>c25n%5XpVG?mt_oHG!yhTcgfO~ZZUbqvP}B1{R!;AVccm|`sH{` z7j+rJxTd`aFAiPnrY0uJA0U{yT~laD`KzkZsmSqSV;-7+{UFB*MT#?)waU7fC}b1N z0yaoKC9I@RLH14)2p{@EQD9UWW+M12oM;5%w+=cxS6n{SyV$(LQBaZ zO-&4hpt4zif)E!l$7g2oK)yEZzCPOF9L$ODu6D8~Kfg*zG^#xmTe=u#Ir zsiZ{@2f&_z4Qo6ltf@Vx#N|+@mJFq!peN+KIUY1;w%DA%mDck+gS^d=zrCT$TS`}~ zOX~|Y#^WLA7oiT0ibMCJuDMdWu7j6z)f>9Qy!%{{q3>m~1%)X5dL5LZx~fbT(}eWWMQ1#`z@4#_b^(D#hq&21>$!7FL7djfw)Ic7Pt5LV<7I>e-~HL z)}t%kz1;;OA3s^7c9?p_}{WpP}%ldqlu z>=15A{5{sf5>5~sH>oHqrQ*m5S4A1BSOOLQe1f!to22tR&b)u`U!w=CMEoN?@dV-H^%h5_wS>Q+^7Gr-eEdonKfvqVaCc2ZZPG z807sF!h1iJnJ>Uy3Ao`1#V!0@FG8EK2Qc|wQ{s9T*X52Do8e@=d?+YU=0**2k0<-R zjbyJV0qWVtL_+IJh2lx^a;QVr`(#-S^(kr`h+J_6f((=fi5Or=+rIvr8OZ@1v6r&; zgK2x@hCS!lpHADWD|U9?Udh_tti7DYZU&9wHLm8O+})FaMqvp59)upH;6&-RMo9oC zUNwY|-C;2u?uYmo9u90wuGl%Cor|iRz_#SWrf1zS1?od7V3z+K!{-}=D*_pKhy}b9 z%f1iff>FS-9|K`WkzMuh0b3Sfqi{&H>_;V8!JZk|DAYX(YZ#OYu%b-Mo(1{_ULXts zA=siMk44(XC`JUe;Ff z5GS{%@Qs3pgX`WQw7a@p64hp$uG(O@f>M{;L*r}OyI|O9(ULJf>TGOs2<<7DPGC6M zAY+(UwM#If!|32vOzw#xp0MtQ*k8DT=xX>zuALWdBF1g)DX8@qwHB!KT-F>0>sE*X zo?@Hs;K)Rv_@;*Na9z8|EA3e*v`ucEbu&7}Uvr$7;H_Qx&T$q#%w9jmmiDkfBU^rk zUHArTIm#}6lbw8?t%lg*m)Q*u>-ZLHs%I~hvDvS(Y#lp(fUSIy4GHYTK^F9~ABEYu zV{CFSbH2_F_}J+e*wj<(#r-Va!oGK!MNhDqudsz@*{4lxd+2dVo?rZG)OY8?{*eeaJ;Sj6e$L7D_L>z*1ZFQunS(7xeB`J2x JeHy+5{09nX=-U7Q literal 0 HcmV?d00001 diff --git a/PSMTabBarControl/English.lproj/PSMTabBarControlPalette.nib/classes.nib b/PSMTabBarControl/English.lproj/PSMTabBarControlPalette.nib/classes.nib new file mode 100644 index 0000000000..4752228596 --- /dev/null +++ b/PSMTabBarControl/English.lproj/PSMTabBarControlPalette.nib/classes.nib @@ -0,0 +1,28 @@ +{ + IBClasses = ( + {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; }, + {CLASS = PSMAquaTabStyle; LANGUAGE = ObjC; SUPERCLASS = NSObject; }, + {CLASS = PSMMetalTabStyle; LANGUAGE = ObjC; SUPERCLASS = NSObject; }, + {CLASS = PSMOverflowPopUpButton; LANGUAGE = ObjC; SUPERCLASS = NSPopUpButton; }, + { + CLASS = PSMProgressIndicator; + LANGUAGE = ObjC; + SUPERCLASS = NSProgressIndicator; + }, + {CLASS = PSMRolloverButton; LANGUAGE = ObjC; SUPERCLASS = NSButton; }, + {CLASS = PSMTabBarCell; LANGUAGE = ObjC; SUPERCLASS = NSActionCell; }, + { + CLASS = PSMTabBarControl; + LANGUAGE = ObjC; + OUTLETS = {delegate = id; partnerView = id; style = id; tabView = NSTabView; }; + SUPERCLASS = NSControl; + }, + { + CLASS = PSMTabBarControlPalette; + LANGUAGE = ObjC; + OUTLETS = {repImage = NSImageView; }; + SUPERCLASS = IBPalette; + } + ); + IBVersion = 1; +} \ No newline at end of file diff --git a/PSMTabBarControl/English.lproj/PSMTabBarControlPalette.nib/info.nib b/PSMTabBarControl/English.lproj/PSMTabBarControlPalette.nib/info.nib new file mode 100644 index 0000000000..866500bb2a --- /dev/null +++ b/PSMTabBarControl/English.lproj/PSMTabBarControlPalette.nib/info.nib @@ -0,0 +1,16 @@ + + + + + IBDocumentLocation + 83 142 356 240 0 0 1680 1028 + IBFramework Version + 443.0 + IBOpenObjects + + 2 + + IBSystem Version + 8H14 + + diff --git a/PSMTabBarControl/English.lproj/PSMTabBarControlPalette.nib/keyedobjects.nib b/PSMTabBarControl/English.lproj/PSMTabBarControlPalette.nib/keyedobjects.nib new file mode 100644 index 0000000000000000000000000000000000000000..635e6d8d17cd5a5f4c2f78e7a739806307fce3a3 GIT binary patch literal 3036 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 + + + + IBDocumentLocation + 35 49 356 240 0 0 1024 746 + IBEditorPositions + + 18 + 271 466 481 64 0 0 1024 746 + 20 + 400 254 224 482 0 0 1024 746 + + IBFramework Version + 446.1 + IBOpenObjects + + 18 + 20 + 5 + + IBSystem Version + 8J135 + + diff --git a/PSMTabBarControl/English.lproj/Window.nib/keyedobjects.nib b/PSMTabBarControl/English.lproj/Window.nib/keyedobjects.nib new file mode 100644 index 0000000000000000000000000000000000000000..d5228b233882ff5ea4828d5254ad3e3cb0e3f163 GIT binary patch literal 16340 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 Th=N0j + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + PSMTabBarControl + CFBundleIconFile + + CFBundleIdentifier + com.positivespinmedia.PSMTabBarControl + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + BNDL + CFBundleSignature + PSM1 + CFBundleVersion + 1.1 + + diff --git a/PSMTabBarControl/PSMTabBarControl.ibclassdescription b/PSMTabBarControl/PSMTabBarControl.ibclassdescription new file mode 100755 index 0000000000..89959b3847 --- /dev/null +++ b/PSMTabBarControl/PSMTabBarControl.ibclassdescription @@ -0,0 +1,7 @@ +{ + PSMTabBarControl = { + SuperClass = NSControl; + Attributes = { + }; + }; +} \ No newline at end of file diff --git a/PSMTabBarControl/PSMTabBarControl.xcodeproj/johnp.mode1 b/PSMTabBarControl/PSMTabBarControl.xcodeproj/johnp.mode1 new file mode 100644 index 0000000000..636da21a11 --- /dev/null +++ b/PSMTabBarControl/PSMTabBarControl.xcodeproj/johnp.mode1 @@ -0,0 +1,1551 @@ + + + + + ActivePerspectiveName + Project + AllowedModules + + + BundleLoadPath + + MaxInstances + n + Module + PBXSmartGroupTreeModule + Name + Groups and Files Outline View + + + BundleLoadPath + + MaxInstances + n + Module + PBXNavigatorGroup + Name + Editor + + + BundleLoadPath + + MaxInstances + n + Module + XCTaskListModule + Name + Task List + + + BundleLoadPath + + MaxInstances + n + Module + XCDetailModule + Name + File and Smart Group Detail Viewer + + + BundleLoadPath + + MaxInstances + 1 + Module + PBXBuildResultsModule + Name + Detailed Build Results Viewer + + + BundleLoadPath + + MaxInstances + 1 + Module + PBXProjectFindModule + Name + Project Batch Find Tool + + + BundleLoadPath + + MaxInstances + n + Module + PBXRunSessionModule + Name + Run Log + + + BundleLoadPath + + MaxInstances + n + Module + PBXBookmarksModule + Name + Bookmarks Tool + + + BundleLoadPath + + MaxInstances + n + Module + PBXClassBrowserModule + Name + Class Browser + + + BundleLoadPath + + MaxInstances + n + Module + PBXCVSModule + Name + Source Code Control Tool + + + BundleLoadPath + + MaxInstances + n + Module + PBXDebugBreakpointsModule + Name + Debug Breakpoints Tool + + + BundleLoadPath + + MaxInstances + n + Module + XCDockableInspector + Name + Inspector + + + BundleLoadPath + + MaxInstances + n + Module + PBXOpenQuicklyModule + Name + Open Quickly Tool + + + BundleLoadPath + + MaxInstances + 1 + Module + PBXDebugSessionModule + Name + Debugger + + + BundleLoadPath + + MaxInstances + 1 + Module + PBXDebugCLIModule + Name + Debug Console + + + Description + DefaultDescriptionKey + DockingSystemVisible + + Extension + mode1 + FavBarConfig + + PBXProjectModuleGUID + A251BE6C0959A0E60058BC7F + XCBarModuleItemNames + + XCBarModuleItems + + + FirstTimeWindowDisplayed + + Identifier + com.apple.perspectives.project.mode1 + MajorVersion + 31 + MinorVersion + 1 + Name + Default + Notifications + + + XCObserverAutoDisconnectKey + + XCObserverDefintionKey + + PBXStatusErrorsKey + 0 + + XCObserverFactoryKey + XCPerspectivesSpecificationIdentifier + XCObserverGUIDKey + XCObserverProjectIdentifier + XCObserverNotificationKey + PBXStatusBuildStateMessageNotification + XCObserverTargetKey + XCMainBuildResultsModuleGUID + XCObserverTriggerKey + awakenModuleWithObserver: + XCObserverValidationKey + + PBXStatusErrorsKey + 2 + + + + OpenEditors + + PerspectiveWidths + + -1 + -1 + + Perspectives + + + ChosenToolbarItems + + active-target-popup + action + NSToolbarFlexibleSpaceItem + buildOrClean + build-and-runOrDebug + com.apple.ide.PBXToolbarStopButton + get-info + toggle-editor + servicesModuleclasses + NSToolbarFlexibleSpaceItem + com.apple.pbx.toolbar.searchfield + + ControllerClassBaseName + + IconName + WindowOfProjectWithEditor + Identifier + perspective.project + IsVertical + + Layout + + + ContentConfiguration + + PBXBottomSmartGroupGIDs + + 1C37FBAC04509CD000000102 + 1C37FAAC04509CD000000102 + 1C08E77C0454961000C914BD + 1C37FABC05509CD000000102 + 1C37FABC05539CD112110102 + E2644B35053B69B200211256 + 1C37FABC04509CD000100104 + 1CC0EA4004350EF90044410B + 1CC0EA4004350EF90041110B + + PBXProjectModuleGUID + 1CE0B1FE06471DED0097A5F4 + PBXProjectModuleLabel + Files + PBXProjectStructureProvided + yes + PBXSmartGroupTreeModuleColumnData + + PBXSmartGroupTreeModuleColumnWidthsKey + + 220 + + PBXSmartGroupTreeModuleColumnsKey_v4 + + MainColumn + + + PBXSmartGroupTreeModuleOutlineStateKey_v7 + + PBXSmartGroupTreeModuleOutlineStateExpansionKey + + 0259C574FE90428111CA0C5A + 1C37FBAC04509CD000000102 + + PBXSmartGroupTreeModuleOutlineStateSelectionKey + + + 1 + 0 + + + PBXSmartGroupTreeModuleOutlineStateVisibleRectKey + {{0, 0}, {220, 819}} + + PBXTopSmartGroupGIDs + + XCIncludePerspectivesSwitch + + XCSharingToken + com.apple.Xcode.GFSharingToken + + GeometryConfiguration + + Frame + {{0, 0}, {237, 837}} + GroupTreeTableConfiguration + + MainColumn + 220 + + RubberWindowFrame + 11 142 905 878 0 0 1680 1028 + + Module + PBXSmartGroupTreeModule + Proportion + 237pt + + + Dock + + + BecomeActive + + ContentConfiguration + + PBXProjectModuleGUID + 1CE0B20306471E060097A5F4 + PBXProjectModuleLabel + ReadMe.rtfd + PBXSplitModuleInNavigatorKey + + Split0 + + PBXProjectModuleGUID + 1CE0B20406471E060097A5F4 + PBXProjectModuleLabel + ReadMe.rtfd + _historyCapacity + 0 + bookmark + A246FB000A2BD6C2005BDF7B + history + + A251BEF10959BC6E0058BC7F + A2F519DB09AA627E00056B6F + A234001B09B2B346001A1B18 + A234006C09B2C55E001A1B18 + A234006D09B2C55E001A1B18 + A2CD7C5709B7738800FBAAAE + A2CD7C8D09B7B55E00FBAAAE + A2BEC7EB09C1F01F00B8B4B6 + A22BAD0209C200AB0004449D + A22BAD2609C203D80004449D + A240E76509C2211500F755E1 + A240E76609C2211500F755E1 + A2ED871409C28FBD006BD5FC + A2179E3B09CA11BE00E40445 + A208348A09CA185D00837C29 + A2A7121E09E5C48C00D0089B + A2CF618009F4099F00A0F9A8 + A2A2B9D909F448F9002BE730 + A2E8401109F48B62000217C4 + A2704C0F09F56903000002CC + A2F0DF4F09F6D68300AA839C + A209E26A09F7E9FE0060532B + A209E28609F83C1E0060532B + A20A6FC109FB23FA0018A4B5 + A20A6FC209FB23FA0018A4B5 + A20A6FC309FB23FA0018A4B5 + A20A6FC409FB23FA0018A4B5 + A27F6A870A1B9AD100AE7009 + A21370F30A1C2CC400673584 + A264DC290A1E83A9001A9027 + A27E46770A28B49E007BA395 + A27E46780A28B49E007BA395 + A27E46C80A28C05D007BA395 + A27E46C90A28C05D007BA395 + A27E475B0A28EBEE007BA395 + A27E47E40A28F7FB007BA395 + A27E47E50A28F7FB007BA395 + A27E47E60A28F7FB007BA395 + A27E47E70A28F7FB007BA395 + A27E47E80A28F7FB007BA395 + A27E47E90A28F7FB007BA395 + A27E47EA0A28F7FB007BA395 + A27E47EB0A28F7FB007BA395 + A27E47EC0A28F7FB007BA395 + A27E47ED0A28F7FB007BA395 + A27E47EE0A28F7FB007BA395 + A27E47EF0A28F7FB007BA395 + A27E47F00A28F7FB007BA395 + A27E47F10A28F7FB007BA395 + A27E47F20A28F7FB007BA395 + A27E47F30A28F7FB007BA395 + A27E47F40A28F7FB007BA395 + A27E47F50A28F7FB007BA395 + A27E47F60A28F7FB007BA395 + A27E47F70A28F7FB007BA395 + A27E47F80A28F7FB007BA395 + A27E47F90A28F7FB007BA395 + A27E47FA0A28F7FB007BA395 + A27E47FB0A28F7FB007BA395 + A27E47FC0A28F7FB007BA395 + A27E47FD0A28F7FB007BA395 + A27E47FE0A28F7FB007BA395 + A2D98B1D0A2B47700064C6F8 + A2D98B1E0A2B47700064C6F8 + A2D98B1F0A2B47700064C6F8 + A2D98B200A2B47700064C6F8 + A2D98B210A2B47700064C6F8 + A2F0AA9E0A2B977F00BEF297 + A246FAF70A2BD6C2005BDF7B + A246FAF80A2BD6C2005BDF7B + A246FAF90A2BD6C2005BDF7B + A246FAFA0A2BD6C2005BDF7B + + prevStack + + A251BE660959A0E60058BC7F + A251BE670959A0E60058BC7F + A251BEF80959BC6E0058BC7F + A251BEFC0959BC6E0058BC7F + A251BEFD0959BC6E0058BC7F + A251BEFE0959BC6E0058BC7F + A251BF000959BC6E0058BC7F + A251BF020959BC6E0058BC7F + A251BF040959BC6E0058BC7F + A251BF050959BC6E0058BC7F + A251BF060959BC6E0058BC7F + A251BF070959BC6E0058BC7F + A251BF0A0959BC6E0058BC7F + A251BF0B0959BC6E0058BC7F + A251BF270959BD670058BC7F + A20822E70959F4CE00C5F5A4 + A20822E80959F4CE00C5F5A4 + A20822EA0959F4CE00C5F5A4 + A208236A095A58C700C5F5A4 + A2082371095A58C700C5F5A4 + A2082398095A630900C5F5A4 + A20823A1095A630900C5F5A4 + A20823A2095A630900C5F5A4 + A20823A3095A630900C5F5A4 + A21F8C430963122D00B04C56 + A21F8C440963122D00B04C56 + A2D32F4609A6441B00EC8662 + A2D32F4909A6441B00EC8662 + A2D32F4A09A6441B00EC8662 + A2D32F5109A6441B00EC8662 + A2D32F5209A6441B00EC8662 + A2D3313F09A67ED000EC8662 + A269364309A7BC8D0006911E + A268E7C609A9792000E082AA + A268E7C709A9792000E082AA + A268EA9709A9876A00E082AA + A268EAA009A9876A00E082AA + A268EAAA09A9876A00E082AA + A2F519E509AA627E00056B6F + A2072A5709ABDC4400304BCB + A2072A5A09ABDC4400304BCB + A2072A5B09ABDC4400304BCB + A234FFFF09B2AF46001A1B18 + A234001E09B2B346001A1B18 + A2758F9B09B4BB1C006E31C3 + A2758F9C09B4BB1C006E31C3 + A22BAD0609C200AB0004449D + A22BAD2A09C203D80004449D + A240E76D09C2211500F755E1 + A2CF618409F4099F00A0F9A8 + A2A2B9E309F448F9002BE730 + A209E26F09F7E9FE0060532B + A209E27009F7E9FE0060532B + A209E28C09F83C1E0060532B + A27E475F0A28EBEE007BA395 + A27E47610A28EBEE007BA395 + A27E47660A28EBEE007BA395 + A27E47670A28EBEE007BA395 + A27E47680A28EBEE007BA395 + A27E47690A28EBEE007BA395 + A27E476A0A28EBEE007BA395 + A27E47740A28EBEE007BA395 + A27E48050A28F7FC007BA395 + A27E48060A28F7FC007BA395 + A27E480E0A28F7FC007BA395 + A27E48100A28F7FC007BA395 + A27E48110A28F7FC007BA395 + A2D98B240A2B47700064C6F8 + A2D98B250A2B47700064C6F8 + A2D98B260A2B47700064C6F8 + A2D98B270A2B47700064C6F8 + A2D98B410A2B55140064C6F8 + A246FAFB0A2BD6C2005BDF7B + A246FAFC0A2BD6C2005BDF7B + A246FAFD0A2BD6C2005BDF7B + A246FAFE0A2BD6C2005BDF7B + A246FAFF0A2BD6C2005BDF7B + + + SplitCount + 1 + + StatusBarVisibility + + + GeometryConfiguration + + Frame + {{0, 0}, {663, 623}} + RubberWindowFrame + 11 142 905 878 0 0 1680 1028 + + Module + PBXNavigatorGroup + Proportion + 623pt + + + ContentConfiguration + + PBXProjectModuleGUID + 1CE0B20506471E060097A5F4 + PBXProjectModuleLabel + Detail + + GeometryConfiguration + + Frame + {{0, 628}, {663, 209}} + RubberWindowFrame + 11 142 905 878 0 0 1680 1028 + + Module + XCDetailModule + Proportion + 209pt + + + Proportion + 663pt + + + Name + Project + ServiceClasses + + XCModuleDock + PBXSmartGroupTreeModule + XCModuleDock + PBXNavigatorGroup + XCDetailModule + + TableOfContents + + A246FB010A2BD6C2005BDF7B + 1CE0B1FE06471DED0097A5F4 + A246FB020A2BD6C2005BDF7B + 1CE0B20306471E060097A5F4 + 1CE0B20506471E060097A5F4 + + ToolbarConfiguration + xcode.toolbar.config.default + + + ControllerClassBaseName + + IconName + WindowOfProject + Identifier + perspective.morph + IsVertical + 0 + Layout + + + BecomeActive + 1 + ContentConfiguration + + PBXBottomSmartGroupGIDs + + 1C37FBAC04509CD000000102 + 1C37FAAC04509CD000000102 + 1C08E77C0454961000C914BD + 1C37FABC05509CD000000102 + 1C37FABC05539CD112110102 + E2644B35053B69B200211256 + 1C37FABC04509CD000100104 + 1CC0EA4004350EF90044410B + 1CC0EA4004350EF90041110B + + PBXProjectModuleGUID + 11E0B1FE06471DED0097A5F4 + PBXProjectModuleLabel + Files + PBXProjectStructureProvided + yes + PBXSmartGroupTreeModuleColumnData + + PBXSmartGroupTreeModuleColumnWidthsKey + + 186 + + PBXSmartGroupTreeModuleColumnsKey_v4 + + MainColumn + + + PBXSmartGroupTreeModuleOutlineStateKey_v7 + + PBXSmartGroupTreeModuleOutlineStateExpansionKey + + 29B97314FDCFA39411CA2CEA + 1C37FABC05509CD000000102 + + PBXSmartGroupTreeModuleOutlineStateSelectionKey + + + 0 + + + PBXSmartGroupTreeModuleOutlineStateVisibleRectKey + {{0, 0}, {186, 337}} + + PBXTopSmartGroupGIDs + + XCIncludePerspectivesSwitch + 1 + XCSharingToken + com.apple.Xcode.GFSharingToken + + GeometryConfiguration + + Frame + {{0, 0}, {203, 355}} + GroupTreeTableConfiguration + + MainColumn + 186 + + RubberWindowFrame + 373 269 690 397 0 0 1440 878 + + Module + PBXSmartGroupTreeModule + Proportion + 100% + + + Name + Morph + PreferredWidth + 300 + ServiceClasses + + XCModuleDock + PBXSmartGroupTreeModule + + TableOfContents + + 11E0B1FE06471DED0097A5F4 + + ToolbarConfiguration + xcode.toolbar.config.default.short + + + PerspectivesBarVisible + + ShelfIsVisible + + SourceDescription + file at '/System/Library/PrivateFrameworks/DevToolsInterface.framework/Versions/A/Resources/XCPerspectivesSpecificationMode1.xcperspec' + StatusbarIsVisible + + TimeStamp + 170645186.180722 + ToolbarDisplayMode + 1 + ToolbarIsVisible + + ToolbarSizeMode + 1 + Type + Perspectives + UpdateMessage + The Default Workspace in this version of Xcode now includes support to hide and show the detail view (what has been referred to as the "Metro-Morph" feature). You must discard your current Default Workspace settings and update to the latest Default Workspace in order to gain this feature. Do you wish to update to the latest Workspace defaults for project '%@'? + WindowJustification + 5 + WindowOrderList + + A251BF0F0959BC6E0058BC7F + /Users/johnp/Positive Spin Media/shareware apps/PSMTabBarControl/PSMTabBarControl.xcodeproj + + WindowString + 11 142 905 878 0 0 1680 1028 + WindowTools + + + FirstTimeWindowDisplayed + + Identifier + windowTool.build + IsVertical + + Layout + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 1CD0528F0623707200166675 + PBXProjectModuleLabel + + StatusBarVisibility + + + GeometryConfiguration + + Frame + {{0, 0}, {893, 219}} + RubberWindowFrame + 741 379 893 501 0 0 1680 1028 + + Module + PBXNavigatorGroup + Proportion + 219pt + + + ContentConfiguration + + PBXProjectModuleGUID + XCMainBuildResultsModuleGUID + PBXProjectModuleLabel + Build + XCBuildResultsTrigger_Collapse + 1021 + XCBuildResultsTrigger_Open + 1012 + + GeometryConfiguration + + Frame + {{0, 224}, {893, 236}} + RubberWindowFrame + 741 379 893 501 0 0 1680 1028 + + Module + PBXBuildResultsModule + Proportion + 236pt + + + Proportion + 460pt + + + Name + Build Results + ServiceClasses + + PBXBuildResultsModule + + StatusbarIsVisible + + TableOfContents + + A251BF0F0959BC6E0058BC7F + A246FB030A2BD6C2005BDF7B + 1CD0528F0623707200166675 + XCMainBuildResultsModuleGUID + + ToolbarConfiguration + xcode.toolbar.config.build + WindowString + 741 379 893 501 0 0 1680 1028 + WindowToolGUID + A251BF0F0959BC6E0058BC7F + WindowToolIsVisible + + + + FirstTimeWindowDisplayed + + Identifier + windowTool.debugger + IsVertical + + Layout + + + Dock + + + ContentConfiguration + + Debugger + + HorizontalSplitView + + _collapsingFrameDimension + 0.0 + _indexOfCollapsedView + 0 + _percentageOfCollapsedView + 0.0 + isCollapsed + yes + sizes + + {{0, 0}, {246, 154}} + {{0, 154}, {246, 231}} + + + VerticalSplitView + + _collapsingFrameDimension + 0.0 + _indexOfCollapsedView + 0 + _percentageOfCollapsedView + 0.0 + isCollapsed + yes + sizes + + {{0, 0}, {246, 385}} + {{246, 0}, {576, 385}} + + + + LauncherConfigVersion + 8 + PBXProjectModuleGUID + 1C162984064C10D400B95A72 + PBXProjectModuleLabel + Debug - GLUTExamples (Underwater) + + GeometryConfiguration + + DebugConsoleDrawerSize + {100, 120} + DebugConsoleVisible + None + DebugConsoleWindowFrame + {{200, 200}, {500, 300}} + DebugSTDIOWindowFrame + {{200, 200}, {500, 300}} + Frame + {{0, 0}, {822, 385}} + RubberWindowFrame + 810 406 822 426 0 0 1680 1028 + + Module + PBXDebugSessionModule + Proportion + 385pt + + + Proportion + 385pt + + + Name + Debugger + ServiceClasses + + PBXDebugSessionModule + + StatusbarIsVisible + + TableOfContents + + 1CD10A99069EF8BA00B06720 + A2704C0609F55E1A000002CC + 1C162984064C10D400B95A72 + A2704C0709F55E1A000002CC + A2704C0809F55E1A000002CC + A2704C0909F55E1A000002CC + A2704C0A09F55E1A000002CC + A2704C0B09F55E1A000002CC + A2704C0C09F55E1A000002CC + + ToolbarConfiguration + xcode.toolbar.config.debug + WindowString + 810 406 822 426 0 0 1680 1028 + WindowToolGUID + 1CD10A99069EF8BA00B06720 + WindowToolIsVisible + + + + FirstTimeWindowDisplayed + + Identifier + windowTool.find + IsVertical + + Layout + + + Dock + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 1CDD528C0622207200134675 + PBXProjectModuleLabel + <No Editor> + StatusBarVisibility + + + GeometryConfiguration + + Frame + {{0, 0}, {791, 418}} + RubberWindowFrame + 710 297 791 676 0 0 1680 1028 + + Module + PBXNavigatorGroup + Proportion + 791pt + + + Proportion + 418pt + + + ContentConfiguration + + PBXProjectModuleGUID + 1CD0528E0623707200166675 + PBXProjectModuleLabel + Project Find + + GeometryConfiguration + + Frame + {{0, 423}, {791, 212}} + RubberWindowFrame + 710 297 791 676 0 0 1680 1028 + + Module + PBXProjectFindModule + Proportion + 212pt + + + Proportion + 635pt + + + Name + Project Find + ServiceClasses + + PBXProjectFindModule + + StatusbarIsVisible + + TableOfContents + + 1C530D57069F1CE1000CFCEE + A27E46850A28BCB6007BA395 + A27E46860A28BCB6007BA395 + 1CDD528C0622207200134675 + 1CD0528E0623707200166675 + + WindowString + 710 297 791 676 0 0 1680 1028 + WindowToolGUID + 1C530D57069F1CE1000CFCEE + WindowToolIsVisible + + + + Identifier + MENUSEPARATOR + + + FirstTimeWindowDisplayed + + Identifier + windowTool.debuggerConsole + IsVertical + + Layout + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 1C78EAAC065D492600B07095 + PBXProjectModuleLabel + Debugger Console + + GeometryConfiguration + + Frame + {{0, 0}, {440, 358}} + RubberWindowFrame + 42 583 440 400 0 0 1680 1028 + + Module + PBXDebugCLIModule + Proportion + 358pt + + + Proportion + 359pt + + + Name + Debugger Console + ServiceClasses + + PBXDebugCLIModule + + StatusbarIsVisible + + TableOfContents + + A257696C0961A49900DDAD2A + A2704C0D09F55E1A000002CC + 1C78EAAC065D492600B07095 + + WindowString + 42 583 440 400 0 0 1680 1028 + WindowToolGUID + A257696C0961A49900DDAD2A + WindowToolIsVisible + + + + FirstTimeWindowDisplayed + + Identifier + windowTool.run + IsVertical + + Layout + + + Dock + + + ContentConfiguration + + LauncherConfigVersion + 3 + PBXProjectModuleGUID + 1CD0528B0623707200166675 + PBXProjectModuleLabel + Run + Runner + + HorizontalSplitView + + _collapsingFrameDimension + 0.0 + _indexOfCollapsedView + 0 + _percentageOfCollapsedView + 0.0 + isCollapsed + yes + sizes + + {{0, 0}, {367, 168}} + {{0, 173}, {367, 270}} + + + VerticalSplitView + + _collapsingFrameDimension + 0.0 + _indexOfCollapsedView + 0 + _percentageOfCollapsedView + 0.0 + isCollapsed + yes + sizes + + {{0, 0}, {406, 443}} + {{411, 0}, {517, 443}} + + + + + GeometryConfiguration + + Frame + {{0, 0}, {459, 159}} + RubberWindowFrame + 898 148 459 200 0 0 1680 1028 + + Module + PBXRunSessionModule + Proportion + 159pt + + + Proportion + 159pt + + + Name + Run Log + ServiceClasses + + PBXRunSessionModule + + StatusbarIsVisible + + TableOfContents + + 1C0AD2B3069F1EA900FABCE6 + A2F0AA9B0A2B977D00BEF297 + 1CD0528B0623707200166675 + A2F0AA9C0A2B977D00BEF297 + + ToolbarConfiguration + xcode.toolbar.config.run + WindowString + 898 148 459 200 0 0 1680 1028 + WindowToolGUID + 1C0AD2B3069F1EA900FABCE6 + WindowToolIsVisible + + + + Identifier + windowTool.scm + Layout + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 1C78EAB2065D492600B07095 + PBXProjectModuleLabel + <No Editor> + PBXSplitModuleInNavigatorKey + + Split0 + + PBXProjectModuleGUID + 1C78EAB3065D492600B07095 + + SplitCount + 1 + + StatusBarVisibility + 1 + + GeometryConfiguration + + Frame + {{0, 0}, {452, 0}} + RubberWindowFrame + 743 379 452 308 0 0 1280 1002 + + Module + PBXNavigatorGroup + Proportion + 0pt + + + BecomeActive + 1 + ContentConfiguration + + PBXProjectModuleGUID + 1CD052920623707200166675 + PBXProjectModuleLabel + SCM + + GeometryConfiguration + + ConsoleFrame + {{0, 259}, {452, 0}} + Frame + {{0, 7}, {452, 259}} + RubberWindowFrame + 743 379 452 308 0 0 1280 1002 + TableConfiguration + + Status + 30 + FileName + 199 + Path + 197.09500122070312 + + TableFrame + {{0, 0}, {452, 250}} + + Module + PBXCVSModule + Proportion + 262pt + + + Proportion + 266pt + + + Name + SCM + ServiceClasses + + PBXCVSModule + + StatusbarIsVisible + 1 + TableOfContents + + 1C78EAB4065D492600B07095 + 1C78EAB5065D492600B07095 + 1C78EAB2065D492600B07095 + 1CD052920623707200166675 + + ToolbarConfiguration + xcode.toolbar.config.scm + WindowString + 743 379 452 308 0 0 1280 1002 + + + FirstTimeWindowDisplayed + + Identifier + windowTool.breakpoints + IsVertical + + Layout + + + Dock + + + BecomeActive + + ContentConfiguration + + PBXBottomSmartGroupGIDs + + 1C77FABC04509CD000000102 + + PBXProjectModuleGUID + 1CE0B1FE06471DED0097A5F4 + PBXProjectModuleLabel + Files + PBXProjectStructureProvided + no + PBXSmartGroupTreeModuleColumnData + + PBXSmartGroupTreeModuleColumnWidthsKey + + 168 + + PBXSmartGroupTreeModuleColumnsKey_v4 + + MainColumn + + + PBXSmartGroupTreeModuleOutlineStateKey_v7 + + PBXSmartGroupTreeModuleOutlineStateExpansionKey + + 1C77FABC04509CD000000102 + + PBXSmartGroupTreeModuleOutlineStateSelectionKey + + + 0 + + + PBXSmartGroupTreeModuleOutlineStateVisibleRectKey + {{0, 0}, {168, 350}} + + PBXTopSmartGroupGIDs + + XCIncludePerspectivesSwitch + + + GeometryConfiguration + + Frame + {{0, 0}, {185, 368}} + GroupTreeTableConfiguration + + MainColumn + 168 + + RubberWindowFrame + 42 573 744 409 0 0 1680 1028 + + Module + PBXSmartGroupTreeModule + Proportion + 185pt + + + ContentConfiguration + + PBXProjectModuleGUID + 1CA1AED706398EBD00589147 + PBXProjectModuleLabel + Detail + + GeometryConfiguration + + Frame + {{190, 0}, {554, 368}} + RubberWindowFrame + 42 573 744 409 0 0 1680 1028 + + Module + XCDetailModule + Proportion + 554pt + + + Proportion + 368pt + + + MajorVersion + 2 + MinorVersion + 0 + Name + Breakpoints + ServiceClasses + + PBXSmartGroupTreeModule + XCDetailModule + + StatusbarIsVisible + + TableOfContents + + A2467AD609B260B500A9F728 + A2467AD709B260B500A9F728 + 1CE0B1FE06471DED0097A5F4 + 1CA1AED706398EBD00589147 + + ToolbarConfiguration + xcode.toolbar.config.breakpoints + WindowString + 42 573 744 409 0 0 1680 1028 + WindowToolGUID + A2467AD609B260B500A9F728 + WindowToolIsVisible + + + + FirstTimeWindowDisplayed + + Identifier + windowTool.debugAnimator + IsVertical + + Layout + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + A2F51A6709AA776500056B6F + PBXProjectModuleLabel + PSMTabBarControl.m_1.xcclassmodel + StatusBarVisibility + + + GeometryConfiguration + + Frame + {{0, 0}, {700, 459}} + RubberWindowFrame + 816 148 700 500 0 0 1680 1028 + + Module + PBXNavigatorGroup + Proportion + 459pt + + + Proportion + 459pt + + + Name + Debug Visualizer + ServiceClasses + + PBXNavigatorGroup + + StatusbarIsVisible + + TableOfContents + + A2F51A8D09AA776500056B6F + A2F51A8E09AA776500056B6F + A2F51A6709AA776500056B6F + + ToolbarConfiguration + xcode.toolbar.config.debugAnimator + WindowString + 816 148 700 500 0 0 1680 1028 + WindowToolGUID + A2F51A8D09AA776500056B6F + WindowToolIsVisible + + + + Identifier + windowTool.bookmarks + Layout + + + Dock + + + Module + PBXBookmarksModule + Proportion + 100% + + + Proportion + 100% + + + Name + Bookmarks + ServiceClasses + + PBXBookmarksModule + + StatusbarIsVisible + 0 + WindowString + 538 42 401 187 0 0 1280 1002 + + + FirstTimeWindowDisplayed + + Identifier + windowTool.classBrowser + IsVertical + + Layout + + + Dock + + + ContentConfiguration + + OptionsSetName + Flat, all classes + PBXProjectModuleGUID + 1CA6456E063B45B4001379D8 + PBXProjectModuleLabel + Class Browser - NSTextFieldCell + + GeometryConfiguration + + ClassesFrame + {{0, 0}, {655, 321}} + ClassesTreeTableConfiguration + + PBXClassNameColumnIdentifier + 208 + PBXClassBookColumnIdentifier + 22 + + Frame + {{0, 0}, {907, 807}} + MembersFrame + {{0, 326}, {655, 481}} + MembersTreeTableConfiguration + + PBXMemberTypeIconColumnIdentifier + 22 + PBXMemberNameColumnIdentifier + 216 + PBXMemberTypeColumnIdentifier + 378 + PBXMemberBookColumnIdentifier + 22 + + RubberWindowFrame + 704 190 907 827 0 0 1680 1028 + + Module + PBXClassBrowserModule + Proportion + 807pt + + + Proportion + 807pt + + + Name + Class Browser + ServiceClasses + + PBXClassBrowserModule + + StatusbarIsVisible + + TableOfContents + + 1C0AD2AF069F1E9B00FABCE6 + A27E47260A28E1D0007BA395 + 1CA6456E063B45B4001379D8 + + ToolbarConfiguration + xcode.toolbar.config.classbrowser + WindowString + 704 190 907 827 0 0 1680 1028 + WindowToolGUID + 1C0AD2AF069F1E9B00FABCE6 + WindowToolIsVisible + + + + + diff --git a/PSMTabBarControl/PSMTabBarControl.xcodeproj/johnp.pbxuser b/PSMTabBarControl/PSMTabBarControl.xcodeproj/johnp.pbxuser new file mode 100644 index 0000000000..4710912397 --- /dev/null +++ b/PSMTabBarControl/PSMTabBarControl.xcodeproj/johnp.pbxuser @@ -0,0 +1,1920 @@ +// !$*UTF8*$! +{ + 0259C573FE90428111CA0C5A /* Project object */ = { + activeBuildConfigurationName = Release; + activeExecutable = A251BEA10959BB5B0058BC7F /* TabBarControlDemo */; + activeTarget = 53DF6901067E5B8E0090B5B0 /* All */; + addToTargets = ( + ); + breakpoints = ( + A25769760961A59400DDAD2A /* -[_NSZombie methodSignatureForSelector:] */, + A2F51A5709AA767B00056B6F /* -[NSException raise] */, + ); + breakpointsGroup = A25769750961A58A00DDAD2A /* XCBreakpointsBucket */; + codeSenseManager = A251BE5509599FBA0058BC7F /* Code sense */; + executables = ( + A251BEA10959BB5B0058BC7F /* TabBarControlDemo */, + ); + perUserDictionary = { + "PBXConfiguration.PBXBreakpointsDataSource.v1:1CA1AED706398EBD00589147" = { + PBXFileTableDataSourceColumnSortingDirectionKey = "-1"; + PBXFileTableDataSourceColumnSortingKey = PBXBreakpointsDataSource_BreakpointID; + PBXFileTableDataSourceColumnWidthsKey = ( + 20, + 20, + 210, + 20, + 110, + 109, + 20, + ); + PBXFileTableDataSourceColumnsKey = ( + PBXBreakpointsDataSource_ActionID, + PBXBreakpointsDataSource_TypeID, + PBXBreakpointsDataSource_BreakpointID, + PBXBreakpointsDataSource_UseID, + PBXBreakpointsDataSource_LocationID, + PBXBreakpointsDataSource_ConditionID, + PBXBreakpointsDataSource_ContinueID, + ); + }; + PBXConfiguration.PBXFileTableDataSource3.PBXErrorsWarningsDataSource = { + PBXFileTableDataSourceColumnSortingDirectionKey = "-1"; + PBXFileTableDataSourceColumnSortingKey = PBXErrorsWarningsDataSource_LocationID; + PBXFileTableDataSourceColumnWidthsKey = ( + 20, + 300, + 200, + ); + PBXFileTableDataSourceColumnsKey = ( + PBXErrorsWarningsDataSource_TypeID, + PBXErrorsWarningsDataSource_MessageID, + PBXErrorsWarningsDataSource_LocationID, + ); + }; + PBXConfiguration.PBXFileTableDataSource3.PBXExecutablesDataSource = { + PBXFileTableDataSourceColumnSortingDirectionKey = "-1"; + PBXFileTableDataSourceColumnSortingKey = PBXExecutablesDataSource_NameID; + PBXFileTableDataSourceColumnWidthsKey = ( + 22, + 300, + 331, + ); + PBXFileTableDataSourceColumnsKey = ( + PBXExecutablesDataSource_ActiveFlagID, + PBXExecutablesDataSource_NameID, + PBXExecutablesDataSource_CommentsID, + ); + }; + PBXConfiguration.PBXFileTableDataSource3.PBXFileTableDataSource = { + PBXFileTableDataSourceColumnSortingDirectionKey = "-1"; + PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID; + PBXFileTableDataSourceColumnWidthsKey = ( + 20, + 424, + 20, + 48, + 43, + 43, + 20, + ); + PBXFileTableDataSourceColumnsKey = ( + PBXFileDataSource_FiletypeID, + PBXFileDataSource_Filename_ColumnID, + PBXFileDataSource_Built_ColumnID, + PBXFileDataSource_ObjectSize_ColumnID, + PBXFileDataSource_Errors_ColumnID, + PBXFileDataSource_Warnings_ColumnID, + PBXFileDataSource_Target_ColumnID, + ); + }; + PBXConfiguration.PBXTargetDataSource.PBXTargetDataSource = { + PBXFileTableDataSourceColumnSortingDirectionKey = "-1"; + PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID; + PBXFileTableDataSourceColumnWidthsKey = ( + 20, + 200, + 218, + 20, + 48, + 43, + 43, + ); + PBXFileTableDataSourceColumnsKey = ( + PBXFileDataSource_FiletypeID, + PBXFileDataSource_Filename_ColumnID, + PBXTargetDataSource_PrimaryAttribute, + PBXFileDataSource_Built_ColumnID, + PBXFileDataSource_ObjectSize_ColumnID, + PBXFileDataSource_Errors_ColumnID, + PBXFileDataSource_Warnings_ColumnID, + ); + }; + PBXPerProjectTemplateStateSaveDate = 170644414; + PBXWorkspaceStateSaveDate = 170644414; + }; + perUserProjectItems = { + A2072A5709ABDC4400304BCB = A2072A5709ABDC4400304BCB /* PBXTextBookmark */; + A2072A5A09ABDC4400304BCB = A2072A5A09ABDC4400304BCB /* PBXBookmark */; + A2072A5B09ABDC4400304BCB = A2072A5B09ABDC4400304BCB /* PBXBookmark */; + A20822E70959F4CE00C5F5A4 = A20822E70959F4CE00C5F5A4 /* PBXTextBookmark */; + A20822E80959F4CE00C5F5A4 = A20822E80959F4CE00C5F5A4 /* PBXTextBookmark */; + A20822EA0959F4CE00C5F5A4 = A20822EA0959F4CE00C5F5A4 /* PBXTextBookmark */; + A208236A095A58C700C5F5A4 = A208236A095A58C700C5F5A4 /* PBXTextBookmark */; + A2082371095A58C700C5F5A4 = A2082371095A58C700C5F5A4 /* PBXTextBookmark */; + A2082398095A630900C5F5A4 = A2082398095A630900C5F5A4 /* PBXTextBookmark */; + A20823A1095A630900C5F5A4 = A20823A1095A630900C5F5A4 /* PBXTextBookmark */; + A20823A2095A630900C5F5A4 = A20823A2095A630900C5F5A4 /* PBXBookmark */; + A20823A3095A630900C5F5A4 = A20823A3095A630900C5F5A4 /* PBXBookmark */; + A208348A09CA185D00837C29 = A208348A09CA185D00837C29 /* PBXTextBookmark */; + A209E26A09F7E9FE0060532B = A209E26A09F7E9FE0060532B /* PBXTextBookmark */; + A209E26F09F7E9FE0060532B = A209E26F09F7E9FE0060532B /* PBXTextBookmark */; + A209E27009F7E9FE0060532B = A209E27009F7E9FE0060532B /* PBXTextBookmark */; + A209E28609F83C1E0060532B = A209E28609F83C1E0060532B /* PBXTextBookmark */; + A209E28C09F83C1E0060532B = A209E28C09F83C1E0060532B /* PBXTextBookmark */; + A20A6FC109FB23FA0018A4B5 = A20A6FC109FB23FA0018A4B5 /* PBXTextBookmark */; + A20A6FC209FB23FA0018A4B5 = A20A6FC209FB23FA0018A4B5 /* PBXTextBookmark */; + A20A6FC309FB23FA0018A4B5 = A20A6FC309FB23FA0018A4B5 /* PBXTextBookmark */; + A20A6FC409FB23FA0018A4B5 = A20A6FC409FB23FA0018A4B5 /* PBXTextBookmark */; + A21370F30A1C2CC400673584 = A21370F30A1C2CC400673584 /* PBXTextBookmark */; + A2179E3B09CA11BE00E40445 = A2179E3B09CA11BE00E40445 /* PBXTextBookmark */; + A21F8C430963122D00B04C56 = A21F8C430963122D00B04C56 /* PBXBookmark */; + A21F8C440963122D00B04C56 = A21F8C440963122D00B04C56 /* PBXBookmark */; + A22BAD0209C200AB0004449D = A22BAD0209C200AB0004449D /* PBXTextBookmark */; + A22BAD0609C200AB0004449D = A22BAD0609C200AB0004449D /* PBXTextBookmark */; + A22BAD2609C203D80004449D = A22BAD2609C203D80004449D /* PBXTextBookmark */; + A22BAD2A09C203D80004449D = A22BAD2A09C203D80004449D /* PBXTextBookmark */; + A234001B09B2B346001A1B18 = A234001B09B2B346001A1B18 /* PBXTextBookmark */; + A234001E09B2B346001A1B18 = A234001E09B2B346001A1B18 /* PBXBookmark */; + A234006C09B2C55E001A1B18 = A234006C09B2C55E001A1B18 /* PBXTextBookmark */; + A234006D09B2C55E001A1B18 = A234006D09B2C55E001A1B18 /* PBXTextBookmark */; + A234FFFF09B2AF46001A1B18 = A234FFFF09B2AF46001A1B18 /* PBXBookmark */; + A240E76509C2211500F755E1 = A240E76509C2211500F755E1 /* PBXTextBookmark */; + A240E76609C2211500F755E1 = A240E76609C2211500F755E1 /* PBXTextBookmark */; + A240E76D09C2211500F755E1 = A240E76D09C2211500F755E1 /* PBXTextBookmark */; + A246FAF70A2BD6C2005BDF7B /* PBXTextBookmark */ = A246FAF70A2BD6C2005BDF7B /* PBXTextBookmark */; + A246FAF80A2BD6C2005BDF7B /* PBXTextBookmark */ = A246FAF80A2BD6C2005BDF7B /* PBXTextBookmark */; + A246FAF90A2BD6C2005BDF7B /* PBXTextBookmark */ = A246FAF90A2BD6C2005BDF7B /* PBXTextBookmark */; + A246FAFA0A2BD6C2005BDF7B /* PBXTextBookmark */ = A246FAFA0A2BD6C2005BDF7B /* PBXTextBookmark */; + A246FAFB0A2BD6C2005BDF7B /* PBXTextBookmark */ = A246FAFB0A2BD6C2005BDF7B /* PBXTextBookmark */; + A246FAFC0A2BD6C2005BDF7B /* PBXTextBookmark */ = A246FAFC0A2BD6C2005BDF7B /* PBXTextBookmark */; + A246FAFD0A2BD6C2005BDF7B /* PBXTextBookmark */ = A246FAFD0A2BD6C2005BDF7B /* PBXTextBookmark */; + A246FAFE0A2BD6C2005BDF7B /* PBXTextBookmark */ = A246FAFE0A2BD6C2005BDF7B /* PBXTextBookmark */; + A246FAFF0A2BD6C2005BDF7B /* PBXTextBookmark */ = A246FAFF0A2BD6C2005BDF7B /* PBXTextBookmark */; + A246FB000A2BD6C2005BDF7B /* PBXTextBookmark */ = A246FB000A2BD6C2005BDF7B /* PBXTextBookmark */; + A24DF7F10A2B9F64004D2710 = A24DF7F10A2B9F64004D2710 /* PBXTextBookmark */; + A251BE660959A0E60058BC7F = A251BE660959A0E60058BC7F /* PBXTextBookmark */; + A251BE670959A0E60058BC7F = A251BE670959A0E60058BC7F /* PBXTextBookmark */; + A251BEF10959BC6E0058BC7F = A251BEF10959BC6E0058BC7F /* PBXTextBookmark */; + A251BEF80959BC6E0058BC7F = A251BEF80959BC6E0058BC7F /* PBXTextBookmark */; + A251BEFC0959BC6E0058BC7F = A251BEFC0959BC6E0058BC7F /* PBXTextBookmark */; + A251BEFD0959BC6E0058BC7F = A251BEFD0959BC6E0058BC7F /* PBXTextBookmark */; + A251BEFE0959BC6E0058BC7F = A251BEFE0959BC6E0058BC7F /* PBXTextBookmark */; + A251BF000959BC6E0058BC7F = A251BF000959BC6E0058BC7F /* PBXTextBookmark */; + A251BF020959BC6E0058BC7F = A251BF020959BC6E0058BC7F /* PBXTextBookmark */; + A251BF040959BC6E0058BC7F = A251BF040959BC6E0058BC7F /* PBXTextBookmark */; + A251BF050959BC6E0058BC7F = A251BF050959BC6E0058BC7F /* PBXTextBookmark */; + A251BF060959BC6E0058BC7F = A251BF060959BC6E0058BC7F /* PBXTextBookmark */; + A251BF070959BC6E0058BC7F = A251BF070959BC6E0058BC7F /* PBXBookmark */; + A251BF0A0959BC6E0058BC7F = A251BF0A0959BC6E0058BC7F /* PBXBookmark */; + A251BF0B0959BC6E0058BC7F = A251BF0B0959BC6E0058BC7F /* PBXBookmark */; + A251BF270959BD670058BC7F = A251BF270959BD670058BC7F /* PBXBookmark */; + A264DC290A1E83A9001A9027 = A264DC290A1E83A9001A9027 /* PBXTextBookmark */; + A268E7C609A9792000E082AA = A268E7C609A9792000E082AA /* PBXBookmark */; + A268E7C709A9792000E082AA = A268E7C709A9792000E082AA /* PBXBookmark */; + A268EA9709A9876A00E082AA = A268EA9709A9876A00E082AA /* PBXTextBookmark */; + A268EAA009A9876A00E082AA = A268EAA009A9876A00E082AA /* PBXTextBookmark */; + A268EAAA09A9876A00E082AA = A268EAAA09A9876A00E082AA /* PBXBookmark */; + A269364309A7BC8D0006911E = A269364309A7BC8D0006911E /* PBXTextBookmark */; + A2704C0F09F56903000002CC = A2704C0F09F56903000002CC /* PBXTextBookmark */; + A2758F9B09B4BB1C006E31C3 = A2758F9B09B4BB1C006E31C3 /* PBXTextBookmark */; + A2758F9C09B4BB1C006E31C3 = A2758F9C09B4BB1C006E31C3 /* PBXTextBookmark */; + A27E46770A28B49E007BA395 = A27E46770A28B49E007BA395 /* PBXTextBookmark */; + A27E46780A28B49E007BA395 = A27E46780A28B49E007BA395 /* PBXTextBookmark */; + A27E46C80A28C05D007BA395 = A27E46C80A28C05D007BA395 /* PBXTextBookmark */; + A27E46C90A28C05D007BA395 = A27E46C90A28C05D007BA395 /* PBXTextBookmark */; + A27E475B0A28EBEE007BA395 = A27E475B0A28EBEE007BA395 /* PBXTextBookmark */; + A27E475F0A28EBEE007BA395 = A27E475F0A28EBEE007BA395 /* PBXBookmark */; + A27E47610A28EBEE007BA395 = A27E47610A28EBEE007BA395 /* PBXBookmark */; + A27E47660A28EBEE007BA395 = A27E47660A28EBEE007BA395 /* PBXTextBookmark */; + A27E47670A28EBEE007BA395 = A27E47670A28EBEE007BA395 /* PBXBookmark */; + A27E47680A28EBEE007BA395 = A27E47680A28EBEE007BA395 /* PBXBookmark */; + A27E47690A28EBEE007BA395 = A27E47690A28EBEE007BA395 /* PBXBookmark */; + A27E476A0A28EBEE007BA395 = A27E476A0A28EBEE007BA395 /* PBXBookmark */; + A27E47740A28EBEE007BA395 = A27E47740A28EBEE007BA395 /* PBXBookmark */; + A27E47E40A28F7FB007BA395 = A27E47E40A28F7FB007BA395 /* PBXBookmark */; + A27E47E50A28F7FB007BA395 = A27E47E50A28F7FB007BA395 /* PBXBookmark */; + A27E47E60A28F7FB007BA395 = A27E47E60A28F7FB007BA395 /* PBXBookmark */; + A27E47E70A28F7FB007BA395 = A27E47E70A28F7FB007BA395 /* PBXBookmark */; + A27E47E80A28F7FB007BA395 = A27E47E80A28F7FB007BA395 /* PBXBookmark */; + A27E47E90A28F7FB007BA395 = A27E47E90A28F7FB007BA395 /* PBXBookmark */; + A27E47EA0A28F7FB007BA395 = A27E47EA0A28F7FB007BA395 /* PBXBookmark */; + A27E47EB0A28F7FB007BA395 = A27E47EB0A28F7FB007BA395 /* PBXBookmark */; + A27E47EC0A28F7FB007BA395 = A27E47EC0A28F7FB007BA395 /* PBXBookmark */; + A27E47ED0A28F7FB007BA395 = A27E47ED0A28F7FB007BA395 /* PBXBookmark */; + A27E47EE0A28F7FB007BA395 = A27E47EE0A28F7FB007BA395 /* PBXBookmark */; + A27E47EF0A28F7FB007BA395 = A27E47EF0A28F7FB007BA395 /* PBXBookmark */; + A27E47F00A28F7FB007BA395 = A27E47F00A28F7FB007BA395 /* PBXBookmark */; + A27E47F10A28F7FB007BA395 = A27E47F10A28F7FB007BA395 /* PBXBookmark */; + A27E47F20A28F7FB007BA395 = A27E47F20A28F7FB007BA395 /* PBXBookmark */; + A27E47F30A28F7FB007BA395 = A27E47F30A28F7FB007BA395 /* PBXBookmark */; + A27E47F40A28F7FB007BA395 = A27E47F40A28F7FB007BA395 /* PBXBookmark */; + A27E47F50A28F7FB007BA395 = A27E47F50A28F7FB007BA395 /* PBXBookmark */; + A27E47F60A28F7FB007BA395 = A27E47F60A28F7FB007BA395 /* PBXBookmark */; + A27E47F70A28F7FB007BA395 = A27E47F70A28F7FB007BA395 /* PBXBookmark */; + A27E47F80A28F7FB007BA395 = A27E47F80A28F7FB007BA395 /* PBXBookmark */; + A27E47F90A28F7FB007BA395 = A27E47F90A28F7FB007BA395 /* PBXBookmark */; + A27E47FA0A28F7FB007BA395 = A27E47FA0A28F7FB007BA395 /* PBXBookmark */; + A27E47FB0A28F7FB007BA395 = A27E47FB0A28F7FB007BA395 /* PBXBookmark */; + A27E47FC0A28F7FB007BA395 = A27E47FC0A28F7FB007BA395 /* PBXBookmark */; + A27E47FD0A28F7FB007BA395 = A27E47FD0A28F7FB007BA395 /* PBXBookmark */; + A27E47FE0A28F7FB007BA395 = A27E47FE0A28F7FB007BA395 /* PBXBookmark */; + A27E48050A28F7FC007BA395 = A27E48050A28F7FC007BA395 /* PBXBookmark */; + A27E48060A28F7FC007BA395 = A27E48060A28F7FC007BA395 /* PBXBookmark */; + A27E480E0A28F7FC007BA395 = A27E480E0A28F7FC007BA395 /* PBXBookmark */; + A27E48100A28F7FC007BA395 = A27E48100A28F7FC007BA395 /* PBXBookmark */; + A27E48110A28F7FC007BA395 = A27E48110A28F7FC007BA395 /* PBXBookmark */; + A27F6A870A1B9AD100AE7009 = A27F6A870A1B9AD100AE7009 /* PBXTextBookmark */; + A2A2B9D909F448F9002BE730 = A2A2B9D909F448F9002BE730 /* PBXTextBookmark */; + A2A2B9E309F448F9002BE730 = A2A2B9E309F448F9002BE730 /* PBXTextBookmark */; + A2A7121E09E5C48C00D0089B = A2A7121E09E5C48C00D0089B /* PBXTextBookmark */; + A2BEC7EB09C1F01F00B8B4B6 = A2BEC7EB09C1F01F00B8B4B6 /* PBXTextBookmark */; + A2CD7C5709B7738800FBAAAE = A2CD7C5709B7738800FBAAAE /* PBXTextBookmark */; + A2CD7C8D09B7B55E00FBAAAE = A2CD7C8D09B7B55E00FBAAAE /* PBXTextBookmark */; + A2CF618009F4099F00A0F9A8 = A2CF618009F4099F00A0F9A8 /* PBXTextBookmark */; + A2CF618409F4099F00A0F9A8 = A2CF618409F4099F00A0F9A8 /* PBXTextBookmark */; + A2D32F4609A6441B00EC8662 = A2D32F4609A6441B00EC8662 /* PBXTextBookmark */; + A2D32F4909A6441B00EC8662 = A2D32F4909A6441B00EC8662 /* PBXTextBookmark */; + A2D32F4A09A6441B00EC8662 = A2D32F4A09A6441B00EC8662 /* PBXTextBookmark */; + A2D32F5109A6441B00EC8662 = A2D32F5109A6441B00EC8662 /* PBXTextBookmark */; + A2D32F5209A6441B00EC8662 = A2D32F5209A6441B00EC8662 /* PBXTextBookmark */; + A2D3313F09A67ED000EC8662 = A2D3313F09A67ED000EC8662 /* PBXBookmark */; + A2D98B1D0A2B47700064C6F8 = A2D98B1D0A2B47700064C6F8 /* PBXBookmark */; + A2D98B1E0A2B47700064C6F8 = A2D98B1E0A2B47700064C6F8 /* PBXTextBookmark */; + A2D98B1F0A2B47700064C6F8 = A2D98B1F0A2B47700064C6F8 /* PBXTextBookmark */; + A2D98B200A2B47700064C6F8 = A2D98B200A2B47700064C6F8 /* PBXTextBookmark */; + A2D98B210A2B47700064C6F8 = A2D98B210A2B47700064C6F8 /* PBXTextBookmark */; + A2D98B240A2B47700064C6F8 = A2D98B240A2B47700064C6F8 /* PBXTextBookmark */; + A2D98B250A2B47700064C6F8 = A2D98B250A2B47700064C6F8 /* PBXTextBookmark */; + A2D98B260A2B47700064C6F8 = A2D98B260A2B47700064C6F8 /* PBXTextBookmark */; + A2D98B270A2B47700064C6F8 = A2D98B270A2B47700064C6F8 /* PBXTextBookmark */; + A2D98B3E0A2B55140064C6F8 = A2D98B3E0A2B55140064C6F8 /* PBXTextBookmark */; + A2D98B410A2B55140064C6F8 = A2D98B410A2B55140064C6F8 /* PBXTextBookmark */; + A2E8401109F48B62000217C4 = A2E8401109F48B62000217C4 /* PBXTextBookmark */; + A2ED871409C28FBD006BD5FC = A2ED871409C28FBD006BD5FC /* PBXTextBookmark */; + A2F0AA9D0A2B977F00BEF297 = A2F0AA9D0A2B977F00BEF297 /* PBXTextBookmark */; + A2F0AA9E0A2B977F00BEF297 = A2F0AA9E0A2B977F00BEF297 /* PBXTextBookmark */; + A2F0AA9F0A2B977F00BEF297 = A2F0AA9F0A2B977F00BEF297 /* PBXTextBookmark */; + A2F0AAA70A2B977F00BEF297 = A2F0AAA70A2B977F00BEF297 /* PBXTextBookmark */; + A2F0DF4F09F6D68300AA839C = A2F0DF4F09F6D68300AA839C /* PBXTextBookmark */; + A2F519DB09AA627E00056B6F = A2F519DB09AA627E00056B6F /* PBXTextBookmark */; + A2F519E509AA627E00056B6F = A2F519E509AA627E00056B6F /* PBXTextBookmark */; + }; + sourceControlManager = A251BE5409599FBA0058BC7F /* Source Control */; + userBuildSettings = { + }; + }; + 0259C576FE90428111CA0C5A /* PSMTabBarControl.m */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {590, 20090}}"; + sepNavSelRange = "{1654, 0}"; + sepNavVisRect = "{{0, 588}, {590, 607}}"; + }; + }; + 0259C577FE90428111CA0C5A /* PSMTabBarControlInspector.m */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {616, 1400}}"; + sepNavSelRange = "{2617, 0}"; + sepNavVisRect = "{{0, 794}, {616, 606}}"; + }; + }; + 0259C578FE90428111CA0C5A /* PSMTabBarControlPalette.m */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {681, 504}}"; + sepNavSelRange = "{242, 25}"; + sepNavVisRect = "{{0, 0}, {681, 494}}"; + }; + }; + 0259C57AFE90428111CA0C5A /* PSMTabBarControl.h */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {616, 1736}}"; + sepNavSelRange = "{3408, 23}"; + sepNavVisRect = "{{0, 1106}, {616, 606}}"; + sepNavWindowFrame = "{{981, 259}, {699, 732}}"; + }; + }; + 0259C57BFE90428111CA0C5A /* PSMTabBarControlInspector.h */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {616, 606}}"; + sepNavSelRange = "{693, 0}"; + sepNavVisRect = "{{0, 0}, {616, 606}}"; + }; + }; + 0259C57CFE90428111CA0C5A /* PSMTabBarControlPalette.h */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {681, 402}}"; + sepNavSelRange = "{356, 0}"; + sepNavVisRect = "{{0, 0}, {681, 402}}"; + }; + }; + 0259C583FE90428111CA0C5A /* palette.table */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {558, 748}}"; + sepNavSelRange = "{232, 0}"; + sepNavVisRect = "{{0, 0}, {558, 748}}"; + sepNavWindowFrame = "{{15, 431}, {689, 592}}"; + }; + }; + 32DBCF980370C29C00C91783 /* PSMTabBarControl_Prefix.pch */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {635, 748}}"; + sepNavSelRange = "{0, 0}"; + sepNavVisRect = "{{0, 0}, {635, 748}}"; + }; + }; + 53DF68FC067E5B5A0090B5B0 /* PSMTabBarControlFramework */ = { + activeExec = 0; + }; + 53DF68FE067E5B5A0090B5B0 /* PSMTabBarControlFramework-Info.plist */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {681, 402}}"; + sepNavSelRange = "{619, 0}"; + sepNavVisRect = "{{0, 0}, {681, 402}}"; + }; + }; + 53DF6901067E5B8E0090B5B0 /* All */ = { + activeExec = 0; + }; + 8D1AC9600486D14A00FE50C9 /* PSMTabBarControl */ = { + activeExec = 0; + }; + 8D1AC9730486D14A00FE50C9 /* Info.plist */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {681, 402}}"; + sepNavSelRange = "{717, 0}"; + sepNavVisRect = "{{0, 0}, {681, 402}}"; + }; + }; + 8D1AC97B0486D23100FE50C9 /* English */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {681, 402}}"; + sepNavSelRange = "{0, 0}"; + sepNavVisRect = "{{0, 0}, {681, 402}}"; + }; + }; + A2072A5709ABDC4400304BCB /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = A251BE8B0959A1EA0058BC7F /* FakeModel.h */; + name = "FakeModel.h: icon"; + rLen = 51; + rLoc = 520; + rType = 0; + vrLen = 532; + vrLoc = 0; + }; + A2072A5A09ABDC4400304BCB /* PBXBookmark */ = { + isa = PBXBookmark; + fRef = A2072A2409ABD88600304BCB /* Folder.tif */; + }; + A2072A5B09ABDC4400304BCB /* PBXBookmark */ = { + isa = PBXBookmark; + fRef = A2072A2509ABD88600304BCB /* Globe.tiff */; + }; + A20822E70959F4CE00C5F5A4 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 54D33B2806778E3300C9C163 /* PSMTabBarControl.ibclassdescription */; + name = "PSMTabBarControl.ibclassdescription: 3"; + rLen = 0; + rLoc = 48; + rType = 0; + vrLen = 77; + vrLoc = 0; + }; + A20822E80959F4CE00C5F5A4 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 0259C57BFE90428111CA0C5A /* PSMTabBarControlInspector.h */; + name = "PSMTabBarControlInspector.h: 1"; + rLen = 0; + rLoc = 0; + rType = 0; + vrLen = 272; + vrLoc = 0; + }; + A20822EA0959F4CE00C5F5A4 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 0259C57CFE90428111CA0C5A /* PSMTabBarControlPalette.h */; + name = "PSMTabBarControlPalette.h: 1"; + rLen = 0; + rLoc = 0; + rType = 0; + vrLen = 399; + vrLoc = 0; + }; + A208236A095A58C700C5F5A4 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 0259C578FE90428111CA0C5A /* PSMTabBarControlPalette.m */; + name = "PSMTabBarControlPalette.m: 1"; + rLen = 0; + rLoc = 0; + rType = 0; + vrLen = 615; + vrLoc = 0; + }; + A2082371095A58C700C5F5A4 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 0259C577FE90428111CA0C5A /* PSMTabBarControlInspector.m */; + name = "PSMTabBarControlInspector.m: 1"; + rLen = 0; + rLoc = 0; + rType = 0; + vrLen = 532; + vrLoc = 0; + }; + A2082398095A630900C5F5A4 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 0259C583FE90428111CA0C5A /* palette.table */; + name = "palette.table: 29"; + rLen = 0; + rLoc = 1168; + rType = 0; + vrLen = 1109; + vrLoc = 0; + }; + A20823A1095A630900C5F5A4 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 32DBCF980370C29C00C91783 /* PSMTabBarControl_Prefix.pch */; + name = "PSMTabBarControl_Prefix.pch: 1"; + rLen = 0; + rLoc = 0; + rType = 0; + vrLen = 213; + vrLoc = 0; + }; + A20823A2095A630900C5F5A4 /* PBXBookmark */ = { + isa = PBXBookmark; + fRef = A20822EF0959F6AA00C5F5A4 /* TabControlRep.tif */; + }; + A20823A3095A630900C5F5A4 /* PBXBookmark */ = { + isa = PBXBookmark; + fRef = A20822F00959F6AA00C5F5A4 /* TabIcon.tif */; + }; + A2082A8D09EAEB33009AC8BE /* PSMTabDragAssistant.h */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {590, 1232}}"; + sepNavSelRange = "{603, 0}"; + sepNavVisRect = "{{0, 161}, {590, 336}}"; + }; + }; + A2082A8E09EAEB33009AC8BE /* PSMTabDragAssistant.m */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {647, 6104}}"; + sepNavSelRange = "{12266, 0}"; + sepNavVisRect = "{{0, 5376}, {647, 336}}"; + }; + }; + A208348A09CA185D00837C29 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = A251BE820959A1B90058BC7F /* PSMOverflowPopUpButton.m */; + name = "PSMOverflowPopUpButton.m: 79"; + rLen = 0; + rLoc = 2437; + rType = 0; + vrLen = 1018; + vrLoc = 1757; + }; + A209E26A09F7E9FE0060532B /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = A2D32EE709A6399300EC8662 /* PSMAquaTabStyle.m */; + name = "- (void)encodeWithCoder:(NSCoder *)aCoder"; + rLen = 42; + rLoc = 16767; + rType = 0; + vrLen = 2285; + vrLoc = 16053; + }; + A209E26F09F7E9FE0060532B /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = A2082A8D09EAEB33009AC8BE /* PSMTabDragAssistant.h */; + name = "- (PSMTabBarCell *)distributePlaceholdersInTabBar:(PSMTabBarControl *)control withDraggedCell:(PSMTabBarCell *)cell;"; + rLen = 106; + rLoc = 2336; + rType = 0; + vrLen = 1705; + vrLoc = 1150; + }; + A209E27009F7E9FE0060532B /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = A2082A8E09EAEB33009AC8BE /* PSMTabDragAssistant.m */; + name = "{"; + rLen = 2; + rLoc = 10115; + rType = 0; + vrLen = 2111; + vrLoc = 9314; + }; + A209E28609F83C1E0060532B /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = A2A711BD09E5BF0500D0089B /* WindowController.h */; + name = "WindowController.h: tabView:shouldCloseTabViewItem:"; + rLen = 267; + rLoc = 1327; + rType = 0; + vrLen = 1765; + vrLoc = 203; + }; + A209E28C09F83C1E0060532B /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = A2A711BD09E5BF0500D0089B /* WindowController.h */; + name = "WindowController.h: tabView:shouldCloseTabViewItem:"; + rLen = 267; + rLoc = 1327; + rType = 0; + vrLen = 1765; + vrLoc = 203; + }; + A20A6FC109FB23FA0018A4B5 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = A2D32EFE09A63D7A00EC8662 /* PSMMetalTabStyle.h */; + name = "PSMMetalTabStyle.h: encodeWithCoder:"; + rLen = 83; + rLoc = 561; + rType = 0; + vrLen = 645; + vrLoc = 0; + }; + A20A6FC209FB23FA0018A4B5 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = A268EA5F09A9831800E082AA /* PSMRolloverButton.h */; + name = "PSMRolloverButton.h: 11"; + rLen = 441; + rLoc = 178; + rType = 0; + vrLen = 536; + vrLoc = 88; + }; + A20A6FC309FB23FA0018A4B5 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = A251BE810959A1B90058BC7F /* PSMOverflowPopUpButton.h */; + name = "PSMOverflowPopUpButton.h: 1"; + rLen = 159; + rLoc = 0; + rType = 0; + vrLen = 477; + vrLoc = 0; + }; + A20A6FC409FB23FA0018A4B5 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = A2129BAF09AEB58F00724E6C /* PSMProgressIndicator.h */; + name = "PSMProgressIndicator.h: 10"; + rLen = 0; + rLoc = 211; + rType = 0; + vrLen = 345; + vrLoc = 0; + }; + A2129BAF09AEB58F00724E6C /* PSMProgressIndicator.h */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {647, 336}}"; + sepNavSelRange = "{211, 0}"; + sepNavVisRect = "{{0, 0}, {647, 336}}"; + }; + }; + A2129BB009AEB58F00724E6C /* PSMProgressIndicator.m */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {529, 368}}"; + sepNavSelRange = "{362, 0}"; + sepNavVisRect = "{{0, 0}, {529, 368}}"; + }; + }; + A21370F30A1C2CC400673584 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = A2D32EDA09A634C900EC8662 /* PSMTabStyle.h */; + name = "PSMTabStyle.h: 48"; + rLen = 78; + rLoc = 1539; + rType = 0; + vrLen = 1532; + vrLoc = 85; + }; + A2179E3B09CA11BE00E40445 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 0259C578FE90428111CA0C5A /* PSMTabBarControlPalette.m */; + name = "- (void)finishInstantiate"; + rLen = 25; + rLoc = 242; + rType = 0; + vrLen = 733; + vrLoc = 0; + }; + A21F8C430963122D00B04C56 /* PBXBookmark */ = { + isa = PBXBookmark; + fRef = A251BE900959A23A0058BC7F /* overflowImage.tiff */; + }; + A21F8C440963122D00B04C56 /* PBXBookmark */ = { + isa = PBXBookmark; + fRef = A251BE910959A23A0058BC7F /* overflowImagePressed.tif */; + }; + A22BAD0209C200AB0004449D /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = A22BAD0309C200AB0004449D /* IBInspector.h */; + name = "(null): 1"; + rLen = 0; + rLoc = 0; + rType = 0; + vrLen = 885; + vrLoc = 0; + }; + A22BAD0309C200AB0004449D /* IBInspector.h */ = { + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = IBInspector.h; + path = /Developer/SDKs/MacOSX10.4u.sdk/System/Library/Frameworks/InterfaceBuilder.framework/Versions/A/Headers/IBInspector.h; + sourceTree = ""; + }; + A22BAD0609C200AB0004449D /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = A22BAD0709C200AB0004449D /* IBInspector.h */; + name = "(null): 1"; + rLen = 0; + rLoc = 0; + rType = 0; + vrLen = 885; + vrLoc = 0; + }; + A22BAD0709C200AB0004449D /* IBInspector.h */ = { + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = IBInspector.h; + path = /Developer/SDKs/MacOSX10.4u.sdk/System/Library/Frameworks/InterfaceBuilder.framework/Versions/A/Headers/IBInspector.h; + sourceTree = ""; + }; + A22BAD2609C203D80004449D /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = A22BAD2709C203D80004449D /* IBViewProtocol.h */; + name = "(null): 23"; + rLen = 141; + rLoc = 911; + rType = 0; + vrLen = 1223; + vrLoc = 231; + }; + A22BAD2709C203D80004449D /* IBViewProtocol.h */ = { + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = IBViewProtocol.h; + path = /Developer/SDKs/MacOSX10.4u.sdk/System/Library/Frameworks/InterfaceBuilder.framework/Versions/A/Headers/IBViewProtocol.h; + sourceTree = ""; + }; + A22BAD2A09C203D80004449D /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = A22BAD2B09C203D80004449D /* IBViewProtocol.h */; + name = "(null): 23"; + rLen = 141; + rLoc = 911; + rType = 0; + vrLen = 1223; + vrLoc = 231; + }; + A22BAD2B09C203D80004449D /* IBViewProtocol.h */ = { + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = IBViewProtocol.h; + path = /Developer/SDKs/MacOSX10.4u.sdk/System/Library/Frameworks/InterfaceBuilder.framework/Versions/A/Headers/IBViewProtocol.h; + sourceTree = ""; + }; + A234001B09B2B346001A1B18 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 32DBCF980370C29C00C91783 /* PSMTabBarControl_Prefix.pch */; + name = "PSMTabBarControl_Prefix.pch: 1"; + rLen = 0; + rLoc = 0; + rType = 0; + vrLen = 213; + vrLoc = 0; + }; + A234001E09B2B346001A1B18 /* PBXBookmark */ = { + isa = PBXBookmark; + fRef = A2C0D99309AF870000ED379C /* pi.png */; + }; + A234006C09B2C55E001A1B18 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 0259C583FE90428111CA0C5A /* palette.table */; + name = "palette.table: 6"; + rLen = 0; + rLoc = 232; + rType = 0; + vrLen = 1312; + vrLoc = 0; + }; + A234006D09B2C55E001A1B18 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 54D33B2806778E3300C9C163 /* PSMTabBarControl.ibclassdescription */; + name = "PSMTabBarControl.ibclassdescription: 3"; + rLen = 0; + rLoc = 48; + rType = 0; + vrLen = 77; + vrLoc = 0; + }; + A234FFFF09B2AF46001A1B18 /* PBXBookmark */ = { + isa = PBXBookmark; + fRef = A2D3317B09A68B7500EC8662 /* AquaTabsDownNonKey.png */; + }; + A240E76509C2211500F755E1 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = A251BEA20959BB5B0058BC7F /* TabBarControlDemo-Info.plist */; + name = "TabBarControlDemo-Info.plist: 18"; + rLen = 0; + rLoc = 607; + rType = 0; + vrLen = 748; + vrLoc = 0; + }; + A240E76609C2211500F755E1 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 53DF68FE067E5B5A0090B5B0 /* PSMTabBarControlFramework-Info.plist */; + name = "PSMTabBarControlFramework-Info.plist: 18"; + rLen = 0; + rLoc = 619; + rType = 0; + vrLen = 710; + vrLoc = 0; + }; + A240E76D09C2211500F755E1 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = A251BEA20959BB5B0058BC7F /* TabBarControlDemo-Info.plist */; + name = "TabBarControlDemo-Info.plist: 1"; + rLen = 0; + rLoc = 0; + rType = 0; + vrLen = 748; + vrLoc = 0; + }; + A246FAF70A2BD6C2005BDF7B /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 0259C57AFE90428111CA0C5A /* PSMTabBarControl.h */; + name = representedTabViewItems; + rLen = 23; + rLoc = 3408; + rType = 0; + vrLen = 1337; + vrLoc = 2496; + }; + A246FAF80A2BD6C2005BDF7B /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 0259C577FE90428111CA0C5A /* PSMTabBarControlInspector.m */; + name = "PSMTabBarControlInspector.m: 75"; + rLen = 0; + rLoc = 2617; + rType = 0; + vrLen = 1624; + vrLoc = 1794; + }; + A246FAF90A2BD6C2005BDF7B /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 0259C57BFE90428111CA0C5A /* PSMTabBarControlInspector.h */; + name = "PSMTabBarControlInspector.h: _allowsDragBetweenWindows"; + rLen = 0; + rLoc = 693; + rType = 0; + vrLen = 720; + vrLoc = 0; + }; + A246FAFA0A2BD6C2005BDF7B /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = A251BE9B0959A2530058BC7F /* ReadMe.rtfd */; + name = "ReadMe.rtfd: 14"; + rLen = 0; + rLoc = 936; + rType = 0; + vrLen = 2325; + vrLoc = 1416; + }; + A246FAFB0A2BD6C2005BDF7B /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = A251BE9B0959A2530058BC7F /* ReadMe.rtfd */; + name = "ReadMe.rtfd: 14"; + rLen = 0; + rLoc = 936; + rType = 0; + vrLen = 2325; + vrLoc = 1416; + }; + A246FAFC0A2BD6C2005BDF7B /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 0259C577FE90428111CA0C5A /* PSMTabBarControlInspector.m */; + name = "[_allowDragBetweenWindows setState:[[self object] allowDragBetweenWindows]];"; + rLen = 83; + rLoc = 3295; + rType = 0; + vrLen = 1176; + vrLoc = 0; + }; + A246FAFD0A2BD6C2005BDF7B /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 0259C57AFE90428111CA0C5A /* PSMTabBarControl.h */; + name = representedTabViewItems; + rLen = 23; + rLoc = 3408; + rType = 0; + vrLen = 1337; + vrLoc = 2496; + }; + A246FAFE0A2BD6C2005BDF7B /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 0259C577FE90428111CA0C5A /* PSMTabBarControlInspector.m */; + name = "PSMTabBarControlInspector.m: 75"; + rLen = 0; + rLoc = 2617; + rType = 0; + vrLen = 1624; + vrLoc = 1794; + }; + A246FAFF0A2BD6C2005BDF7B /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 0259C57BFE90428111CA0C5A /* PSMTabBarControlInspector.h */; + name = "PSMTabBarControlInspector.h: _allowsDragBetweenWindows"; + rLen = 0; + rLoc = 693; + rType = 0; + vrLen = 720; + vrLoc = 0; + }; + A246FB000A2BD6C2005BDF7B /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = A251BE9B0959A2530058BC7F /* ReadMe.rtfd */; + name = "ReadMe.rtfd: 71"; + rLen = 0; + rLoc = 8293; + rType = 0; + vrLen = 1928; + vrLoc = 0; + }; + A24DF7F10A2B9F64004D2710 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = A251BE9B0959A2530058BC7F /* ReadMe.rtfd */; + name = "ReadMe.rtfd: 82"; + rLen = 0; + rLoc = 9026; + rType = 0; + vrLen = 2005; + vrLoc = 0; + }; + A251BE5409599FBA0058BC7F /* Source Control */ = { + isa = PBXSourceControlManager; + fallbackIsa = XCSourceControlManager; + isSCMEnabled = 0; + scmConfiguration = { + }; + scmType = ""; + }; + A251BE5509599FBA0058BC7F /* Code sense */ = { + isa = PBXCodeSenseManager; + indexTemplatePath = ""; + }; + A251BE660959A0E60058BC7F /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 53DF68FE067E5B5A0090B5B0 /* PSMTabBarControlFramework-Info.plist */; + name = "PSMTabBarControlFramework-Info.plist: 1"; + rLen = 0; + rLoc = 0; + rType = 0; + vrLen = 710; + vrLoc = 0; + }; + A251BE670959A0E60058BC7F /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 8D1AC9730486D14A00FE50C9 /* Info.plist */; + name = "Info.plist: 1"; + rLen = 0; + rLoc = 0; + rType = 0; + vrLen = 740; + vrLoc = 0; + }; + A251BE810959A1B90058BC7F /* PSMOverflowPopUpButton.h */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {647, 336}}"; + sepNavSelRange = "{0, 159}"; + sepNavVisRect = "{{0, 0}, {647, 336}}"; + }; + }; + A251BE820959A1B90058BC7F /* PSMOverflowPopUpButton.m */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {681, 1330}}"; + sepNavSelRange = "{2437, 0}"; + sepNavVisRect = "{{0, 824}, {681, 494}}"; + }; + }; + A251BE830959A1B90058BC7F /* PSMTabBarCell.h */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {590, 1456}}"; + sepNavSelRange = "{317, 0}"; + sepNavVisRect = "{{0, 178}, {590, 336}}"; + sepNavWindowFrame = "{{983, 278}, {699, 732}}"; + }; + }; + A251BE840959A1B90058BC7F /* PSMTabBarCell.m */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {590, 5656}}"; + sepNavSelRange = "{8864, 24}"; + sepNavVisRect = "{{0, 5233}, {590, 336}}"; + }; + }; + A251BE890959A1EA0058BC7F /* AppController.h */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {827, 727}}"; + sepNavSelRange = "{176, 0}"; + sepNavVisRect = "{{0, 0}, {827, 727}}"; + }; + }; + A251BE8A0959A1EA0058BC7F /* AppController.m */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {647, 694}}"; + sepNavSelRange = "{401, 0}"; + sepNavVisRect = "{{0, 0}, {647, 694}}"; + }; + }; + A251BE8B0959A1EA0058BC7F /* FakeModel.h */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {681, 755}}"; + sepNavSelRange = "{572, 65}"; + sepNavVisRect = "{{0, 0}, {681, 755}}"; + }; + }; + A251BE8C0959A1EA0058BC7F /* FakeModel.m */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {681, 1092}}"; + sepNavSelRange = "{349, 63}"; + sepNavVisRect = "{{0, 112}, {681, 755}}"; + }; + }; + A251BE8D0959A1EA0058BC7F /* main.m */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {595, 368}}"; + sepNavSelRange = "{201, 0}"; + sepNavVisRect = "{{0, 0}, {595, 368}}"; + }; + }; + A251BE9B0959A2530058BC7F /* ReadMe.rtfd */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {616, 3271}}"; + sepNavSelRange = "{8293, 0}"; + sepNavVisRect = "{{0, 0}, {616, 606}}"; + }; + }; + A251BE9F0959BB5B0058BC7F /* TabBarControlDemo */ = { + activeExec = 0; + executables = ( + A251BEA10959BB5B0058BC7F /* TabBarControlDemo */, + ); + }; + A251BEA10959BB5B0058BC7F /* TabBarControlDemo */ = { + isa = PBXExecutable; + activeArgIndex = 2147483647; + activeArgIndices = ( + ); + argumentStrings = ( + ); + autoAttachOnCrash = 1; + configStateDict = { + }; + customDataFormattersEnabled = 1; + debuggerPlugin = GDBDebugging; + disassemblyDisplayState = 0; + dylibVariantSuffix = ""; + enableDebugStr = 1; + environmentEntries = ( + { + active = YES; + name = NSZombieEnabled; + value = YES; + }, + ); + executableSystemSymbolLevel = 0; + executableUserSymbolLevel = 0; + libgmallocEnabled = 0; + name = TabBarControlDemo; + savedGlobals = { + }; + sourceDirectories = ( + ); + }; + A251BEA20959BB5B0058BC7F /* TabBarControlDemo-Info.plist */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {681, 402}}"; + sepNavSelRange = "{607, 0}"; + sepNavVisRect = "{{0, 0}, {681, 402}}"; + }; + }; + A251BEF10959BC6E0058BC7F /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = A251BE8D0959A1EA0058BC7F /* main.m */; + name = "main.m: 1"; + rLen = 0; + rLoc = 0; + rType = 0; + vrLen = 262; + vrLoc = 0; + }; + A251BEF80959BC6E0058BC7F /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 8D1AC97B0486D23100FE50C9 /* English */; + name = "English: 1"; + rLen = 0; + rLoc = 0; + rType = 0; + vrLen = 103; + vrLoc = 0; + }; + A251BEFC0959BC6E0058BC7F /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = A251BE9B0959A2530058BC7F /* ReadMe.rtfd */; + name = "ReadMe.rtfd: 1"; + rLen = 0; + rLoc = 0; + rType = 0; + vrLen = 1487; + vrLoc = 0; + }; + A251BEFD0959BC6E0058BC7F /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = A251BE810959A1B90058BC7F /* PSMOverflowPopUpButton.h */; + name = "PSMOverflowPopUpButton.h: 1"; + rLen = 0; + rLoc = 0; + rType = 0; + vrLen = 241; + vrLoc = 0; + }; + A251BEFE0959BC6E0058BC7F /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = A251BE820959A1B90058BC7F /* PSMOverflowPopUpButton.m */; + name = "PSMOverflowPopUpButton.m: 1"; + rLen = 0; + rLoc = 0; + rType = 0; + vrLen = 876; + vrLoc = 0; + }; + A251BF000959BC6E0058BC7F /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = A251BE830959A1B90058BC7F /* PSMTabBarCell.h */; + name = "PSMTabBarCell.h: 1"; + rLen = 0; + rLoc = 0; + rType = 0; + vrLen = 1044; + vrLoc = 0; + }; + A251BF020959BC6E0058BC7F /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = A251BE840959A1B90058BC7F /* PSMTabBarCell.m */; + name = "PSMTabBarCell.m: 1"; + rLen = 0; + rLoc = 0; + rType = 0; + vrLen = 1109; + vrLoc = 0; + }; + A251BF040959BC6E0058BC7F /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = A251BE8A0959A1EA0058BC7F /* AppController.m */; + name = "AppController.m: 1"; + rLen = 0; + rLoc = 0; + rType = 0; + vrLen = 430; + vrLoc = 0; + }; + A251BF050959BC6E0058BC7F /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = A251BE8C0959A1EA0058BC7F /* FakeModel.m */; + name = "FakeModel.m: 1"; + rLen = 0; + rLoc = 0; + rType = 0; + vrLen = 563; + vrLoc = 0; + }; + A251BF060959BC6E0058BC7F /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = A251BE8D0959A1EA0058BC7F /* main.m */; + name = "main.m: 1"; + rLen = 0; + rLoc = 0; + rType = 0; + vrLen = 262; + vrLoc = 0; + }; + A251BF070959BC6E0058BC7F /* PBXBookmark */ = { + isa = PBXBookmark; + fRef = A251BE8F0959A23A0058BC7F /* 32x32cancel.png */; + }; + A251BF0A0959BC6E0058BC7F /* PBXBookmark */ = { + isa = PBXBookmark; + fRef = A251BE920959A23A0058BC7F /* TabClose_Front_Pressed.tif */; + }; + A251BF0B0959BC6E0058BC7F /* PBXBookmark */ = { + isa = PBXBookmark; + fRef = A251BE930959A23A0058BC7F /* TabClose_Front_Rollover.tif */; + }; + A251BF270959BD670058BC7F /* PBXBookmark */ = { + isa = PBXBookmark; + fRef = A251BE940959A23A0058BC7F /* TabClose_Front.tif */; + }; + A25769750961A58A00DDAD2A /* XCBreakpointsBucket */ = { + isa = XCBreakpointsBucket; + name = "Project Breakpoints"; + objects = ( + A25769760961A59400DDAD2A /* -[_NSZombie methodSignatureForSelector:] */, + A2F51A5709AA767B00056B6F /* -[NSException raise] */, + ); + }; + A25769760961A59400DDAD2A /* -[_NSZombie methodSignatureForSelector:] */ = { + isa = PBXSymbolicBreakpoint; + actions = ( + ); + breakpointStyle = 0; + continueAfterActions = 0; + delayBeforeContinue = 0; + hitCount = 1; + modificationTime = 167074336.702008; + state = 1; + symbolName = "-[_NSZombie methodSignatureForSelector:]"; + }; + A264DC290A1E83A9001A9027 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = A2D32EFF09A63D7A00EC8662 /* PSMMetalTabStyle.m */; + name = "PSMMetalTabStyle.m: 352"; + rLen = 96; + rLoc = 11166; + rType = 0; + vrLen = 1794; + vrLoc = 10828; + }; + A268E7C609A9792000E082AA /* PBXBookmark */ = { + isa = PBXBookmark; + fRef = A2D3317A09A68B7500EC8662 /* AquaTabsDownGraphite.png */; + }; + A268E7C709A9792000E082AA /* PBXBookmark */ = { + isa = PBXBookmark; + fRef = A2D32EF509A63BF700EC8662 /* AquaTabsSeparator.png */; + }; + A268EA5F09A9831800E082AA /* PSMRolloverButton.h */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {647, 406}}"; + sepNavSelRange = "{178, 441}"; + sepNavVisRect = "{{0, 70}, {647, 336}}"; + }; + }; + A268EA6009A9831800E082AA /* PSMRolloverButton.m */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {647, 1484}}"; + sepNavSelRange = "{1492, 0}"; + sepNavVisRect = "{{0, 333}, {647, 694}}"; + }; + }; + A268EA9709A9876A00E082AA /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = A268EA5F09A9831800E082AA /* PSMRolloverButton.h */; + name = "PSMRolloverButton.h: 1"; + rLen = 0; + rLoc = 0; + rType = 0; + vrLen = 496; + vrLoc = 0; + }; + A268EAA009A9876A00E082AA /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = A268EA6009A9831800E082AA /* PSMRolloverButton.m */; + name = "PSMRolloverButton.m: 2"; + rLen = 0; + rLoc = 31; + rType = 0; + vrLen = 962; + vrLoc = 0; + }; + A268EAAA09A9876A00E082AA /* PBXBookmark */ = { + isa = PBXBookmark; + fRef = A268E7F809A9822900E082AA /* AquaTabNew.png */; + }; + A269364309A7BC8D0006911E /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = A251BE890959A1EA0058BC7F /* AppController.h */; + name = "AppController.h: drawer"; + rLen = 0; + rLoc = 220; + rType = 0; + vrLen = 832; + vrLoc = 0; + }; + A2704C0F09F56903000002CC /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = A251BE8A0959A1EA0058BC7F /* AppController.m */; + name = "AppController.m: 20"; + rLen = 0; + rLoc = 401; + rType = 0; + vrLen = 650; + vrLoc = 0; + }; + A2758F9B09B4BB1C006E31C3 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = A2129BAF09AEB58F00724E6C /* PSMProgressIndicator.h */; + name = "PSMProgressIndicator.h: 12"; + rLen = 0; + rLoc = 267; + rType = 0; + vrLen = 250; + vrLoc = 0; + }; + A2758F9C09B4BB1C006E31C3 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = A2129BB009AEB58F00724E6C /* PSMProgressIndicator.m */; + name = "[(PSMTabBarControl *)[self superview] update];"; + rLen = 51; + rLoc = 362; + rType = 0; + vrLen = 421; + vrLoc = 0; + }; + A27E46770A28B49E007BA395 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = A2082A8E09EAEB33009AC8BE /* PSMTabDragAssistant.m */; + name = "PSMTabDragAssistant.m: 386"; + rLen = 0; + rLoc = 12266; + rType = 0; + vrLen = 1227; + vrLoc = 11663; + }; + A27E46780A28B49E007BA395 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = A2082A8D09EAEB33009AC8BE /* PSMTabDragAssistant.h */; + name = "PSMTabDragAssistant.h: _destinationTabBar"; + rLen = 0; + rLoc = 603; + rType = 0; + vrLen = 746; + vrLoc = 334; + }; + A27E46C80A28C05D007BA395 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = A251BE830959A1B90058BC7F /* PSMTabBarCell.h */; + name = "PSMTabBarCell.h: 21"; + rLen = 0; + rLoc = 469; + rType = 0; + vrLen = 842; + vrLoc = 425; + }; + A27E46C90A28C05D007BA395 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = A251BE840959A1B90058BC7F /* PSMTabBarCell.m */; + name = "NSLog(@\"decoding cell\");"; + rLen = 24; + rLoc = 8864; + rType = 0; + vrLen = 1375; + vrLoc = 8588; + }; + A27E475B0A28EBEE007BA395 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 8D1AC97B0486D23100FE50C9 /* English */; + name = "English: 1"; + rLen = 0; + rLoc = 0; + rType = 0; + vrLen = 103; + vrLoc = 0; + }; + A27E475F0A28EBEE007BA395 /* PBXBookmark */ = { + isa = PBXBookmark; + fRef = A269361009A778770006911E /* 32x32_log.tiff */; + }; + A27E47610A28EBEE007BA395 /* PBXBookmark */ = { + isa = PBXBookmark; + fRef = A2D32EF209A63BF700EC8662 /* AquaTabClose_Front.tif */; + }; + A27E47660A28EBEE007BA395 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 0259C576FE90428111CA0C5A /* PSMTabBarControl.m */; + name = "PSMTabBarControl.m: 1214"; + rLen = 0; + rLoc = 42889; + rType = 0; + vrLen = 1340; + vrLoc = 41507; + }; + A27E47670A28EBEE007BA395 /* PBXBookmark */ = { + isa = PBXBookmark; + fRef = A2072B5C09AC1FA500304BCB /* Warning.png */; + }; + A27E47680A28EBEE007BA395 /* PBXBookmark */ = { + isa = PBXBookmark; + fRef = A268E7FD09A9822900E082AA /* TabNewMetalRollover.png */; + }; + A27E47690A28EBEE007BA395 /* PBXBookmark */ = { + isa = PBXBookmark; + fRef = A268E7FC09A9822900E082AA /* TabNewMetalPressed.png */; + }; + A27E476A0A28EBEE007BA395 /* PBXBookmark */ = { + isa = PBXBookmark; + fRef = A268E7FB09A9822900E082AA /* TabNewMetal.png */; + }; + A27E47740A28EBEE007BA395 /* PBXBookmark */ = { + isa = PBXBookmark; + fRef = A2D32EF609A63BF700EC8662 /* AquaTabsSeparatorDown.png */; + }; + A27E47E40A28F7FB007BA395 /* PBXBookmark */ = { + isa = PBXBookmark; + fRef = A2C0D99309AF870000ED379C /* pi.png */; + }; + A27E47E50A28F7FB007BA395 /* PBXBookmark */ = { + isa = PBXBookmark; + fRef = A2072B5C09AC1FA500304BCB /* Warning.png */; + }; + A27E47E60A28F7FB007BA395 /* PBXBookmark */ = { + isa = PBXBookmark; + fRef = A2072A2409ABD88600304BCB /* Folder.tif */; + }; + A27E47E70A28F7FB007BA395 /* PBXBookmark */ = { + isa = PBXBookmark; + fRef = A2072A2509ABD88600304BCB /* Globe.tiff */; + }; + A27E47E80A28F7FB007BA395 /* PBXBookmark */ = { + isa = PBXBookmark; + fRef = A268E7F809A9822900E082AA /* AquaTabNew.png */; + }; + A27E47E90A28F7FB007BA395 /* PBXBookmark */ = { + isa = PBXBookmark; + fRef = A268E7F909A9822900E082AA /* AquaTabNewPressed.png */; + }; + A27E47EA0A28F7FB007BA395 /* PBXBookmark */ = { + isa = PBXBookmark; + fRef = A268E7FA09A9822900E082AA /* AquaTabNewRollover.png */; + }; + A27E47EB0A28F7FB007BA395 /* PBXBookmark */ = { + isa = PBXBookmark; + fRef = A268E7FB09A9822900E082AA /* TabNewMetal.png */; + }; + A27E47EC0A28F7FB007BA395 /* PBXBookmark */ = { + isa = PBXBookmark; + fRef = A268E7FC09A9822900E082AA /* TabNewMetalPressed.png */; + }; + A27E47ED0A28F7FB007BA395 /* PBXBookmark */ = { + isa = PBXBookmark; + fRef = A268E7FD09A9822900E082AA /* TabNewMetalRollover.png */; + }; + A27E47EE0A28F7FB007BA395 /* PBXBookmark */ = { + isa = PBXBookmark; + fRef = A269361009A778770006911E /* 32x32_log.tiff */; + }; + A27E47EF0A28F7FB007BA395 /* PBXBookmark */ = { + isa = PBXBookmark; + fRef = A2D3317A09A68B7500EC8662 /* AquaTabsDownGraphite.png */; + }; + A27E47F00A28F7FB007BA395 /* PBXBookmark */ = { + isa = PBXBookmark; + fRef = A2D3317B09A68B7500EC8662 /* AquaTabsDownNonKey.png */; + }; + A27E47F10A28F7FB007BA395 /* PBXBookmark */ = { + isa = PBXBookmark; + fRef = A2D32EF009A63BF700EC8662 /* AquaTabClose_Front_Pressed.tif */; + }; + A27E47F20A28F7FB007BA395 /* PBXBookmark */ = { + isa = PBXBookmark; + fRef = A2D32EF109A63BF700EC8662 /* AquaTabClose_Front_Rollover.tif */; + }; + A27E47F30A28F7FB007BA395 /* PBXBookmark */ = { + isa = PBXBookmark; + fRef = A2D32EF209A63BF700EC8662 /* AquaTabClose_Front.tif */; + }; + A27E47F40A28F7FB007BA395 /* PBXBookmark */ = { + isa = PBXBookmark; + fRef = A2D32EF309A63BF700EC8662 /* AquaTabsBackground.png */; + }; + A27E47F50A28F7FB007BA395 /* PBXBookmark */ = { + isa = PBXBookmark; + fRef = A2D32EF409A63BF700EC8662 /* AquaTabsDown.png */; + }; + A27E47F60A28F7FB007BA395 /* PBXBookmark */ = { + isa = PBXBookmark; + fRef = A2D32EF509A63BF700EC8662 /* AquaTabsSeparator.png */; + }; + A27E47F70A28F7FB007BA395 /* PBXBookmark */ = { + isa = PBXBookmark; + fRef = A2D32EF609A63BF700EC8662 /* AquaTabsSeparatorDown.png */; + }; + A27E47F80A28F7FB007BA395 /* PBXBookmark */ = { + isa = PBXBookmark; + fRef = A251BE8F0959A23A0058BC7F /* 32x32cancel.png */; + }; + A27E47F90A28F7FB007BA395 /* PBXBookmark */ = { + isa = PBXBookmark; + fRef = A251BE900959A23A0058BC7F /* overflowImage.tiff */; + }; + A27E47FA0A28F7FB007BA395 /* PBXBookmark */ = { + isa = PBXBookmark; + fRef = A251BE910959A23A0058BC7F /* overflowImagePressed.tif */; + }; + A27E47FB0A28F7FB007BA395 /* PBXBookmark */ = { + isa = PBXBookmark; + fRef = A251BE920959A23A0058BC7F /* TabClose_Front_Pressed.tif */; + }; + A27E47FC0A28F7FB007BA395 /* PBXBookmark */ = { + isa = PBXBookmark; + fRef = A251BE930959A23A0058BC7F /* TabClose_Front_Rollover.tif */; + }; + A27E47FD0A28F7FB007BA395 /* PBXBookmark */ = { + isa = PBXBookmark; + fRef = A251BE940959A23A0058BC7F /* TabClose_Front.tif */; + }; + A27E47FE0A28F7FB007BA395 /* PBXBookmark */ = { + isa = PBXBookmark; + fRef = A20822EF0959F6AA00C5F5A4 /* TabControlRep.tif */; + }; + A27E48050A28F7FC007BA395 /* PBXBookmark */ = { + isa = PBXBookmark; + fRef = A268E7F909A9822900E082AA /* AquaTabNewPressed.png */; + }; + A27E48060A28F7FC007BA395 /* PBXBookmark */ = { + isa = PBXBookmark; + fRef = A268E7FA09A9822900E082AA /* AquaTabNewRollover.png */; + }; + A27E480E0A28F7FC007BA395 /* PBXBookmark */ = { + isa = PBXBookmark; + fRef = A2D32EF109A63BF700EC8662 /* AquaTabClose_Front_Rollover.tif */; + }; + A27E48100A28F7FC007BA395 /* PBXBookmark */ = { + isa = PBXBookmark; + fRef = A2D32EF309A63BF700EC8662 /* AquaTabsBackground.png */; + }; + A27E48110A28F7FC007BA395 /* PBXBookmark */ = { + isa = PBXBookmark; + fRef = A2D32EF409A63BF700EC8662 /* AquaTabsDown.png */; + }; + A27F6A870A1B9AD100AE7009 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = A2D32EE609A6399300EC8662 /* PSMAquaTabStyle.h */; + name = "PSMAquaTabStyle.h: initWithCoder:"; + rLen = 0; + rLoc = 837; + rType = 0; + vrLen = 843; + vrLoc = 0; + }; + A2A2B9D909F448F9002BE730 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = A2A2B9DA09F448F9002BE730 /* ESFloater.h */; + name = "(null): 1"; + rLen = 0; + rLoc = 0; + rType = 0; + vrLen = 668; + vrLoc = 0; + }; + A2A2B9DA09F448F9002BE730 /* ESFloater.h */ = { + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = ESFloater.h; + path = "/Users/johnp/Positive Spin Media/shareware apps/possibilities:code/CustomTabs/ESFloater.h"; + sourceTree = ""; + }; + A2A2B9E309F448F9002BE730 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = A2A2B9E409F448F9002BE730 /* ESFloater.h */; + name = "(null): 1"; + rLen = 0; + rLoc = 0; + rType = 0; + vrLen = 668; + vrLoc = 0; + }; + A2A2B9E409F448F9002BE730 /* ESFloater.h */ = { + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = ESFloater.h; + path = "/Users/johnp/Positive Spin Media/shareware apps/possibilities:code/CustomTabs/ESFloater.h"; + sourceTree = ""; + }; + A2A711BD09E5BF0500D0089B /* WindowController.h */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {647, 840}}"; + sepNavSelRange = "{1327, 267}"; + sepNavVisRect = "{{0, 146}, {647, 694}}"; + }; + }; + A2A711BE09E5BF0500D0089B /* WindowController.m */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {744, 4004}}"; + sepNavSelRange = "{6878, 5}"; + sepNavVisRect = "{{0, 2915}, {744, 401}}"; + }; + }; + A2A7121E09E5C48C00D0089B /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = A251BE890959A1EA0058BC7F /* AppController.h */; + name = "AppController.h: 9"; + rLen = 0; + rLoc = 176; + rType = 0; + vrLen = 264; + vrLoc = 0; + }; + A2BEC7EB09C1F01F00B8B4B6 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 0259C57CFE90428111CA0C5A /* PSMTabBarControlPalette.h */; + name = "PSMTabBarControlPalette.h: _customControl"; + rLen = 0; + rLoc = 356; + rType = 0; + vrLen = 483; + vrLoc = 0; + }; + A2CD7C5709B7738800FBAAAE /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = A251BE8B0959A1EA0058BC7F /* FakeModel.h */; + name = "FakeModel.h: iconName"; + rLen = 65; + rLoc = 572; + rType = 0; + vrLen = 735; + vrLoc = 0; + }; + A2CD7C8D09B7B55E00FBAAAE /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = A251BE8C0959A1EA0058BC7F /* FakeModel.m */; + name = "controller = [[NSObjectController alloc] initWithContent:self];"; + rLen = 63; + rLoc = 349; + rType = 0; + vrLen = 752; + vrLoc = 146; + }; + A2CF618009F4099F00A0F9A8 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = A2CF618109F4099F00A0F9A8 /* EXCustomTabDragging.m */; + name = "(null): 1"; + rLen = 0; + rLoc = 0; + rType = 0; + vrLen = 1247; + vrLoc = 0; + }; + A2CF618109F4099F00A0F9A8 /* EXCustomTabDragging.m */ = { + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; + name = EXCustomTabDragging.m; + path = "/Users/johnp/Positive Spin Media/shareware apps/possibilities:code/CustomTabs/EXCustomTabDragging.m"; + sourceTree = ""; + }; + A2CF618409F4099F00A0F9A8 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = A2CF618509F4099F00A0F9A8 /* EXCustomTabDragging.m */; + name = "(null): 1"; + rLen = 0; + rLoc = 0; + rType = 0; + vrLen = 1247; + vrLoc = 0; + }; + A2CF618509F4099F00A0F9A8 /* EXCustomTabDragging.m */ = { + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; + name = EXCustomTabDragging.m; + path = "/Users/johnp/Positive Spin Media/shareware apps/possibilities:code/CustomTabs/EXCustomTabDragging.m"; + sourceTree = ""; + }; + A2D32EDA09A634C900EC8662 /* PSMTabStyle.h */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {647, 770}}"; + sepNavSelRange = "{1539, 78}"; + sepNavVisRect = "{{0, 76}, {647, 694}}"; + }; + }; + A2D32EE609A6399300EC8662 /* PSMAquaTabStyle.h */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {647, 694}}"; + sepNavSelRange = "{837, 0}"; + sepNavVisRect = "{{0, 0}, {647, 694}}"; + }; + }; + A2D32EE709A6399300EC8662 /* PSMAquaTabStyle.m */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {647, 7672}}"; + sepNavSelRange = "{16767, 42}"; + sepNavVisRect = "{{0, 6730}, {647, 694}}"; + }; + }; + A2D32EFE09A63D7A00EC8662 /* PSMMetalTabStyle.h */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {647, 378}}"; + sepNavSelRange = "{561, 83}"; + sepNavVisRect = "{{0, 0}, {647, 336}}"; + }; + }; + A2D32EFF09A63D7A00EC8662 /* PSMMetalTabStyle.m */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {647, 7686}}"; + sepNavSelRange = "{11166, 96}"; + sepNavVisRect = "{{0, 4956}, {647, 694}}"; + }; + }; + A2D32F4609A6441B00EC8662 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = A2D32EDA09A634C900EC8662 /* PSMTabStyle.h */; + name = "PSMTabStyle.h: 17"; + rLen = 0; + rLoc = 907; + rType = 0; + vrLen = 1106; + vrLoc = 0; + }; + A2D32F4909A6441B00EC8662 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = A2D32EE609A6399300EC8662 /* PSMAquaTabStyle.h */; + name = "PSMAquaTabStyle.h: 25"; + rLen = 0; + rLoc = 837; + rType = 0; + vrLen = 644; + vrLoc = 0; + }; + A2D32F4A09A6441B00EC8662 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = A2D32EE709A6399300EC8662 /* PSMAquaTabStyle.m */; + name = "PSMAquaTabStyle.m: 320"; + rLen = 0; + rLoc = 19140; + rType = 0; + vrLen = 1484; + vrLoc = 0; + }; + A2D32F5109A6441B00EC8662 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = A2D32EFE09A63D7A00EC8662 /* PSMMetalTabStyle.h */; + name = "PSMMetalTabStyle.h: 20"; + rLen = 0; + rLoc = 645; + rType = 0; + vrLen = 521; + vrLoc = 0; + }; + A2D32F5209A6441B00EC8662 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = A2D32EFF09A63D7A00EC8662 /* PSMMetalTabStyle.m */; + name = "PSMMetalTabStyle.m: 26"; + rLen = 0; + rLoc = 1707; + rType = 0; + vrLen = 1411; + vrLoc = 0; + }; + A2D3313F09A67ED000EC8662 /* PBXBookmark */ = { + isa = PBXBookmark; + fRef = A2D32EF009A63BF700EC8662 /* AquaTabClose_Front_Pressed.tif */; + }; + A2D98B070A2B432C0064C6F8 /* PSMUnifiedTabStyle.h */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {590, 607}}"; + sepNavSelRange = "{495, 0}"; + sepNavVisRect = "{{0, 0}, {590, 607}}"; + }; + }; + A2D98B080A2B432C0064C6F8 /* PSMUnifiedTabStyle.m */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {590, 8078}}"; + sepNavSelRange = "{0, 0}"; + sepNavVisRect = "{{0, 215}, {590, 607}}"; + }; + }; + A2D98B0F0A2B43FA0064C6F8 /* NSBezierPath_AMShading.h */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {590, 607}}"; + sepNavSelRange = "{0, 0}"; + sepNavVisRect = "{{0, 0}, {590, 607}}"; + }; + }; + A2D98B1D0A2B47700064C6F8 /* PBXBookmark */ = { + isa = PBXBookmark; + fRef = A20822F00959F6AA00C5F5A4 /* TabIcon.tif */; + }; + A2D98B1E0A2B47700064C6F8 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = A2D98B070A2B432C0064C6F8 /* PSMUnifiedTabStyle.h */; + name = "PSMUnifiedTabStyle.h: leftMargin"; + rLen = 0; + rLoc = 495; + rType = 0; + vrLen = 573; + vrLoc = 0; + }; + A2D98B1F0A2B47700064C6F8 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = A2D98B080A2B432C0064C6F8 /* PSMUnifiedTabStyle.m */; + name = "PSMUnifiedTabStyle.m: 1"; + rLen = 0; + rLoc = 0; + rType = 0; + vrLen = 1409; + vrLoc = 365; + }; + A2D98B200A2B47700064C6F8 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = A2D98B0F0A2B43FA0064C6F8 /* NSBezierPath_AMShading.h */; + name = "NSBezierPath_AMShading.h: 1"; + rLen = 0; + rLoc = 0; + rType = 0; + vrLen = 634; + vrLoc = 0; + }; + A2D98B210A2B47700064C6F8 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = A2D98B100A2B43FA0064C6F8 /* NSBezierPath_AMShading.m */; + name = "NSBezierPath_AMShading.m: 1"; + rLen = 0; + rLoc = 0; + rType = 0; + vrLen = 1116; + vrLoc = 0; + }; + A2D98B240A2B47700064C6F8 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = A2D98B070A2B432C0064C6F8 /* PSMUnifiedTabStyle.h */; + name = "PSMUnifiedTabStyle.h: leftMargin"; + rLen = 0; + rLoc = 495; + rType = 0; + vrLen = 573; + vrLoc = 0; + }; + A2D98B250A2B47700064C6F8 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = A2D98B080A2B432C0064C6F8 /* PSMUnifiedTabStyle.m */; + name = "PSMUnifiedTabStyle.m: 1"; + rLen = 0; + rLoc = 0; + rType = 0; + vrLen = 1409; + vrLoc = 365; + }; + A2D98B260A2B47700064C6F8 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = A2D98B0F0A2B43FA0064C6F8 /* NSBezierPath_AMShading.h */; + name = "NSBezierPath_AMShading.h: 1"; + rLen = 0; + rLoc = 0; + rType = 0; + vrLen = 634; + vrLoc = 0; + }; + A2D98B270A2B47700064C6F8 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = A2D98B100A2B43FA0064C6F8 /* NSBezierPath_AMShading.m */; + name = "NSBezierPath_AMShading.m: 1"; + rLen = 0; + rLoc = 0; + rType = 0; + vrLen = 1116; + vrLoc = 0; + }; + A2D98B3E0A2B55140064C6F8 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 0259C57BFE90428111CA0C5A /* PSMTabBarControlInspector.h */; + name = "PSMTabBarControlInspector.h: _allowDragBetweenWindows"; + rLen = 0; + rLoc = 712; + rType = 0; + vrLen = 719; + vrLoc = 0; + }; + A2D98B410A2B55140064C6F8 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 0259C57AFE90428111CA0C5A /* PSMTabBarControl.h */; + name = setAllowsDragBetweenWindows; + rLen = 27; + rLoc = 3070; + rType = 0; + vrLen = 1170; + vrLoc = 2219; + }; + A2E8401109F48B62000217C4 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = A2129BB009AEB58F00724E6C /* PSMProgressIndicator.m */; + name = "PSMProgressIndicator.m: 10"; + rLen = 0; + rLoc = 192; + rType = 0; + vrLen = 421; + vrLoc = 0; + }; + A2ED871409C28FBD006BD5FC /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 8D1AC9730486D14A00FE50C9 /* Info.plist */; + name = "Info.plist: 22"; + rLen = 0; + rLoc = 717; + rType = 0; + vrLen = 744; + vrLoc = 0; + }; + A2F0AA9D0A2B977F00BEF297 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 0259C577FE90428111CA0C5A /* PSMTabBarControlInspector.m */; + name = "PSMTabBarControlInspector.m: 94"; + rLen = 0; + rLoc = 3374; + rType = 0; + vrLen = 1176; + vrLoc = 0; + }; + A2F0AA9E0A2B977F00BEF297 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 0259C576FE90428111CA0C5A /* PSMTabBarControl.m */; + name = "PSMTabBarControl.m: 58"; + rLen = 0; + rLoc = 1654; + rType = 0; + vrLen = 1392; + vrLoc = 968; + }; + A2F0AA9F0A2B977F00BEF297 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 0259C57AFE90428111CA0C5A /* PSMTabBarControl.h */; + name = representedTabViewItems; + rLen = 23; + rLoc = 3408; + rType = 0; + vrLen = 1337; + vrLoc = 2496; + }; + A2F0AAA70A2B977F00BEF297 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = A251BE9B0959A2530058BC7F /* ReadMe.rtfd */; + name = "ReadMe.rtfd: 82"; + rLen = 0; + rLoc = 9026; + rType = 0; + vrLen = 2005; + vrLoc = 0; + }; + A2F0DF4F09F6D68300AA839C /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = A268EA6009A9831800E082AA /* PSMRolloverButton.m */; + name = "PSMRolloverButton.m: 72"; + rLen = 0; + rLoc = 1690; + rType = 0; + vrLen = 1678; + vrLoc = 918; + }; + A2F519DB09AA627E00056B6F /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = A2F519DC09AA627E00056B6F /* NSToolbar.h */; + name = "(null): 1"; + rLen = 0; + rLoc = 0; + rType = 0; + vrLen = 1465; + vrLoc = 0; + }; + A2F519DC09AA627E00056B6F /* NSToolbar.h */ = { + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = NSToolbar.h; + path = /Developer/SDKs/MacOSX10.3.9.sdk/System/Library/Frameworks/AppKit.framework/Versions/C/Headers/NSToolbar.h; + sourceTree = ""; + }; + A2F519E509AA627E00056B6F /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = A2F519E609AA627E00056B6F /* NSToolbar.h */; + name = "(null): 1"; + rLen = 0; + rLoc = 0; + rType = 0; + vrLen = 1465; + vrLoc = 0; + }; + A2F519E609AA627E00056B6F /* NSToolbar.h */ = { + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = NSToolbar.h; + path = /Developer/SDKs/MacOSX10.3.9.sdk/System/Library/Frameworks/AppKit.framework/Versions/C/Headers/NSToolbar.h; + sourceTree = ""; + }; + A2F51A5709AA767B00056B6F /* -[NSException raise] */ = { + isa = PBXSymbolicBreakpoint; + actions = ( + ); + breakpointStyle = 0; + continueAfterActions = 0; + delayBeforeContinue = 0; + hitCount = 1; + modificationTime = 167074336.702084; + state = 1; + symbolName = "-[NSException raise]"; + }; +} diff --git a/PSMTabBarControl/PSMTabBarControl.xcodeproj/project.pbxproj b/PSMTabBarControl/PSMTabBarControl.xcodeproj/project.pbxproj new file mode 100644 index 0000000000..78cf6b6d03 --- /dev/null +++ b/PSMTabBarControl/PSMTabBarControl.xcodeproj/project.pbxproj @@ -0,0 +1,677 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 42; + objects = { + +/* Begin PBXAggregateTarget section */ + 53DF6901067E5B8E0090B5B0 /* All */ = { + isa = PBXAggregateTarget; + buildConfigurationList = C056398708A954F8003078D8 /* Build configuration list for PBXAggregateTarget "All" */; + buildPhases = ( + ); + dependencies = ( + 53DF6905067E5B930090B5B0 /* PBXTargetDependency */, + ); + name = All; + productName = All; + }; +/* End PBXAggregateTarget section */ + +/* Begin PBXBuildFile section */ + 13F8B89007B43554008AE28D /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DD92D38A0106425D02CA0E72 /* Cocoa.framework */; }; + 546DEAF1067F63070098DCC4 /* PSMTabBarControl.m in Sources */ = {isa = PBXBuildFile; fileRef = 0259C576FE90428111CA0C5A /* PSMTabBarControl.m */; }; + 546DEAF2067F630E0098DCC4 /* PSMTabBarControl.h in Headers */ = {isa = PBXBuildFile; fileRef = 0259C57AFE90428111CA0C5A /* PSMTabBarControl.h */; settings = {ATTRIBUTES = (Public, ); }; }; + A2082A9009EAEB34009AC8BE /* PSMTabDragAssistant.h in Headers */ = {isa = PBXBuildFile; fileRef = A2082A8D09EAEB33009AC8BE /* PSMTabDragAssistant.h */; }; + A2082A9109EAEB34009AC8BE /* PSMTabDragAssistant.m in Sources */ = {isa = PBXBuildFile; fileRef = A2082A8E09EAEB33009AC8BE /* PSMTabDragAssistant.m */; }; + A2129BB209AEB58F00724E6C /* PSMProgressIndicator.h in Headers */ = {isa = PBXBuildFile; fileRef = A2129BAF09AEB58F00724E6C /* PSMProgressIndicator.h */; }; + A2129BB309AEB58F00724E6C /* PSMProgressIndicator.m in Sources */ = {isa = PBXBuildFile; fileRef = A2129BB009AEB58F00724E6C /* PSMProgressIndicator.m */; }; + A251BE850959A1B90058BC7F /* PSMOverflowPopUpButton.h in Headers */ = {isa = PBXBuildFile; fileRef = A251BE810959A1B90058BC7F /* PSMOverflowPopUpButton.h */; }; + A251BE860959A1B90058BC7F /* PSMOverflowPopUpButton.m in Sources */ = {isa = PBXBuildFile; fileRef = A251BE820959A1B90058BC7F /* PSMOverflowPopUpButton.m */; }; + A251BE870959A1B90058BC7F /* PSMTabBarCell.h in Headers */ = {isa = PBXBuildFile; fileRef = A251BE830959A1B90058BC7F /* PSMTabBarCell.h */; }; + A251BE880959A1B90058BC7F /* PSMTabBarCell.m in Sources */ = {isa = PBXBuildFile; fileRef = A251BE840959A1B90058BC7F /* PSMTabBarCell.m */; }; + A251BE960959A23A0058BC7F /* overflowImage.tiff in Resources */ = {isa = PBXBuildFile; fileRef = A251BE900959A23A0058BC7F /* overflowImage.tiff */; }; + A251BE970959A23A0058BC7F /* overflowImagePressed.tif in Resources */ = {isa = PBXBuildFile; fileRef = A251BE910959A23A0058BC7F /* overflowImagePressed.tif */; }; + A251BE980959A23A0058BC7F /* TabClose_Front_Pressed.tif in Resources */ = {isa = PBXBuildFile; fileRef = A251BE920959A23A0058BC7F /* TabClose_Front_Pressed.tif */; }; + A251BE990959A23A0058BC7F /* TabClose_Front_Rollover.tif in Resources */ = {isa = PBXBuildFile; fileRef = A251BE930959A23A0058BC7F /* TabClose_Front_Rollover.tif */; }; + A251BE9A0959A23A0058BC7F /* TabClose_Front.tif in Resources */ = {isa = PBXBuildFile; fileRef = A251BE940959A23A0058BC7F /* TabClose_Front.tif */; }; + A268E80409A9822A00E082AA /* AquaTabNew.png in Resources */ = {isa = PBXBuildFile; fileRef = A268E7F809A9822900E082AA /* AquaTabNew.png */; }; + A268E80509A9822A00E082AA /* AquaTabNewPressed.png in Resources */ = {isa = PBXBuildFile; fileRef = A268E7F909A9822900E082AA /* AquaTabNewPressed.png */; }; + A268E80609A9822A00E082AA /* AquaTabNewRollover.png in Resources */ = {isa = PBXBuildFile; fileRef = A268E7FA09A9822900E082AA /* AquaTabNewRollover.png */; }; + A268E80709A9822A00E082AA /* TabNewMetal.png in Resources */ = {isa = PBXBuildFile; fileRef = A268E7FB09A9822900E082AA /* TabNewMetal.png */; }; + A268E80809A9822A00E082AA /* TabNewMetalPressed.png in Resources */ = {isa = PBXBuildFile; fileRef = A268E7FC09A9822900E082AA /* TabNewMetalPressed.png */; }; + A268E80909A9822A00E082AA /* TabNewMetalRollover.png in Resources */ = {isa = PBXBuildFile; fileRef = A268E7FD09A9822900E082AA /* TabNewMetalRollover.png */; }; + A268EA6209A9831800E082AA /* PSMRolloverButton.h in Headers */ = {isa = PBXBuildFile; fileRef = A268EA5F09A9831800E082AA /* PSMRolloverButton.h */; }; + A268EA6309A9831800E082AA /* PSMRolloverButton.m in Sources */ = {isa = PBXBuildFile; fileRef = A268EA6009A9831800E082AA /* PSMRolloverButton.m */; }; + A27E47850A28EE76007BA395 /* TabIcon.tif in Resources */ = {isa = PBXBuildFile; fileRef = A20822F00959F6AA00C5F5A4 /* TabIcon.tif */; }; + A27E47880A28EE7C007BA395 /* TabControlRep.tif in Resources */ = {isa = PBXBuildFile; fileRef = A20822EF0959F6AA00C5F5A4 /* TabControlRep.tif */; }; + A2C0D99509AF870000ED379C /* pi.png in Resources */ = {isa = PBXBuildFile; fileRef = A2C0D99309AF870000ED379C /* pi.png */; }; + A2D32EDC09A634C900EC8662 /* PSMTabStyle.h in Headers */ = {isa = PBXBuildFile; fileRef = A2D32EDA09A634C900EC8662 /* PSMTabStyle.h */; }; + A2D32EE809A6399300EC8662 /* PSMAquaTabStyle.h in Headers */ = {isa = PBXBuildFile; fileRef = A2D32EE609A6399300EC8662 /* PSMAquaTabStyle.h */; }; + A2D32EE909A6399300EC8662 /* PSMAquaTabStyle.m in Sources */ = {isa = PBXBuildFile; fileRef = A2D32EE709A6399300EC8662 /* PSMAquaTabStyle.m */; }; + A2D32EF709A63BF700EC8662 /* AquaTabClose_Front_Pressed.tif in Resources */ = {isa = PBXBuildFile; fileRef = A2D32EF009A63BF700EC8662 /* AquaTabClose_Front_Pressed.tif */; }; + A2D32EF809A63BF700EC8662 /* AquaTabClose_Front_Rollover.tif in Resources */ = {isa = PBXBuildFile; fileRef = A2D32EF109A63BF700EC8662 /* AquaTabClose_Front_Rollover.tif */; }; + A2D32EF909A63BF700EC8662 /* AquaTabClose_Front.tif in Resources */ = {isa = PBXBuildFile; fileRef = A2D32EF209A63BF700EC8662 /* AquaTabClose_Front.tif */; }; + A2D32EFA09A63BF700EC8662 /* AquaTabsBackground.png in Resources */ = {isa = PBXBuildFile; fileRef = A2D32EF309A63BF700EC8662 /* AquaTabsBackground.png */; }; + A2D32EFB09A63BF700EC8662 /* AquaTabsDown.png in Resources */ = {isa = PBXBuildFile; fileRef = A2D32EF409A63BF700EC8662 /* AquaTabsDown.png */; }; + A2D32EFC09A63BF700EC8662 /* AquaTabsSeparator.png in Resources */ = {isa = PBXBuildFile; fileRef = A2D32EF509A63BF700EC8662 /* AquaTabsSeparator.png */; }; + A2D32EFD09A63BF700EC8662 /* AquaTabsSeparatorDown.png in Resources */ = {isa = PBXBuildFile; fileRef = A2D32EF609A63BF700EC8662 /* AquaTabsSeparatorDown.png */; }; + A2D32F0009A63D7A00EC8662 /* PSMMetalTabStyle.h in Headers */ = {isa = PBXBuildFile; fileRef = A2D32EFE09A63D7A00EC8662 /* PSMMetalTabStyle.h */; }; + A2D32F0109A63D7A00EC8662 /* PSMMetalTabStyle.m in Sources */ = {isa = PBXBuildFile; fileRef = A2D32EFF09A63D7A00EC8662 /* PSMMetalTabStyle.m */; }; + A2D3317C09A68B7500EC8662 /* AquaTabsDownGraphite.png in Resources */ = {isa = PBXBuildFile; fileRef = A2D3317A09A68B7500EC8662 /* AquaTabsDownGraphite.png */; }; + A2D3317D09A68B7500EC8662 /* AquaTabsDownNonKey.png in Resources */ = {isa = PBXBuildFile; fileRef = A2D3317B09A68B7500EC8662 /* AquaTabsDownNonKey.png */; }; + A2D98B0A0A2B432C0064C6F8 /* PSMUnifiedTabStyle.h in Headers */ = {isa = PBXBuildFile; fileRef = A2D98B070A2B432C0064C6F8 /* PSMUnifiedTabStyle.h */; }; + A2D98B0B0A2B432C0064C6F8 /* PSMUnifiedTabStyle.m in Sources */ = {isa = PBXBuildFile; fileRef = A2D98B080A2B432C0064C6F8 /* PSMUnifiedTabStyle.m */; }; + A2D98B120A2B43FA0064C6F8 /* NSBezierPath_AMShading.h in Headers */ = {isa = PBXBuildFile; fileRef = A2D98B0F0A2B43FA0064C6F8 /* NSBezierPath_AMShading.h */; }; + A2D98B130A2B43FA0064C6F8 /* NSBezierPath_AMShading.m in Sources */ = {isa = PBXBuildFile; fileRef = A2D98B100A2B43FA0064C6F8 /* NSBezierPath_AMShading.m */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 53DF6904067E5B930090B5B0 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0259C573FE90428111CA0C5A /* Project object */; + proxyType = 1; + remoteGlobalIDString = 53DF68FC067E5B5A0090B5B0; + remoteInfo = PSMTabBarControlFramework; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 0259C576FE90428111CA0C5A /* PSMTabBarControl.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; name = PSMTabBarControl.m; path = source/PSMTabBarControl.m; sourceTree = ""; }; + 0259C577FE90428111CA0C5A /* PSMTabBarControlInspector.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; name = PSMTabBarControlInspector.m; path = source/PSMTabBarControlInspector.m; sourceTree = ""; }; + 0259C578FE90428111CA0C5A /* PSMTabBarControlPalette.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; name = PSMTabBarControlPalette.m; path = source/PSMTabBarControlPalette.m; sourceTree = ""; }; + 0259C57AFE90428111CA0C5A /* PSMTabBarControl.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = PSMTabBarControl.h; path = source/PSMTabBarControl.h; sourceTree = ""; }; + 0259C57BFE90428111CA0C5A /* PSMTabBarControlInspector.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = PSMTabBarControlInspector.h; path = source/PSMTabBarControlInspector.h; sourceTree = ""; }; + 0259C57CFE90428111CA0C5A /* PSMTabBarControlPalette.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = PSMTabBarControlPalette.h; path = source/PSMTabBarControlPalette.h; sourceTree = ""; }; + 0259C57FFE90428111CA0C5A /* English */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = English; path = English.lproj/PSMTabBarControlInspector.nib; sourceTree = ""; }; + 0259C581FE90428111CA0C5A /* English */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = English; path = English.lproj/PSMTabBarControlPalette.nib; sourceTree = ""; }; + 0259C583FE90428111CA0C5A /* palette.table */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = palette.table; sourceTree = ""; }; + 13EB9DBD07DE0F1E00EB933A /* InterfaceBuilder.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = InterfaceBuilder.framework; path = /System/Library/Frameworks/InterfaceBuilder.framework; sourceTree = ""; }; + 13F8B88807B434F6008AE28D /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = ""; }; + 13F8B88A07B434F6008AE28D /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = ""; }; + 32DBCF980370C29C00C91783 /* PSMTabBarControl_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PSMTabBarControl_Prefix.pch; path = source/PSMTabBarControl_Prefix.pch; sourceTree = ""; }; + 53DF68FD067E5B5A0090B5B0 /* PSMTabBarControl.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = PSMTabBarControl.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 53DF68FE067E5B5A0090B5B0 /* PSMTabBarControlFramework-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = "PSMTabBarControlFramework-Info.plist"; sourceTree = ""; }; + 54D33B2806778E3300C9C163 /* PSMTabBarControl.ibclassdescription */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = PSMTabBarControl.ibclassdescription; sourceTree = ""; }; + 8D1AC9730486D14A00FE50C9 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; }; + 8D1AC97B0486D23100FE50C9 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = ""; }; + A2072A2409ABD88600304BCB /* Folder.tif */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; name = Folder.tif; path = images/Folder.tif; sourceTree = ""; }; + A2072A2509ABD88600304BCB /* Globe.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; name = Globe.tiff; path = images/Globe.tiff; sourceTree = ""; }; + A2072B5C09AC1FA500304BCB /* Warning.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Warning.png; path = images/Warning.png; sourceTree = ""; }; + A20822EF0959F6AA00C5F5A4 /* TabControlRep.tif */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; name = TabControlRep.tif; path = images/TabControlRep.tif; sourceTree = ""; }; + A20822F00959F6AA00C5F5A4 /* TabIcon.tif */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; name = TabIcon.tif; path = images/TabIcon.tif; sourceTree = ""; }; + A2082A8D09EAEB33009AC8BE /* PSMTabDragAssistant.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PSMTabDragAssistant.h; path = source/PSMTabDragAssistant.h; sourceTree = ""; }; + A2082A8E09EAEB33009AC8BE /* PSMTabDragAssistant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = PSMTabDragAssistant.m; path = source/PSMTabDragAssistant.m; sourceTree = ""; wrapsLines = 0; }; + A2129BAF09AEB58F00724E6C /* PSMProgressIndicator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PSMProgressIndicator.h; path = source/PSMProgressIndicator.h; sourceTree = ""; }; + A2129BB009AEB58F00724E6C /* PSMProgressIndicator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = PSMProgressIndicator.m; path = source/PSMProgressIndicator.m; sourceTree = ""; }; + A246FB040A2BD6F9005BDF7B /* PSMTabBarControlDoc.html */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.html.documentation; name = PSMTabBarControlDoc.html; path = documentation/PSMTabBarControlDoc.html; sourceTree = ""; }; + A251BE810959A1B90058BC7F /* PSMOverflowPopUpButton.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 30; name = PSMOverflowPopUpButton.h; path = source/PSMOverflowPopUpButton.h; sourceTree = ""; }; + A251BE820959A1B90058BC7F /* PSMOverflowPopUpButton.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; name = PSMOverflowPopUpButton.m; path = source/PSMOverflowPopUpButton.m; sourceTree = ""; }; + A251BE830959A1B90058BC7F /* PSMTabBarCell.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = PSMTabBarCell.h; path = source/PSMTabBarCell.h; sourceTree = ""; }; + A251BE840959A1B90058BC7F /* PSMTabBarCell.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; name = PSMTabBarCell.m; path = source/PSMTabBarCell.m; sourceTree = ""; }; + A251BE890959A1EA0058BC7F /* AppController.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = AppController.h; path = source/AppController.h; sourceTree = ""; }; + A251BE8A0959A1EA0058BC7F /* AppController.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; name = AppController.m; path = source/AppController.m; sourceTree = ""; }; + A251BE8B0959A1EA0058BC7F /* FakeModel.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = FakeModel.h; path = source/FakeModel.h; sourceTree = ""; }; + A251BE8C0959A1EA0058BC7F /* FakeModel.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; name = FakeModel.m; path = source/FakeModel.m; sourceTree = ""; }; + A251BE8D0959A1EA0058BC7F /* main.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; name = main.m; path = source/main.m; sourceTree = ""; }; + A251BE8F0959A23A0058BC7F /* 32x32cancel.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = 32x32cancel.png; path = images/32x32cancel.png; sourceTree = ""; }; + A251BE900959A23A0058BC7F /* overflowImage.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; name = overflowImage.tiff; path = images/overflowImage.tiff; sourceTree = ""; }; + A251BE910959A23A0058BC7F /* overflowImagePressed.tif */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; name = overflowImagePressed.tif; path = images/overflowImagePressed.tif; sourceTree = ""; }; + A251BE920959A23A0058BC7F /* TabClose_Front_Pressed.tif */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; name = TabClose_Front_Pressed.tif; path = images/TabClose_Front_Pressed.tif; sourceTree = ""; }; + A251BE930959A23A0058BC7F /* TabClose_Front_Rollover.tif */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; name = TabClose_Front_Rollover.tif; path = images/TabClose_Front_Rollover.tif; sourceTree = ""; }; + A251BE940959A23A0058BC7F /* TabClose_Front.tif */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; name = TabClose_Front.tif; path = images/TabClose_Front.tif; sourceTree = ""; }; + A251BE9B0959A2530058BC7F /* ReadMe.rtfd */ = {isa = PBXFileReference; lastKnownFileType = wrapper.rtfd; path = ReadMe.rtfd; sourceTree = ""; }; + A251BEA20959BB5B0058BC7F /* TabBarControlDemo-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = "TabBarControlDemo-Info.plist"; sourceTree = ""; }; + A251BEC30959BC0E0058BC7F /* English */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = English; path = English.lproj/MainMenu.nib; sourceTree = ""; }; + A268E7F809A9822900E082AA /* AquaTabNew.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = AquaTabNew.png; path = images/AquaTabNew.png; sourceTree = ""; }; + A268E7F909A9822900E082AA /* AquaTabNewPressed.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = AquaTabNewPressed.png; path = images/AquaTabNewPressed.png; sourceTree = ""; }; + A268E7FA09A9822900E082AA /* AquaTabNewRollover.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = AquaTabNewRollover.png; path = images/AquaTabNewRollover.png; sourceTree = ""; }; + A268E7FB09A9822900E082AA /* TabNewMetal.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = TabNewMetal.png; path = images/TabNewMetal.png; sourceTree = ""; }; + A268E7FC09A9822900E082AA /* TabNewMetalPressed.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = TabNewMetalPressed.png; path = images/TabNewMetalPressed.png; sourceTree = ""; }; + A268E7FD09A9822900E082AA /* TabNewMetalRollover.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = TabNewMetalRollover.png; path = images/TabNewMetalRollover.png; sourceTree = ""; }; + A268EA5F09A9831800E082AA /* PSMRolloverButton.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = PSMRolloverButton.h; path = source/PSMRolloverButton.h; sourceTree = ""; }; + A268EA6009A9831800E082AA /* PSMRolloverButton.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; name = PSMRolloverButton.m; path = source/PSMRolloverButton.m; sourceTree = ""; }; + A269361009A778770006911E /* 32x32_log.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; name = 32x32_log.tiff; path = images/32x32_log.tiff; sourceTree = ""; }; + A2A711BA09E5AE1E00D0089B /* English */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = English; path = English.lproj/Window.nib; sourceTree = ""; }; + A2A711BD09E5BF0500D0089B /* WindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WindowController.h; path = source/WindowController.h; sourceTree = ""; }; + A2A711BE09E5BF0500D0089B /* WindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = WindowController.m; path = source/WindowController.m; sourceTree = ""; }; + A2C0D99309AF870000ED379C /* pi.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = pi.png; path = images/pi.png; sourceTree = ""; }; + A2D32EDA09A634C900EC8662 /* PSMTabStyle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PSMTabStyle.h; path = source/PSMTabStyle.h; sourceTree = ""; }; + A2D32EE609A6399300EC8662 /* PSMAquaTabStyle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PSMAquaTabStyle.h; path = source/PSMAquaTabStyle.h; sourceTree = ""; }; + A2D32EE709A6399300EC8662 /* PSMAquaTabStyle.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = PSMAquaTabStyle.m; path = source/PSMAquaTabStyle.m; sourceTree = ""; }; + A2D32EF009A63BF700EC8662 /* AquaTabClose_Front_Pressed.tif */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; name = AquaTabClose_Front_Pressed.tif; path = images/AquaTabClose_Front_Pressed.tif; sourceTree = ""; }; + A2D32EF109A63BF700EC8662 /* AquaTabClose_Front_Rollover.tif */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; name = AquaTabClose_Front_Rollover.tif; path = images/AquaTabClose_Front_Rollover.tif; sourceTree = ""; }; + A2D32EF209A63BF700EC8662 /* AquaTabClose_Front.tif */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; name = AquaTabClose_Front.tif; path = images/AquaTabClose_Front.tif; sourceTree = ""; }; + A2D32EF309A63BF700EC8662 /* AquaTabsBackground.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = AquaTabsBackground.png; path = images/AquaTabsBackground.png; sourceTree = ""; }; + A2D32EF409A63BF700EC8662 /* AquaTabsDown.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = AquaTabsDown.png; path = images/AquaTabsDown.png; sourceTree = ""; }; + A2D32EF509A63BF700EC8662 /* AquaTabsSeparator.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = AquaTabsSeparator.png; path = images/AquaTabsSeparator.png; sourceTree = ""; }; + A2D32EF609A63BF700EC8662 /* AquaTabsSeparatorDown.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = AquaTabsSeparatorDown.png; path = images/AquaTabsSeparatorDown.png; sourceTree = ""; }; + A2D32EFE09A63D7A00EC8662 /* PSMMetalTabStyle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PSMMetalTabStyle.h; path = source/PSMMetalTabStyle.h; sourceTree = ""; }; + A2D32EFF09A63D7A00EC8662 /* PSMMetalTabStyle.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = PSMMetalTabStyle.m; path = source/PSMMetalTabStyle.m; sourceTree = ""; }; + A2D3317A09A68B7500EC8662 /* AquaTabsDownGraphite.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = AquaTabsDownGraphite.png; path = images/AquaTabsDownGraphite.png; sourceTree = ""; }; + A2D3317B09A68B7500EC8662 /* AquaTabsDownNonKey.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = AquaTabsDownNonKey.png; path = images/AquaTabsDownNonKey.png; sourceTree = ""; }; + A2D98B070A2B432C0064C6F8 /* PSMUnifiedTabStyle.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = PSMUnifiedTabStyle.h; path = source/PSMUnifiedTabStyle.h; sourceTree = ""; }; + A2D98B080A2B432C0064C6F8 /* PSMUnifiedTabStyle.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; name = PSMUnifiedTabStyle.m; path = source/PSMUnifiedTabStyle.m; sourceTree = ""; }; + A2D98B0F0A2B43FA0064C6F8 /* NSBezierPath_AMShading.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = NSBezierPath_AMShading.h; path = source/NSBezierPath_AMShading.h; sourceTree = ""; }; + A2D98B100A2B43FA0064C6F8 /* NSBezierPath_AMShading.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; name = NSBezierPath_AMShading.m; path = source/NSBezierPath_AMShading.m; sourceTree = ""; }; + DD92D38A0106425D02CA0E72 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 53DF68FB067E5B5A0090B5B0 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 13F8B89007B43554008AE28D /* Cocoa.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 0259C574FE90428111CA0C5A /* PSMTabBarControl */ = { + isa = PBXGroup; + children = ( + A251BE9B0959A2530058BC7F /* ReadMe.rtfd */, + A246FADE0A2BD446005BDF7B /* Documentation */, + 32DBCF9E0370C38000C91783 /* Palette */, + 54D33B2C06778E4400C9C163 /* Framework */, + A251BE590959A0550058BC7F /* Demo App */, + 0259C582FE90428111CA0C5A /* Resources */, + 1ED78706FE9D4A0611CA0C5A /* Products */, + 2E58F364FFB232C311CA0CBA /* Frameworks */, + ); + name = PSMTabBarControl; + sourceTree = ""; + }; + 0259C582FE90428111CA0C5A /* Resources */ = { + isa = PBXGroup; + children = ( + A251BEC20959BC0E0058BC7F /* MainMenu.nib */, + A251BE8E0959A21A0058BC7F /* Images */, + 8D1AC9730486D14A00FE50C9 /* Info.plist */, + 53DF68FE067E5B5A0090B5B0 /* PSMTabBarControlFramework-Info.plist */, + A251BEA20959BB5B0058BC7F /* TabBarControlDemo-Info.plist */, + 8D1AC97F0486D23B00FE50C9 /* InfoPlist.strings */, + A2A711B909E5AE1E00D0089B /* Window.nib */, + ); + name = Resources; + sourceTree = ""; + }; + 131E8FE8067F80F40006E0CE /* Resources */ = { + isa = PBXGroup; + children = ( + A20822EF0959F6AA00C5F5A4 /* TabControlRep.tif */, + A20822F00959F6AA00C5F5A4 /* TabIcon.tif */, + 0259C57EFE90428111CA0C5A /* PSMTabBarControlInspector.nib */, + 0259C580FE90428111CA0C5A /* PSMTabBarControlPalette.nib */, + ); + name = Resources; + sourceTree = ""; + }; + 13F8B6FD07B43410008AE28D /* Linked Frameworks */ = { + isa = PBXGroup; + children = ( + 13EB9DBD07DE0F1E00EB933A /* InterfaceBuilder.framework */, + DD92D38A0106425D02CA0E72 /* Cocoa.framework */, + ); + name = "Linked Frameworks"; + sourceTree = ""; + }; + 13F8B70407B43425008AE28D /* Other Frameworks */ = { + isa = PBXGroup; + children = ( + 13F8B88807B434F6008AE28D /* AppKit.framework */, + 13F8B88A07B434F6008AE28D /* Foundation.framework */, + ); + name = "Other Frameworks"; + sourceTree = ""; + }; + 1ED78706FE9D4A0611CA0C5A /* Products */ = { + isa = PBXGroup; + children = ( + 53DF68FD067E5B5A0090B5B0 /* PSMTabBarControl.framework */, + ); + name = Products; + sourceTree = ""; + }; + 2E58F364FFB232C311CA0CBA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 13F8B6FD07B43410008AE28D /* Linked Frameworks */, + 13F8B70407B43425008AE28D /* Other Frameworks */, + ); + name = Frameworks; + sourceTree = ""; + }; + 32DBCF9E0370C38000C91783 /* Palette */ = { + isa = PBXGroup; + children = ( + 54D33B2406778DD400C9C163 /* Undo Support */, + 54D33B2506778DF000C9C163 /* Classes */, + 32DBCF9F0370C38200C91783 /* Other Sources */, + 131E8FE8067F80F40006E0CE /* Resources */, + 0259C583FE90428111CA0C5A /* palette.table */, + ); + name = Palette; + sourceTree = ""; + }; + 32DBCF9F0370C38200C91783 /* Other Sources */ = { + isa = PBXGroup; + children = ( + 32DBCF980370C29C00C91783 /* PSMTabBarControl_Prefix.pch */, + ); + name = "Other Sources"; + sourceTree = ""; + }; + 54D33B2406778DD400C9C163 /* Undo Support */ = { + isa = PBXGroup; + children = ( + 54D33B2806778E3300C9C163 /* PSMTabBarControl.ibclassdescription */, + ); + name = "Undo Support"; + sourceTree = ""; + }; + 54D33B2506778DF000C9C163 /* Classes */ = { + isa = PBXGroup; + children = ( + 0259C57BFE90428111CA0C5A /* PSMTabBarControlInspector.h */, + 0259C577FE90428111CA0C5A /* PSMTabBarControlInspector.m */, + 0259C57CFE90428111CA0C5A /* PSMTabBarControlPalette.h */, + 0259C578FE90428111CA0C5A /* PSMTabBarControlPalette.m */, + ); + name = Classes; + sourceTree = ""; + }; + 54D33B2C06778E4400C9C163 /* Framework */ = { + isa = PBXGroup; + children = ( + 0259C57AFE90428111CA0C5A /* PSMTabBarControl.h */, + 0259C576FE90428111CA0C5A /* PSMTabBarControl.m */, + A251BE830959A1B90058BC7F /* PSMTabBarCell.h */, + A251BE840959A1B90058BC7F /* PSMTabBarCell.m */, + A2D32EDA09A634C900EC8662 /* PSMTabStyle.h */, + A2D32EE609A6399300EC8662 /* PSMAquaTabStyle.h */, + A2D32EE709A6399300EC8662 /* PSMAquaTabStyle.m */, + A2D32EFE09A63D7A00EC8662 /* PSMMetalTabStyle.h */, + A2D32EFF09A63D7A00EC8662 /* PSMMetalTabStyle.m */, + A2D98B070A2B432C0064C6F8 /* PSMUnifiedTabStyle.h */, + A2D98B080A2B432C0064C6F8 /* PSMUnifiedTabStyle.m */, + A268EA5F09A9831800E082AA /* PSMRolloverButton.h */, + A268EA6009A9831800E082AA /* PSMRolloverButton.m */, + A251BE810959A1B90058BC7F /* PSMOverflowPopUpButton.h */, + A251BE820959A1B90058BC7F /* PSMOverflowPopUpButton.m */, + A2129BAF09AEB58F00724E6C /* PSMProgressIndicator.h */, + A2129BB009AEB58F00724E6C /* PSMProgressIndicator.m */, + A2082A8D09EAEB33009AC8BE /* PSMTabDragAssistant.h */, + A2082A8E09EAEB33009AC8BE /* PSMTabDragAssistant.m */, + A2D98B0F0A2B43FA0064C6F8 /* NSBezierPath_AMShading.h */, + A2D98B100A2B43FA0064C6F8 /* NSBezierPath_AMShading.m */, + ); + name = Framework; + sourceTree = ""; + }; + A246FADE0A2BD446005BDF7B /* Documentation */ = { + isa = PBXGroup; + children = ( + A246FB040A2BD6F9005BDF7B /* PSMTabBarControlDoc.html */, + ); + name = Documentation; + sourceTree = ""; + }; + A251BE590959A0550058BC7F /* Demo App */ = { + isa = PBXGroup; + children = ( + A251BE890959A1EA0058BC7F /* AppController.h */, + A251BE8A0959A1EA0058BC7F /* AppController.m */, + A2A711BD09E5BF0500D0089B /* WindowController.h */, + A2A711BE09E5BF0500D0089B /* WindowController.m */, + A251BE8B0959A1EA0058BC7F /* FakeModel.h */, + A251BE8C0959A1EA0058BC7F /* FakeModel.m */, + A251BE8D0959A1EA0058BC7F /* main.m */, + ); + name = "Demo App"; + sourceTree = ""; + }; + A251BE8E0959A21A0058BC7F /* Images */ = { + isa = PBXGroup; + children = ( + A2C0D99309AF870000ED379C /* pi.png */, + A2072B5C09AC1FA500304BCB /* Warning.png */, + A2072A2409ABD88600304BCB /* Folder.tif */, + A2072A2509ABD88600304BCB /* Globe.tiff */, + A268E7F809A9822900E082AA /* AquaTabNew.png */, + A268E7F909A9822900E082AA /* AquaTabNewPressed.png */, + A268E7FA09A9822900E082AA /* AquaTabNewRollover.png */, + A268E7FB09A9822900E082AA /* TabNewMetal.png */, + A268E7FC09A9822900E082AA /* TabNewMetalPressed.png */, + A268E7FD09A9822900E082AA /* TabNewMetalRollover.png */, + A269361009A778770006911E /* 32x32_log.tiff */, + A2D3317A09A68B7500EC8662 /* AquaTabsDownGraphite.png */, + A2D3317B09A68B7500EC8662 /* AquaTabsDownNonKey.png */, + A2D32EF009A63BF700EC8662 /* AquaTabClose_Front_Pressed.tif */, + A2D32EF109A63BF700EC8662 /* AquaTabClose_Front_Rollover.tif */, + A2D32EF209A63BF700EC8662 /* AquaTabClose_Front.tif */, + A2D32EF309A63BF700EC8662 /* AquaTabsBackground.png */, + A2D32EF409A63BF700EC8662 /* AquaTabsDown.png */, + A2D32EF509A63BF700EC8662 /* AquaTabsSeparator.png */, + A2D32EF609A63BF700EC8662 /* AquaTabsSeparatorDown.png */, + A251BE8F0959A23A0058BC7F /* 32x32cancel.png */, + A251BE900959A23A0058BC7F /* overflowImage.tiff */, + A251BE910959A23A0058BC7F /* overflowImagePressed.tif */, + A251BE920959A23A0058BC7F /* TabClose_Front_Pressed.tif */, + A251BE930959A23A0058BC7F /* TabClose_Front_Rollover.tif */, + A251BE940959A23A0058BC7F /* TabClose_Front.tif */, + ); + name = Images; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 53DF68F8067E5B5A0090B5B0 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 546DEAF2067F630E0098DCC4 /* PSMTabBarControl.h in Headers */, + A251BE850959A1B90058BC7F /* PSMOverflowPopUpButton.h in Headers */, + A251BE870959A1B90058BC7F /* PSMTabBarCell.h in Headers */, + A2D32EDC09A634C900EC8662 /* PSMTabStyle.h in Headers */, + A2D32EE809A6399300EC8662 /* PSMAquaTabStyle.h in Headers */, + A2D32F0009A63D7A00EC8662 /* PSMMetalTabStyle.h in Headers */, + A268EA6209A9831800E082AA /* PSMRolloverButton.h in Headers */, + A2129BB209AEB58F00724E6C /* PSMProgressIndicator.h in Headers */, + A2082A9009EAEB34009AC8BE /* PSMTabDragAssistant.h in Headers */, + A2D98B0A0A2B432C0064C6F8 /* PSMUnifiedTabStyle.h in Headers */, + A2D98B120A2B43FA0064C6F8 /* NSBezierPath_AMShading.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 53DF68FC067E5B5A0090B5B0 /* PSMTabBarControlFramework */ = { + isa = PBXNativeTarget; + buildConfigurationList = C056397F08A954F8003078D8 /* Build configuration list for PBXNativeTarget "PSMTabBarControlFramework" */; + buildPhases = ( + 53DF68F8067E5B5A0090B5B0 /* Headers */, + 53DF68F9067E5B5A0090B5B0 /* Resources */, + 53DF68FA067E5B5A0090B5B0 /* Sources */, + 53DF68FB067E5B5A0090B5B0 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = PSMTabBarControlFramework; + productName = PSMTabBarControlFramework; + productReference = 53DF68FD067E5B5A0090B5B0 /* PSMTabBarControl.framework */; + productType = "com.apple.product-type.framework"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 0259C573FE90428111CA0C5A /* Project object */ = { + isa = PBXProject; + buildConfigurationList = C056398B08A954F8003078D8 /* Build configuration list for PBXProject "PSMTabBarControl" */; + hasScannedForEncodings = 1; + mainGroup = 0259C574FE90428111CA0C5A /* PSMTabBarControl */; + projectDirPath = ""; + targets = ( + 53DF68FC067E5B5A0090B5B0 /* PSMTabBarControlFramework */, + 53DF6901067E5B8E0090B5B0 /* All */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 53DF68F9067E5B5A0090B5B0 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + A251BE960959A23A0058BC7F /* overflowImage.tiff in Resources */, + A251BE970959A23A0058BC7F /* overflowImagePressed.tif in Resources */, + A251BE980959A23A0058BC7F /* TabClose_Front_Pressed.tif in Resources */, + A251BE990959A23A0058BC7F /* TabClose_Front_Rollover.tif in Resources */, + A251BE9A0959A23A0058BC7F /* TabClose_Front.tif in Resources */, + A2D32EF709A63BF700EC8662 /* AquaTabClose_Front_Pressed.tif in Resources */, + A2D32EF809A63BF700EC8662 /* AquaTabClose_Front_Rollover.tif in Resources */, + A2D32EF909A63BF700EC8662 /* AquaTabClose_Front.tif in Resources */, + A2D32EFA09A63BF700EC8662 /* AquaTabsBackground.png in Resources */, + A2D32EFB09A63BF700EC8662 /* AquaTabsDown.png in Resources */, + A2D32EFC09A63BF700EC8662 /* AquaTabsSeparator.png in Resources */, + A2D32EFD09A63BF700EC8662 /* AquaTabsSeparatorDown.png in Resources */, + A2D3317C09A68B7500EC8662 /* AquaTabsDownGraphite.png in Resources */, + A2D3317D09A68B7500EC8662 /* AquaTabsDownNonKey.png in Resources */, + A268E80409A9822A00E082AA /* AquaTabNew.png in Resources */, + A268E80509A9822A00E082AA /* AquaTabNewPressed.png in Resources */, + A268E80609A9822A00E082AA /* AquaTabNewRollover.png in Resources */, + A268E80709A9822A00E082AA /* TabNewMetal.png in Resources */, + A268E80809A9822A00E082AA /* TabNewMetalPressed.png in Resources */, + A268E80909A9822A00E082AA /* TabNewMetalRollover.png in Resources */, + A2C0D99509AF870000ED379C /* pi.png in Resources */, + A27E47850A28EE76007BA395 /* TabIcon.tif in Resources */, + A27E47880A28EE7C007BA395 /* TabControlRep.tif in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 53DF68FA067E5B5A0090B5B0 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 546DEAF1067F63070098DCC4 /* PSMTabBarControl.m in Sources */, + A251BE860959A1B90058BC7F /* PSMOverflowPopUpButton.m in Sources */, + A251BE880959A1B90058BC7F /* PSMTabBarCell.m in Sources */, + A2D32EE909A6399300EC8662 /* PSMAquaTabStyle.m in Sources */, + A2D32F0109A63D7A00EC8662 /* PSMMetalTabStyle.m in Sources */, + A268EA6309A9831800E082AA /* PSMRolloverButton.m in Sources */, + A2129BB309AEB58F00724E6C /* PSMProgressIndicator.m in Sources */, + A2082A9109EAEB34009AC8BE /* PSMTabDragAssistant.m in Sources */, + A2D98B0B0A2B432C0064C6F8 /* PSMUnifiedTabStyle.m in Sources */, + A2D98B130A2B43FA0064C6F8 /* NSBezierPath_AMShading.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 53DF6905067E5B930090B5B0 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 53DF68FC067E5B5A0090B5B0 /* PSMTabBarControlFramework */; + targetProxy = 53DF6904067E5B930090B5B0 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 0259C57EFE90428111CA0C5A /* PSMTabBarControlInspector.nib */ = { + isa = PBXVariantGroup; + children = ( + 0259C57FFE90428111CA0C5A /* English */, + ); + name = PSMTabBarControlInspector.nib; + sourceTree = ""; + }; + 0259C580FE90428111CA0C5A /* PSMTabBarControlPalette.nib */ = { + isa = PBXVariantGroup; + children = ( + 0259C581FE90428111CA0C5A /* English */, + ); + name = PSMTabBarControlPalette.nib; + sourceTree = ""; + }; + 8D1AC97F0486D23B00FE50C9 /* InfoPlist.strings */ = { + isa = PBXVariantGroup; + children = ( + 8D1AC97B0486D23100FE50C9 /* English */, + ); + name = InfoPlist.strings; + sourceTree = ""; + }; + A251BEC20959BC0E0058BC7F /* MainMenu.nib */ = { + isa = PBXVariantGroup; + children = ( + A251BEC30959BC0E0058BC7F /* English */, + ); + name = MainMenu.nib; + sourceTree = ""; + }; + A2A711B909E5AE1E00D0089B /* Window.nib */ = { + isa = PBXVariantGroup; + children = ( + A2A711BA09E5AE1E00D0089B /* English */, + ); + name = Window.nib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + C056398008A954F8003078D8 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + ppc, + i386, + ); + COPY_PHASE_STRIP = NO; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + FRAMEWORK_VERSION = A; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_MODEL_TUNING = G5; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/AppKit.framework/Headers/AppKit.h"; + INFOPLIST_FILE = "PSMTabBarControlFramework-Info.plist"; + INSTALL_PATH = "@executable_path/../Frameworks"; + OTHER_LDFLAGS = ( + "-seg1addr", + 0xc0000000, + ); + PRODUCT_NAME = PSMTabBarControl; + SYMROOT = ../build; + ZERO_LINK = NO; + }; + name = Debug; + }; + C056398108A954F8003078D8 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + ppc, + i386, + ); + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + FRAMEWORK_VERSION = A; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = G5; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/AppKit.framework/Headers/AppKit.h"; + INFOPLIST_FILE = "PSMTabBarControlFramework-Info.plist"; + INSTALL_PATH = "@executable_path/../Frameworks"; + OTHER_LDFLAGS = ( + "-seg1addr", + 0xc0000000, + ); + PRODUCT_NAME = PSMTabBarControl; + SYMROOT = ../build; + }; + name = Release; + }; + C056398808A954F8003078D8 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_MODEL_TUNING = G5; + GCC_OPTIMIZATION_LEVEL = 0; + PRODUCT_NAME = All; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + ZERO_LINK = YES; + }; + name = Debug; + }; + C056398908A954F8003078D8 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + ppc, + i386, + ); + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = G5; + PRODUCT_NAME = All; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + }; + name = Release; + }; + C056398C08A954F8003078D8 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + PREBINDING = NO; + SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk; + }; + name = Debug; + }; + C056398D08A954F8003078D8 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + PREBINDING = NO; + SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + C056397F08A954F8003078D8 /* Build configuration list for PBXNativeTarget "PSMTabBarControlFramework" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C056398008A954F8003078D8 /* Debug */, + C056398108A954F8003078D8 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C056398708A954F8003078D8 /* Build configuration list for PBXAggregateTarget "All" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C056398808A954F8003078D8 /* Debug */, + C056398908A954F8003078D8 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C056398B08A954F8003078D8 /* Build configuration list for PBXProject "PSMTabBarControl" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C056398C08A954F8003078D8 /* Debug */, + C056398D08A954F8003078D8 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 0259C573FE90428111CA0C5A /* Project object */; +} diff --git a/PSMTabBarControl/PSMTabBarControl.xcodeproj/winckler.mode1 b/PSMTabBarControl/PSMTabBarControl.xcodeproj/winckler.mode1 new file mode 100644 index 0000000000..fc778d781a --- /dev/null +++ b/PSMTabBarControl/PSMTabBarControl.xcodeproj/winckler.mode1 @@ -0,0 +1,1330 @@ + + + + + ActivePerspectiveName + Project + AllowedModules + + + BundleLoadPath + + MaxInstances + n + Module + PBXSmartGroupTreeModule + Name + Groups and Files Outline View + + + BundleLoadPath + + MaxInstances + n + Module + PBXNavigatorGroup + Name + Editor + + + BundleLoadPath + + MaxInstances + n + Module + XCTaskListModule + Name + Task List + + + BundleLoadPath + + MaxInstances + n + Module + XCDetailModule + Name + File and Smart Group Detail Viewer + + + BundleLoadPath + + MaxInstances + 1 + Module + PBXBuildResultsModule + Name + Detailed Build Results Viewer + + + BundleLoadPath + + MaxInstances + 1 + Module + PBXProjectFindModule + Name + Project Batch Find Tool + + + BundleLoadPath + + MaxInstances + n + Module + PBXRunSessionModule + Name + Run Log + + + BundleLoadPath + + MaxInstances + n + Module + PBXBookmarksModule + Name + Bookmarks Tool + + + BundleLoadPath + + MaxInstances + n + Module + PBXClassBrowserModule + Name + Class Browser + + + BundleLoadPath + + MaxInstances + n + Module + PBXCVSModule + Name + Source Code Control Tool + + + BundleLoadPath + + MaxInstances + n + Module + PBXDebugBreakpointsModule + Name + Debug Breakpoints Tool + + + BundleLoadPath + + MaxInstances + n + Module + XCDockableInspector + Name + Inspector + + + BundleLoadPath + + MaxInstances + n + Module + PBXOpenQuicklyModule + Name + Open Quickly Tool + + + BundleLoadPath + + MaxInstances + 1 + Module + PBXDebugSessionModule + Name + Debugger + + + BundleLoadPath + + MaxInstances + 1 + Module + PBXDebugCLIModule + Name + Debug Console + + + Description + DefaultDescriptionKey + DockingSystemVisible + + Extension + mode1 + FavBarConfig + + PBXProjectModuleGUID + 1D82C60D0AC093AF00AAD418 + XCBarModuleItemNames + + XCBarModuleItems + + + FirstTimeWindowDisplayed + + Identifier + com.apple.perspectives.project.mode1 + MajorVersion + 31 + MinorVersion + 1 + Name + Default + Notifications + + OpenEditors + + PerspectiveWidths + + -1 + -1 + + Perspectives + + + ChosenToolbarItems + + active-target-popup + active-buildstyle-popup + action + NSToolbarFlexibleSpaceItem + buildOrClean + build-and-runOrDebug + com.apple.ide.PBXToolbarStopButton + get-info + toggle-editor + NSToolbarFlexibleSpaceItem + com.apple.pbx.toolbar.searchfield + + ControllerClassBaseName + + IconName + WindowOfProjectWithEditor + Identifier + perspective.project + IsVertical + + Layout + + + BecomeActive + + ContentConfiguration + + PBXBottomSmartGroupGIDs + + 1C37FBAC04509CD000000102 + 1C37FAAC04509CD000000102 + 1C08E77C0454961000C914BD + 1C37FABC05509CD000000102 + 1C37FABC05539CD112110102 + E2644B35053B69B200211256 + 1C37FABC04509CD000100104 + 1CC0EA4004350EF90044410B + 1CC0EA4004350EF90041110B + + PBXProjectModuleGUID + 1CE0B1FE06471DED0097A5F4 + PBXProjectModuleLabel + Files + PBXProjectStructureProvided + yes + PBXSmartGroupTreeModuleColumnData + + PBXSmartGroupTreeModuleColumnWidthsKey + + 186 + + PBXSmartGroupTreeModuleColumnsKey_v4 + + MainColumn + + + PBXSmartGroupTreeModuleOutlineStateKey_v7 + + PBXSmartGroupTreeModuleOutlineStateExpansionKey + + 0259C574FE90428111CA0C5A + 1C37FBAC04509CD000000102 + 1C37FABC05509CD000000102 + + PBXSmartGroupTreeModuleOutlineStateSelectionKey + + + 9 + + + PBXSmartGroupTreeModuleOutlineStateVisibleRectKey + {{0, 0}, {186, 338}} + + PBXTopSmartGroupGIDs + + XCIncludePerspectivesSwitch + + XCSharingToken + com.apple.Xcode.GFSharingToken + + GeometryConfiguration + + Frame + {{0, 0}, {203, 356}} + GroupTreeTableConfiguration + + MainColumn + 186 + + RubberWindowFrame + 160 82 690 397 0 0 1024 746 + + Module + PBXSmartGroupTreeModule + Proportion + 203pt + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 1CE0B20306471E060097A5F4 + PBXProjectModuleLabel + MyNewFile14.java + PBXSplitModuleInNavigatorKey + + Split0 + + PBXProjectModuleGUID + 1CE0B20406471E060097A5F4 + PBXProjectModuleLabel + MyNewFile14.java + + SplitCount + 1 + + StatusBarVisibility + + + GeometryConfiguration + + Frame + {{0, 0}, {482, 0}} + RubberWindowFrame + 160 82 690 397 0 0 1024 746 + + Module + PBXNavigatorGroup + Proportion + 0pt + + + ContentConfiguration + + PBXProjectModuleGUID + 1CE0B20506471E060097A5F4 + PBXProjectModuleLabel + Detail + + GeometryConfiguration + + Frame + {{0, 5}, {482, 351}} + RubberWindowFrame + 160 82 690 397 0 0 1024 746 + + Module + XCDetailModule + Proportion + 351pt + + + Proportion + 482pt + + + Name + Project + ServiceClasses + + XCModuleDock + PBXSmartGroupTreeModule + XCModuleDock + PBXNavigatorGroup + XCDetailModule + + TableOfContents + + 1D493DC50C5253D100AB718C + 1CE0B1FE06471DED0097A5F4 + 1D493DC60C5253D100AB718C + 1CE0B20306471E060097A5F4 + 1CE0B20506471E060097A5F4 + + ToolbarConfiguration + xcode.toolbar.config.default + + + ControllerClassBaseName + + IconName + WindowOfProject + Identifier + perspective.morph + IsVertical + 0 + Layout + + + BecomeActive + 1 + ContentConfiguration + + PBXBottomSmartGroupGIDs + + 1C37FBAC04509CD000000102 + 1C37FAAC04509CD000000102 + 1C08E77C0454961000C914BD + 1C37FABC05509CD000000102 + 1C37FABC05539CD112110102 + E2644B35053B69B200211256 + 1C37FABC04509CD000100104 + 1CC0EA4004350EF90044410B + 1CC0EA4004350EF90041110B + + PBXProjectModuleGUID + 11E0B1FE06471DED0097A5F4 + PBXProjectModuleLabel + Files + PBXProjectStructureProvided + yes + PBXSmartGroupTreeModuleColumnData + + PBXSmartGroupTreeModuleColumnWidthsKey + + 186 + + PBXSmartGroupTreeModuleColumnsKey_v4 + + MainColumn + + + PBXSmartGroupTreeModuleOutlineStateKey_v7 + + PBXSmartGroupTreeModuleOutlineStateExpansionKey + + 29B97314FDCFA39411CA2CEA + 1C37FABC05509CD000000102 + + PBXSmartGroupTreeModuleOutlineStateSelectionKey + + + 0 + + + PBXSmartGroupTreeModuleOutlineStateVisibleRectKey + {{0, 0}, {186, 337}} + + PBXTopSmartGroupGIDs + + XCIncludePerspectivesSwitch + 1 + XCSharingToken + com.apple.Xcode.GFSharingToken + + GeometryConfiguration + + Frame + {{0, 0}, {203, 355}} + GroupTreeTableConfiguration + + MainColumn + 186 + + RubberWindowFrame + 373 269 690 397 0 0 1440 878 + + Module + PBXSmartGroupTreeModule + Proportion + 100% + + + Name + Morph + PreferredWidth + 300 + ServiceClasses + + XCModuleDock + PBXSmartGroupTreeModule + + TableOfContents + + 11E0B1FE06471DED0097A5F4 + + ToolbarConfiguration + xcode.toolbar.config.default.short + + + PerspectivesBarVisible + + ShelfIsVisible + + SourceDescription + file at '/System/Library/PrivateFrameworks/DevToolsInterface.framework/Versions/A/Resources/XCPerspectivesSpecificationMode1.xcperspec' + StatusbarIsVisible + + TimeStamp + 0.0 + ToolbarDisplayMode + 1 + ToolbarIsVisible + + ToolbarSizeMode + 1 + Type + Perspectives + UpdateMessage + The Default Workspace in this version of Xcode now includes support to hide and show the detail view (what has been referred to as the "Metro-Morph" feature). You must discard your current Default Workspace settings and update to the latest Default Workspace in order to gain this feature. Do you wish to update to the latest Workspace defaults for project '%@'? + WindowJustification + 5 + WindowOrderList + + 1D82C60E0AC093AF00AAD418 + /Users/winckler/Projects/vim70/src/MacVim/PSMTabBarControl/PSMTabBarControl.xcodeproj + + WindowString + 160 82 690 397 0 0 1024 746 + WindowTools + + + FirstTimeWindowDisplayed + + Identifier + windowTool.build + IsVertical + + Layout + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 1CD0528F0623707200166675 + PBXProjectModuleLabel + + StatusBarVisibility + + + GeometryConfiguration + + Frame + {{0, 0}, {500, 218}} + RubberWindowFrame + 188 201 500 500 0 0 1024 746 + + Module + PBXNavigatorGroup + Proportion + 218pt + + + ContentConfiguration + + PBXProjectModuleGUID + XCMainBuildResultsModuleGUID + PBXProjectModuleLabel + Build + XCBuildResultsTrigger_Collapse + 1021 + XCBuildResultsTrigger_Open + 1011 + + GeometryConfiguration + + Frame + {{0, 223}, {500, 236}} + RubberWindowFrame + 188 201 500 500 0 0 1024 746 + + Module + PBXBuildResultsModule + Proportion + 236pt + + + Proportion + 459pt + + + Name + Build Results + ServiceClasses + + PBXBuildResultsModule + + StatusbarIsVisible + + TableOfContents + + 1D82C60E0AC093AF00AAD418 + 1D493DC70C5253D100AB718C + 1CD0528F0623707200166675 + XCMainBuildResultsModuleGUID + + ToolbarConfiguration + xcode.toolbar.config.build + WindowString + 188 201 500 500 0 0 1024 746 + WindowToolGUID + 1D82C60E0AC093AF00AAD418 + WindowToolIsVisible + + + + Identifier + windowTool.debugger + Layout + + + Dock + + + ContentConfiguration + + Debugger + + HorizontalSplitView + + _collapsingFrameDimension + 0.0 + _indexOfCollapsedView + 0 + _percentageOfCollapsedView + 0.0 + isCollapsed + yes + sizes + + {{0, 0}, {317, 164}} + {{317, 0}, {377, 164}} + + + VerticalSplitView + + _collapsingFrameDimension + 0.0 + _indexOfCollapsedView + 0 + _percentageOfCollapsedView + 0.0 + isCollapsed + yes + sizes + + {{0, 0}, {694, 164}} + {{0, 164}, {694, 216}} + + + + LauncherConfigVersion + 8 + PBXProjectModuleGUID + 1C162984064C10D400B95A72 + PBXProjectModuleLabel + Debug - GLUTExamples (Underwater) + + GeometryConfiguration + + DebugConsoleDrawerSize + {100, 120} + DebugConsoleVisible + None + DebugConsoleWindowFrame + {{200, 200}, {500, 300}} + DebugSTDIOWindowFrame + {{200, 200}, {500, 300}} + Frame + {{0, 0}, {694, 380}} + RubberWindowFrame + 321 238 694 422 0 0 1440 878 + + Module + PBXDebugSessionModule + Proportion + 100% + + + Proportion + 100% + + + Name + Debugger + ServiceClasses + + PBXDebugSessionModule + + StatusbarIsVisible + 1 + TableOfContents + + 1CD10A99069EF8BA00B06720 + 1C0AD2AB069F1E9B00FABCE6 + 1C162984064C10D400B95A72 + 1C0AD2AC069F1E9B00FABCE6 + + ToolbarConfiguration + xcode.toolbar.config.debug + WindowString + 321 238 694 422 0 0 1440 878 + WindowToolGUID + 1CD10A99069EF8BA00B06720 + WindowToolIsVisible + 0 + + + Identifier + windowTool.find + Layout + + + Dock + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 1CDD528C0622207200134675 + PBXProjectModuleLabel + <No Editor> + PBXSplitModuleInNavigatorKey + + Split0 + + PBXProjectModuleGUID + 1CD0528D0623707200166675 + + SplitCount + 1 + + StatusBarVisibility + 1 + + GeometryConfiguration + + Frame + {{0, 0}, {781, 167}} + RubberWindowFrame + 62 385 781 470 0 0 1440 878 + + Module + PBXNavigatorGroup + Proportion + 781pt + + + Proportion + 50% + + + BecomeActive + 1 + ContentConfiguration + + PBXProjectModuleGUID + 1CD0528E0623707200166675 + PBXProjectModuleLabel + Project Find + + GeometryConfiguration + + Frame + {{8, 0}, {773, 254}} + RubberWindowFrame + 62 385 781 470 0 0 1440 878 + + Module + PBXProjectFindModule + Proportion + 50% + + + Proportion + 428pt + + + Name + Project Find + ServiceClasses + + PBXProjectFindModule + + StatusbarIsVisible + 1 + TableOfContents + + 1C530D57069F1CE1000CFCEE + 1C530D58069F1CE1000CFCEE + 1C530D59069F1CE1000CFCEE + 1CDD528C0622207200134675 + 1C530D5A069F1CE1000CFCEE + 1CE0B1FE06471DED0097A5F4 + 1CD0528E0623707200166675 + + WindowString + 62 385 781 470 0 0 1440 878 + WindowToolGUID + 1C530D57069F1CE1000CFCEE + WindowToolIsVisible + 0 + + + Identifier + MENUSEPARATOR + + + Identifier + windowTool.debuggerConsole + Layout + + + Dock + + + BecomeActive + 1 + ContentConfiguration + + PBXProjectModuleGUID + 1C78EAAC065D492600B07095 + PBXProjectModuleLabel + Debugger Console + + GeometryConfiguration + + Frame + {{0, 0}, {440, 358}} + RubberWindowFrame + 650 41 440 400 0 0 1280 1002 + + Module + PBXDebugCLIModule + Proportion + 358pt + + + Proportion + 358pt + + + Name + Debugger Console + ServiceClasses + + PBXDebugCLIModule + + StatusbarIsVisible + 1 + TableOfContents + + 1C78EAAD065D492600B07095 + 1C78EAAE065D492600B07095 + 1C78EAAC065D492600B07095 + + WindowString + 650 41 440 400 0 0 1280 1002 + + + FirstTimeWindowDisplayed + + Identifier + windowTool.run + IsVertical + + Layout + + + Dock + + + ContentConfiguration + + LauncherConfigVersion + 3 + PBXProjectModuleGUID + 1CD0528B0623707200166675 + PBXProjectModuleLabel + Run + Runner + + HorizontalSplitView + + _collapsingFrameDimension + 0.0 + _indexOfCollapsedView + 0 + _percentageOfCollapsedView + 0.0 + isCollapsed + yes + sizes + + {{0, 0}, {493, 167}} + {{0, 176}, {493, 267}} + + + VerticalSplitView + + _collapsingFrameDimension + 0.0 + _indexOfCollapsedView + 0 + _percentageOfCollapsedView + 0.0 + isCollapsed + yes + sizes + + {{0, 0}, {405, 443}} + {{414, 0}, {514, 443}} + + + + + GeometryConfiguration + + Frame + {{0, 0}, {459, 159}} + RubberWindowFrame + 188 501 459 200 0 0 1024 746 + + Module + PBXRunSessionModule + Proportion + 159pt + + + Proportion + 159pt + + + Name + Run Log + ServiceClasses + + PBXRunSessionModule + + StatusbarIsVisible + + TableOfContents + + 1C0AD2B3069F1EA900FABCE6 + 1DE46F2A0BAB3A66004EEB67 + 1CD0528B0623707200166675 + 1DE46F2B0BAB3A66004EEB67 + + ToolbarConfiguration + xcode.toolbar.config.run + WindowString + 188 501 459 200 0 0 1024 746 + WindowToolGUID + 1C0AD2B3069F1EA900FABCE6 + WindowToolIsVisible + + + + Identifier + windowTool.scm + Layout + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 1C78EAB2065D492600B07095 + PBXProjectModuleLabel + <No Editor> + PBXSplitModuleInNavigatorKey + + Split0 + + PBXProjectModuleGUID + 1C78EAB3065D492600B07095 + + SplitCount + 1 + + StatusBarVisibility + 1 + + GeometryConfiguration + + Frame + {{0, 0}, {452, 0}} + RubberWindowFrame + 743 379 452 308 0 0 1280 1002 + + Module + PBXNavigatorGroup + Proportion + 0pt + + + BecomeActive + 1 + ContentConfiguration + + PBXProjectModuleGUID + 1CD052920623707200166675 + PBXProjectModuleLabel + SCM + + GeometryConfiguration + + ConsoleFrame + {{0, 259}, {452, 0}} + Frame + {{0, 7}, {452, 259}} + RubberWindowFrame + 743 379 452 308 0 0 1280 1002 + TableConfiguration + + Status + 30 + FileName + 199 + Path + 197.09500122070312 + + TableFrame + {{0, 0}, {452, 250}} + + Module + PBXCVSModule + Proportion + 262pt + + + Proportion + 266pt + + + Name + SCM + ServiceClasses + + PBXCVSModule + + StatusbarIsVisible + 1 + TableOfContents + + 1C78EAB4065D492600B07095 + 1C78EAB5065D492600B07095 + 1C78EAB2065D492600B07095 + 1CD052920623707200166675 + + ToolbarConfiguration + xcode.toolbar.config.scm + WindowString + 743 379 452 308 0 0 1280 1002 + + + Identifier + windowTool.breakpoints + IsVertical + 0 + Layout + + + Dock + + + BecomeActive + 1 + ContentConfiguration + + PBXBottomSmartGroupGIDs + + 1C77FABC04509CD000000102 + + PBXProjectModuleGUID + 1CE0B1FE06471DED0097A5F4 + PBXProjectModuleLabel + Files + PBXProjectStructureProvided + no + PBXSmartGroupTreeModuleColumnData + + PBXSmartGroupTreeModuleColumnWidthsKey + + 168 + + PBXSmartGroupTreeModuleColumnsKey_v4 + + MainColumn + + + PBXSmartGroupTreeModuleOutlineStateKey_v7 + + PBXSmartGroupTreeModuleOutlineStateExpansionKey + + 1C77FABC04509CD000000102 + + PBXSmartGroupTreeModuleOutlineStateSelectionKey + + + 0 + + + PBXSmartGroupTreeModuleOutlineStateVisibleRectKey + {{0, 0}, {168, 350}} + + PBXTopSmartGroupGIDs + + XCIncludePerspectivesSwitch + 0 + + GeometryConfiguration + + Frame + {{0, 0}, {185, 368}} + GroupTreeTableConfiguration + + MainColumn + 168 + + RubberWindowFrame + 315 424 744 409 0 0 1440 878 + + Module + PBXSmartGroupTreeModule + Proportion + 185pt + + + ContentConfiguration + + PBXProjectModuleGUID + 1CA1AED706398EBD00589147 + PBXProjectModuleLabel + Detail + + GeometryConfiguration + + Frame + {{190, 0}, {554, 368}} + RubberWindowFrame + 315 424 744 409 0 0 1440 878 + + Module + XCDetailModule + Proportion + 554pt + + + Proportion + 368pt + + + MajorVersion + 2 + MinorVersion + 0 + Name + Breakpoints + ServiceClasses + + PBXSmartGroupTreeModule + XCDetailModule + + StatusbarIsVisible + 1 + TableOfContents + + 1CDDB66807F98D9800BB5817 + 1CDDB66907F98D9800BB5817 + 1CE0B1FE06471DED0097A5F4 + 1CA1AED706398EBD00589147 + + ToolbarConfiguration + xcode.toolbar.config.breakpoints + WindowString + 315 424 744 409 0 0 1440 878 + WindowToolGUID + 1CDDB66807F98D9800BB5817 + WindowToolIsVisible + 1 + + + Identifier + windowTool.debugAnimator + Layout + + + Dock + + + Module + PBXNavigatorGroup + Proportion + 100% + + + Proportion + 100% + + + Name + Debug Visualizer + ServiceClasses + + PBXNavigatorGroup + + StatusbarIsVisible + 1 + ToolbarConfiguration + xcode.toolbar.config.debugAnimator + WindowString + 100 100 700 500 0 0 1280 1002 + + + Identifier + windowTool.bookmarks + Layout + + + Dock + + + Module + PBXBookmarksModule + Proportion + 100% + + + Proportion + 100% + + + Name + Bookmarks + ServiceClasses + + PBXBookmarksModule + + StatusbarIsVisible + 0 + WindowString + 538 42 401 187 0 0 1280 1002 + + + Identifier + windowTool.classBrowser + Layout + + + Dock + + + BecomeActive + 1 + ContentConfiguration + + OptionsSetName + Hierarchy, all classes + PBXProjectModuleGUID + 1CA6456E063B45B4001379D8 + PBXProjectModuleLabel + Class Browser - NSObject + + GeometryConfiguration + + ClassesFrame + {{0, 0}, {374, 96}} + ClassesTreeTableConfiguration + + PBXClassNameColumnIdentifier + 208 + PBXClassBookColumnIdentifier + 22 + + Frame + {{0, 0}, {630, 331}} + MembersFrame + {{0, 105}, {374, 395}} + MembersTreeTableConfiguration + + PBXMemberTypeIconColumnIdentifier + 22 + PBXMemberNameColumnIdentifier + 216 + PBXMemberTypeColumnIdentifier + 97 + PBXMemberBookColumnIdentifier + 22 + + PBXModuleWindowStatusBarHidden2 + 1 + RubberWindowFrame + 385 179 630 352 0 0 1440 878 + + Module + PBXClassBrowserModule + Proportion + 332pt + + + Proportion + 332pt + + + Name + Class Browser + ServiceClasses + + PBXClassBrowserModule + + StatusbarIsVisible + 0 + TableOfContents + + 1C0AD2AF069F1E9B00FABCE6 + 1C0AD2B0069F1E9B00FABCE6 + 1CA6456E063B45B4001379D8 + + ToolbarConfiguration + xcode.toolbar.config.classbrowser + WindowString + 385 179 630 352 0 0 1440 878 + WindowToolGUID + 1C0AD2AF069F1E9B00FABCE6 + WindowToolIsVisible + 0 + + + + diff --git a/PSMTabBarControl/PSMTabBarControl.xcodeproj/winckler.pbxuser b/PSMTabBarControl/PSMTabBarControl.xcodeproj/winckler.pbxuser new file mode 100644 index 0000000000..745102e89d --- /dev/null +++ b/PSMTabBarControl/PSMTabBarControl.xcodeproj/winckler.pbxuser @@ -0,0 +1,178 @@ +// !$*UTF8*$! +{ + 0259C573FE90428111CA0C5A /* Project object */ = { + activeBuildConfigurationName = Debug; + activeTarget = 53DF68FC067E5B5A0090B5B0 /* PSMTabBarControlFramework */; + codeSenseManager = 1D82C6110AC093AF00AAD418 /* Code sense */; + perUserDictionary = { + PBXConfiguration.PBXFileTableDataSource3.PBXFileTableDataSource = { + PBXFileTableDataSourceColumnSortingDirectionKey = "-1"; + PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID; + PBXFileTableDataSourceColumnWidthsKey = ( + 20, + 243, + 20, + 48, + 43, + 43, + 20, + ); + PBXFileTableDataSourceColumnsKey = ( + PBXFileDataSource_FiletypeID, + PBXFileDataSource_Filename_ColumnID, + PBXFileDataSource_Built_ColumnID, + PBXFileDataSource_ObjectSize_ColumnID, + PBXFileDataSource_Errors_ColumnID, + PBXFileDataSource_Warnings_ColumnID, + PBXFileDataSource_Target_ColumnID, + ); + }; + PBXConfiguration.PBXTargetDataSource.PBXTargetDataSource = { + PBXFileTableDataSourceColumnSortingDirectionKey = "-1"; + PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID; + PBXFileTableDataSourceColumnWidthsKey = ( + 20, + 200, + 63, + 20, + 48, + 43, + 43, + ); + PBXFileTableDataSourceColumnsKey = ( + PBXFileDataSource_FiletypeID, + PBXFileDataSource_Filename_ColumnID, + PBXTargetDataSource_PrimaryAttribute, + PBXFileDataSource_Built_ColumnID, + PBXFileDataSource_ObjectSize_ColumnID, + PBXFileDataSource_Errors_ColumnID, + PBXFileDataSource_Warnings_ColumnID, + ); + }; + PBXPerProjectTemplateStateSaveDate = 206721719; + PBXWorkspaceStateSaveDate = 206721719; + }; + sourceControlManager = 1D82C6100AC093AF00AAD418 /* Source Control */; + userBuildSettings = { + }; + }; + 0259C576FE90428111CA0C5A /* PSMTabBarControl.m */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {4143, 22432}}"; + sepNavSelRange = "{48941, 0}"; + sepNavVisRect = "{{0, 1451}, {459, 186}}"; + sepNavWindowFrame = "{{15, -1}, {750, 742}}"; + }; + }; + 0259C57AFE90428111CA0C5A /* PSMTabBarControl.h */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {1077, 2000}}"; + sepNavSelRange = "{3919, 0}"; + sepNavVisRect = "{{0, 1387}, {711, 613}}"; + sepNavWindowFrame = "{{15, -1}, {750, 742}}"; + }; + }; + 1D82C6100AC093AF00AAD418 /* Source Control */ = { + isa = PBXSourceControlManager; + fallbackIsa = XCSourceControlManager; + isSCMEnabled = 0; + scmConfiguration = { + }; + scmType = ""; + }; + 1D82C6110AC093AF00AAD418 /* Code sense */ = { + isa = PBXCodeSenseManager; + indexTemplatePath = ""; + }; + 53DF68FC067E5B5A0090B5B0 /* PSMTabBarControlFramework */ = { + activeExec = 0; + }; + 53DF6901067E5B8E0090B5B0 /* All */ = { + activeExec = 0; + }; + A2082A8E09EAEB33009AC8BE /* PSMTabDragAssistant.m */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {1420, 7040}}"; + sepNavSelRange = "{14900, 0}"; + sepNavVisRect = "{{0, 3817}, {978, 600}}"; + sepNavWindowFrame = "{{6, 17}, {1017, 729}}"; + }; + }; + A246FB040A2BD6F9005BDF7B /* PSMTabBarControlDoc.html */ = { + uiCtxt = { + sepNavWindowFrame = "{{15, 3}, {750, 742}}"; + }; + }; + A251BE830959A1B90058BC7F /* PSMTabBarCell.h */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {804, 1648}}"; + sepNavSelRange = "{0, 0}"; + sepNavVisRect = "{{0, 744}, {619, 599}}"; + sepNavWindowFrame = "{{15, 13}, {658, 728}}"; + }; + }; + A251BE840959A1B90058BC7F /* PSMTabBarCell.m */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {972, 6368}}"; + sepNavSelRange = "{0, 0}"; + sepNavVisRect = "{{0, 5769}, {619, 599}}"; + sepNavWindowFrame = "{{15, 13}, {658, 728}}"; + }; + }; + A251BE8A0959A1EA0058BC7F /* AppController.m */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {711, 613}}"; + sepNavSelRange = "{0, 0}"; + sepNavVisRect = "{{0, 0}, {711, 613}}"; + sepNavWindowFrame = "{{15, -1}, {750, 742}}"; + }; + }; + A251BE8B0959A1EA0058BC7F /* FakeModel.h */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {711, 613}}"; + sepNavSelRange = "{0, 0}"; + sepNavVisRect = "{{0, 0}, {711, 613}}"; + sepNavWindowFrame = "{{15, -1}, {750, 742}}"; + }; + }; + A251BE8C0959A1EA0058BC7F /* FakeModel.m */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {711, 1248}}"; + sepNavSelRange = "{0, 0}"; + sepNavVisRect = "{{0, 117}, {711, 613}}"; + sepNavWindowFrame = "{{15, -1}, {750, 742}}"; + }; + }; + A251BE9B0959A2530058BC7F /* ReadMe.rtfd */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {711, 3047}}"; + sepNavSelRange = "{0, 0}"; + sepNavVisRect = "{{0, 2419}, {711, 628}}"; + sepNavWindowFrame = "{{15, -1}, {750, 742}}"; + }; + }; + A2A711BD09E5BF0500D0089B /* WindowController.h */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {958, 944}}"; + sepNavSelRange = "{0, 0}"; + sepNavVisRect = "{{0, 197}, {711, 613}}"; + sepNavWindowFrame = "{{15, -1}, {750, 742}}"; + }; + }; + A2A711BE09E5BF0500D0089B /* WindowController.m */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {1399, 4496}}"; + sepNavSelRange = "{2008, 125}"; + sepNavVisRect = "{{0, 824}, {784, 608}}"; + sepNavWindowFrame = "{{15, 4}, {823, 737}}"; + }; + }; + A2D32EFF09A63D7A00EC8662 /* PSMMetalTabStyle.m */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {1728, 8400}}"; + sepNavSelRange = "{683, 5}"; + sepNavVisRect = "{{0, 0}, {781, 608}}"; + sepNavWindowFrame = "{{15, 4}, {820, 737}}"; + }; + }; +} diff --git a/PSMTabBarControl/PSMTabBarControlFramework-Info.plist b/PSMTabBarControl/PSMTabBarControlFramework-Info.plist new file mode 100644 index 0000000000..f7840b712b --- /dev/null +++ b/PSMTabBarControl/PSMTabBarControlFramework-Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + PSMTabBarControl + CFBundleIdentifier + com.positivespinmedia.PSMTabBarControlFramework + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + FMWK + CFBundleSignature + PSM1 + CFBundleVersion + 1.1 + NSPrincipalClass + PSMTabBarControl + + diff --git a/PSMTabBarControl/PSMTabBarControl_Prefix.pch b/PSMTabBarControl/PSMTabBarControl_Prefix.pch new file mode 100644 index 0000000000..65df9ffedb --- /dev/null +++ b/PSMTabBarControl/PSMTabBarControl_Prefix.pch @@ -0,0 +1,8 @@ +// +// Prefix header for all source files of the 'PSMTabBarControl' target in the 'PSMTabBarControl' project +// + +#ifdef __OBJC__ + #import + #import +#endif diff --git a/PSMTabBarControl/ReadMe.rtfd/TXT.rtf b/PSMTabBarControl/ReadMe.rtfd/TXT.rtf new file mode 100644 index 0000000000..acd9372a24 --- /dev/null +++ b/PSMTabBarControl/ReadMe.rtfd/TXT.rtf @@ -0,0 +1,186 @@ +{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf380 +{\fonttbl\f0\fswiss\fcharset77 Helvetica-Bold;\f1\fswiss\fcharset77 Helvetica;\f2\fswiss\fcharset77 Helvetica-Oblique; +\f3\fnil\fcharset77 Monaco;} +{\colortbl;\red255\green255\blue255;\red118\green15\blue80;\red0\green0\blue255;\red35\green110\blue37; +} +{\*\listtable{\list\listtemplateid1\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc2\leveljcn2\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{disc\}}{\leveltext\leveltemplateid0\'02\'05.;}{\levelnumbers\'01;}}{\listname ;}\listid1}} +{\*\listoverridetable{\listoverride\listid1\listoverridecount0\ls1}} +\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\qc\pardirnatural + +\f0\b\fs24 \cf0 \ +PSMTabBarControl (and related classes)\ + +\f1\b0 developed by John Pannell, Positive Spin Media\ +\ +as seen in the super-cool app...\ +\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\qc\pardirnatural +\cf0 {{\NeXTGraphic startpage.gif \width7200 \height2820 +}¬}\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\qc\pardirnatural +\cf0 \ +\ +\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural +\cf0 This source code and all related materials are released under the BSD license, which is explained at the end of this document, along with some other legalese. I've made my best effort to make everything bug free, but please let me know of any bugs found or suggestions you have: johnp@positivespinmedia.com.\ +\ + +\f0\b Purpose +\f1\b0 \ +\ +PSMTabBarControl seeks to provide developers with a high-quality, easy to use GUI to manage an NSTabView (or subclasses) in a manner similar to Safari's tabbed browsing implementation. It attempts to add a few features as well. Here's what you get:\ +\ + +\f0\b The look: +\f1\b0 a control/cell architecture that draws the expected tab appearance below a toolbar or similar view. Included styles work consistently in Aqua, Metal, or customized metal variations by basing fills on the window's background color. Includes drawing of a close button, and rollover states for the close button and tab cell. Also provides pop-up button and menu when tabs overflow available space, and support for individual tab progress indicators, icons, and object counters. Tabs can be drawn sized to fit the string content of the label, or uniformly sized.\ +\ + +\f0\b The functionality: +\f1\b0 Close button removes tabs, click on a tab cell selects. Indicators start, stop, and hide if things are hooked up correctly.\ +\ + +\f0\b Extras: +\f1\b0 Supports multi-window drag-and-drop reordering of the tabs with aqua-licious animation.\ +\ + +\f0\b Files +\f1\b0 \ +\ +Your project will need the files in the "Framework" folder of the project. The actual framework packages these (and some images) up nicely for you, if desired. Please look over the "TabBarControlDemo" target of the source code project to see exactly what is needed to get everything to build. Building and playing with the demo is also a good way to get a feel for the features provided by these classes.\ +\ + +\f0\b Usage +\f1\b0 \ +\ +Simply drag a custom view object from the views palette in IB, read the PSMTabBarControl class into IB, and set the view's custom class to PSMTabBarControl. Then connect the control's tabview outlet to the tab view being controlled, and make the control the delegate of the tab view. You can also connect the control's "partner view" outlet to another view that will resize in response to the hide/show behavior of the control.\ +\ +Alternately, you can build the Palette subproject and add the built IB palette to Interface Builder. In this case, creating and configuring an instance is as easy and drag, drop, and a few clicks. A demo movie and the built palette are available in a separate download from my website: http://www.positivespinmedia.com/dev/PSMTabBarControl.html\ +\ + +\f2\i Please read the PSMTabBarControlDoc.html file in the documentation folder of this project. It provides an Apple-ish page describing the interface and usage of this object. +\f1\i0 \ +\ + +\f0\b Patterns of Use +\f1\b0 \ +\ +There are a few random notes I can think of for usage guidelines...\ +\ +- You may see a line between the toolbar and the control in your app; it is part of the toolbar. In Tiger, you can eliminate the appearance of this line:\ +\ +\pard\tx960\tx1920\tx2880\tx3840\tx4800\tx5760\tx6720\tx7680\tx8640\tx9600\tx10560\tx11520\tx12480\tx13440\tx14400\tx15360\tx16320\tx17280\tx18240\tx19200\tx20160\tx21120\tx22080\tx23040\tx24000\tx24960\tx25920\tx26880\tx27840\tx28800\tx29760\tx30720\tx31680\tx32640\tx33600\tx34560\tx35520\tx36480\tx37440\tx38400\tx39360\tx40320\tx41280\tx42240\tx43200\tx44160\tx45120\tx46080\tx47040\tx48000\tx48960\tx49920\tx50880\tx51840\tx52800\tx53760\tx54720\tx55680\tx56640\tx57600\tx58560\tx59520\tx60480\tx61440\tx62400\tx63360\tx64320\tx65280\tx66240\tx67200\tx68160\tx69120\tx70080\tx71040\tx72000\tx72960\tx73920\tx74880\tx75840\tx76800\tx77760\tx78720\tx79680\tx80640\tx81600\tx82560\tx83520\tx84480\tx85440\tx86400\tx87360\tx88320\tx89280\tx90240\tx91200\tx92160\tx93120\tx94080\tx95040\tx96000\ql\qnatural\pardirnatural + +\f3\fs20 \cf0 \CocoaLigature0 SInt32 MacVersion;\ +\pard\tx960\tx1920\tx2880\tx3840\tx4800\tx5760\tx6720\tx7680\tx8640\tx9600\tx10560\tx11520\tx12480\tx13440\tx14400\tx15360\tx16320\tx17280\tx18240\tx19200\tx20160\tx21120\tx22080\tx23040\tx24000\tx24960\tx25920\tx26880\tx27840\tx28800\tx29760\tx30720\tx31680\tx32640\tx33600\tx34560\tx35520\tx36480\tx37440\tx38400\tx39360\tx40320\tx41280\tx42240\tx43200\tx44160\tx45120\tx46080\tx47040\tx48000\tx48960\tx49920\tx50880\tx51840\tx52800\tx53760\tx54720\tx55680\tx56640\tx57600\tx58560\tx59520\tx60480\tx61440\tx62400\tx63360\tx64320\tx65280\tx66240\tx67200\tx68160\tx69120\tx70080\tx71040\tx72000\tx72960\tx73920\tx74880\tx75840\tx76800\tx77760\tx78720\tx79680\tx80640\tx81600\tx82560\tx83520\tx84480\tx85440\tx86400\tx87360\tx88320\tx89280\tx90240\tx91200\tx92160\tx93120\tx94080\tx95040\tx96000\ql\qnatural\pardirnatural +\cf2 if\cf0 (Gestalt(gestaltSystemVersion, &MacVersion) == noErr)\{\ + \cf2 if\cf0 (MacVersion >= \cf3 0x1040\cf0 )\{\ + \cf4 // this call is Tiger only\cf0 \ + [toolbar setShowsBaselineSeparator:\cf2 NO\cf0 ];\ + \}\ +\}\ +\ +\pard\tx960\tx1920\tx2880\tx3840\tx4800\tx5760\tx6720\tx7680\tx8640\tx9600\tx10560\tx11520\tx12480\tx13440\tx14400\tx15360\tx16320\tx17280\tx18240\tx19200\tx20160\tx21120\tx22080\tx23040\tx24000\tx24960\tx25920\tx26880\tx27840\tx28800\tx29760\tx30720\tx31680\tx32640\tx33600\tx34560\tx35520\tx36480\tx37440\tx38400\tx39360\tx40320\tx41280\tx42240\tx43200\tx44160\tx45120\tx46080\tx47040\tx48000\tx48960\tx49920\tx50880\tx51840\tx52800\tx53760\tx54720\tx55680\tx56640\tx57600\tx58560\tx59520\tx60480\tx61440\tx62400\tx63360\tx64320\tx65280\tx66240\tx67200\tx68160\tx69120\tx70080\tx71040\tx72000\tx72960\tx73920\tx74880\tx75840\tx76800\tx77760\tx78720\tx79680\tx80640\tx81600\tx82560\tx83520\tx84480\tx85440\tx86400\tx87360\tx88320\tx89280\tx90240\tx91200\tx92160\tx93120\tx94080\tx95040\tx96000\ql\qnatural\pardirnatural + +\f1\fs24 \cf0 - In general, there is no reason for your app objects to communicate (outside of configuration) with the PSMTabBarControl at all. Changes made to the NSTabView instance programmatically should be directed at the NSTabView instance itself, and the control will update to reflect the changes made.\ +\ +- Your app might want to receive tab view delegate notifications in order to perform some actions. No problem, simply make the desired object the delegate of the PSMTabBarControl instance... it passes along all tab view notifications. Note that it uses these notifications to make changes itself - read the source code to make sure you aren't tripping over something.\ +\ +- The control creates bindings between each cell's progress indicator and the represented NSTabViewItem's identifier object, if it can. In my app design, I set an instance of NSObjectController as the NSTabViewItem's identifier, and then bind to the "isProcessing" key of the controller's content object. All of this can be seen in the source of the demo app...\ +\ +- The control can be set to hide itself when there is only a single tab, and can also be told to hide/show on demand. It can animate to appear and disappear, and will resize something to compensate for the missing window real estate. By default, it will resize the window, but you can also connect the "partnerView" outlet in IB to specify another view to resize to take up the missing space. Note that this takes some attention to sizing springs and wires to get right, and complex views may need a container view to achieve the desired effect.\ +\ +- The control can be configured to draw an attractive "Add Tab" button at the end of the tab cells. Unfortunately, the button is all looks and no brains - it has no idea what your app wants to do when adding a tab. If you configure your app to show the add tab button, you need to hook up the add tab button to the proper target with the proper selector. Something like this will do nicely in your app controller's awakeFromNib:\ +\ +\pard\tx960\tx1920\tx2880\tx3840\tx4800\tx5760\tx6720\tx7680\tx8640\tx9600\tx10560\tx11520\tx12480\tx13440\tx14400\tx15360\tx16320\tx17280\tx18240\tx19200\tx20160\tx21120\tx22080\tx23040\tx24000\tx24960\tx25920\tx26880\tx27840\tx28800\tx29760\tx30720\tx31680\tx32640\tx33600\tx34560\tx35520\tx36480\tx37440\tx38400\tx39360\tx40320\tx41280\tx42240\tx43200\tx44160\tx45120\tx46080\tx47040\tx48000\tx48960\tx49920\tx50880\tx51840\tx52800\tx53760\tx54720\tx55680\tx56640\tx57600\tx58560\tx59520\tx60480\tx61440\tx62400\tx63360\tx64320\tx65280\tx66240\tx67200\tx68160\tx69120\tx70080\tx71040\tx72000\tx72960\tx73920\tx74880\tx75840\tx76800\tx77760\tx78720\tx79680\tx80640\tx81600\tx82560\tx83520\tx84480\tx85440\tx86400\tx87360\tx88320\tx89280\tx90240\tx91200\tx92160\tx93120\tx94080\tx95040\tx96000\ql\qnatural\pardirnatural + +\f3\fs20 \cf4 // hook up add tab button\cf0 \ +[[tabBar addTabButton] setTarget:\cf2 self\cf0 ];\ +[[tabBar addTabButton] setAction:\cf2 @selector\cf0 (addNewTab:)]; +\f1\fs24 \ +\ +- The tabs have some sizing options: You can specify the minimum width, maximum width, and optimum width, as well as spcifying if the tabs should size to fit their label or not. The sizing bahavior of the tabs is as follows: If "size to fit" is specified, then tabs will be generated to fit the label, but will never exceed the specified max or min widths. Once the end of the control is reached, the overflow menu will appear as tabs are added; the last tab will squeeze in if it can, or the remaining tabs will stretch to occupy the full control. If "size to fit" is not specified, then all successive tabs will appear at the optimum width. Once the end of the control is reached, adding new tabs will cause all tabs to shrink to accomodate, until the minumum width is reached, and then the overflow menu will be used; max width is ignored in this case. Hopefully that all makes sense :-)\ +\ +- PSMTabBarControl will load the existing tabs from the tabView outlet at startup. However, many of the advanced features (icon display, progress indicator, object count) rely on binding to a controller that is likely not set up in IB. Solution? Nuke the existing tabs in the NSTabView and add new ones, configured the way you like. The demo app does this in the awakeFromNib: method of the app controller.\ +\ +- As a design choice, I elected to keep a cell object around until its tab was closed, instead of "churning" cell objects in each update cycle. Each cell keeps its NSTabViewItem as its representedObject and maintains reference that way, rather than by any index. As a result of this, drag-and-drop reordering of tabs does not change the underlying NSTabView instance at all. All that to say: don't rely on numerical indices if communicating with both the control and the tab view - the indices may not correlate if the user moved some tabs around (and remember - you shouldn't need to communicate with the control anyway :-). The Shiira Project, from which I gained much insight and inspiration from for this UI element, elected to scrap and rebuild the array of cells each time through the update cycle, and rely on indices to correlate between cells and NSTabViewItems. I felt the representedObject route was cleaner, and preferred not to churn objects.\ +\ +\pard\tx960\tx1920\tx2880\tx3840\tx4800\tx5760\tx6720\tx7680\tx8640\tx9600\tx10560\tx11520\tx12480\tx13440\tx14400\tx15360\tx16320\tx17280\tx18240\tx19200\tx20160\tx21120\tx22080\tx23040\tx24000\tx24960\tx25920\tx26880\tx27840\tx28800\tx29760\tx30720\tx31680\tx32640\tx33600\tx34560\tx35520\tx36480\tx37440\tx38400\tx39360\tx40320\tx41280\tx42240\tx43200\tx44160\tx45120\tx46080\tx47040\tx48000\tx48960\tx49920\tx50880\tx51840\tx52800\tx53760\tx54720\tx55680\tx56640\tx57600\tx58560\tx59520\tx60480\tx61440\tx62400\tx63360\tx64320\tx65280\tx66240\tx67200\tx68160\tx69120\tx70080\tx71040\tx72000\tx72960\tx73920\tx74880\tx75840\tx76800\tx77760\tx78720\tx79680\tx80640\tx81600\tx82560\tx83520\tx84480\tx85440\tx86400\tx87360\tx88320\tx89280\tx90240\tx91200\tx92160\tx93120\tx94080\tx95040\tx96000\ql\qnatural\pardirnatural + +\f0\b \cf0 Improvements? +\f1\b0 \ +\ +Pipe up if you think of something you'd like to see; here's my current list:\ +\ +- "Pop-up" tabs - like pop-up folders in the finder, in case you want to drag to a destination in another tab.\ +- Support for the +\f3\fs22 \CocoaLigature1 NSUnifiedTitleAndToolbarWindowMask +\f1\fs24 \CocoaLigature0 "unified" window appearance. (Help! I really searched around to try to make this work... the color pattern of the title and toolbar seem to be top secret! The new "unified" style is an excellent replication of a unified look, but isn't "built from" the unified appearance like the metal is.)\ +- During multi-window drag, having a "drag window/image" that shows the represented view getting moved to the other window.\ +- During multi-window drag, support for dragging out solo tabs to consolidate in another window, removing the source window in the process.\ +- Support vertical as well as horizontal alignment.\ +\ + +\f0\b Version History +\f1\b0 \ +\ +Version 1.3 (May 29, 2006)\ +- new feature: Unified tab style, compliments of Keith Blount\ +- new feature: allow multi-window drag config option (again from Keith).\ +- fixed bug: Palette installation/usage instructions were wrong.\ +- enhancement: exposed the +\f3\fs20 representedTabViewItems +\f1\fs24 method, which can be used to retrieve the order of the tabs as displayed in the control, since the underlying NSTabView does not get reordered during drag and drop rearrangement.\ +\ +Version 1.2 (April 20, 2006)\ +- new feature: multi-window drag and drop support.\ +- bug fixed: zombie issue with tabView:didCloseTabViewItem\ +- bugs fixed: some drawing issues around the progress indicators in tabs, and the add tab button.\ +- enhancement: the hide/show animation has been improved with less "flickering" of progress indicators during the hide and show.\ +\ +Version 1.1.2 (April 5, 2006)\ +- fixed bug: tabs of non-integer width resulted in occasional anti-aliased drawing issues of dividers between tabs in the Metal style (Thanks, Kent).\ +- added feature: delegate can now respond to -tabView:shouldCloseTabViewItem: and -tabView:willCloseTabViewItem:, and -tabView:didCloseTabViewItem: messages, so your app can take care of any needed setup/cleanup for these actions.\ +- fixed bug: tab close buttons now show down state when pressed down.\ +\ +Version 1.1.1 (March 16, 2006)\ +- fixed bug: Palette inspector would not reflect state of previously instantiated control. This has been fixed (Thanks, Guillaume).\ +- enhancement: Overflow button now highlights when mouse down (Thanks, Kent).\ +- fixed bug: when set to not close a solo tab, the close button would be hidden for the tab, but could still be closed if you clicked the tab in the right location. This has been fixed (Thanks, malcom).\ +\ +Version 1.1 (March 10, 2006)\ +- Bound the "title" of the cell to the "label" of the source tabview item. Just in case you wanted to change the label on the tab during the running of your application.\ +- PSMTabBarCell factored to support new tab "styles", or appearances in drawing. Now supported are the existing "Metal" style and a new "Aqua" style. Many thanks to David Smith, Seth Willits, and Chris Forsythe for their contributions!\ +- Control can be configured to "Hide for single tab", so it doesn't appear unless there are more than a single tab view present. Features animated show/hide behavior (that can be called anytime, and is called automatically in the case that a single tab exists). The show/hide behavior can also be set up to resize either the window (default) or a selected "partner view" to compensate for the lost height of the tab bar.\ +- Control can be configured for "Can close only tab" behavior. If set to NO, no close button will appear on a lone tab.\ +- Cells can be set to "size to fit", or given uniform min/max/optimum sizes.\ +- Added support for display of an icon and an object count, if the proper app design pattern is followed.\ +- Sweet animated drag-and-drop drawing!\ +- A few drawing bugs surrounding the progress indicators in cells were squished.\ +- New documentation, in case you found this read me a little pithy.\ +\ +Version 1.0 (December 2005)\ +Initial release of safari-like tab implementation.\ +\ + +\f0\b The standard disavowal of this beautiful mess +\f1\b0 \ +\ +I should note that portions of this source code were inspired by the Shiira project's implementation of Safari-style tabs. While I made some different design decisions, the drawing and some other aspects are only slight modifications of their excellent work. As such, I note their copyright under their BSD licence:\ +\ +\pard\tx960\tx1920\tx2880\tx3840\tx4800\tx5760\tx6720\tx7680\tx8640\tx9600\tx10560\tx11520\tx12480\tx13440\tx14400\tx15360\tx16320\tx17280\tx18240\tx19200\tx20160\tx21120\tx22080\tx23040\tx24000\tx24960\tx25920\tx26880\tx27840\tx28800\tx29760\tx30720\tx31680\tx32640\tx33600\tx34560\tx35520\tx36480\tx37440\tx38400\tx39360\tx40320\tx41280\tx42240\tx43200\tx44160\tx45120\tx46080\tx47040\tx48000\tx48960\tx49920\tx50880\tx51840\tx52800\tx53760\tx54720\tx55680\tx56640\tx57600\tx58560\tx59520\tx60480\tx61440\tx62400\tx63360\tx64320\tx65280\tx66240\tx67200\tx68160\tx69120\tx70080\tx71040\tx72000\tx72960\tx73920\tx74880\tx75840\tx76800\tx77760\tx78720\tx79680\tx80640\tx81600\tx82560\tx83520\tx84480\tx85440\tx86400\tx87360\tx88320\tx89280\tx90240\tx91200\tx92160\tx93120\tx94080\tx95040\tx96000\ql\qnatural\pardirnatural + +\f3\fs20 \cf4 Portions of this software Copyright 2004 The Shiira Project. All rights reserved.\ +\pard\tx960\tx1920\tx2880\tx3840\tx4800\tx5760\tx6720\tx7680\tx8640\tx9600\tx10560\tx11520\tx12480\tx13440\tx14400\tx15360\tx16320\tx17280\tx18240\tx19200\tx20160\tx21120\tx22080\tx23040\tx24000\tx24960\tx25920\tx26880\tx27840\tx28800\tx29760\tx30720\tx31680\tx32640\tx33600\tx34560\tx35520\tx36480\tx37440\tx38400\tx39360\tx40320\tx41280\tx42240\tx43200\tx44160\tx45120\tx46080\tx47040\tx48000\tx48960\tx49920\tx50880\tx51840\tx52800\tx53760\tx54720\tx55680\tx56640\tx57600\tx58560\tx59520\tx60480\tx61440\tx62400\tx63360\tx64320\tx65280\tx66240\tx67200\tx68160\tx69120\tx70080\tx71040\tx72000\tx72960\tx73920\tx74880\tx75840\tx76800\tx77760\tx78720\tx79680\tx80640\tx81600\tx82560\tx83520\tx84480\tx85440\tx86400\tx87360\tx88320\tx89280\tx90240\tx91200\tx92160\tx93120\tx94080\tx95040\tx96000\ql\qnatural\pardirnatural + +\f1\fs24 \cf0 Check them out at: http://hmdt-web.net/shiira/\ +\ +This source code is provided under BSD license, the conditions of which are listed below. I hope you'll make note somewhere in your about window or ReadMe stating the sweet coding goodness of Positive Spin Media and link to the fascinating and informative website at www.positivespinmedia.com\ +\ +\pard\pardeftab720\sa320\ql\qnatural +\cf0 \CocoaLigature1 Copyright (c) 2005, Positive Spin Media\uc0\u8232 All rights reserved.\ +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:\ +\pard\tx220\tx720\pardeftab720\li720\fi-720\ql\qnatural +\ls1\ilvl0\cf0 {\listtext \'a5 }Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.\ +{\listtext \'a5 }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.\ +{\listtext \'a5 }Neither the name of Positive Spin Media nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.\ + \ +\pard\pardeftab720\sa320\ql\qnatural +\cf0 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 OWNER 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.\CocoaLigature0 \ +} \ No newline at end of file diff --git a/PSMTabBarControl/ReadMe.rtfd/startpage.gif b/PSMTabBarControl/ReadMe.rtfd/startpage.gif new file mode 100644 index 0000000000000000000000000000000000000000..8707a77ab0af2648e9e13dd44e44982eaee9c85a GIT binary patch literal 11246 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 N{Tml;OacJC{{wL3HY@-D literal 0 HcmV?d00001 diff --git a/PSMTabBarControl/TabBarControlDemo-Info.plist b/PSMTabBarControl/TabBarControlDemo-Info.plist new file mode 100644 index 0000000000..673218b406 --- /dev/null +++ b/PSMTabBarControl/TabBarControlDemo-Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + com.positivespinmedia.TabBarControlDemo + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 1.1 + NSMainNibFile + MainMenu + NSPrincipalClass + NSApplication + + diff --git a/PSMTabBarControl/documentation/PSMTabBarControlDoc.html b/PSMTabBarControl/documentation/PSMTabBarControlDoc.html new file mode 100644 index 0000000000..fa8b99009a --- /dev/null +++ b/PSMTabBarControl/documentation/PSMTabBarControlDoc.html @@ -0,0 +1,301 @@ + + + + + PSMTabBarControl - Safari-style Tabs (Objective-C) + + + + + + + + +

PSMTabBarControl

+ + + +
Inherits from
Conforms to
Declared in
PSMTabBarControl.h
+

Class Description

+ +

PSMTabBarControl provides a user interface for the management of tabbed views that has an appearance similar to Apple's Safari web browser.

+

Internally, PSMTabBarControl uses a custom cell class and supporting style objects to implement its user interface.

+

Currently, this object supports "Aqua" and "Metal" tab styles to present an appearance consistent with the rest of your application. Numerous configuration options exist to customize behavior, as outlined below. PSMTabBarControl instances require a few specific connections with other application objects to perform properly at runtime:

+
    +
  • The control's "tabView" outlet must be connected to the desired NSTabView instance in Interface Builder, or set programmatically with the setTabView: method.
  • +
  • The "delegate" outlet of the NSTabView being controlled must be connected to the instance of PSMTabBarControl, either programmatically or in IB.
  • +
  • Optionally, you may connect the control's "partnerView" outlet to a view that will be resized to compensate when PSMTabBarControl changes size due to hide/show behavior. If no connection is made, PSMTabBarControl will resize the window in response to hide/show messages.
  • +
+

A PSMTabBarControl instance should occupy the width of the window, and should be precisely 22 pixels in height. It should be resizable in width, but not height. It can be placed at the top or botton of the window (or anywhere in between, if desired).

+

Outside of configuring it, your application should have little interaction with this class. The presented tabs will change in conjunction with changes your application makes in the NSTabView being controlled.

+ +

A Usage Pattern

+ +

PSMTabBarControl becomes even more powerful if your application design matches an expected pattern: the control attempts to bind a number of tab attributes to the NSTabViewItem's identifier object if possible. These visible attributes include a progress indicator, an icon, and an object counter. Additionally, the control binds each tab's title to the label of the represented NSTabViewItem.

+ +

Taking advantage of these features requires no glue code on your part, but it does require providing a particular object graph. Here's the basics...

+ +
  • For each tab that is created, your application should have a model object that keeps the state of model attributes: isProcessing (a BOOL), objectCount (an int), and icon (an NSImage). You can pick and choose any number of these to support, or none, at your option. +
  • Your application should create an NSObjectController to control your model (the model object is the "content" of the NSObjectController instance). +
  • When you create new tabs (via the NSTabView interface), you should set the object controller instance to be the identifier object of the newly created NSTabViewItem object.
+ +

The demo application included with this project illustrates a very quick way to accomplish these goals. If this pattern is followed, PSMTabBarControl will take care of the rest.

+ + +

Methods by Task

+

Setting needed connections

+
– setTabView:

Specifies the instance of NSTabView to be controlled.

+ +
– tabView

Returns the instance of NSTabView being controlled.

+ +

Setting optional connections

+
– setPartnerView:

Specifies a view that will resize to compensate for control size changes in response to hide and show messages.

+ +
– partnerView

Returns the instance of a view that will resize to compensate for control size changes in response to hide and show messages.

+ +
– setDelegate:

Specifies an object that will receive delegate messages as passed through from the NSTabView instance.

+ +
– delegate:

Returns the specified delegate object.

+ +

Control configuration

+
– canCloseOnlyTab

Returns YES if the user is allowed to close a tab when it is the only tab left, NO otherwise.

+ +
– setCanCloseOnlyTab:

Controls whether the receiver will present a close button for a single tab in a tab bar.

+ +
– styleName

Returns the name of the current drawing style. "Aqua", "Metal", and "Unified" are the currently supported options.

+ +
– setStyleNamed:

Specifies the style in which the tabs and control are drawn. "Aqua", "Metal", and "Unified" are the currently supported options.

+ +
– hideForSingleTab

Returns YES if the control will hide if there is only one tab left, NO otherwise.

+ +
– setHideForSingleTab:

Controls whether the receiver will hide when the user closes all but a single tab in a tab bar.

+ +
– showAddTabButton

Returns YES if the control will display a small "add tab" button at the rightmost end of the tabs, NO otherwise.

+ +
– setShowAddTabButton:

Controls whether the receiver will will display a small "add tab" button at the rightmost end of the tabs.

+ +
– cellMinWidth

Returns the minimum width (in pixels) that a tab will be allowed to occupy.

+ +
– setCellMinWidth:

Specifies the maximum width (in pixels) that a tab will be allowed to occupy.

+ +
– cellMaxWidth

Returns the maximum width (in pixels) that a tab will be allowed to occupy.

+ +
– setCellMaxWidth:

Specifies the maximum width (in pixels) that a tab will be allowed to occupy.

+ +
– cellOptimumWidth

Returns the default width (in pixels) that a tab will be allowed to occupy when tabs are drawn with uniform size.

+ +
– setCellMaxWidth:

Specifies the default width (in pixels) that a tab will be allowed to occupy when tabs are drawn with uniform size.

+ +
– sizeCellsToFit

Returns YES if the control will make the tabs sized to fit the content of the tab, NO otherwise.

+ +
– setSizeCellsToFit:

Controls whether the receiver will make the tabs sized to fit the content of the tab.

+ +
– allowsDragBetweenWindows

Returns YES if the control allows a user to drag a tab to another instance of this control, NO otherwise.

+ +
– setAllowsDragBetweenWindows:

Controls whether the receiver will allow a user to drag a tab to another instance of this control.

+ +

Internal UI components

+
– addTabButton

Returns an instance of an NSButton subclass that is used to present the "add tab" button. If "showAddTabButton" is YES, developers must use this method to access the button and specify a target and action for the button.

+ +
– overflowPopUpButton

Returns an instance of an NSPopUpButton subclass that is used to present the overflow menu (which shows when there are more tabs than can fit across the control).

+ +
– representedTabViewItems

Returns an array of the NSTabViewItems represented by the tabs in the control. Useful if you want to archive the order of the tabs between runs of your program.

+ +

Visibility

+
– hideTabBar:animate:

If desired, obejcts can tell the tab bar to hide (reduce in size to a single pixel line spanning the window) or show, and optionally whether to animate this effect or not.

+ +

Instance Methods

+ +

addTabButton

+

Returns an instance of an NSButton subclass that is used to present the "add tab" button. If "showAddTabButton" is YES, developers must use this method to access the button and specify a target and action for the button.

- (PSMRolloverButton *)addTabButton;

+
Discussion

If you have configured the control to show the add tab button, you must use this method to access the button and set the target and action for it. Example:

[[tabBar addTabButton] setTarget:self];
+[[tabBar addTabButton] setAction:@selector(addNewTab:)];

+
See Also
+ +

allowsDragBetweenWindows

+

Returns YES if the control allows a user to drag a tab to another instance of this control, NO otherwise.

- (BOOL)allowsDragBetweenWindows

+
Discussion

The default is YES.

+
See Also
+ +

canCloseOnlyTab

+

Returns YES if the receiver has been configured to allow users to close a single remaining tab.

- (BOOL)canCloseOnlyTab

+
Discussion

The default is NO.

+
See Also
+ +

cellMaxWidth

+

Returns the maximum width (in pixels) that a tab will be allowed to occupy.

- (int)cellMaxWidth

+
Discussion

The cellMaxWidth value applies to both uniformly sized tabs, and tabs that are sized to fit. No tab will be drawn wider than the specified value.

+
See Also
+ +

cellMinWidth

+

Returns the minimum width (in pixels) that a tab will be allowed to occupy.

- (int)cellMinWidth

+
Discussion

The cellMinWidth value applies only to uniformly sized tabs. No tab will be drawn smaller than the specified value. Size-to-fit tabs ignore this value, and are made just small enough to fit their content.

+
See Also
+ +

cellOptimumWidth

+

Returns the width (in pixels) that a tab will be made to occupy if the tabs are uniformly sized.

- (int)cellOptimumWidth

+
Discussion

The cellOptimumWidth value applies only to uniformly sized tabs. All tabs will be drawn at the specified value. Size-to-fit tabs ignore this value, and are made just small enough to fit their content.

+
See Also
+ +

delegate

+

Returns the object that will be sent passed-through NSTabView delegate messages.

- (id)delegate

+
See Also
+ +

hideForSingleTab

+

Returns YES if the receiver has been configured to hide if there is a single remaining tab.

- (BOOL)hideForSingleTab

+
Discussion

The default is NO.

+
See Also
+ +

hideTabBar:animate:

+

If desired, obejcts can tell the tab bar to hide (reduce in size to a single pixel line spanning the window) or show, and optionally whether to animate this effect or not.

- (void)hideTabBar:(BOOL)hide animate:(BOOL)animate

+
Discussion

If hide is YES the control will shrink to a single pixel line spanning the window; otherwise the control will expand to its normal appearance. If animate is YES, the shrinking and expanding will happen in a visible animation; otherwise the transition will be instant. There is no effect if the control is already in the specified state.

+ +

overflowPopUpButton

+

Returns an instance of an NSPopUpButton subclass that is used to present the overflow menu.

- (PSMOverflowPopUpButton *)overflowPopUpButton;

+
Discussion

This method could be used to modify the button or menu if desired.

+ +

partnerView

+

Returns the object that will be resized to compensate for the changing size of the control during hide/show behavior.

- (id)partnerView

+
Discussion

If a partnerView has not been specified, the window will be resized during hide/show.

+
See Also
+ +

representedTabViewItems

+

Returns an array of NSTabViewItems, ordered according to the display order of the tabs in the control.

- (NSMutableArray *)representedTabViewItems;

+
Discussion

This method could be used archive the order of the tabs between application runs. When the user reorders tabs via drag and drop, the represented NSTabView does not change order.

+ +

setAllowsDragBetweenWindows

+

If set to YES, the receiver is configured to allow users to drag a tab to an instance of PSMTabBarControl in another window.

- (void)setAllowsDragBetweenWindows:(BOOL)value

+
Discussion

The default is YES.

+
See Also
+ +

setCanCloseOnlyTab:

+

If set to YES, the receiver is configured to allow users to close a single remaining tab.

- (void)setCanCloseOnlyTab:(BOOL)value

+
Discussion

The default is NO.

+
See Also
+ +

setCellMaxWidth:

+

Specifies the maximum width (in pixels) that a tab will be allowed to occupy.

- (void)setCellMaxWidth:(int)value

+
Discussion

No tab will be drawn any wider than the specified value.

+
See Also
+ +

setCellMinWidth:

+

Specifies the minimum width (in pixels) that a tab will be allowed to occupy.

- (void)setCellMinWidth:(int)value

+
Discussion

No tab will be drawn any smaller than the specified value. This value is ignored when drawing in size-to-fit; tabs are made just small enough to fit their content.

+
See Also
+ +

setCellOptimumWidth:

+

Specifies the width (in pixels) that a tab will occupy when tabs are uniformly sized.

- (void)setCellOptimumWidth:(int)value

+
Discussion

This value is ignored when drawing in size-to-fit; tabs are made just small enough to fit their content.

+
See Also
+ +

setDelegate:

+

Specifies an object that will receive delegate messages as passed through from the NSTabView instance.

- (void)setDelegate:(id)object

+
See Also
+ +

setHideForSingleTab:

+

If set to YES, the receiver is configured to hide when there is a single remaining tab.

- (void)setHideForSingleTab:(BOOL)value

+
Discussion

The default is NO.

+
See Also
+ +

setPartnerView:

+

Specifies a view that will resize to compensate for control size changes in response to hide and show messages.

- (void)setPartnerView:(id)view

+
Discussion

if nil, the control will resize the window in response to hide/show messages.

+
See Also
+ +

setStyleNamed:

+

Specifies the style in which the tabs and control are drawn.

- (void)setStyleNamed:(NSString *)name

+
Discussion

"Aqua" and "Metal" are the currently supported options.

+
See Also
+ +

setShowAddTabButton:

+

Controls whether the receiver will will display a small "add tab" button at the rightmost end of the tabs.

- (void)setShowAddTabButton:(BOOL)value

+
Discussion

Default is NO.

+
See Also
+ +

setSizeCellsToFit:

+

Controls whether the receiver will make the tabs sized to fit the content of the tab.

- (void)setSizeCellsToFit:(BOOL)value

+
Discussion

Default is NO.

+
See Also
+ +

setTabView:

+

Specifies the instance of NSTabView to be controlled.

- (void)setTabView:(NSTabView *)view

+
Discussion

This class will not function properly without this outlet being set.

+
See Also
+ +

sizeCellsToFit

+

Returns YES if the control will make the tabs sized to fit the content of the tab, NO otherwise.

+

Discussion

The default is NO.

+
See Also
+ +

styleName:

+

Returns the name of the current drawing style.

- (NSString *)styleName

+
Discussion

"Aqua" and "Metal" are the currently supported options.

+
See Also
+ +

tabView:

+

Returns the instance of NSTabView being controlled.

- (NSTabView *)tabView

+
Discussion

This class will not function properly if this object is nil.

+
See Also
+ +

Delegate Methods

+ +

You application controller can keep track of activity from the tab view and the user via the following delegate methods.

+ +

tabView:shouldCloseTabViewItem:

+

Sent when a user clicks the close button on a tab.

- (BOOL)tabView:(NSTabView *)tabView shouldCloseTabViewItem:(NSTabViewItem *)tabViewItem

+
Discussion

If you return NO, the tab will not be closed. Please make sure to alert the user as to why with a sheet or dialog.

+ +

tabView:willCloseTabViewItem:

+

Sent when tab is about to be closed.

- (void)tabView:(NSTabView *)tabView willCloseTabViewItem:(NSTabViewItem *)tabViewItem

+
Discussion

This presents you with an opportunity to clean up the application objects/events/sessions represented by the tab.

+ +

tabView:didCloseTabViewItem:

+

Sent after a tab has been closed.

- (void)tabView:(NSTabView *)tabView didCloseTabViewItem:(NSTabViewItem *)tabViewItem

+
Discussion

This presents you with an opportunity to clean up the application objects/events/sessions represented by the tab. Don't go trying to modify the tabViewItem - it is about to be released, and has already been removed from the tabView!

+ +

tabView:didSelectTabViewItem:

+

Informs the delegate that tabView has selected tabViewItem.

- (void)tabView:(NSTabView *)tabView didSelectTabViewItem:(NSTabViewItem *)tabViewItem

+ +

tabView:shouldSelectTabViewItem:

+

Invoked just before tabViewItem in tabView is selected.

- (BOOL)tabView:(NSTabView *)tabView shouldSelectTabViewItem:(NSTabViewItem *)tabViewItem

+
Discussion

The delegate can return NO to prevent selection of specific tabs.

+ +

tabView:willSelectTabViewItem:

+

Informs the delegate that tabView is about to select tabViewItem.

- (void)tabView:(NSTabView *)tabView willSelectTabViewItem:(NSTabViewItem *)tabViewItem

+ +

tabViewDidChangeNumberOfTabViewItems:

+

Informs the delegate that the number of tab view items in tabView has changed.

- (void)tabViewDidChangeNumberOfTabViewItems:(NSTabView *)tabView

+ + + + + + \ No newline at end of file diff --git a/PSMTabBarControl/documentation/frameset_styles.css b/PSMTabBarControl/documentation/frameset_styles.css new file mode 100644 index 0000000000..298e192a89 --- /dev/null +++ b/PSMTabBarControl/documentation/frameset_styles.css @@ -0,0 +1,943 @@ +/* link classes */ +A:link { COLOR: #0000FF; TEXT-DECORATION: none; } +A:link:hover { COLOR: #FF6600; TEXT-DECORATION: underline; } +A:active { COLOR: #FF6600; TEXT-DECORATION: underline; } + +/* apple.com site does not explicitly define visited link properties, but we do here */ +A:visited { COLOR: #0000AA; TEXT-DECORATION: none; } +A:visited:hover { COLOR: #FF6600; TEXT-DECORATION: underline; } + +/* used to convert otherCodeCharacters to code, thus saving character space in HTML for smaller file sizes */ +tt { + FONT-SIZE: 11px; FONT-FAMILY: monaco, courier, monospace; } + +/* redefine preformated text and code blocks */ +PRE { + FONT-SIZE: 11px; FONT-FAMILY: monaco, courier, monospace; margin-top: 5px; margin-bottom: 10px;} +CODE { + FONT-SIZE: 11px; FONT-FAMILY: monaco, courier, monospace; } + + +/* JavaScript toc frame */ +.jtoc_closed { background-color: #e9e9e9; } +.jtoc_open { background-color: #FFFFFF; padding-bottom: 10px; } +.jtoc_open_top_line {border-top: 1px solid #CCC; background-color: #fff; padding-bottom: 10px;} +.jtoc_open_bottom_line {border-bottom: 1px solid #CCC; background-color: #fff; padding-bottom: 10px;} +.jtoc_open_both_lines {border-bottom: 1px solid #CCC; border-top: 1px solid #CCC; background-color: #fff; padding-bottom: 10px;} + +/* frameset: toc frame */ +.toc_contents_text { + font-family: lucida grande, geneva, helvetica, arial, sans-serif; font-size: 12px; font-weight: bold; padding-top: 4px 0; + color: #0000FF; +} +.toc_contents_text_open { + font-family: lucida grande, geneva, helvetica, arial, sans-serif; font-size: 12px; + background: #FFFFFF; color: #0000FF; +} +.low_level_text { + font-family: lucida grande, geneva, helvetica, arial, sans-serif; font-size: 11px; padding: 4px 5px 4px 5px + color: #0000FF; +} + +#toc_contents_title { + font-family: lucida grande, geneva, helvetica, arial, sans-serif; font-size: 16px; color: #FFFFFF; font-weight: bold; +} +.toc_contents_heading { + font-family: lucida grande, geneva, helvetica, arial, sans-serif; font-size: 12px; font-weight: bold; +} + +/* Special TOC heading for Help books only */ +.toc_contents_help_heading { + font-family: lucida grande, geneva, helvetica, arial, sans-serif; font-size: 14px; color: #330099; font-weight: bold; +} + +/* frameset: toc frame styles WEB AS. used for any document that uses the disclosure model for TOC like conceptural and procedural C documents*/ +#toc { + padding: 0 0 0 0; +} + +#toc p.download { + padding: 5px 10px; + margin: 0; + font-weight: normal; font-size: 11px; +} + +#toc_PDFbottomborder { + padding-top: 5px; + border-bottom: 1px solid #CCC; +} + + +#toc h2 { + margin: 0; + padding: 10px; + font-size: 15px; font-weight: bold; + border-bottom: 0px solid; +} + +#toc h3 { + margin: 6px 5px 0 10px; + font-size: 13px; font-weight: bold; color: black; +} + +#toc h4 { + font-size: 11px; font-weight: bold; color: black; + margin: -5px 0px 0 14px; +} + +#toc_staticbox { + padding: 0 0 0 0; + border: 1px solid #919699; + background: #e9e9e9; +} + +#toc ul { + list-style: none outside; + margin-left: 20px; margin-bottom: -2px; + padding: 0px; +} + +#toc ul ul{ + list-style: none outside; + margin-left: 10px; margin-bottom: -2px; + padding: 0px; +} + +#toc li a { + margin-left: 5px; + display: block; + padding: 0px 5px 0px 5px; +} + +#toc li a.location { + font-weight: bold; color: #000; + text-decoration: none; +} + +#toc li{ + font-weight: normal; font-size: 11px; + padding: 0px 5px 0px 0px; + list-style-type: none; background: url(../Images/bullet.gif) no-repeat 0px .5em; + } + +#toc li li a { + margin-left: 0px; +} + + +#toc ul ul li { + background: url(../Images/dash.gif) no-repeat 0px .6em; +} + +#toc ul ul ul li { + background: url(../Images/sm_bullet.gif) no-repeat 0px .5em; +} + +#toc li.open { + border-top: 1px solid #CCC; border-bottom: 1px solid #CCC; background-color: #fff; +} + +#toc .open ul { + background-color: #fff; +} + +li img { + margin-left: 0px; +} +/*#toc li.open { background: #FFF;}*/ + + +/* frameset: toc frame styles WEB AS. used for any document that uses the static model for TOC topics documents*/ + +#topicstoc { + padding: 0px 0px 0px; +} + + +#topicstoc p.download { + border-bottom: 1px solid #CCC; + padding: 5px 10px; + margin: 0px; + font-weight: normal; font-size: 11px; +} + +#topicstoc h2 { + margin: 0; + padding: 10px; + font-size: 15px; font-weight: bold; + border-bottom: 0px solid; +} + +#topicstoc h3 { + margin: 6px 5px 0 10px; + font-size: 13px; font-weight: bold; color: black; +} + +#topicstoc h4 { + font-size: 11px; font-weight: bold; color: black; + margin: 2px 0px 0px 14px; +} + +#topicstoc ul { + list-style: none outside; + margin-left: 13px; margin-bottom: -2px; + padding: 0px; +} + + +#topicstoc ul ul{ + list-style: none outside; + margin-left: 10px; margin-bottom: -2px; + padding: 0px; +} + +#topicstoc li{ + font-weight: normal; font-size: 12px; + padding: 0px 5px 2px 10px; + list-style-type: none; background: url(../Images/bullet.gif) no-repeat 0px .5em; +} + +#topicstoc li.intro { + font-weight: normal; + padding: 0px 0px; + list-style-type: none; background: none; +} + +#topicstoc li a { + display: block; + padding: 0px 5px 0px 0px; +} + +#topicstoc li a.location { + font-weight: bold; color: #000; + text-decoration: none; +} + +#topicstoc li.intro a { + margin-left: -5px; + display: block; +} + + +img.toplevel { float: left; } + + + +/* frameset: content frame */ +BODY { + margin-top: 0; + color: #000; + font: 12px lucida grande, geneva, helvetica, arial, sans-serif; + } + +/* frameset: H1,H2,H3,H4,H5,Head for code voice */ + +h1 { + margin-top: 1em; + margin-bottom: 25px; + font: bold 30px lucida grande, geneva, helvetica, arial, sans-serif; + color: #000; + } +h2 { + margin-top: 2.5em; + font-size: 24px; + color: #000; + padding-bottom: 2px; border-bottom: 1px solid black; + } +h3 { + margin-top: 2em; + margin-bottom: .5em; + font-size: 19px; + color: #000; + } +h3.tight { + margin-top: 3em; + margin-bottom: -.25em; + font-size: 19px; + color: #000; + } +h4 { + margin-top: 2em; + margin-bottom: .5em; + font-size: 15px; + color: #000; + } +h5 { + margin: 20 0 0 0; + padding: 0; + font-size: 13px; + color: #000; + } +.mach4{ + margin-top: 40; + margin-bottom: 0; + padding-top: 0; + font: bold 16px lucida grande, geneva, helvetica, arial, sans-serif; + color: #000; + } +.mach5{ + margin: 30 0 -9 0; + font: bold 13px lucida grande, geneva, helvetica, arial, sans-serif; + color: #000; + } +h5.tight{ + margin: 1.5em 0 2px 0; + font: bold 13px lucida grande, geneva, helvetica, arial, sans-serif; + color: #000; + } + + +.code_head{ + FONT-SIZE: 18px; FONT-FAMILY: monaco, courier, monospace; font-weight: bold; +} +p { + margin-top: 0px; margin-bottom: 10px; font: 12px lucida grande, geneva, helvetica, arial, sans-serif; + } +p.spaceabove { + margin-top: 13px; margin-bottom: 10px; font: 12px lucida grande, geneva, helvetica, arial, sans-serif; + } +p.spaceabovemethod { + font: 11px monaco, courier, monospace; margin-top: 13px; margin-bottom: 10px; +} +h3.tight + p { + margin-top: 13px; margin-bottom: 10px; font: 12px lucida grande, geneva, helvetica, arial, sans-serif; + } +h3.tight + p.spaceabovemethod { + font: 11px monaco, courier, monospace; margin-top: 13px; margin-bottom: 10px; +} +.content_text{ + margin-top: 0px; margin-bottom: 10px; font: 12px lucida grande, geneva, helvetica, arial, sans-serif; +} +p.blockquote{ + padding-left: 50pt; + padding-right: 50pt; + } +ul.availability { + list-style-type: none; + margin: 0 0 -10px 0; + } +.availability li { + margin: 2px 0 0 -6px; + } + +/* frameset: content frame bold style for text*/ +b{ + font-family: lucida grande, geneva, helvetica, arial, sans-serif; font-size: 12px; font-weight: bold; +} + +/* Used for text that is sligtly larger than bold text like lables and captions*/ +.content_text_label{ + font-family: lucida grande, geneva, helvetica, arial, sans-serif; font-size: 12px; +} + +/* frameset: content frame italic style for text*/ +i{ + font-family: lucida grande, geneva, helvetica, arial, sans-serif; font-size: 12px; font-style: italic; +} + +/* Used for reference heads in ProcedualC and AppleScript Language*/ +.content_ref_head{ + font-family: lucida grande, geneva, helvetica, arial, sans-serif; + font-size: 16px; font-weight: bold; margin-top: 50px; padding-bottom: 4px; border-bottom: 1px solid black + } + +.content_ref_head_code{ + font-family: monaco, courier, monospace; + font-size: 16px; font-weight: bold; margin-top: 50px; padding-bottom: 4px; border-bottom: 1px solid black + } + +/* frameset: page title */ +.page_title{ + font-family: lucida grande, geneva, helvetica, arial, sans-serif; + font-size: 34px; + font-weight: bold; + color: #000000; + padding-top: 10px; + } + +/* frameset: Unordered List */ + +ul.spaceabove { + list-style: square outside; + margin: 0 0 0 30px; + padding: 7 0 12px 6px; + } + +ul { + list-style: square outside; + margin: 0 0 0 30px; + padding: 0 0 12px 6px; + } + +li { + margin-top: 7px; + } + + +li p { + margin-top: 8px; + } + +ul ul { + list-style: circle outside; + margin: 6 0 0 30px; + padding: 0 0 12px 6px; + } +ul.3head { + list-style: square outside; + margin: 0 0 0 20px; + padding: 0 0 0px 0px; + } + + +/* alternate mappings for 2nd level bulleted list that are still in testing phase*/ +.nested li { + list-style-image: url(../Images/openbullet.gif); + list-style-position: outside; + } + +ul.nested { + list-style: none; + margin: 6 0 0 30px; + } + +ol { + list-style-type: decimal; + list-style-position: outside; + margin: 0 0 0 30px; + padding: 0 0 12px 6px; + } + +ol ol { + list-style-type: lower-alpha; + list-style-position: outside; + margin: 7 0 0 30px; + padding: 0 0 12px 10px; + } + +ul.simple-spaceabove { + list-style-type: none; + margin: 5 0 0 20px; + } +.simple-spaceabove li { + margin-top: 1px; + } + +ul.simple { + list-style-type: none; + margin: 0 0 0 30px; + } +.simple li { + margin-top: -1px; + } + +dl.table-display { + clear: both; + width: auto; + margin: 0; + padding: 0px; + } + +.table-display dt { + width: 8em; + float: left; + margin: 0 0 0 0; + padding: .1em; + } + +/* commented backslash hack for mac-ie5 \*/ +dt { clear: both; } + + +.table-display dd { + float: left; + width: 80%; + margin: 0 0 0 0; + padding: .1em; + display: block; + } + +.clear { + clear: both; + } +dl.termdef { + margin-top: 0px; + margin-bottom: 10px; } +.termdef dt { + margin-top: 0px; } +.termdef dd { + margin-left: 15px; + margin-top: 1px; + margin-bottom: 6px; } +.termdef p{ + margin-left: 15px; + margin-top: -1px; + margin-bottom: 6px; } +h3.tight + dl.termdef { + margin-top: 13px; + margin-bottom: 10px; } + +/* frameset: list items */ +/* Everything in a list item is wrapped in an element now. */ +/* First para in a list item should be inline, others should be block. */ +li>p { display: inline } +li>p+p { display: block } + + +/* frameset: Index styles for docs */ +/* frameset: Index styles for alpah listing */ +.index_alpa{ + font-size: 18px; padding-bottom: 5px; margin: 25px 0 15px; border-bottom: 1px solid #91969C; } + +/* frameset: Index styles for singal and page range entries */ +.libindex{ +font-size: 12px; padding: 0 3px; background-color: #FFFFFF; margin: 0 3px; } + + + +/* frameset: mini navigation style (Hide/Show TOC & next/prev) */ +.mini_nav_text { + font-family: lucida grande, geneva, helvetica, arial, sans-serif; + font-size: 9px; + font-weight: normal; +} + +.breadcrumb { + font-family: lucida grande, geneva, helvetica, arial, sans-serif; + font-size: 10px; + font-weight: normal; + margin-left: 10px; + margin-top: 8px; +} + +/* ADC header/footer mappings for Getting Started */ +/* header */ +#adcnavheader td { + font: 10px lucida grande, geneva, helvetica, arial, sans-serif; + } + +#adcnavheader input { + margin: 0 3px 0 0; + padding: 0; + } + +#adcnavheader .textpadding { + padding-top: 2px; + vertical-align: middle; + } + +#adcnavheader .searchbutton { + border: 0; + } + +#adcnavheader h6 { + margin: 0; + padding: 0; + font: normal 12px lucida grande, geneva, helvetica, arial, sans-serif; + color: #000; +} + +#adcnavheader form { + margin: 0; +} + + +/* footer */ +#footer td, #footer p { + font-size: 10px; + } + + +/* Getting Started styles */ + +/* font definitions */ + +/* keep ".gettingstarted pre, code" above ".gettingstarted h1" below otherwise, +the main h1 tag above will be used instead of".gettingstarted h1" */ +.gettingstarted pre, code { + font: 11px Monaco, Courier, monospace; + } + +/* Added this style since the ADC template was trying to do this with a graphic (Note: their h2 +attached to the image tag is only used by search engines; their h2 does not function if the +graphic is missing).--DA */ +.gettingstarted h2 { + margin: 0; + margin-bottom: 15px; + padding: 0px; + font: bold 32px 'Lucida Grande', Geneva, Verdana, Arial, Helvetica, sans-serif; + color: #000; + } + +.gettingstarted h3 { + margin: 0 0 5px 0; + padding: 0px; + font: bold 16px 'Lucida Grande', Geneva, Verdana, Arial, Helvetica, sans-serif; + color: #000; + } + +.gettingstarted p + .gettingstarted h3 { + margin-top: 20px; + } + +.gettingstarted ol + .gettingstarted h3 { + margin-top: 20px; + } + +.gettingstarted ul + .gettingstarted h3 { + margin-top: 20px; + } + +.gettingstarted h4 { + margin: 0px; + padding: 0px; + font: bold 12px 'Lucida Grande', Geneva, Verdana, Arial, Helvetica, sans-serif; + color: #000; + } + +.gettingstarted h4 + .gettingstarted table { + margin-top: 10px; + } + +.gettingstarted p { + margin-top: 0; + margin-bottom: 10px; + padding: 0; + font: 12px 'Lucida Grande', Geneva, Verdana, Arial, Helvetica, sans-serif; + color: #000; + } + +.gettingstarted th { + font-weight: bold; + text-align: left; + } + + +/* list definitions */ +.gettingstarted ul { + font: 12px 'Lucida Grande', Geneva, Verdana, Arial, Helvetica, sans-serif; + padding-left: 10px; + margin-top: 0; + margin-left: 10px; + margin-bottom: 10px; + list-style-type: none; + } + +.gettingstarted li { + margin-top: 3px; + } + + +.gettingstarted ul li { + list-style: square outside; + margin: 0 0 0 30px; + padding: 0 0 4px 0; + } + +.gettingstarted ul ul { + margin-left: 20px; + } + +.gettingstarted ol { + font: 12px 'Lucida Grande', Geneva, Verdana, Arial, Helvetica, sans-serif; + margin-top: 0; + margin-left: 1.5em; + margin-bottom: 10px; + padding-left: 1.5em; + } + +.gettingstarted ul.inline, .gettingstarted ol.inline, .gettingstarted p.inline { + margin-top: -7px; + } + +/* table styles */ +caption.tablecaption { + margin-bottom: 5px; + text-align: left; +} +.sourcecodebox { + border: 1px solid #c7cfd5; + background: #f1f5f9; + margin: 20px 0; + } + +div.tableholder { + margin-top: 20px; + margin-bottom: 20px; + } + +p.tableholder { + margin-bottom: 7px; + font: 12px lucida grande, geneva, helvetica, arial, sans-serif; + } + +.graybox { + border-top: 1px solid #919699; + border-left: 1px solid #919699; + } + +.graybox th { + padding: 4px 8px 4px 8px; + background: #E2E2E2; + font-size: 12px; + border-bottom: 1px solid #919699; + border-right: 1px solid #919699; + } +.graybox th p { + font-weight: bold; + margin-bottom: 0px; + } + +.graybox td { + padding: 8px; + font-size: 12px; + text-align: left; + vertical-align: top; + border-bottom: 1px solid #919699; + border-right: 1px solid #919699; + } +.graybox td p { + margin-bottom: 0px; + } +.graybox td p + p { + margin-top: 5px; + } +.graybox td p + p + p { + margin-top: 5px; + } + + +/* footnote definitions */ +.footnote h4, .footnote p { + color: #76797C; + font-size: 11px; + } + +.gettingstarted .footnote { + font-size: 11px; + color: #76797C; + } + + +.notebox { + border: 1px solid #a1a5a9; + background-color: #f7f7f7; + margin: 20px 0; + padding: 0px 8px 1px 9px; + text-align: left; + } +.notebox p { + font: 12px lucida grande, geneva, helvetica, arial, sans-serif; + margin-top: 7px; + margin-bottom: 0px; + } +.importantbox { + border: 1px solid #111; + background-color: #e8e8e8; + margin: 20px 0; + padding: 0px 8px 1px 9px; + text-align: left; + } +.importantbox p { + font: 12px lucida grande, geneva, helvetica, arial, sans-serif; + margin-top: 7px; + margin-bottom: 0px; + } +.warningbox { + border: 1px solid #000; + background-color: #fff; + margin: 20px 0; + padding: 8px; + text-align: left; + } +.warningicon { + background-color: transparent; + padding-right: 10px; + float: left; + } +.warningbox p { + border-style: none; + font: 12px lucida grande, geneva, helvetica, arial, sans-serif; + margin: -8px 0 -8px 30px; + } +div.codesample { + margin: 20px 0; + } +.codesample pre { + font-size: 11px; + font-family: monaco, courier, monospace; + margin: -1px 4px -3px 6px; + white-space: pre; + } +.codesample span { + margin-right: 8px; + float: right; + } +p.codesample { + margin-top: 20px; margin-bottom: -15px; font: 12px lucida grande, geneva, helvetica, arial, sans-serif; + } + + +/* Controller Layer Bindings styles */ + +.class_binding_block { + } + +.binding_category_block { + margin-left: 1em + } + +.binding_category_name { + font-size: 24px; font-family: lucida grande, geneva, helvetica, arial, sans-serif; font-weight: bold; line-height: 35px; padding-bottom: 1px; border-top: 2px solid black + } + +.binding_block { + margin-left: 2em + } + +.binding_name { + font-size: 18px; font-family: monaco, courier, monospace; font-weight: 400; margin-top: 10px; margin-bottom: 12px; border-bottom: 1px solid #69f + } + +.bindings_tablehead { font-size: 14px; font-family: lucida grande, geneva, helvetica, arial, sans-serif; font-weight: bold; position: relative; top: -5px; margin-left: -20px + } + +.placeholder_options_block { + margin-left: 2em + } + +.availabilityList { + border: none; + margin-top: 5px; + margin-bottom: 0px; + font-size: 12px; + text-align: left; + } + +.availabilityItem { + margin-top: -15px; + margin-bottom: 15px; + padding-left: 78px; + } + + +.metadata_attributes_name { + font-size: 24px; font-family: lucida grande, geneva, helvetica, arial, sans-serif; font-weight: bold; padding-top: 5px; margin-bottom: -10px; border-top: 2px solid black + } + +.metadata_attribute_name { + font-size: 18px; font-family: monaco, courier, monospace; font-weight: 400; margin-top: 10px; padding-bottom: 2px; + } + + +/* Spec Sheet Info Box */ +/* Used in AppKit Obj-C, Appkit Java, Foundation Obj-C, and Foundation Java References */ + +.spec_sheet_info_box { margin-left: 1em } + +/* This builds a table */ +.specbox { + border-top: 1px solid #919699; + border-left: 1px solid #919699; + border-right: 1px solid #919699; + margin-bottom: 10px; + } + +.specbox td { + padding: 8px; + font-size: 12px; + text-align: left; + vertical-align: top; + border-bottom: 1px solid #919699; + } + +/* This alternates colors in up to six table rows (light blue for odd, white for even)*/ + +.specbox tr { + background: #F0F5F9; +} + +.specbox tr + tr { + background: #FFFFFF; +} + +.specbox tr + tr + tr { + background: #F0F5F9; +} + +.specbox tr + tr + tr + tr { + background: #FFFFFF; +} + +.specbox tr + tr + tr +tr + tr { + background: #F0F5F9; +} + +.specbox tr + tr + tr + tr + tr + tr { + background: #FFFFFF; +} + +/* informal protocol subtitling */ + +.protocol_subtitle { + margin-top: -25px; + margin-bottom: 25px; + font-size: 13px; +} + +/* HeaderDoc headings */ + +.hd_tocAccess { + margin-left: 16px; + margin-top: 3px; + display: block; + font-weight: bold; +} +.hd_tocAccessSpace { + display: block; + font-size: 8px; +} + +.hd_tocGroup { + margin-left: 8px; + margin-top: 5px; + display: block; + font-style: italic; +} +.hd_tocGroupSpace { + display: block; + font-size: 8px; +} + +/* "Collection page" mappings */ + +.forums { margin-bottom: 5px;} +.forums b, +.forums a:link, +.forums a:visited { color: #017; font-family: lucida grande, geneva, helvetica, arial, sans-serif; font-size: 11px; font-weight: bold; line-height: 13px;} +.forums a:hover { color: #00F; text-decoration: underline; font-weight: bold;} +.collection { margin-bottom: 5px;} +.collection h3, +.collection a:link, +.collection a:visited { font-size: 13px; color: #76797C; padding-bottom: 2px; border-bottom: 1px dotted #a1a5a9; margin-bottom: 0px; margin-right: 3px;} +.collection a:hover { color: #00F; text-decoration: underline; font-weight: bold;} + +.collection_title { width: 100%; + background-color: #7E91A4; + padding: 15px; + padding-right: 15px; + padding-bottom: 2px; + padding-left: 15px; + } + +.collection_title a:link, +.collection_title a:visited { color: #E8F3FD; } + +h1.collections { + margin-top: 0px; + margin-bottom: 25px; + font: bold 30px lucida grande, geneva, helvetica, arial, sans-serif; + color: #ffffff; + text-align: center; } + + \ No newline at end of file diff --git a/PSMTabBarControl/images/32x32_log.tiff b/PSMTabBarControl/images/32x32_log.tiff new file mode 100644 index 0000000000000000000000000000000000000000..86cdfb51116ccf04b04114327380fff707a24bac GIT binary patch literal 20328 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 OMpmprX|x{M<^Kl-Vhvyb literal 0 HcmV?d00001 diff --git a/PSMTabBarControl/images/AquaTabNew.png b/PSMTabBarControl/images/AquaTabNew.png new file mode 100644 index 0000000000000000000000000000000000000000..843b3c386d52b0b487cca15df6d207890bc9a666 GIT binary patch literal 3139 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 literal 0 HcmV?d00001 diff --git a/PSMTabBarControl/images/AquaTabNewRollover.png b/PSMTabBarControl/images/AquaTabNewRollover.png new file mode 100644 index 0000000000000000000000000000000000000000..f7285117956f4356eb19b4ed8edc7f99a95a9841 GIT binary patch literal 3147 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 literal 0 HcmV?d00001 diff --git a/PSMTabBarControl/images/AquaTabsBackground.png b/PSMTabBarControl/images/AquaTabsBackground.png new file mode 100644 index 0000000000000000000000000000000000000000..456ca6172d9e6ec3a6f46078b5c6cdbb898012d7 GIT binary patch literal 3091 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 literal 0 HcmV?d00001 diff --git a/PSMTabBarControl/images/AquaTabsDown.png b/PSMTabBarControl/images/AquaTabsDown.png new file mode 100644 index 0000000000000000000000000000000000000000..2db28ae1f4a58288922f7abeb7da69e6a14dd28b GIT binary patch literal 2901 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 VF0>PS{}KQI002ovPDHLkV1ldzb_@Uj literal 0 HcmV?d00001 diff --git a/PSMTabBarControl/images/AquaTabsDownNonKey.png b/PSMTabBarControl/images/AquaTabsDownNonKey.png new file mode 100644 index 0000000000000000000000000000000000000000..34a57ff6396a34b6ec6ab983d16e788ad1a4eceb GIT binary patch literal 787 zcmV+u1MK{XP)KLZ*U+a;PZ6DwmS#U-~Zwqe!V{P^5NQ_9g-#oEmo*;xPb(iB&l8cre(mz}OV*eH{#TR|kW=R}lIJ?{~DG)Bo+4 zAbf;><^G%f96osg?Z>_^0LZWiQ~(8dnuN(GaAFtKB$Sef@py224*@uu&M1l$ljTHK zt?-}2?DT>;$ABYkFINIi10NQgY%ySKzHl{Q!_CYMd)nDtz_zCj@7`&ZDgj?_Tv3NQ zoq`guZlp5--{|Itvka>|)OY)H!ydhn&X4p{g@8$uK|w(xhKx*tEGiZMzX2RyhVO^s z`Kt2n`O3XNJ@AZM9zd#V-*(!~mM6{HcE^xXUDNJ)h7*-?mUba3#bh}F@C(a=tFsg9 z>D&MS00d`2O+f$v*z5Hi6siCK03c&XQcVB=ZYKZ$bFTmZ^``&;g(d(1Z?6CV=e_^{ zG3)>U7w#KILV^GQ08~jtK~#9!l+U3Nz%UF$(WtSrKgt!Bw%gg%z9b8%z@NSo5azra z3uZ<^B7#F^a#(8>Veef8036(%!qt9~F$Ra;I|o%QE<~iZK>0@<R|DNig)WpGT%PfAtr%uP&B4N6T+sVqF1Y6Da>+0(@_q~cc6Jj>!|{(JaZG%Q-e|yQz{EjrrH1%&GK|{45_%4G|McP&4IyirNl2r z7JD iYe34jRB<{qFfs(35dFs3=&}LmN(N6?KbLh*2~7Yrom!Lt literal 0 HcmV?d00001 diff --git a/PSMTabBarControl/images/Folder.tif b/PSMTabBarControl/images/Folder.tif new file mode 100644 index 0000000000000000000000000000000000000000..4d4cc0bbceafa936043573af09417be64d097b1c GIT binary patch literal 926 zcmebEWzb?^V7k%3pb%i8BF4+!;*=P$BgIUXzk?yk@qtOmG>0C|(2v`HuCrOi;or}+Y?(XADyh*pJ0ENuig9abN70CP5-Z#o)&#m z2?^>r;v_onbGg<1H{Vuge!GxkasOHHA;B{$@>8!fbtn81*s{a^ez^JHYj4Zy?q!@e zU;OvZhf4dKzG=Vzx@}FgKkw-}`OmqApnVs*uC4y#mh7>Oaps08iZXp3333tQ!o4T{ zXKXcE^{TE+8HU4N1SSx?xXs~(O+HCtvUEe-`__y*RbQ|>;?bY4>iUibUaI3&Wjs^cb);~w1Mkv}Zx|aMczCt(Cogzb(zk?@tA6sbl@GaP z++Y3)lRkd%m%o(z#&7O3-A{gTl4$?<$9{&uiXX9am%rHNKAruChBEK76HJT@2}^}+ z`r0ebSoWuXfw=pt9#aV%B*r04CAX|_DC=b-jz`(&M3Ka*6Fp9y%nHU(w;q3E_QVc*7 qKrWR0gSr3%lm-AXOkSS= literal 0 HcmV?d00001 diff --git a/PSMTabBarControl/images/Globe.tiff b/PSMTabBarControl/images/Globe.tiff new file mode 100644 index 0000000000000000000000000000000000000000..3c893505eb64071e676a67591d5712682e7fee55 GIT binary patch literal 17104 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 literal 0 HcmV?d00001 diff --git a/PSMTabBarControl/images/TabClose_Front.tif b/PSMTabBarControl/images/TabClose_Front.tif new file mode 100644 index 0000000000000000000000000000000000000000..abdea19f7a02aacd797e91af4fd275bffd56b1ca GIT binary patch literal 518 zcmebEWzb?^V036;PzbP4V31@MJ8;s#=!=mkN8`Z<8!aSa#Kko_7JD@ADYbH&psm7^ zno^QCx0hq0U_qptwg?+*n(M|jSIvCq=sah+dF5HT?L7Zyi$m_5(2DM8)^wgFbFXOs z3j2#w&EEX04|X%p;{N`ZE7yyS&sEI0H>#+0i^c0wt))p@1Ggx~lx05c2`H3}3l?{s zDfVagj$5nD_VE7b+PyE%-LomoG_Yp=!cTtOvFlaZ3sTfAE(I-EIp6QT?hS80w(EKO z(oc0>O55_e=2Fat(|hO5T3mB&GQWutXL-%y`TaY5bmx9fKO}Fk{P&|*{T2K#m`}+X z+Z#99y$Pr`VVxhnEWr4S;|GWLQ><4RNY#2K-QVgF_(S_2t7!d}ZA-pN1>Ng6DAQ=# z<9LKchI@j>4y%I#K7!2L6C?^g+P~mnVBlk9U|?nd1|b6vkYI$ed4X&uFq;L)ddJ8N z6=wzV*r04CAX|_DC=b-jz`(&M3Ka+G5QB*`tzs01u^G)7r5J!FfYdX7W0Z!o|1ruy d^@3zHkjxK4hy(QjZGl3rKMf2F>H-W<8USCtlym?9 literal 0 HcmV?d00001 diff --git a/PSMTabBarControl/images/TabClose_Front_Pressed.tif b/PSMTabBarControl/images/TabClose_Front_Pressed.tif new file mode 100644 index 0000000000000000000000000000000000000000..125cf7e310067592a9a516a5d6d325503172bf60 GIT binary patch literal 520 zcmebEWzb?^V03C=PzbP4U{GdOJaG1cNs5suN8`Z<8!aR{gvBje7khowDXr0;V5GwI z&85U^UoY#_j|HCRv_&}1IH_-xxmsa7$5@@&^2)Pv+j;)a7MVUd@m-MhlIIo6Jx?Y5 z>t|~Db^iIcB&8(yV*f9ZTa&oeIdnW;t$A`Vz3kd5Q>(pc3)2m(b2gtAXq3_1qnnp= zF!$@yf-P5cBe-8|U0S_|D{OI0GTV21!<5*v)nP72ULQYK*c`^mZ?kdl?Sir%)>XHw z&kI~r@lBHZzIeyOsAyeXr|)Z&6pzi`q^Vz9HRn;(ZS8xfTkY=)UE95Jp@{r>_Q_Um z@BEpX?cS9B_BprSV@BQ!<_C@U6-t&qH=MrLOUQp~p4AV-eay?uw@ljpReXwF(Zv2! ze2Y4?56L(*9@xp;-MmJW^=K2P;rnBF_<{hDn@Y_o6(9NIl~ZMrjzE hiGfiDsuv`qfn4i-PgtI_GWKi^sVQAk$*()!9N=+&FADie)m~K zZZ7lMi_e99=NzaJu)fbXWsjRO|5O{lFFGA^+t}AM9QYzUEiRa=`bdyr1@lG^{epu3 z?MzQt^!PUD@G>1pdcq)M-T#P*fq{>afq|I;7<>#oK!Op<<^{5uz-$&E>lGt2RGbya zV}r7Rni&Ndfbu}S3=ABMqEK;=4l$TG(<(-B7@N_UQHlX*0!TgMCq`*F`xm1OR4+(I Z1Ihd#gg8(i&=x4<`qRL`pf11wr2(Hfla>Gg literal 0 HcmV?d00001 diff --git a/PSMTabBarControl/images/TabControlRep.tif b/PSMTabBarControl/images/TabControlRep.tif new file mode 100644 index 0000000000000000000000000000000000000000..6ad0f4042a2a716d62a0480d2432d3cdb2280df7 GIT binary patch literal 29768 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 literal 0 HcmV?d00001 diff --git a/PSMTabBarControl/images/TabNewMetal.png b/PSMTabBarControl/images/TabNewMetal.png new file mode 100644 index 0000000000000000000000000000000000000000..5b8301845a2397fd3335f7c3c6a55e716833032c GIT binary patch literal 3137 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 bkIw@DtN)X%NLHKy00000NkvXXu0mjf9LMoo literal 0 HcmV?d00001 diff --git a/PSMTabBarControl/images/TabNewMetalPressed.png b/PSMTabBarControl/images/TabNewMetalPressed.png new file mode 100644 index 0000000000000000000000000000000000000000..b18f6d4cfeebd6f6b279cd0097685b06b64037da GIT binary patch literal 3160 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 literal 0 HcmV?d00001 diff --git a/PSMTabBarControl/images/overflowImagePressed.tif b/PSMTabBarControl/images/overflowImagePressed.tif new file mode 100755 index 0000000000000000000000000000000000000000..f6ad227df7b32d6e4b174ab4f3813e450da480c9 GIT binary patch literal 1018 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 + + + + + Class PSMTabBarControlPalette + + + NibFile PSMTabBarControlPalette + + + Icon TabIcon.tif + + + ToolTips PSMTabBarControl + + + ExportClasses + + PSMTabBarControl + PSMTabBarCell + PSMAquaTabStyle + PSMMetalTabStyle + PSMRolloverButton + PSMProgressIndcator + PSMOverflowPopUpButton + + + + ExportImages + + TabControlRep.tif + TabIcon.tif + + + + ExportSounds + + + + + diff --git a/PSMTabBarControl/source/AppController.h b/PSMTabBarControl/source/AppController.h new file mode 100644 index 0000000000..532e91da64 --- /dev/null +++ b/PSMTabBarControl/source/AppController.h @@ -0,0 +1,17 @@ +// +// AppController.h +// PSMTabBarControl +// +// Created by John Pannell on 12/19/05. +// Copyright 2005 Positive Spin Media. All rights reserved. +// + +#import + +@interface AppController : NSObject { + +} + +- (IBAction)newWindow:(id)sender; + +@end diff --git a/PSMTabBarControl/source/AppController.m b/PSMTabBarControl/source/AppController.m new file mode 100644 index 0000000000..16dfd30c44 --- /dev/null +++ b/PSMTabBarControl/source/AppController.m @@ -0,0 +1,30 @@ +// +// AppController.m +// TabBarControl +// +// Created by John Pannell on 12/19/05. +// Copyright 2005 Positive Spin Media. All rights reserved. +// + +#import "AppController.h" +#import "WindowController.h" + +@implementation AppController + +- (void)awakeFromNib +{ + [self newWindow:self]; + [self newWindow:self]; + NSRect frontFrame = [[NSApp keyWindow] frame]; + frontFrame.origin.x += 400; + [[NSApp keyWindow] setFrame:frontFrame display:YES]; +} + +- (IBAction)newWindow:(id)sender +{ + // put up a window + WindowController *newWindow = [[WindowController alloc] initWithWindowNibName:@"Window"]; + [newWindow showWindow:self]; +} + +@end diff --git a/PSMTabBarControl/source/FakeModel.h b/PSMTabBarControl/source/FakeModel.h new file mode 100644 index 0000000000..aeece3f530 --- /dev/null +++ b/PSMTabBarControl/source/FakeModel.h @@ -0,0 +1,34 @@ +// +// FakeModel.h +// TabBarControl +// +// Created by John Pannell on 12/19/05. +// Copyright 2005 Positive Spin Media. All rights reserved. +// + +#import + + +@interface FakeModel : NSObject { + BOOL _isProcessing; + NSImage *_icon; + NSString *_iconName; + NSObjectController *controller; + int _objectCount; +} + +// creation/destruction +- (id)init; + +// accessors +- (BOOL)isProcessing; +- (void)setIsProcessing:(BOOL)value; +- (NSImage *)icon; +- (void)setIcon:(NSImage *)icon; +- (NSString *)iconName; +- (void)setIconName:(NSString *)iconName; +- (int)objectCount; +- (void)setObjectCount:(int)value; +- (NSObjectController *)controller; + +@end diff --git a/PSMTabBarControl/source/FakeModel.m b/PSMTabBarControl/source/FakeModel.m new file mode 100644 index 0000000000..dee72ec085 --- /dev/null +++ b/PSMTabBarControl/source/FakeModel.m @@ -0,0 +1,77 @@ +// +// FakeModel.m +// TabBarControl +// +// Created by John Pannell on 12/19/05. +// Copyright 2005 Positive Spin Media. All rights reserved. +// + +#import "FakeModel.h" + + +@implementation FakeModel + +- (id)init +{ + if(self == [super init]){ + _isProcessing = YES; + _icon = nil; + _iconName = nil; + _objectCount = 2; + controller = [[NSObjectController alloc] initWithContent:self]; + } + return self; +} + + +// accessors +- (BOOL)isProcessing +{ + return _isProcessing; +} + +- (void)setIsProcessing:(BOOL)value +{ + _isProcessing = value; +} + +- (NSImage *)icon +{ + return _icon; +} + +- (void)setIcon:(NSImage *)icon +{ + [icon retain]; + [_icon release]; + _icon = icon; +} + +- (NSString *)iconName +{ + return _iconName; +} + +- (void)setIconName:(NSString *)iconName +{ + [iconName retain]; + [_iconName release]; + _iconName = iconName; +} + +- (int)objectCount +{ + return _objectCount; +} + +- (void)setObjectCount:(int)value +{ + _objectCount = value; +} + +- (NSObjectController *)controller +{ + return controller; +} + +@end diff --git a/PSMTabBarControl/source/NSBezierPath_AMShading.h b/PSMTabBarControl/source/NSBezierPath_AMShading.h new file mode 100755 index 0000000000..9c6c335fbe --- /dev/null +++ b/PSMTabBarControl/source/NSBezierPath_AMShading.h @@ -0,0 +1,23 @@ +// +// NSBezierPath_AMShading.h +// ------------------------ +// +// Created by Andreas on 2005-06-01. +// Copyright 2005 Andreas Mayer. All rights reserved. +// +// based on http://www.cocoadev.com/index.pl?GradientFill + + +#import + + +@interface NSBezierPath (AMShading) + +- (void)customHorizontalFillWithCallbacks:(CGFunctionCallbacks)functionCallbacks firstColor:(NSColor *)firstColor secondColor:(NSColor *)secondColor; + +- (void)linearGradientFillWithStartColor:(NSColor *)startColor endColor:(NSColor *)endColor; + +- (void)bilinearGradientFillWithOuterColor:(NSColor *)outerColor innerColor:(NSColor *)innerColor; + + +@end diff --git a/PSMTabBarControl/source/NSBezierPath_AMShading.m b/PSMTabBarControl/source/NSBezierPath_AMShading.m new file mode 100755 index 0000000000..1d1755b84e --- /dev/null +++ b/PSMTabBarControl/source/NSBezierPath_AMShading.m @@ -0,0 +1,169 @@ +// +// NSBezierPath_AMShading.m +// ------------------------ +// +// Created by Andreas on 2005-06-01. +// Copyright 2005 Andreas Mayer. All rights reserved. +// + +#import "NSBezierPath_AMShading.h" + + +@implementation NSBezierPath (AMShading) + +static void linearShadedColor(void *info, const float *in, float *out) +{ + float *colors = info; + *out++ = colors[0] + *in * colors[8]; + *out++ = colors[1] + *in * colors[9]; + *out++ = colors[2] + *in * colors[10]; + *out++ = colors[3] + *in * colors[11]; +} + +static void bilinearShadedColor(void *info, const float *in, float *out) +{ + float *colors = info; + float factor = (*in)*2.0; + if (*in > 0.5) { + factor = 2-factor; + } + *out++ = colors[0] + factor * colors[8]; + *out++ = colors[1] + factor * colors[9]; + *out++ = colors[2] + factor * colors[10]; + *out++ = colors[3] + factor * colors[11]; +} + +- (void)linearGradientFillWithStartColor:(NSColor *)startColor endColor:(NSColor *)endColor +{ + /* + CGColorSpaceRef colorspace; + CGShadingRef shading; + CGPoint startPoint = {0, 0}; + CGPoint endPoint = {0, 0}; + CGFunctionRef function; + float colors[12]; // pointer to color values + + // get my context + CGContextRef currentContext = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort]; + + NSColor *deviceDependentStartColor = [startColor colorUsingColorSpaceName:NSDeviceRGBColorSpace]; + NSColor *deviceDependentEndColor = [endColor colorUsingColorSpaceName:NSDeviceRGBColorSpace]; + + // set up colors for gradient + colors[0] = [deviceDependentStartColor redComponent]; + colors[1] = [deviceDependentStartColor greenComponent]; + colors[2] = [deviceDependentStartColor blueComponent]; + colors[3] = [deviceDependentStartColor alphaComponent]; + + colors[4] = [deviceDependentEndColor redComponent]; + colors[5] = [deviceDependentEndColor greenComponent]; + colors[6] = [deviceDependentEndColor blueComponent]; + colors[7] = [deviceDependentEndColor alphaComponent]; + + // difference between start and end color for each color components + colors[8] = (colors[4]-colors[0]); + colors[9] = (colors[5]-colors[1]); + colors[10] = (colors[6]-colors[2]); + colors[11] = (colors[7]-colors[3]); + + // draw gradient + colorspace = CGColorSpaceCreateDeviceRGB(); + + size_t components = 1 + CGColorSpaceGetNumberOfComponents(colorspace); + static const float domain[2] = {0.0, 1.0}; + static const float range[10] = {0, 1, 0, 1, 0, 1, 0, 1, 0, 1}; + static const CGFunctionCallbacks callbacks = {0, &shadedColor, NULL}; + + // Create a CGFunctionRef that describes a function taking 1 input and kChannelsPerColor outputs. + function = CGFunctionCreate(colors, 1, domain, components, range, &callbacks); + + startPoint.x=0; + startPoint.y=[self bounds].origin.y; + endPoint.x=0; + endPoint.y=NSMaxY([self bounds]); + + shading = CGShadingCreateAxial(colorspace, startPoint, endPoint, function, NO, NO); + + CGContextSaveGState(currentContext); + [self addClip]; + CGContextDrawShading(currentContext, shading); + CGContextRestoreGState(currentContext); + + CGShadingRelease(shading); + CGFunctionRelease(function); + CGColorSpaceRelease(colorspace); + */ + + static const CGFunctionCallbacks callbacks = {0, &linearShadedColor, NULL}; + + [self customHorizontalFillWithCallbacks:callbacks firstColor:startColor secondColor:endColor]; +}; + +- (void)bilinearGradientFillWithOuterColor:(NSColor *)outerColor innerColor:(NSColor *)innerColor +{ + static const CGFunctionCallbacks callbacks = {0, &bilinearShadedColor, NULL}; + + [self customHorizontalFillWithCallbacks:callbacks firstColor:innerColor secondColor:outerColor]; +} + +- (void)customHorizontalFillWithCallbacks:(CGFunctionCallbacks)functionCallbacks firstColor:(NSColor *)firstColor secondColor:(NSColor *)secondColor +{ + CGColorSpaceRef colorspace; + CGShadingRef shading; + CGPoint startPoint = {0, 0}; + CGPoint endPoint = {0, 0}; + CGFunctionRef function; + float colors[12]; // pointer to color values + + // get my context + CGContextRef currentContext = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort]; + + NSColor *deviceDependentFirstColor = [firstColor colorUsingColorSpaceName:NSDeviceRGBColorSpace]; + NSColor *deviceDependentSecondColor = [secondColor colorUsingColorSpaceName:NSDeviceRGBColorSpace]; + + // set up colors for gradient + colors[0] = [deviceDependentFirstColor redComponent]; + colors[1] = [deviceDependentFirstColor greenComponent]; + colors[2] = [deviceDependentFirstColor blueComponent]; + colors[3] = [deviceDependentFirstColor alphaComponent]; + + colors[4] = [deviceDependentSecondColor redComponent]; + colors[5] = [deviceDependentSecondColor greenComponent]; + colors[6] = [deviceDependentSecondColor blueComponent]; + colors[7] = [deviceDependentSecondColor alphaComponent]; + + // difference between start and end color for each color components + colors[8] = (colors[4]-colors[0]); + colors[9] = (colors[5]-colors[1]); + colors[10] = (colors[6]-colors[2]); + colors[11] = (colors[7]-colors[3]); + + // draw gradient + colorspace = CGColorSpaceCreateDeviceRGB(); + size_t components = 1 + CGColorSpaceGetNumberOfComponents(colorspace); + static const float domain[2] = {0.0, 1.0}; + static const float range[10] = {0, 1, 0, 1, 0, 1, 0, 1, 0, 1}; + //static const CGFunctionCallbacks callbacks = {0, &bilinearShadedColor, NULL}; + + // Create a CGFunctionRef that describes a function taking 1 input and kChannelsPerColor outputs. + function = CGFunctionCreate(colors, 1, domain, components, range, &functionCallbacks); + + startPoint.x=0; + startPoint.y=[self bounds].origin.y; + endPoint.x=0; + endPoint.y=NSMaxY([self bounds]); + + shading = CGShadingCreateAxial(colorspace, startPoint, endPoint, function, NO, NO); + + CGContextSaveGState(currentContext); + [self addClip]; + CGContextDrawShading(currentContext, shading); + CGContextRestoreGState(currentContext); + + CGShadingRelease(shading); + CGFunctionRelease(function); + CGColorSpaceRelease(colorspace); +} + + +@end diff --git a/PSMTabBarControl/source/PSMAquaTabStyle.h b/PSMTabBarControl/source/PSMAquaTabStyle.h new file mode 100644 index 0000000000..06540dac1a --- /dev/null +++ b/PSMTabBarControl/source/PSMAquaTabStyle.h @@ -0,0 +1,32 @@ +// +// PSMAquaTabStyle.h +// PSMTabBarControl +// +// Created by John Pannell on 2/17/06. +// Copyright 2006 Positive Spin Media. All rights reserved. +// + +#import +#import "PSMTabStyle.h" + +@interface PSMAquaTabStyle : NSObject { + NSImage *aquaTabBg; + NSImage *aquaTabBgDown; + NSImage *aquaTabBgDownGraphite; + NSImage *aquaTabBgDownNonKey; + NSImage *aquaDividerDown; + NSImage *aquaDivider; + NSImage *aquaCloseButton; + NSImage *aquaCloseButtonDown; + NSImage *aquaCloseButtonOver; + NSImage *_addTabButtonImage; + NSImage *_addTabButtonPressedImage; + NSImage *_addTabButtonRolloverImage; +} + +- (void)loadImages; +- (void)drawInteriorWithTabCell:(PSMTabBarCell *)cell inView:(NSView*)controlView; + +- (void)encodeWithCoder:(NSCoder *)aCoder; +- (id)initWithCoder:(NSCoder *)aDecoder; +@end diff --git a/PSMTabBarControl/source/PSMAquaTabStyle.m b/PSMTabBarControl/source/PSMAquaTabStyle.m new file mode 100644 index 0000000000..7235c4c6b4 --- /dev/null +++ b/PSMTabBarControl/source/PSMAquaTabStyle.m @@ -0,0 +1,516 @@ +// +// PSMAquaTabStyle.m +// PSMTabBarControl +// +// Created by John Pannell on 2/17/06. +// Copyright 2006 Positive Spin Media. All rights reserved. +// + +#import "PSMAquaTabStyle.h" +#import "PSMTabBarCell.h" +#import "PSMTabBarControl.h" + +#define kPSMAquaObjectCounterRadius 7.0 +#define kPSMAquaCounterMinWidth 20 + +@implementation PSMAquaTabStyle + +- (NSString *)name +{ + return @"Aqua"; +} + +#pragma mark - +#pragma mark Creation/Destruction + +- (id) init +{ + if((self = [super init])) + { + [self loadImages]; + } + return self; +} + +- (void) loadImages +{ + NSLog(@"PSMAquaTabStyle loadImages"); + + // Aqua Tabs Images + aquaTabBg = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"AquaTabsBackground"]]; + [aquaTabBg setFlipped:YES]; + + aquaTabBgDown = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"AquaTabsDown"]]; + [aquaTabBgDown setFlipped:YES]; + + aquaTabBgDownGraphite = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"AquaTabsDownGraphite"]]; + [aquaTabBgDown setFlipped:YES]; + + aquaTabBgDownNonKey = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"AquaTabsDownNonKey"]]; + [aquaTabBgDown setFlipped:YES]; + + aquaDividerDown = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"AquaTabsSeparatorDown"]]; + [aquaDivider setFlipped:NO]; + + aquaDivider = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"AquaTabsSeparator"]]; + [aquaDivider setFlipped:NO]; + + aquaCloseButton = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"AquaTabClose_Front"]]; + aquaCloseButtonDown = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"AquaTabClose_Front_Pressed"]]; + aquaCloseButtonOver = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"AquaTabClose_Front_Rollover"]]; + + _addTabButtonImage = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"AquaTabNew"]]; + _addTabButtonPressedImage = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"AquaTabNewPressed"]]; + _addTabButtonRolloverImage = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"AquaTabNewRollover"]]; +} + +- (void)dealloc +{ + [aquaTabBg release]; + [aquaTabBgDown release]; + [aquaDividerDown release]; + [aquaDivider release]; + [aquaCloseButton release]; + [aquaCloseButtonDown release]; + [aquaCloseButtonOver release]; + [_addTabButtonImage release]; + [_addTabButtonPressedImage release]; + [_addTabButtonRolloverImage release]; + + [super dealloc]; +} + +#pragma mark - +#pragma mark Control Specifics + +- (float)leftMarginForTabBarControl +{ + return 0.0f; +} + +- (float)rightMarginForTabBarControl +{ + return 24.0f; +} + +#pragma mark - +#pragma mark Add Tab Button + +- (NSImage *)addTabButtonImage +{ + return _addTabButtonImage; +} + +- (NSImage *)addTabButtonPressedImage +{ + return _addTabButtonPressedImage; +} + +- (NSImage *)addTabButtonRolloverImage +{ + return _addTabButtonRolloverImage; +} + +#pragma mark - +#pragma mark Cell Specifics + +- (NSRect)closeButtonRectForTabCell:(PSMTabBarCell *)cell +{ + NSRect cellFrame = [cell frame]; + + if ([cell hasCloseButton] == NO) { + return NSZeroRect; + } + + NSRect result; + result.size = [aquaCloseButton size]; + result.origin.x = cellFrame.origin.x + MARGIN_X; + result.origin.y = cellFrame.origin.y + MARGIN_Y + 2.0; + + return result; +} + +- (NSRect)iconRectForTabCell:(PSMTabBarCell *)cell +{ + NSRect cellFrame = [cell frame]; + + if ([cell hasIcon] == NO) { + return NSZeroRect; + } + + NSRect result; + result.size = NSMakeSize(kPSMTabBarIconWidth, kPSMTabBarIconWidth); + result.origin.x = cellFrame.origin.x + MARGIN_X; + result.origin.y = cellFrame.origin.y + MARGIN_Y; + + if([cell hasCloseButton] && ![cell isCloseButtonSuppressed]) + result.origin.x += [aquaCloseButton size].width + kPSMTabBarCellPadding; + + return result; +} + +- (NSRect)indicatorRectForTabCell:(PSMTabBarCell *)cell +{ + NSRect cellFrame = [cell frame]; + + if ([[cell indicator] isHidden]) { + return NSZeroRect; + } + + NSRect result; + result.size = NSMakeSize(kPSMTabBarIndicatorWidth, kPSMTabBarIndicatorWidth); + result.origin.x = cellFrame.origin.x + cellFrame.size.width - MARGIN_X - kPSMTabBarIndicatorWidth; + result.origin.y = cellFrame.origin.y + MARGIN_Y; + + return result; +} + +- (NSRect)objectCounterRectForTabCell:(PSMTabBarCell *)cell +{ + NSRect cellFrame = [cell frame]; + + if ([cell count] == 0) { + return NSZeroRect; + } + + float countWidth = [[self attributedObjectCountValueForTabCell:cell] size].width; + countWidth += (2 * kPSMAquaObjectCounterRadius - 6.0); + if(countWidth < kPSMAquaCounterMinWidth) + countWidth = kPSMAquaCounterMinWidth; + + NSRect result; + result.size = NSMakeSize(countWidth, 2 * kPSMAquaObjectCounterRadius); // temp + result.origin.x = cellFrame.origin.x + cellFrame.size.width - MARGIN_X - result.size.width; + result.origin.y = cellFrame.origin.y + MARGIN_Y + 1.0; + + if(![[cell indicator] isHidden]) + result.origin.x -= kPSMTabBarIndicatorWidth + kPSMTabBarCellPadding; + + return result; +} + +- (float)minimumWidthOfTabCell:(PSMTabBarCell *)cell +{ + float resultWidth = 0.0; + + // left margin + resultWidth = MARGIN_X; + + // close button? + if ([cell hasCloseButton] && ![cell isCloseButtonSuppressed]) + resultWidth += [aquaCloseButton size].width + kPSMTabBarCellPadding; + + // icon? + if([cell hasIcon]) + resultWidth += kPSMTabBarIconWidth + kPSMTabBarCellPadding; + + // the label + resultWidth += kPSMMinimumTitleWidth; + + // object counter? + if([cell count] > 0) + resultWidth += [self objectCounterRectForTabCell:cell].size.width + kPSMTabBarCellPadding; + + // indicator? + if ([[cell indicator] isHidden] == NO) + resultWidth += kPSMTabBarCellPadding + kPSMTabBarIndicatorWidth; + + // right margin + resultWidth += MARGIN_X; + + return ceil(resultWidth); +} + +- (float)desiredWidthOfTabCell:(PSMTabBarCell *)cell +{ + float resultWidth = 0.0; + + // left margin + resultWidth = MARGIN_X; + + // close button? + if ([cell hasCloseButton] && ![cell isCloseButtonSuppressed]) + resultWidth += [aquaCloseButton size].width + kPSMTabBarCellPadding; + + // icon? + if([cell hasIcon]) + resultWidth += kPSMTabBarIconWidth + kPSMTabBarCellPadding; + + // the label + resultWidth += [[cell attributedStringValue] size].width; + + // object counter? + if([cell count] > 0) + resultWidth += [self objectCounterRectForTabCell:cell].size.width + kPSMTabBarCellPadding; + + // indicator? + if ([[cell indicator] isHidden] == NO) + resultWidth += kPSMTabBarCellPadding + kPSMTabBarIndicatorWidth; + + // right margin + resultWidth += MARGIN_X; + + return ceil(resultWidth); +} + +#pragma mark - +#pragma mark Cell Values + +- (NSAttributedString *)attributedObjectCountValueForTabCell:(PSMTabBarCell *)cell +{ + NSMutableAttributedString *attrStr; + NSFontManager *fm = [NSFontManager sharedFontManager]; + NSNumberFormatter *nf = [[[NSNumberFormatter alloc] init] autorelease]; + [nf setLocalizesFormat:YES]; + [nf setFormat:@"0"]; + [nf setHasThousandSeparators:YES]; + NSString *contents = [nf stringFromNumber:[NSNumber numberWithInt:[cell count]]]; + attrStr = [[[NSMutableAttributedString alloc] initWithString:contents] autorelease]; + NSRange range = NSMakeRange(0, [contents length]); + + // Add font attribute + [attrStr addAttribute:NSFontAttributeName value:[fm convertFont:[NSFont fontWithName:@"Helvetica" size:11.0] toHaveTrait:NSBoldFontMask] range:range]; + [attrStr addAttribute:NSForegroundColorAttributeName value:[[NSColor whiteColor] colorWithAlphaComponent:0.85] range:range]; + + return attrStr; +} + +- (NSAttributedString *)attributedStringValueForTabCell:(PSMTabBarCell *)cell +{ + NSMutableAttributedString *attrStr; + NSString * contents = [cell stringValue]; + attrStr = [[[NSMutableAttributedString alloc] initWithString:contents] autorelease]; + NSRange range = NSMakeRange(0, [contents length]); + + [attrStr addAttribute:NSFontAttributeName value:[NSFont systemFontOfSize:11.0] range:range]; + + // Paragraph Style for Truncating Long Text + static NSMutableParagraphStyle *TruncatingTailParagraphStyle = nil; + if (!TruncatingTailParagraphStyle) { + TruncatingTailParagraphStyle = [[[NSParagraphStyle defaultParagraphStyle] mutableCopy] retain]; + [TruncatingTailParagraphStyle setLineBreakMode:NSLineBreakByTruncatingTail]; + [TruncatingTailParagraphStyle setAlignment:NSCenterTextAlignment]; + } + [attrStr addAttribute:NSParagraphStyleAttributeName value:TruncatingTailParagraphStyle range:range]; + + return attrStr; +} + +#pragma mark - +#pragma mark Drawing + +- (void)drawTabCell:(PSMTabBarCell *)cell; +{ + NSRect cellFrame = [cell frame]; + + // Selected Tab + if ([cell state] == NSOnState) { + NSRect aRect = NSMakeRect(cellFrame.origin.x, cellFrame.origin.y, cellFrame.size.width, cellFrame.size.height-2.5); + aRect.size.height -= 0.5; + + // proper tint + NSControlTint currentTint; + if ([cell controlTint] == NSDefaultControlTint) + currentTint = [NSColor currentControlTint]; + else + currentTint = [cell controlTint]; + + if (![[[cell controlView] window] isKeyWindow]) + currentTint = NSClearControlTint; + + NSImage *bgImage; + switch(currentTint){ + case NSGraphiteControlTint: + bgImage = aquaTabBgDownGraphite; + break; + case NSClearControlTint: + bgImage = aquaTabBgDownNonKey; + break; + case NSBlueControlTint: + default: + bgImage = aquaTabBgDown; + break; + } + + [bgImage drawInRect:cellFrame fromRect:NSMakeRect(0.0, 0.0, 1.0, 22.0) operation:NSCompositeSourceOver fraction:1.0]; + [aquaDivider compositeToPoint:NSMakePoint(cellFrame.origin.x + cellFrame.size.width - 1.0, cellFrame.origin.y + cellFrame.size.height) operation:NSCompositeSourceOver]; + + aRect.size.height+=0.5; + + } else { // Unselected Tab + + NSRect aRect = NSMakeRect(cellFrame.origin.x, cellFrame.origin.y, cellFrame.size.width, cellFrame.size.height); + aRect.origin.y += 0.5; + aRect.origin.x += 1.5; + aRect.size.width -= 1; + + aRect.origin.x -= 1; + aRect.size.width += 1; + + // Rollover + if ([cell isHighlighted]) { + [[NSColor colorWithCalibratedWhite:0.0 alpha:0.1] set]; + NSRectFillUsingOperation(aRect, NSCompositeSourceAtop); + } + + [aquaDivider compositeToPoint:NSMakePoint(cellFrame.origin.x + cellFrame.size.width - 1.0, cellFrame.origin.y + cellFrame.size.height) operation:NSCompositeSourceOver]; + } + + [self drawInteriorWithTabCell:cell inView:[cell controlView]]; +} + +- (void)drawTabBar:(PSMTabBarControl *)bar inRect:(NSRect)rect +{ + [aquaTabBg drawInRect:rect fromRect:NSMakeRect(0.0, 0.0, 1.0, 22.0) operation:NSCompositeSourceOver fraction:1.0]; + + // no tab view == not connected + if(![bar tabView]){ + NSRect labelRect = rect; + labelRect.size.height -= 4.0; + labelRect.origin.y += 4.0; + NSMutableAttributedString *attrStr; + NSString *contents = @"PSMTabBarControl"; + attrStr = [[[NSMutableAttributedString alloc] initWithString:contents] autorelease]; + NSRange range = NSMakeRange(0, [contents length]); + [attrStr addAttribute:NSFontAttributeName value:[NSFont systemFontOfSize:11.0] range:range]; + NSMutableParagraphStyle *centeredParagraphStyle = nil; + if (!centeredParagraphStyle) { + centeredParagraphStyle = [[[NSParagraphStyle defaultParagraphStyle] mutableCopy] retain]; + [centeredParagraphStyle setAlignment:NSCenterTextAlignment]; + } + [attrStr addAttribute:NSParagraphStyleAttributeName value:centeredParagraphStyle range:range]; + [attrStr drawInRect:labelRect]; + return; + } + + // Draw cells + NSEnumerator *e = [[bar cells] objectEnumerator]; + PSMTabBarCell *cell; + while(cell = [e nextObject]){ + if(![cell isInOverflowMenu]){ + [cell drawWithFrame:[cell frame] inView:bar]; + } + } +} + +- (void)drawInteriorWithTabCell:(PSMTabBarCell *)cell inView:(NSView*)controlView +{ + NSRect cellFrame = [cell frame]; + float labelPosition = cellFrame.origin.x + MARGIN_X; + + // close button + if([cell hasCloseButton] && ![cell isCloseButtonSuppressed]) { + NSSize closeButtonSize = NSZeroSize; + NSRect closeButtonRect = [cell closeButtonRectForFrame:cellFrame]; + NSImage *closeButton = nil; + + closeButton = aquaCloseButton; + if([cell closeButtonOver]) closeButton = aquaCloseButtonOver; + if([cell closeButtonPressed]) closeButton = aquaCloseButtonDown; + + closeButtonSize = [closeButton size]; + if([controlView isFlipped]) { + closeButtonRect.origin.y += closeButtonRect.size.height; + } + + [closeButton compositeToPoint:closeButtonRect.origin operation:NSCompositeSourceOver fraction:1.0]; + + // scoot label over + labelPosition += closeButtonSize.width + kPSMTabBarCellPadding; + } + + // icon + if([cell hasIcon]){ + NSRect iconRect = [self iconRectForTabCell:cell]; + NSImage *icon = [[[[cell representedObject] identifier] content] icon]; + if ([controlView isFlipped]) { + iconRect.origin.y = cellFrame.size.height - iconRect.origin.y; + } + [icon compositeToPoint:iconRect.origin operation:NSCompositeSourceOver fraction:1.0]; + + // scoot label over + labelPosition += iconRect.size.width + kPSMTabBarCellPadding; + } + + // object counter + if([cell count] > 0){ + [[NSColor colorWithCalibratedWhite:0.3 alpha:0.45] set]; + NSBezierPath *path = [NSBezierPath bezierPath]; + NSRect myRect = [self objectCounterRectForTabCell:cell]; + [path moveToPoint:NSMakePoint(myRect.origin.x + kPSMAquaObjectCounterRadius, myRect.origin.y)]; + [path lineToPoint:NSMakePoint(myRect.origin.x + myRect.size.width - kPSMAquaObjectCounterRadius, myRect.origin.y)]; + [path appendBezierPathWithArcWithCenter:NSMakePoint(myRect.origin.x + myRect.size.width - kPSMAquaObjectCounterRadius, myRect.origin.y + kPSMAquaObjectCounterRadius) radius:kPSMAquaObjectCounterRadius startAngle:270.0 endAngle:90.0]; + [path lineToPoint:NSMakePoint(myRect.origin.x + kPSMAquaObjectCounterRadius, myRect.origin.y + myRect.size.height)]; + [path appendBezierPathWithArcWithCenter:NSMakePoint(myRect.origin.x + kPSMAquaObjectCounterRadius, myRect.origin.y + kPSMAquaObjectCounterRadius) radius:kPSMAquaObjectCounterRadius startAngle:90.0 endAngle:270.0]; + [path fill]; + + // draw attributed string centered in area + NSRect counterStringRect; + NSAttributedString *counterString = [self attributedObjectCountValueForTabCell:cell]; + counterStringRect.size = [counterString size]; + counterStringRect.origin.x = myRect.origin.x + ((myRect.size.width - counterStringRect.size.width) / 2.0) + 0.25; + counterStringRect.origin.y = myRect.origin.y + ((myRect.size.height - counterStringRect.size.height) / 2.0) + 0.5; + [counterString drawInRect:counterStringRect]; + } + + + // label rect + NSRect labelRect; + labelRect.origin.x = labelPosition; + labelRect.size.width = cellFrame.size.width - (labelRect.origin.x - cellFrame.origin.x) - kPSMTabBarCellPadding; + labelRect.size.height = cellFrame.size.height; + labelRect.origin.y = cellFrame.origin.y + MARGIN_Y + 1.0; + + if(![[cell indicator] isHidden]) + labelRect.size.width -= (kPSMTabBarIndicatorWidth + kPSMTabBarCellPadding); + + if([cell count] > 0) + labelRect.size.width -= ([self objectCounterRectForTabCell:cell].size.width + kPSMTabBarCellPadding); + + // Draw Label + [[cell attributedStringValue] drawInRect:labelRect]; +} + +#pragma mark - +#pragma mark Archiving + +- (void)encodeWithCoder:(NSCoder *)aCoder { + //[super encodeWithCoder:aCoder]; + if ([aCoder allowsKeyedCoding]) { + [aCoder encodeObject:aquaTabBg forKey:@"aquaTabBg"]; + [aCoder encodeObject:aquaTabBgDown forKey:@"aquaTabBgDown"]; + [aCoder encodeObject:aquaTabBgDownGraphite forKey:@"aquaTabBgDownGraphite"]; + [aCoder encodeObject:aquaTabBgDownNonKey forKey:@"aquaTabBgDownNonKey"]; + [aCoder encodeObject:aquaDividerDown forKey:@"aquaDividerDown"]; + [aCoder encodeObject:aquaDivider forKey:@"aquaDivider"]; + [aCoder encodeObject:aquaCloseButton forKey:@"aquaCloseButton"]; + [aCoder encodeObject:aquaCloseButtonDown forKey:@"aquaCloseButtonDown"]; + [aCoder encodeObject:aquaCloseButtonOver forKey:@"aquaCloseButtonOver"]; + [aCoder encodeObject:_addTabButtonImage forKey:@"addTabButtonImage"]; + [aCoder encodeObject:_addTabButtonPressedImage forKey:@"addTabButtonPressedImage"]; + [aCoder encodeObject:_addTabButtonRolloverImage forKey:@"addTabButtonRolloverImage"]; + } +} + +- (id)initWithCoder:(NSCoder *)aDecoder { + //self = [super initWithCoder:aDecoder]; + //if (self) { + if ([aDecoder allowsKeyedCoding]) { + aquaTabBg = [[aDecoder decodeObjectForKey:@"aquaTabBg"] retain]; + aquaTabBgDown = [[aDecoder decodeObjectForKey:@"aquaTabBgDown"] retain]; + aquaTabBgDownGraphite = [[aDecoder decodeObjectForKey:@"aquaTabBgDownGraphite"] retain]; + aquaTabBgDownNonKey = [[aDecoder decodeObjectForKey:@"aquaTabBgDownNonKey"] retain]; + aquaDividerDown = [[aDecoder decodeObjectForKey:@"aquaDividerDown"] retain]; + aquaDivider = [[aDecoder decodeObjectForKey:@"aquaDivider"] retain]; + aquaCloseButton = [[aDecoder decodeObjectForKey:@"aquaCloseButton"] retain]; + aquaCloseButtonDown = [[aDecoder decodeObjectForKey:@"aquaCloseButtonDown"] retain]; + aquaCloseButtonOver = [[aDecoder decodeObjectForKey:@"aquaCloseButtonOver"] retain]; + _addTabButtonImage = [[aDecoder decodeObjectForKey:@"addTabButtonImage"] retain]; + _addTabButtonPressedImage = [[aDecoder decodeObjectForKey:@"addTabButtonPressedImage"] retain]; + _addTabButtonRolloverImage = [[aDecoder decodeObjectForKey:@"addTabButtonRolloverImage"] retain]; + } + //} + return self; +} + +@end diff --git a/PSMTabBarControl/source/PSMMetalTabStyle.h b/PSMTabBarControl/source/PSMMetalTabStyle.h new file mode 100644 index 0000000000..0cbdb1ee85 --- /dev/null +++ b/PSMTabBarControl/source/PSMMetalTabStyle.h @@ -0,0 +1,26 @@ +// +// PSMMetalTabStyle.h +// PSMTabBarControl +// +// Created by John Pannell on 2/17/06. +// Copyright 2006 Positive Spin Media. All rights reserved. +// + +#import +#import "PSMTabStyle.h" + +@interface PSMMetalTabStyle : NSObject { + NSImage *metalCloseButton; + NSImage *metalCloseButtonDown; + NSImage *metalCloseButtonOver; + NSImage *_addTabButtonImage; + NSImage *_addTabButtonPressedImage; + NSImage *_addTabButtonRolloverImage; +} + +- (void)drawInteriorWithTabCell:(PSMTabBarCell *)cell inView:(NSView*)controlView; + +- (void)encodeWithCoder:(NSCoder *)aCoder; +- (id)initWithCoder:(NSCoder *)aDecoder; + +@end diff --git a/PSMTabBarControl/source/PSMMetalTabStyle.m b/PSMTabBarControl/source/PSMMetalTabStyle.m new file mode 100644 index 0000000000..ca0051f19b --- /dev/null +++ b/PSMTabBarControl/source/PSMMetalTabStyle.m @@ -0,0 +1,524 @@ +// +// PSMMetalTabStyle.m +// PSMTabBarControl +// +// Created by John Pannell on 2/17/06. +// Copyright 2006 Positive Spin Media. All rights reserved. +// + +#import "PSMMetalTabStyle.h" +#import "PSMTabBarCell.h" +#import "PSMTabBarControl.h" + +#define kPSMMetalObjectCounterRadius 7.0 +#define kPSMMetalCounterMinWidth 20 + +@implementation PSMMetalTabStyle + +- (NSString *)name +{ + return @"Metal"; +} + +#pragma mark - +#pragma mark Creation/Destruction + +- (id) init +{ + //NSLog(@"PSMMetalTabStyle init"); + + if((self = [super init])) + { + + metalCloseButton = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"TabClose_Front"]]; + //NSLog(@"metalCloseButton=%@ path=%@", metalCloseButton, + // [[PSMTabBarControl bundle] pathForImageResource:@"TabClose_Front"]); + metalCloseButtonDown = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"TabClose_Front_Pressed"]]; + metalCloseButtonOver = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"TabClose_Front_Rollover"]]; + + _addTabButtonImage = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"TabNewMetal"]]; + _addTabButtonPressedImage = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"TabNewMetalPressed"]]; + _addTabButtonRolloverImage = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"TabNewMetalRollover"]]; + } + return self; +} + +- (void)dealloc +{ + [metalCloseButton release]; + [metalCloseButtonDown release]; + [metalCloseButtonOver release]; + [_addTabButtonImage release]; + [_addTabButtonPressedImage release]; + [_addTabButtonRolloverImage release]; + + [super dealloc]; +} + +#pragma mark - +#pragma mark Control Specific + +- (float)leftMarginForTabBarControl +{ + return 10.0f; +} + +- (float)rightMarginForTabBarControl +{ + return 24.0f; +} + +#pragma mark - +#pragma mark Add Tab Button + +- (NSImage *)addTabButtonImage +{ + return _addTabButtonImage; +} + +- (NSImage *)addTabButtonPressedImage +{ + return _addTabButtonPressedImage; +} + +- (NSImage *)addTabButtonRolloverImage +{ + return _addTabButtonRolloverImage; +} + +#pragma mark - +#pragma mark Cell Specific + +- (NSRect) closeButtonRectForTabCell:(PSMTabBarCell *)cell +{ + NSRect cellFrame = [cell frame]; + + if ([cell hasCloseButton] == NO) { + return NSZeroRect; + } + + NSRect result; + result.size = [metalCloseButton size]; + result.origin.x = cellFrame.origin.x + MARGIN_X; + result.origin.y = cellFrame.origin.y + MARGIN_Y + 2.0; + + if([cell state] == NSOnState){ + result.origin.y -= 1; + } + + return result; +} + +- (NSRect)iconRectForTabCell:(PSMTabBarCell *)cell +{ + NSRect cellFrame = [cell frame]; + + if ([cell hasIcon] == NO) { + return NSZeroRect; + } + + NSRect result; + result.size = NSMakeSize(kPSMTabBarIconWidth, kPSMTabBarIconWidth); + result.origin.x = cellFrame.origin.x + MARGIN_X; + result.origin.y = cellFrame.origin.y + MARGIN_Y; + + if([cell hasCloseButton] && ![cell isCloseButtonSuppressed]) + result.origin.x += [metalCloseButton size].width + kPSMTabBarCellPadding; + + if([cell state] == NSOnState){ + result.origin.y += 1; + } + + return result; +} + +- (NSRect)indicatorRectForTabCell:(PSMTabBarCell *)cell +{ + NSRect cellFrame = [cell frame]; + + if ([[cell indicator] isHidden]) { + return NSZeroRect; + } + + NSRect result; + result.size = NSMakeSize(kPSMTabBarIndicatorWidth, kPSMTabBarIndicatorWidth); + result.origin.x = cellFrame.origin.x + cellFrame.size.width - MARGIN_X - kPSMTabBarIndicatorWidth; + result.origin.y = cellFrame.origin.y + MARGIN_Y; + + if([cell state] == NSOnState){ + result.origin.y -= 1; + } + + return result; +} + +- (NSRect)objectCounterRectForTabCell:(PSMTabBarCell *)cell +{ + NSRect cellFrame = [cell frame]; + + if ([cell count] == 0) { + return NSZeroRect; + } + + float countWidth = [[self attributedObjectCountValueForTabCell:cell] size].width; + countWidth += (2 * kPSMMetalObjectCounterRadius - 6.0); + if(countWidth < kPSMMetalCounterMinWidth) + countWidth = kPSMMetalCounterMinWidth; + + NSRect result; + result.size = NSMakeSize(countWidth, 2 * kPSMMetalObjectCounterRadius); // temp + result.origin.x = cellFrame.origin.x + cellFrame.size.width - MARGIN_X - result.size.width; + result.origin.y = cellFrame.origin.y + MARGIN_Y + 1.0; + + if(![[cell indicator] isHidden]) + result.origin.x -= kPSMTabBarIndicatorWidth + kPSMTabBarCellPadding; + + return result; +} + + +- (float)minimumWidthOfTabCell:(PSMTabBarCell *)cell +{ + float resultWidth = 0.0; + + // left margin + resultWidth = MARGIN_X; + + // close button? + if([cell hasCloseButton] && ![cell isCloseButtonSuppressed]) + resultWidth += [metalCloseButton size].width + kPSMTabBarCellPadding; + + // icon? + if([cell hasIcon]) + resultWidth += kPSMTabBarIconWidth + kPSMTabBarCellPadding; + + // the label + resultWidth += kPSMMinimumTitleWidth; + + // object counter? + if([cell count] > 0) + resultWidth += [self objectCounterRectForTabCell:cell].size.width + kPSMTabBarCellPadding; + + // indicator? + if ([[cell indicator] isHidden] == NO) + resultWidth += kPSMTabBarCellPadding + kPSMTabBarIndicatorWidth; + + // right margin + resultWidth += MARGIN_X; + + return ceil(resultWidth); +} + +- (float)desiredWidthOfTabCell:(PSMTabBarCell *)cell +{ + float resultWidth = 0.0; + + // left margin + resultWidth = MARGIN_X; + + // close button? + if ([cell hasCloseButton] && ![cell isCloseButtonSuppressed]) + resultWidth += [metalCloseButton size].width + kPSMTabBarCellPadding; + + // icon? + if([cell hasIcon]) + resultWidth += kPSMTabBarIconWidth + kPSMTabBarCellPadding; + + // the label + resultWidth += [[cell attributedStringValue] size].width; + + // object counter? + if([cell count] > 0) + resultWidth += [self objectCounterRectForTabCell:cell].size.width + kPSMTabBarCellPadding; + + // indicator? + if ([[cell indicator] isHidden] == NO) + resultWidth += kPSMTabBarCellPadding + kPSMTabBarIndicatorWidth; + + // right margin + resultWidth += MARGIN_X; + + return ceil(resultWidth); +} + +#pragma mark - +#pragma mark Cell Values + +- (NSAttributedString *)attributedObjectCountValueForTabCell:(PSMTabBarCell *)cell +{ + NSMutableAttributedString *attrStr; + NSFontManager *fm = [NSFontManager sharedFontManager]; + NSNumberFormatter *nf = [[[NSNumberFormatter alloc] init] autorelease]; + [nf setLocalizesFormat:YES]; + [nf setFormat:@"0"]; + [nf setHasThousandSeparators:YES]; + NSString *contents = [nf stringFromNumber:[NSNumber numberWithInt:[cell count]]]; + attrStr = [[[NSMutableAttributedString alloc] initWithString:contents] autorelease]; + NSRange range = NSMakeRange(0, [contents length]); + + // Add font attribute + [attrStr addAttribute:NSFontAttributeName value:[fm convertFont:[NSFont fontWithName:@"Helvetica" size:11.0] toHaveTrait:NSBoldFontMask] range:range]; + [attrStr addAttribute:NSForegroundColorAttributeName value:[[NSColor whiteColor] colorWithAlphaComponent:0.85] range:range]; + + return attrStr; +} + +- (NSAttributedString *)attributedStringValueForTabCell:(PSMTabBarCell *)cell +{ + NSMutableAttributedString *attrStr; + NSString *contents = [cell stringValue]; + attrStr = [[[NSMutableAttributedString alloc] initWithString:contents] autorelease]; + NSRange range = NSMakeRange(0, [contents length]); + + // Add font attribute + [attrStr addAttribute:NSFontAttributeName value:[NSFont boldSystemFontOfSize:11.0] range:range]; + [attrStr addAttribute:NSForegroundColorAttributeName value:[[NSColor textColor] colorWithAlphaComponent:0.75] range:range]; + + // Add shadow attribute + NSShadow* shadow; + shadow = [[[NSShadow alloc] init] autorelease]; + float shadowAlpha; + if(([cell state] == NSOnState) || [cell isHighlighted]){ + shadowAlpha = 0.8; + } else { + shadowAlpha = 0.5; + } + [shadow setShadowColor:[NSColor colorWithCalibratedWhite:1.0 alpha:shadowAlpha]]; + [shadow setShadowOffset:NSMakeSize(0, -1)]; + [shadow setShadowBlurRadius:1.0]; + [attrStr addAttribute:NSShadowAttributeName value:shadow range:range]; + + // Paragraph Style for Truncating Long Text + static NSMutableParagraphStyle *TruncatingTailParagraphStyle = nil; + if (!TruncatingTailParagraphStyle) { + TruncatingTailParagraphStyle = [[[NSParagraphStyle defaultParagraphStyle] mutableCopy] retain]; + [TruncatingTailParagraphStyle setLineBreakMode:NSLineBreakByTruncatingTail]; + [TruncatingTailParagraphStyle setAlignment:NSCenterTextAlignment]; + } + [attrStr addAttribute:NSParagraphStyleAttributeName value:TruncatingTailParagraphStyle range:range]; + + return attrStr; +} + +#pragma mark - +#pragma mark ---- drawing ---- + +- (void)drawTabCell:(PSMTabBarCell *)cell +{ + NSRect cellFrame = [cell frame]; + NSColor * lineColor = nil; + NSBezierPath* bezier = [NSBezierPath bezierPath]; + lineColor = [NSColor darkGrayColor]; + + if ([cell state] == NSOnState) { + // selected tab + NSRect aRect = NSMakeRect(cellFrame.origin.x, cellFrame.origin.y, cellFrame.size.width, cellFrame.size.height-2.5); + aRect.size.height -= 0.5; + + // background + NSDrawWindowBackground(aRect); + + aRect.size.height+=0.5; + + // frame + aRect.origin.x += 0.5; + [lineColor set]; + [bezier moveToPoint:NSMakePoint(aRect.origin.x, aRect.origin.y)]; + [bezier lineToPoint:NSMakePoint(aRect.origin.x, aRect.origin.y+aRect.size.height-1.5)]; + [bezier lineToPoint:NSMakePoint(aRect.origin.x+1.5, aRect.origin.y+aRect.size.height)]; + [bezier lineToPoint:NSMakePoint(aRect.origin.x+aRect.size.width-1.5, aRect.origin.y+aRect.size.height)]; + [bezier lineToPoint:NSMakePoint(aRect.origin.x+aRect.size.width, aRect.origin.y+aRect.size.height-1.5)]; + [bezier lineToPoint:NSMakePoint(aRect.origin.x+aRect.size.width, aRect.origin.y)]; + if([[cell controlView] frame].size.height < 2){ + // special case of hidden control; need line across top of cell + [bezier moveToPoint:NSMakePoint(aRect.origin.x, aRect.origin.y+0.5)]; + [bezier lineToPoint:NSMakePoint(aRect.origin.x+aRect.size.width, aRect.origin.y+0.5)]; + } + [bezier stroke]; + } else { + + // unselected tab + NSRect aRect = NSMakeRect(cellFrame.origin.x, cellFrame.origin.y, cellFrame.size.width, cellFrame.size.height); + aRect.origin.y += 0.5; + aRect.origin.x += 1.5; + aRect.size.width -= 1; + + // rollover + if ([cell isHighlighted]) { + [[NSColor colorWithCalibratedWhite:0.0 alpha:0.1] set]; + NSRectFillUsingOperation(aRect, NSCompositeSourceAtop); + } + + aRect.origin.x -= 1; + aRect.size.width += 1; + + // frame + [lineColor set]; + [bezier moveToPoint:NSMakePoint(aRect.origin.x, aRect.origin.y)]; + [bezier lineToPoint:NSMakePoint(aRect.origin.x + aRect.size.width, aRect.origin.y)]; + if(!([cell tabState] & PSMTab_RightIsSelectedMask)){ + [bezier lineToPoint:NSMakePoint(aRect.origin.x + aRect.size.width, aRect.origin.y + aRect.size.height)]; + } + [bezier stroke]; + } + + [self drawInteriorWithTabCell:cell inView:[cell controlView]]; +} + + + +- (void)drawInteriorWithTabCell:(PSMTabBarCell *)cell inView:(NSView*)controlView +{ + NSRect cellFrame = [cell frame]; + float labelPosition = cellFrame.origin.x + MARGIN_X; + + // close button + if ([cell hasCloseButton] && ![cell isCloseButtonSuppressed]) { + NSSize closeButtonSize = NSZeroSize; + NSRect closeButtonRect = [cell closeButtonRectForFrame:cellFrame]; + NSImage * closeButton = nil; + + closeButton = metalCloseButton; + if ([cell closeButtonOver]) closeButton = metalCloseButtonOver; + if ([cell closeButtonPressed]) closeButton = metalCloseButtonDown; + + closeButtonSize = [closeButton size]; + if ([controlView isFlipped]) { + closeButtonRect.origin.y += closeButtonRect.size.height; + } + + [closeButton compositeToPoint:closeButtonRect.origin operation:NSCompositeSourceOver fraction:1.0]; + + // scoot label over + labelPosition += closeButtonSize.width + kPSMTabBarCellPadding; + } + + // icon + if([cell hasIcon]){ + NSRect iconRect = [self iconRectForTabCell:cell]; + NSImage *icon = [[[[cell representedObject] identifier] content] icon]; + if ([controlView isFlipped]) { + iconRect.origin.y = cellFrame.size.height - iconRect.origin.y; + } + [icon compositeToPoint:iconRect.origin operation:NSCompositeSourceOver fraction:1.0]; + + // scoot label over + labelPosition += iconRect.size.width + kPSMTabBarCellPadding; + } + + // object counter + if([cell count] > 0){ + [[NSColor colorWithCalibratedWhite:0.3 alpha:0.6] set]; + NSBezierPath *path = [NSBezierPath bezierPath]; + NSRect myRect = [self objectCounterRectForTabCell:cell]; + if([cell state] == NSOnState) + myRect.origin.y -= 1.0; + [path moveToPoint:NSMakePoint(myRect.origin.x + kPSMMetalObjectCounterRadius, myRect.origin.y)]; + [path lineToPoint:NSMakePoint(myRect.origin.x + myRect.size.width - kPSMMetalObjectCounterRadius, myRect.origin.y)]; + [path appendBezierPathWithArcWithCenter:NSMakePoint(myRect.origin.x + myRect.size.width - kPSMMetalObjectCounterRadius, myRect.origin.y + kPSMMetalObjectCounterRadius) radius:kPSMMetalObjectCounterRadius startAngle:270.0 endAngle:90.0]; + [path lineToPoint:NSMakePoint(myRect.origin.x + kPSMMetalObjectCounterRadius, myRect.origin.y + myRect.size.height)]; + [path appendBezierPathWithArcWithCenter:NSMakePoint(myRect.origin.x + kPSMMetalObjectCounterRadius, myRect.origin.y + kPSMMetalObjectCounterRadius) radius:kPSMMetalObjectCounterRadius startAngle:90.0 endAngle:270.0]; + [path fill]; + + // draw attributed string centered in area + NSRect counterStringRect; + NSAttributedString *counterString = [self attributedObjectCountValueForTabCell:cell]; + counterStringRect.size = [counterString size]; + counterStringRect.origin.x = myRect.origin.x + ((myRect.size.width - counterStringRect.size.width) / 2.0) + 0.25; + counterStringRect.origin.y = myRect.origin.y + ((myRect.size.height - counterStringRect.size.height) / 2.0) + 0.5; + [counterString drawInRect:counterStringRect]; + } + + // label rect + NSRect labelRect; + labelRect.origin.x = labelPosition; + labelRect.size.width = cellFrame.size.width - (labelRect.origin.x - cellFrame.origin.x) - kPSMTabBarCellPadding; + labelRect.size.height = cellFrame.size.height; + labelRect.origin.y = cellFrame.origin.y + MARGIN_Y + 1.0; + + if([cell state] == NSOnState){ + labelRect.origin.y -= 1; + } + + if(![[cell indicator] isHidden]) + labelRect.size.width -= (kPSMTabBarIndicatorWidth + kPSMTabBarCellPadding); + + if([cell count] > 0) + labelRect.size.width -= ([self objectCounterRectForTabCell:cell].size.width + kPSMTabBarCellPadding); + + // label + [[cell attributedStringValue] drawInRect:labelRect]; +} + +- (void)drawTabBar:(PSMTabBarControl *)bar inRect:(NSRect)rect +{ + NSDrawWindowBackground(rect); + [[NSColor colorWithCalibratedWhite:0.0 alpha:0.2] set]; + NSRectFillUsingOperation(rect, NSCompositeSourceAtop); + [[NSColor darkGrayColor] set]; + [NSBezierPath strokeLineFromPoint:NSMakePoint(rect.origin.x,rect.origin.y+0.5) toPoint:NSMakePoint(rect.origin.x+rect.size.width,rect.origin.y+0.5)]; + [NSBezierPath strokeLineFromPoint:NSMakePoint(rect.origin.x,rect.origin.y+rect.size.height-0.5) toPoint:NSMakePoint(rect.origin.x+rect.size.width,rect.origin.y+rect.size.height-0.5)]; + + // no tab view == not connected + if(![bar tabView]){ + NSRect labelRect = rect; + labelRect.size.height -= 4.0; + labelRect.origin.y += 4.0; + NSMutableAttributedString *attrStr; + NSString *contents = @"PSMTabBarControl"; + attrStr = [[[NSMutableAttributedString alloc] initWithString:contents] autorelease]; + NSRange range = NSMakeRange(0, [contents length]); + [attrStr addAttribute:NSFontAttributeName value:[NSFont systemFontOfSize:11.0] range:range]; + NSMutableParagraphStyle *centeredParagraphStyle = nil; + if (!centeredParagraphStyle) { + centeredParagraphStyle = [[[NSParagraphStyle defaultParagraphStyle] mutableCopy] retain]; + [centeredParagraphStyle setAlignment:NSCenterTextAlignment]; + } + [attrStr addAttribute:NSParagraphStyleAttributeName value:centeredParagraphStyle range:range]; + [attrStr drawInRect:labelRect]; + return; + } + + // draw cells + NSEnumerator *e = [[bar cells] objectEnumerator]; + PSMTabBarCell *cell; + while(cell = [e nextObject]){ + if(![cell isInOverflowMenu]){ + [cell drawWithFrame:[cell frame] inView:bar]; + } + } +} + +#pragma mark - +#pragma mark Archiving + +- (void)encodeWithCoder:(NSCoder *)aCoder +{ + //[super encodeWithCoder:aCoder]; + if ([aCoder allowsKeyedCoding]) { + [aCoder encodeObject:metalCloseButton forKey:@"metalCloseButton"]; + [aCoder encodeObject:metalCloseButtonDown forKey:@"metalCloseButtonDown"]; + [aCoder encodeObject:metalCloseButtonOver forKey:@"metalCloseButtonOver"]; + [aCoder encodeObject:_addTabButtonImage forKey:@"addTabButtonImage"]; + [aCoder encodeObject:_addTabButtonPressedImage forKey:@"addTabButtonPressedImage"]; + [aCoder encodeObject:_addTabButtonRolloverImage forKey:@"addTabButtonRolloverImage"]; + } +} + +- (id)initWithCoder:(NSCoder *)aDecoder +{ + // self = [super initWithCoder:aDecoder]; + //if (self) { + if ([aDecoder allowsKeyedCoding]) { + metalCloseButton = [[aDecoder decodeObjectForKey:@"metalCloseButton"] retain]; + metalCloseButtonDown = [[aDecoder decodeObjectForKey:@"metalCloseButtonDown"] retain]; + metalCloseButtonOver = [[aDecoder decodeObjectForKey:@"metalCloseButtonOver"] retain]; + _addTabButtonImage = [[aDecoder decodeObjectForKey:@"addTabButtonImage"] retain]; + _addTabButtonPressedImage = [[aDecoder decodeObjectForKey:@"addTabButtonPressedImage"] retain]; + _addTabButtonRolloverImage = [[aDecoder decodeObjectForKey:@"addTabButtonRolloverImage"] retain]; + } + //} + return self; +} + +@end diff --git a/PSMTabBarControl/source/PSMOverflowPopUpButton.h b/PSMTabBarControl/source/PSMOverflowPopUpButton.h new file mode 100644 index 0000000000..1ee16bdcb2 --- /dev/null +++ b/PSMTabBarControl/source/PSMOverflowPopUpButton.h @@ -0,0 +1,21 @@ +// +// PSMOverflowPopUpButton.h +// PSMTabBarControl +// +// Created by John Pannell on 11/4/05. +// Copyright 2005 Positive Spin Media. All rights reserved. +// + +#import + + +@interface PSMOverflowPopUpButton : NSPopUpButton { + NSImage *_PSMTabBarOverflowPopUpImage; + NSImage *_PSMTabBarOverflowDownPopUpImage; + BOOL _down; +} + +// archiving +- (void)encodeWithCoder:(NSCoder *)aCoder; +- (id)initWithCoder:(NSCoder *)aDecoder; +@end diff --git a/PSMTabBarControl/source/PSMOverflowPopUpButton.m b/PSMTabBarControl/source/PSMOverflowPopUpButton.m new file mode 100644 index 0000000000..d3623f1edc --- /dev/null +++ b/PSMTabBarControl/source/PSMOverflowPopUpButton.m @@ -0,0 +1,89 @@ +// +// PSMOverflowPopUpButton.m +// PSMTabBarControl +// +// Created by John Pannell on 11/4/05. +// Copyright 2005 Positive Spin Media. All rights reserved. +// + +#import "PSMOverflowPopUpButton.h" +#import "PSMTabBarControl.h" + +@implementation PSMOverflowPopUpButton + +- (id)initWithFrame:(NSRect)frameRect pullsDown:(BOOL)flag +{ + self=[super initWithFrame:frameRect pullsDown:YES]; + if (self) { + [self setBezelStyle:NSRegularSquareBezelStyle]; + [self setBordered:NO]; + [self setTitle:@""]; + [self setPreferredEdge:NSMaxXEdge]; + _PSMTabBarOverflowPopUpImage = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"overflowImage"]]; + _PSMTabBarOverflowDownPopUpImage = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"overflowImagePressed"]]; + } + return self; +} + +- (void)dealloc +{ + [_PSMTabBarOverflowPopUpImage release]; + [_PSMTabBarOverflowDownPopUpImage release]; + [super dealloc]; +} + +- (void)drawRect:(NSRect)rect +{ + if(_PSMTabBarOverflowPopUpImage == nil){ + [super drawRect:rect]; + return; + } + + NSImage *image = (_down) ? _PSMTabBarOverflowDownPopUpImage : _PSMTabBarOverflowPopUpImage; + NSSize imageSize = [image size]; + rect.origin.x = NSMidX(rect) - (imageSize.width * 0.5); + rect.origin.y = NSMidY(rect) - (imageSize.height * 0.5); + if([self isFlipped]) { + rect.origin.y += imageSize.height; + } + [image compositeToPoint:rect.origin operation:NSCompositeSourceOver]; +} + +- (void)mouseDown:(NSEvent *)event +{ + _down = YES; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(notificationReceived:) name:NSMenuDidEndTrackingNotification object:[self menu]]; + [self setNeedsDisplay:YES]; + [super mouseDown:event]; +} + +- (void)notificationReceived:(NSNotification *)notification +{ + _down = NO; + [self setNeedsDisplay:YES]; + [[NSNotificationCenter defaultCenter] removeObserver:self]; +} + +#pragma mark - +#pragma mark Archiving + +- (void)encodeWithCoder:(NSCoder *)aCoder { + [super encodeWithCoder:aCoder]; + if ([aCoder allowsKeyedCoding]) { + [aCoder encodeObject:_PSMTabBarOverflowPopUpImage forKey:@"PSMTabBarOverflowPopUpImage"]; + [aCoder encodeObject:_PSMTabBarOverflowDownPopUpImage forKey:@"PSMTabBarOverflowDownPopUpImage"]; + } +} + +- (id)initWithCoder:(NSCoder *)aDecoder { + self = [super initWithCoder:aDecoder]; + if (self) { + if ([aDecoder allowsKeyedCoding]) { + _PSMTabBarOverflowPopUpImage = [[aDecoder decodeObjectForKey:@"PSMTabBarOverflowPopUpImage"] retain]; + _PSMTabBarOverflowDownPopUpImage = [[aDecoder decodeObjectForKey:@"PSMTabBarOverflowDownPopUpImage"] retain]; + } + } + return self; +} + +@end diff --git a/PSMTabBarControl/source/PSMProgressIndicator.h b/PSMTabBarControl/source/PSMProgressIndicator.h new file mode 100644 index 0000000000..8f56bd73ae --- /dev/null +++ b/PSMTabBarControl/source/PSMProgressIndicator.h @@ -0,0 +1,23 @@ +// +// PSMProgressIndicator.h +// PSMTabBarControl +// +// Created by John Pannell on 2/23/06. +// Copyright 2006 Positive Spin Media. All rights reserved. +// + +#import +#import "PSMTabBarControl.h" + + +@interface PSMProgressIndicator : NSProgressIndicator { + +} + +@end + +@interface PSMTabBarControl (LayoutPlease) + +- (void)update; + +@end \ No newline at end of file diff --git a/PSMTabBarControl/source/PSMProgressIndicator.m b/PSMTabBarControl/source/PSMProgressIndicator.m new file mode 100644 index 0000000000..d3046d518a --- /dev/null +++ b/PSMTabBarControl/source/PSMProgressIndicator.m @@ -0,0 +1,20 @@ +// +// PSMProgressIndicator.m +// PSMTabBarControl +// +// Created by John Pannell on 2/23/06. +// Copyright 2006 Positive Spin Media. All rights reserved. +// + +#import "PSMProgressIndicator.h" + +@implementation PSMProgressIndicator + +// overrides to make tab bar control re-layout things if status changes +- (void)setHidden:(BOOL)flag +{ + [super setHidden:flag]; + [(PSMTabBarControl *)[self superview] update]; +} + +@end diff --git a/PSMTabBarControl/source/PSMRolloverButton.h b/PSMTabBarControl/source/PSMRolloverButton.h new file mode 100644 index 0000000000..d78b47c272 --- /dev/null +++ b/PSMTabBarControl/source/PSMRolloverButton.h @@ -0,0 +1,29 @@ +// +// PSMOverflowPopUpButton.h +// NetScrape +// +// Created by John Pannell on 8/4/04. +// Copyright 2004 Positive Spin Media. All rights reserved. +// + +#import + +@interface PSMRolloverButton : NSButton +{ + NSImage *_rolloverImage; + NSImage *_usualImage; + NSTrackingRectTag _myTrackingRectTag; +} + +// the regular image +- (void)setUsualImage:(NSImage *)newImage; +- (NSImage *)usualImage; + +// the rollover image +- (void)setRolloverImage:(NSImage *)newImage; +- (NSImage *)rolloverImage; + +// tracking rect for mouse events +- (void)addTrackingRect; +- (void)removeTrackingRect; +@end \ No newline at end of file diff --git a/PSMTabBarControl/source/PSMRolloverButton.m b/PSMTabBarControl/source/PSMRolloverButton.m new file mode 100644 index 0000000000..2ed10f95c6 --- /dev/null +++ b/PSMTabBarControl/source/PSMRolloverButton.m @@ -0,0 +1,107 @@ +// +// PSMOverflowPopUpButton.m +// NetScrape +// +// Created by John Pannell on 8/4/04. +// Copyright 2004 Positive Spin Media. All rights reserved. +// + +#import "PSMRolloverButton.h" + +@implementation PSMRolloverButton + +// the regular image +- (void)setUsualImage:(NSImage *)newImage +{ + [newImage retain]; + [_usualImage release]; + _usualImage = newImage; + [self setImage:_usualImage]; +} + +- (NSImage *)usualImage +{ + return _usualImage; +} + +- (void)setRolloverImage:(NSImage *)newImage +{ + [newImage retain]; + [_rolloverImage release]; + _rolloverImage = newImage; +} + +- (NSImage *)rolloverImage +{ + return _rolloverImage; +} + +- (void)addTrackingRect +{ + // assign a tracking rect to watch for mouse enter/exit + _myTrackingRectTag = [self addTrackingRect:[self bounds] owner:self userData:nil assumeInside:NO]; +} + +- (void)removeTrackingRect +{ + [self removeTrackingRect:_myTrackingRectTag]; +} + +// override for rollover effect +- (void)mouseEntered:(NSEvent *)theEvent; +{ + // set rollover image + [self setImage:_rolloverImage]; + [self setNeedsDisplay]; + [[self superview] setNeedsDisplay:YES]; // eliminates a drawing artifact +} + +- (void)mouseExited:(NSEvent *)theEvent; +{ + // restore usual image + [self setImage:_usualImage]; + [self setNeedsDisplay]; + [[self superview] setNeedsDisplay:YES]; // eliminates a drawing artifact +} + +- (void)mouseDown:(NSEvent *)theEvent +{ + // eliminates drawing artifact + [[NSRunLoop currentRunLoop] performSelector:@selector(display) target:[self superview] argument:nil order:1 modes:[NSArray arrayWithObjects:@"NSEventTrackingRunLoopMode", @"NSDefaultRunLoopMode", nil]]; + [super mouseDown:theEvent]; +} + +- (void)resetCursorRects +{ + // called when the button rect has been changed + [self removeTrackingRect]; + [self addTrackingRect]; + [[self superview] setNeedsDisplay:YES]; // eliminates a drawing artifact +} + +#pragma mark - +#pragma mark Archiving + +- (void)encodeWithCoder:(NSCoder *)aCoder { + [super encodeWithCoder:aCoder]; + if ([aCoder allowsKeyedCoding]) { + [aCoder encodeObject:_rolloverImage forKey:@"rolloverImage"]; + [aCoder encodeObject:_usualImage forKey:@"usualImage"]; + [aCoder encodeInt:_myTrackingRectTag forKey:@"myTrackingRectTag"]; + } +} + +- (id)initWithCoder:(NSCoder *)aDecoder { + self = [super initWithCoder:aDecoder]; + if (self) { + if ([aDecoder allowsKeyedCoding]) { + _rolloverImage = [[aDecoder decodeObjectForKey:@"rolloverImage"] retain]; + _usualImage = [[aDecoder decodeObjectForKey:@"usualImage"] retain]; + _myTrackingRectTag = [aDecoder decodeIntForKey:@"myTrackingRectTag"]; + } + } + return self; +} + + +@end diff --git a/PSMTabBarControl/source/PSMTabBarCell.h b/PSMTabBarControl/source/PSMTabBarCell.h new file mode 100644 index 0000000000..51717d6280 --- /dev/null +++ b/PSMTabBarControl/source/PSMTabBarCell.h @@ -0,0 +1,102 @@ +// +// PSMTabBarCell.h +// PSMTabBarControl +// +// Created by John Pannell on 10/13/05. +// Copyright 2005 Positive Spin Media. All rights reserved. +// + +#import +#import "PSMTabBarControl.h" + +@class PSMTabBarControl; +@class PSMProgressIndicator; + +@interface PSMTabBarCell : NSActionCell { + // sizing + NSRect _frame; + NSSize _stringSize; + int _currentStep; + BOOL _isPlaceholder; + + // state + int _tabState; + NSTrackingRectTag _closeButtonTrackingTag; // left side tracking, if dragging + NSTrackingRectTag _cellTrackingTag; // right side tracking, if dragging + BOOL _closeButtonOver; + BOOL _closeButtonPressed; + PSMProgressIndicator *_indicator; + BOOL _isInOverflowMenu; + BOOL _hasCloseButton; + BOOL _isCloseButtonSuppressed; + BOOL _hasIcon; + int _count; +} + +// creation/destruction +- (id)initWithControlView:(PSMTabBarControl *)controlView; +- (id)initPlaceholderWithFrame:(NSRect)frame expanded:(BOOL)value inControlView:(PSMTabBarControl *)controlView; +- (void)dealloc; + +// accessors +- (id)controlView; +- (void)setControlView:(id)view; +- (NSTrackingRectTag)closeButtonTrackingTag; +- (void)setCloseButtonTrackingTag:(NSTrackingRectTag)tag; +- (NSTrackingRectTag)cellTrackingTag; +- (void)setCellTrackingTag:(NSTrackingRectTag)tag; +- (float)width; +- (NSRect)frame; +- (void)setFrame:(NSRect)rect; +- (void)setStringValue:(NSString *)aString; +- (NSSize)stringSize; +- (NSAttributedString *)attributedStringValue; +- (int)tabState; +- (void)setTabState:(int)state; +- (NSProgressIndicator *)indicator; +- (BOOL)isInOverflowMenu; +- (void)setIsInOverflowMenu:(BOOL)value; +- (BOOL)closeButtonPressed; +- (void)setCloseButtonPressed:(BOOL)value; +- (BOOL)closeButtonOver; +- (void)setCloseButtonOver:(BOOL)value; +- (BOOL)hasCloseButton; +- (void)setHasCloseButton:(BOOL)set; +- (void)setCloseButtonSuppressed:(BOOL)suppress; +- (BOOL)isCloseButtonSuppressed; +- (BOOL)hasIcon; +- (void)setHasIcon:(BOOL)value; +- (int)count; +- (void)setCount:(int)value; +- (BOOL)isPlaceholder; +- (void)setIsPlaceholder:(BOOL)value; +- (int)currentStep; +- (void)setCurrentStep:(int)value; + +// component attributes +- (NSRect)indicatorRectForFrame:(NSRect)cellFrame; +- (NSRect)closeButtonRectForFrame:(NSRect)cellFrame; +- (float)minimumWidthOfCell; +- (float)desiredWidthOfCell; + +// drawing +- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView; + +// tracking the mouse +- (void)mouseEntered:(NSEvent *)theEvent; +- (void)mouseExited:(NSEvent *)theEvent; + +// drag support +- (NSImage*)dragImageForRect:(NSRect)cellFrame; + +// archiving +- (void)encodeWithCoder:(NSCoder *)aCoder; +- (id)initWithCoder:(NSCoder *)aDecoder; + +@end + +@interface PSMTabBarControl (CellAccessors) + +- (id)style; + +@end diff --git a/PSMTabBarControl/source/PSMTabBarCell.m b/PSMTabBarControl/source/PSMTabBarCell.m new file mode 100644 index 0000000000..c71793ba16 --- /dev/null +++ b/PSMTabBarControl/source/PSMTabBarCell.m @@ -0,0 +1,397 @@ +// +// PSMTabBarCell.m +// PSMTabBarControl +// +// Created by John Pannell on 10/13/05. +// Copyright 2005 Positive Spin Media. All rights reserved. +// + +#import "PSMTabBarCell.h" +#import "PSMTabBarControl.h" +#import "PSMTabStyle.h" +#import "PSMProgressIndicator.h" +#import "PSMTabDragAssistant.h" + + +@implementation PSMTabBarCell + +#pragma mark - +#pragma mark Creation/Destruction +- (id)initWithControlView:(PSMTabBarControl *)controlView +{ + self = [super init]; + if(self){ + _controlView = controlView; + _closeButtonTrackingTag = 0; + _cellTrackingTag = 0; + _closeButtonOver = NO; + _closeButtonPressed = NO; + _indicator = [[PSMProgressIndicator alloc] initWithFrame:NSMakeRect(0.0,0.0,kPSMTabBarIndicatorWidth,kPSMTabBarIndicatorWidth)]; + [_indicator setStyle:NSProgressIndicatorSpinningStyle]; + [_indicator setAutoresizingMask:NSViewMinYMargin]; + _hasCloseButton = YES; + _isCloseButtonSuppressed = NO; + _count = 0; + _isPlaceholder = NO; + } + return self; +} + +- (id)initPlaceholderWithFrame:(NSRect)frame expanded:(BOOL)value inControlView:(PSMTabBarControl *)controlView +{ + self = [super init]; + if(self){ + _controlView = controlView; + _isPlaceholder = YES; + if(!value) + frame.size.width = 0.0; + [self setFrame:frame]; + _closeButtonTrackingTag = 0; + _cellTrackingTag = 0; + _closeButtonOver = NO; + _closeButtonPressed = NO; + _indicator = nil; + _hasCloseButton = YES; + _isCloseButtonSuppressed = NO; + _count = 0; + + if(value){ + [self setCurrentStep:(kPSMTabDragAnimationSteps - 1)]; + } else { + [self setCurrentStep:0]; + } + + } + + return self; +} + +- (void)dealloc +{ + [_indicator release]; + [super dealloc]; +} + +#pragma mark - +#pragma mark Accessors + +- (id)controlView +{ + return _controlView; +} + +- (void)setControlView:(id)view +{ + // no retain release pattern, as this simply switches a tab to another view. + _controlView = view; +} + +- (NSTrackingRectTag)closeButtonTrackingTag +{ + return _closeButtonTrackingTag; +} + +- (void)setCloseButtonTrackingTag:(NSTrackingRectTag)tag +{ + _closeButtonTrackingTag = tag; +} + +- (NSTrackingRectTag)cellTrackingTag +{ + return _cellTrackingTag; +} + +- (void)setCellTrackingTag:(NSTrackingRectTag)tag +{ + _cellTrackingTag = tag; +} + +- (float)width +{ + return _frame.size.width; +} + +- (NSRect)frame +{ + return _frame; +} + +- (void)setFrame:(NSRect)rect +{ + _frame = rect; +} + +- (void)setStringValue:(NSString *)aString +{ + [super setStringValue:aString]; + _stringSize = [[self attributedStringValue] size]; + // need to redisplay now - binding observation was too quick. + [_controlView update]; +} + +- (NSSize)stringSize +{ + return _stringSize; +} + +- (NSAttributedString *)attributedStringValue +{ + return [(id )[_controlView style] attributedStringValueForTabCell:self]; +} + +- (int)tabState +{ + return _tabState; +} + +- (void)setTabState:(int)state +{ + _tabState = state; +} + +- (NSProgressIndicator *)indicator +{ + return _indicator; +} + +- (BOOL)isInOverflowMenu +{ + return _isInOverflowMenu; +} + +- (void)setIsInOverflowMenu:(BOOL)value +{ + _isInOverflowMenu = value; +} + +- (BOOL)closeButtonPressed +{ + return _closeButtonPressed; +} + +- (void)setCloseButtonPressed:(BOOL)value +{ + _closeButtonPressed = value; +} + +- (BOOL)closeButtonOver +{ + return _closeButtonOver; +} + +- (void)setCloseButtonOver:(BOOL)value +{ + _closeButtonOver = value; +} + +- (BOOL)hasCloseButton +{ + return _hasCloseButton; +} + +- (void)setHasCloseButton:(BOOL)set; +{ + _hasCloseButton = set; +} + +- (void)setCloseButtonSuppressed:(BOOL)suppress; +{ + _isCloseButtonSuppressed = suppress; +} + +- (BOOL)isCloseButtonSuppressed; +{ + return _isCloseButtonSuppressed; +} + +- (BOOL)hasIcon +{ + return _hasIcon; +} + +- (void)setHasIcon:(BOOL)value +{ + _hasIcon = value; + [_controlView update]; // binding notice is too fast +} + +- (int)count +{ + return _count; +} + +- (void)setCount:(int)value +{ + _count = value; + [_controlView update]; // binding notice is too fast +} + +- (BOOL)isPlaceholder +{ + return _isPlaceholder; +} + +- (void)setIsPlaceholder:(BOOL)value; +{ + _isPlaceholder = value; +} + +- (int)currentStep +{ + return _currentStep; +} + +- (void)setCurrentStep:(int)value +{ + if(value < 0) + value = 0; + + if(value > (kPSMTabDragAnimationSteps - 1)) + value = (kPSMTabDragAnimationSteps - 1); + + _currentStep = value; +} + +#pragma mark - +#pragma mark Component Attributes + +- (NSRect)indicatorRectForFrame:(NSRect)cellFrame +{ + return [(id )[_controlView style] indicatorRectForTabCell:self]; +} + +- (NSRect)closeButtonRectForFrame:(NSRect)cellFrame +{ + return [(id )[_controlView style] closeButtonRectForTabCell:self]; +} + +- (float)minimumWidthOfCell +{ + return [(id )[_controlView style] minimumWidthOfTabCell:self]; +} + +- (float)desiredWidthOfCell +{ + return [(id )[_controlView style] desiredWidthOfTabCell:self]; +} + +#pragma mark - +#pragma mark Drawing + +- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView +{ + if(_isPlaceholder){ + [[NSColor colorWithCalibratedWhite:0.0 alpha:0.2] set]; + NSRectFillUsingOperation(cellFrame, NSCompositeSourceAtop); + return; + } + + [(id )[_controlView style] drawTabCell:self]; +} + +#pragma mark - +#pragma mark Tracking + +- (void)mouseEntered:(NSEvent *)theEvent +{ + // check for which tag + if([theEvent trackingNumber] == _closeButtonTrackingTag){ + _closeButtonOver = YES; + } + if([theEvent trackingNumber] == _cellTrackingTag){ + [self setHighlighted:YES]; + } + [_controlView setNeedsDisplay]; +} + +- (void)mouseExited:(NSEvent *)theEvent +{ + // check for which tag + if([theEvent trackingNumber] == _closeButtonTrackingTag){ + _closeButtonOver = NO; + } + if([theEvent trackingNumber] == _cellTrackingTag){ + [self setHighlighted:NO]; + } + [_controlView setNeedsDisplay]; +} + +#pragma mark - +#pragma mark Drag Support + +- (NSImage*)dragImageForRect:(NSRect)cellFrame +{ + if(([self state] == NSOnState) && ([[_controlView styleName] isEqualToString:@"Metal"])) + cellFrame.size.width += 1.0; + [_controlView lockFocus]; + NSBitmapImageRep *rep = [[NSBitmapImageRep alloc] initWithFocusedViewRect:cellFrame]; + [_controlView unlockFocus]; + NSImage *image = [[[NSImage alloc] initWithSize:[rep size]] autorelease]; + [image addRepresentation:rep]; + NSImage *returnImage = [[[NSImage alloc] initWithSize:[rep size]] autorelease]; + [returnImage lockFocus]; + [image compositeToPoint:NSMakePoint(0.0, 0.0) operation:NSCompositeSourceOver fraction:0.7]; + [returnImage unlockFocus]; + if(![[self indicator] isHidden]){ + NSImage *pi = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"pi"]]; + [returnImage lockFocus]; + NSPoint indicatorPoint = NSMakePoint([self frame].size.width - MARGIN_X - kPSMTabBarIndicatorWidth, MARGIN_Y); + if(([self state] == NSOnState) && ([[_controlView styleName] isEqualToString:@"Metal"])) + indicatorPoint.y += 1.0; + [pi compositeToPoint:indicatorPoint operation:NSCompositeSourceOver fraction:0.7]; + [returnImage unlockFocus]; + [pi release]; + } + return returnImage; +} + +#pragma mark - +#pragma mark Archiving + +- (void)encodeWithCoder:(NSCoder *)aCoder { + [super encodeWithCoder:aCoder]; + if ([aCoder allowsKeyedCoding]) { + [aCoder encodeRect:_frame forKey:@"frame"]; + [aCoder encodeSize:_stringSize forKey:@"stringSize"]; + [aCoder encodeInt:_currentStep forKey:@"currentStep"]; + [aCoder encodeBool:_isPlaceholder forKey:@"isPlaceholder"]; + [aCoder encodeInt:_tabState forKey:@"tabState"]; + [aCoder encodeInt:_closeButtonTrackingTag forKey:@"closeButtonTrackingTag"]; + [aCoder encodeInt:_cellTrackingTag forKey:@"cellTrackingTag"]; + [aCoder encodeBool:_closeButtonOver forKey:@"closeButtonOver"]; + [aCoder encodeBool:_closeButtonPressed forKey:@"closeButtonPressed"]; + [aCoder encodeObject:_indicator forKey:@"indicator"]; + [aCoder encodeBool:_isInOverflowMenu forKey:@"isInOverflowMenu"]; + [aCoder encodeBool:_hasCloseButton forKey:@"hasCloseButton"]; + [aCoder encodeBool:_isCloseButtonSuppressed forKey:@"isCloseButtonSuppressed"]; + [aCoder encodeBool:_hasIcon forKey:@"hasIcon"]; + [aCoder encodeInt:_count forKey:@"count"]; + } +} + +- (id)initWithCoder:(NSCoder *)aDecoder { + self = [super initWithCoder:aDecoder]; + if (self) { + if ([aDecoder allowsKeyedCoding]) { + _frame = [aDecoder decodeRectForKey:@"frame"]; + NSLog(@"decoding cell"); + _stringSize = [aDecoder decodeSizeForKey:@"stringSize"]; + _currentStep = [aDecoder decodeIntForKey:@"currentStep"]; + _isPlaceholder = [aDecoder decodeBoolForKey:@"isPlaceholder"]; + _tabState = [aDecoder decodeIntForKey:@"tabState"]; + _closeButtonTrackingTag = [aDecoder decodeIntForKey:@"closeButtonTrackingTag"]; + _cellTrackingTag = [aDecoder decodeIntForKey:@"cellTrackingTag"]; + _closeButtonOver = [aDecoder decodeBoolForKey:@"closeButtonOver"]; + _closeButtonPressed = [aDecoder decodeBoolForKey:@"closeButtonPressed"]; + _indicator = [[aDecoder decodeObjectForKey:@"indicator"] retain]; + _isInOverflowMenu = [aDecoder decodeBoolForKey:@"isInOverflowMenu"]; + _hasCloseButton = [aDecoder decodeBoolForKey:@"hasCloseButton"]; + _isCloseButtonSuppressed = [aDecoder decodeBoolForKey:@"isCloseButtonSuppressed"]; + _hasIcon = [aDecoder decodeBoolForKey:@"hasIcon"]; + _count = [aDecoder decodeIntForKey:@"count"]; + } + } + return self; +} + +@end diff --git a/PSMTabBarControl/source/PSMTabBarControl.h b/PSMTabBarControl/source/PSMTabBarControl.h new file mode 100644 index 0000000000..361c744136 --- /dev/null +++ b/PSMTabBarControl/source/PSMTabBarControl.h @@ -0,0 +1,124 @@ +// +// PSMTabBarControl.h +// PSMTabBarControl +// +// Created by John Pannell on 10/13/05. +// Copyright 2005 Positive Spin Media. All rights reserved. +// + +/* + This view provides a control interface to manage a regular NSTabView. It looks and works like the tabbed browsing interface of many popular browsers. + */ + +#import + +#define kPSMTabBarControlHeight 22 +// internal cell border +#define MARGIN_X 6 +#define MARGIN_Y 3 +// padding between objects +#define kPSMTabBarCellPadding 4 +// fixed size objects +#define kPSMMinimumTitleWidth 30 +#define kPSMTabBarIndicatorWidth 16.0 +#define kPSMTabBarIconWidth 16.0 +#define kPSMHideAnimationSteps 2.0 + +@class PSMOverflowPopUpButton; +@class PSMRolloverButton; +@class PSMTabBarCell; +@protocol PSMTabStyle; + +enum { + PSMTab_SelectedMask = 1 << 1, + PSMTab_LeftIsSelectedMask = 1 << 2, + PSMTab_RightIsSelectedMask = 1 << 3, + PSMTab_PositionLeftMask = 1 << 4, + PSMTab_PositionMiddleMask = 1 << 5, + PSMTab_PositionRightMask = 1 << 6, + PSMTab_PositionSingleMask = 1 << 7 +}; + +@interface PSMTabBarControl : NSControl { + + // control basics + NSMutableArray *_cells; // the cells that draw the tabs + IBOutlet NSTabView *tabView; // the tab view being navigated + PSMOverflowPopUpButton *_overflowPopUpButton; // for too many tabs + PSMRolloverButton *_addTabButton; + + // drawing style + id style; + BOOL _canCloseOnlyTab; + BOOL _hideForSingleTab; + BOOL _showAddTabButton; + BOOL _sizeCellsToFit; + + // cell width + int _cellMinWidth; + int _cellMaxWidth; + int _cellOptimumWidth; + + // animation for hide/show + int _currentStep; + BOOL _isHidden; + BOOL _hideIndicators; + IBOutlet id partnerView; // gets resized when hide/show + BOOL _awakenedFromNib; + + // drag and drop + NSEvent *_lastMouseDownEvent; // keep this for dragging reference + BOOL _allowsDragBetweenWindows; + + // MVC help + IBOutlet id delegate; +} + +// control characteristics ++ (NSBundle *)bundle; + +// control configuration +- (BOOL)canCloseOnlyTab; +- (void)setCanCloseOnlyTab:(BOOL)value; +- (NSString *)styleName; +- (void)setStyleNamed:(NSString *)name; +- (BOOL)hideForSingleTab; +- (void)setHideForSingleTab:(BOOL)value; +- (BOOL)showAddTabButton; +- (void)setShowAddTabButton:(BOOL)value; +- (int)cellMinWidth; +- (void)setCellMinWidth:(int)value; +- (int)cellMaxWidth; +- (void)setCellMaxWidth:(int)value; +- (int)cellOptimumWidth; +- (void)setCellOptimumWidth:(int)value; +- (BOOL)sizeCellsToFit; +- (void)setSizeCellsToFit:(BOOL)value; +- (BOOL)allowsDragBetweenWindows; +- (void)setAllowsDragBetweenWindows:(BOOL)flag; + +// accessors +- (NSTabView *)tabView; +- (void)setTabView:(NSTabView *)view; +- (id)delegate; +- (void)setDelegate:(id)object; +- (id)partnerView; +- (void)setPartnerView:(id)view; + +// the buttons +- (PSMRolloverButton *)addTabButton; +- (PSMOverflowPopUpButton *)overflowPopUpButton; +- (NSMutableArray *)representedTabViewItems; + +// special effects +- (void)hideTabBar:(BOOL)hide animate:(BOOL)animate; + +@end + + +@interface NSObject (TabBarControlDelegateMethods) +- (BOOL)tabView:(NSTabView *)aTabView shouldCloseTabViewItem:(NSTabViewItem *)tabViewItem; +- (void)tabView:(NSTabView *)aTabView willCloseTabViewItem:(NSTabViewItem *)tabViewItem; +- (void)tabView:(NSTabView *)aTabView didCloseTabViewItem:(NSTabViewItem *)tabViewItem; +- (void)tabView:(NSTabView *)aTabView didDragTabViewItem:(NSTabViewItem *)tabViewItem toIndex:(int)idx; +@end diff --git a/PSMTabBarControl/source/PSMTabBarControl.m b/PSMTabBarControl/source/PSMTabBarControl.m new file mode 100644 index 0000000000..df4c6aed51 --- /dev/null +++ b/PSMTabBarControl/source/PSMTabBarControl.m @@ -0,0 +1,1398 @@ +// +// PSMTabBarControl.m +// PSMTabBarControl +// +// Created by John Pannell on 10/13/05. +// Copyright 2005 Positive Spin Media. All rights reserved. +// + +#import "PSMTabBarControl.h" +#import "PSMTabBarCell.h" +#import "PSMOverflowPopUpButton.h" +#import "PSMRolloverButton.h" +#import "PSMTabStyle.h" +#import "PSMMetalTabStyle.h" +#import "PSMAquaTabStyle.h" +#import "PSMUnifiedTabStyle.h" +#import "PSMTabDragAssistant.h" + +@interface PSMTabBarControl (Private) +// characteristics +- (float)availableCellWidth; +- (NSRect)genericCellRect; + + // constructor/destructor +- (void)initAddedProperties; +- (void)dealloc; + + // accessors +- (NSEvent *)lastMouseDownEvent; +- (void)setLastMouseDownEvent:(NSEvent *)event; + + // contents +- (void)addTabViewItem:(NSTabViewItem *)item; +- (void)removeTabForCell:(PSMTabBarCell *)cell; + + // draw +- (void)update; + + // actions +- (void)overflowMenuAction:(id)sender; +- (void)closeTabClick:(id)sender; +- (void)tabClick:(id)sender; +- (void)tabNothing:(id)sender; +- (void)frameDidChange:(NSNotification *)notification; +- (void)windowDidMove:(NSNotification *)aNotification; +- (void)windowStatusDidChange:(NSNotification *)notification; + + // NSTabView delegate +- (void)tabView:(NSTabView *)tabView didSelectTabViewItem:(NSTabViewItem *)tabViewItem; +- (BOOL)tabView:(NSTabView *)tabView shouldSelectTabViewItem:(NSTabViewItem *)tabViewItem; +- (void)tabView:(NSTabView *)tabView willSelectTabViewItem:(NSTabViewItem *)tabViewItem; +- (void)tabViewDidChangeNumberOfTabViewItems:(NSTabView *)tabView; + + // archiving +- (void)encodeWithCoder:(NSCoder *)aCoder; +- (id)initWithCoder:(NSCoder *)aDecoder; + + // convenience +- (id)cellForPoint:(NSPoint)point cellFrame:(NSRectPointer)outFrame; +- (PSMTabBarCell *)lastVisibleTab; +- (int)numberOfVisibleTabs; + +@end + +@implementation PSMTabBarControl +#pragma mark - +#pragma mark Characteristics ++ (NSBundle *)bundle; +{ + static NSBundle *bundle = nil; + if (!bundle) bundle = [NSBundle bundleForClass:[PSMTabBarControl class]]; + return bundle; +} + +- (float)availableCellWidth +{ + float width = [self frame].size.width; + width = width - [style leftMarginForTabBarControl] - [style rightMarginForTabBarControl]; + return width; +} + +- (NSRect)genericCellRect +{ + NSRect aRect=[self frame]; + aRect.origin.x = [style leftMarginForTabBarControl]; + aRect.origin.y = 0.0; + aRect.size.width = [self availableCellWidth]; + aRect.size.height = kPSMTabBarControlHeight; + return aRect; +} + +#pragma mark - +#pragma mark Constructor/destructor + +- (void)initAddedProperties +{ + _cells = [[NSMutableArray alloc] initWithCapacity:10]; + + // default config + _allowsDragBetweenWindows = YES; + _canCloseOnlyTab = NO; + _showAddTabButton = NO; + _hideForSingleTab = NO; + _sizeCellsToFit = NO; + _isHidden = NO; + _hideIndicators = NO; + _awakenedFromNib = NO; + _cellMinWidth = 100; + _cellMaxWidth = 280; + _cellOptimumWidth = 130; + style = [[PSMMetalTabStyle alloc] init]; + + // the overflow button/menu + NSRect overflowButtonRect = NSMakeRect([self frame].size.width - [style rightMarginForTabBarControl] + 1, 0, [style rightMarginForTabBarControl] - 1, [self frame].size.height); + _overflowPopUpButton = [[PSMOverflowPopUpButton alloc] initWithFrame:overflowButtonRect pullsDown:YES]; + if(_overflowPopUpButton){ + // configure + [_overflowPopUpButton setAutoresizingMask:NSViewNotSizable|NSViewMinXMargin]; + } + + // new tab button + NSRect addTabButtonRect = NSMakeRect([self frame].size.width - [style rightMarginForTabBarControl] + 1, 3.0, 16.0, 16.0); + _addTabButton = [[PSMRolloverButton alloc] initWithFrame:addTabButtonRect]; + if(_addTabButton){ + NSImage *newButtonImage = [style addTabButtonImage]; + if(newButtonImage) + [_addTabButton setUsualImage:newButtonImage]; + newButtonImage = [style addTabButtonPressedImage]; + if(newButtonImage) + [_addTabButton setAlternateImage:newButtonImage]; + newButtonImage = [style addTabButtonRolloverImage]; + if(newButtonImage) + [_addTabButton setRolloverImage:newButtonImage]; + [_addTabButton setTitle:@""]; + [_addTabButton setImagePosition:NSImageOnly]; + [_addTabButton setButtonType:NSMomentaryChangeButton]; + [_addTabButton setBordered:NO]; + [_addTabButton setBezelStyle:NSShadowlessSquareBezelStyle]; + if(_showAddTabButton){ + [_addTabButton setHidden:NO]; + } else { + [_addTabButton setHidden:YES]; + } + [_addTabButton setNeedsDisplay:YES]; + } +} + +- (id)initWithFrame:(NSRect)frame +{ + self = [super initWithFrame:frame]; + if (self) { + // Initialization + [self initAddedProperties]; + [self registerForDraggedTypes:[NSArray arrayWithObjects: @"PSMTabBarControlItemPBType", nil]]; + } + [self setTarget:self]; + return self; +} + +- (void)dealloc +{ + [_overflowPopUpButton release]; + [_cells release]; + [tabView release]; + [_addTabButton release]; + [partnerView release]; + [_lastMouseDownEvent release]; + [style release]; + [delegate release]; + + [self unregisterDraggedTypes]; + + [super dealloc]; +} + +- (void)awakeFromNib +{ + // build cells from existing tab view items + NSArray *existingItems = [tabView tabViewItems]; + NSEnumerator *e = [existingItems objectEnumerator]; + NSTabViewItem *item; + while(item = [e nextObject]){ + if(![[self representedTabViewItems] containsObject:item]) + [self addTabViewItem:item]; + } + + // resize + [self setPostsFrameChangedNotifications:YES]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(frameDidChange:) name:NSViewFrameDidChangeNotification object:self]; + + // window status + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(windowStatusDidChange:) name:NSWindowDidBecomeKeyNotification object:[self window]]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(windowStatusDidChange:) name:NSWindowDidResignKeyNotification object:[self window]]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(windowDidMove:) name:NSWindowDidMoveNotification object:[self window]]; +} + + +#pragma mark - +#pragma mark Accessors + +- (NSMutableArray *)cells +{ + return _cells; +} + +- (NSEvent *)lastMouseDownEvent +{ + return _lastMouseDownEvent; +} + +- (void)setLastMouseDownEvent:(NSEvent *)event +{ + [event retain]; + [_lastMouseDownEvent release]; + _lastMouseDownEvent = event; +} + +- (id)delegate +{ + return delegate; +} + +- (void)setDelegate:(id)object +{ + [object retain]; + [delegate release]; + delegate = object; +} + +- (NSTabView *)tabView +{ + return tabView; +} + +- (void)setTabView:(NSTabView *)view +{ + [view retain]; + [tabView release]; + tabView = view; +} + +- (id)style +{ + return style; +} + +- (NSString *)styleName +{ + return [style name]; +} + +- (void)setStyleNamed:(NSString *)name +{ + [style release]; + if([name isEqualToString:@"Aqua"]){ + style = [[PSMAquaTabStyle alloc] init]; + } + else if ([name isEqualToString:@"Unified"]){ + style = [[PSMUnifiedTabStyle alloc] init]; + } + else { + style = [[PSMMetalTabStyle alloc] init]; + } + + // restyle add tab button + if(_addTabButton){ + NSImage *newButtonImage = [style addTabButtonImage]; + if(newButtonImage) + [_addTabButton setUsualImage:newButtonImage]; + newButtonImage = [style addTabButtonPressedImage]; + if(newButtonImage) + [_addTabButton setAlternateImage:newButtonImage]; + newButtonImage = [style addTabButtonRolloverImage]; + if(newButtonImage) + [_addTabButton setRolloverImage:newButtonImage]; + } + + [self update]; +} + +- (BOOL)canCloseOnlyTab +{ + return _canCloseOnlyTab; +} + +- (void)setCanCloseOnlyTab:(BOOL)value +{ + _canCloseOnlyTab = value; + if ([_cells count] == 1) { + [self update]; + } +} + +- (BOOL)allowsDragBetweenWindows +{ + return _allowsDragBetweenWindows; +} + +- (void)setAllowsDragBetweenWindows:(BOOL)flag +{ + _allowsDragBetweenWindows = flag; +} + +- (BOOL)hideForSingleTab +{ + return _hideForSingleTab; +} + +- (void)setHideForSingleTab:(BOOL)value +{ + _hideForSingleTab = value; + [self update]; +} + +- (BOOL)showAddTabButton +{ + return _showAddTabButton; +} + +- (void)setShowAddTabButton:(BOOL)value +{ + _showAddTabButton = value; + [self update]; +} + +- (int)cellMinWidth +{ + return _cellMinWidth; +} + +- (void)setCellMinWidth:(int)value +{ + _cellMinWidth = value; + [self update]; +} + +- (int)cellMaxWidth +{ + return _cellMaxWidth; +} + +- (void)setCellMaxWidth:(int)value +{ + _cellMaxWidth = value; + [self update]; +} + +- (int)cellOptimumWidth +{ + return _cellOptimumWidth; +} + +- (void)setCellOptimumWidth:(int)value +{ + _cellOptimumWidth = value; + [self update]; +} + +- (BOOL)sizeCellsToFit +{ + return _sizeCellsToFit; +} + +- (void)setSizeCellsToFit:(BOOL)value +{ + _sizeCellsToFit = value; + [self update]; +} + +- (PSMRolloverButton *)addTabButton +{ + return _addTabButton; +} + +- (PSMOverflowPopUpButton *)overflowPopUpButton +{ + return _overflowPopUpButton; +} + +#pragma mark - +#pragma mark Functionality +- (void)addTabViewItem:(NSTabViewItem *)item +{ + // create cell + PSMTabBarCell *cell = [[PSMTabBarCell alloc] initWithControlView:self]; + [cell setRepresentedObject:item]; + // bind the indicator to the represented object's status (if it exists) + [[cell indicator] setHidden:YES]; + if([item identifier] != nil){ + if([[item identifier] respondsToSelector:@selector(content)]){ + if([[[[cell representedObject] identifier] content] respondsToSelector:@selector(isProcessing)]){ + NSMutableDictionary *bindingOptions = [NSMutableDictionary dictionary]; + [bindingOptions setObject:NSNegateBooleanTransformerName forKey:@"NSValueTransformerName"]; + [[cell indicator] bind:@"animate" toObject:[item identifier] withKeyPath:@"selection.isProcessing" options:nil]; + [[cell indicator] bind:@"hidden" toObject:[item identifier] withKeyPath:@"selection.isProcessing" options:bindingOptions]; + [[item identifier] addObserver:self forKeyPath:@"selection.isProcessing" options:nil context:nil]; + } + } + } + + // bind for the existence of an icon + [cell setHasIcon:NO]; + if([item identifier] != nil){ + if([[item identifier] respondsToSelector:@selector(content)]){ + if([[[[cell representedObject] identifier] content] respondsToSelector:@selector(icon)]){ + NSMutableDictionary *bindingOptions = [NSMutableDictionary dictionary]; + [bindingOptions setObject:NSIsNotNilTransformerName forKey:@"NSValueTransformerName"]; + [cell bind:@"hasIcon" toObject:[item identifier] withKeyPath:@"selection.icon" options:bindingOptions]; + [[item identifier] addObserver:self forKeyPath:@"selection.icon" options:nil context:nil]; + } + } + } + + // bind for the existence of a counter + [cell setCount:0]; + if([item identifier] != nil){ + if([[item identifier] respondsToSelector:@selector(content)]){ + if([[[[cell representedObject] identifier] content] respondsToSelector:@selector(objectCount)]){ + [cell bind:@"count" toObject:[item identifier] withKeyPath:@"selection.objectCount" options:nil]; + [[item identifier] addObserver:self forKeyPath:@"selection.objectCount" options:nil context:nil]; + } + } + } + + // bind my string value to the label on the represented tab + [cell bind:@"title" toObject:item withKeyPath:@"label" options:nil]; + + // add to collection + [_cells addObject:cell]; + [cell release]; + if([_cells count] == [tabView numberOfTabViewItems]){ + [self update]; // don't update unless all are accounted for! + } +} + +- (void)removeTabForCell:(PSMTabBarCell *)cell +{ + // unbind + [[cell indicator] unbind:@"animate"]; + [[cell indicator] unbind:@"hidden"]; + [cell unbind:@"hasIcon"]; + [cell unbind:@"title"]; + [cell unbind:@"count"]; + + // remove indicator + if([[self subviews] containsObject:[cell indicator]]){ + [[cell indicator] removeFromSuperview]; + } + // remove tracking + [[NSNotificationCenter defaultCenter] removeObserver:cell]; + if([cell closeButtonTrackingTag] != 0){ + [self removeTrackingRect:[cell closeButtonTrackingTag]]; + } + if([cell cellTrackingTag] != 0){ + [self removeTrackingRect:[cell cellTrackingTag]]; + } + + // pull from collection + [_cells removeObject:cell]; + + [self update]; +} + +- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context +{ + // the progress indicator, label, icon, or count has changed - must redraw + [self update]; +} + +#pragma mark - +#pragma mark Hide/Show + +- (void)hideTabBar:(BOOL)hide animate:(BOOL)animate +{ + if(!_awakenedFromNib) + return; + if(_isHidden && hide) + return; + if(!_isHidden && !hide) + return; + + [[self subviews] makeObjectsPerformSelector:@selector(removeFromSuperview)]; + _hideIndicators = YES; + + NSTimer *animationTimer; + _isHidden = hide; + _currentStep = 0; + if(!animate) + _currentStep = (int)kPSMHideAnimationSteps; + + float partnerOriginalHeight, partnerOriginalY, myOriginalHeight, myOriginalY, partnerTargetHeight, partnerTargetY, myTargetHeight, myTargetY; + + // current (original) values + myOriginalHeight = [self frame].size.height; + myOriginalY = [self frame].origin.y; + if(partnerView){ + partnerOriginalHeight = [partnerView frame].size.height; + partnerOriginalY = [partnerView frame].origin.y; + } else { + partnerOriginalHeight = [[self window] frame].size.height; + partnerOriginalY = [[self window] frame].origin.y; + } + + // target values for partner + if(partnerView){ + // above or below me? + if((myOriginalY - 22) > partnerOriginalY){ + // partner is below me + if(_isHidden){ + // I'm shrinking + myTargetY = myOriginalY + 21; + myTargetHeight = myOriginalHeight - 21; + partnerTargetY = partnerOriginalY; + partnerTargetHeight = partnerOriginalHeight + 21; + } else { + // I'm growing + myTargetY = myOriginalY - 21; + myTargetHeight = myOriginalHeight + 21; + partnerTargetY = partnerOriginalY; + partnerTargetHeight = partnerOriginalHeight - 21; + } + } else { + // partner is above me + if(_isHidden){ + // I'm shrinking + myTargetY = myOriginalY; + myTargetHeight = myOriginalHeight - 21; + partnerTargetY = partnerOriginalY - 21; + partnerTargetHeight = partnerOriginalHeight + 21; + } else { + // I'm growing + myTargetY = myOriginalY; + myTargetHeight = myOriginalHeight + 21; + partnerTargetY = partnerOriginalY + 21; + partnerTargetHeight = partnerOriginalHeight - 21; + } + } + } else { + // for window movement + if(_isHidden){ + // I'm shrinking + myTargetY = myOriginalY; + myTargetHeight = myOriginalHeight - 21; + partnerTargetY = partnerOriginalY + 21; + partnerTargetHeight = partnerOriginalHeight - 21; + } else { + // I'm growing + myTargetY = myOriginalY; + myTargetHeight = myOriginalHeight + 21; + partnerTargetY = partnerOriginalY - 21; + partnerTargetHeight = partnerOriginalHeight + 21; + } + } + + NSDictionary *userInfo = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithFloat:myOriginalY], @"myOriginalY", [NSNumber numberWithFloat:partnerOriginalY], @"partnerOriginalY", [NSNumber numberWithFloat:myOriginalHeight], @"myOriginalHeight", [NSNumber numberWithFloat:partnerOriginalHeight], @"partnerOriginalHeight", [NSNumber numberWithFloat:myTargetY], @"myTargetY", [NSNumber numberWithFloat:partnerTargetY], @"partnerTargetY", [NSNumber numberWithFloat:myTargetHeight], @"myTargetHeight", [NSNumber numberWithFloat:partnerTargetHeight], @"partnerTargetHeight", nil]; + animationTimer = [NSTimer scheduledTimerWithTimeInterval:(1.0/20.0) target:self selector:@selector(animateShowHide:) userInfo:userInfo repeats:YES]; +} + +- (void)animateShowHide:(NSTimer *)timer +{ + // moves the frame of the tab bar and window (or partner view) linearly to hide or show the tab bar + NSRect myFrame = [self frame]; + float myCurrentY = ([[[timer userInfo] objectForKey:@"myOriginalY"] floatValue] + (([[[timer userInfo] objectForKey:@"myTargetY"] floatValue] - [[[timer userInfo] objectForKey:@"myOriginalY"] floatValue]) * (_currentStep/kPSMHideAnimationSteps))); + float myCurrentHeight = ([[[timer userInfo] objectForKey:@"myOriginalHeight"] floatValue] + (([[[timer userInfo] objectForKey:@"myTargetHeight"] floatValue] - [[[timer userInfo] objectForKey:@"myOriginalHeight"] floatValue]) * (_currentStep/kPSMHideAnimationSteps))); + float partnerCurrentY = ([[[timer userInfo] objectForKey:@"partnerOriginalY"] floatValue] + (([[[timer userInfo] objectForKey:@"partnerTargetY"] floatValue] - [[[timer userInfo] objectForKey:@"partnerOriginalY"] floatValue]) * (_currentStep/kPSMHideAnimationSteps))); + float partnerCurrentHeight = ([[[timer userInfo] objectForKey:@"partnerOriginalHeight"] floatValue] + (([[[timer userInfo] objectForKey:@"partnerTargetHeight"] floatValue] - [[[timer userInfo] objectForKey:@"partnerOriginalHeight"] floatValue]) * (_currentStep/kPSMHideAnimationSteps))); + + NSRect myNewFrame = NSMakeRect(myFrame.origin.x, myCurrentY, myFrame.size.width, myCurrentHeight); + + if(partnerView){ + // resize self and view + [partnerView setFrame:NSMakeRect([partnerView frame].origin.x, partnerCurrentY, [partnerView frame].size.width, partnerCurrentHeight)]; + [partnerView setNeedsDisplay:YES]; + [self setFrame:myNewFrame]; + } else { + // resize self and window + [[self window] setFrame:NSMakeRect([[self window] frame].origin.x, partnerCurrentY, [[self window] frame].size.width, partnerCurrentHeight) display:YES]; + [self setFrame:myNewFrame]; + } + + // next + _currentStep++; + if(_currentStep == kPSMHideAnimationSteps + 1){ + [timer invalidate]; + [self viewDidEndLiveResize]; + _hideIndicators = NO; + [self update]; + } + [[self window] display]; +} + +- (id)partnerView +{ + return partnerView; +} + +- (void)setPartnerView:(id)view +{ + [partnerView release]; + [view retain]; + partnerView = view; +} + +#pragma mark - +#pragma mark Drawing + +- (BOOL)isFlipped +{ + return YES; +} + +- (void)drawRect:(NSRect)rect +{ + [style drawTabBar:self inRect:rect]; +} + +- (void)update +{ + // abandon hope, all ye who enter here :-) + // this method handles all of the cell layout, and is called when something changes to require the refresh. This method is not called during drag and drop; see the PSMTabDragAssistant's calculateDragAnimationForTabBar: method, which does layout in that case. + + // make sure all of our tabs are accounted for before updating + if ([tabView numberOfTabViewItems] != [_cells count]) { + return; + } + + // hide/show? (these return if already in desired state) + if((_hideForSingleTab) && ([_cells count] <= 1)){ + [self hideTabBar:YES animate:YES]; + } else { + [self hideTabBar:NO animate:YES]; + } + + // size all cells appropriately and create tracking rects + // nuke old tracking rects + int i, cellCount = [_cells count]; + for(i = 0; i < cellCount; i++){ + id cell = [_cells objectAtIndex:i]; + [[NSNotificationCenter defaultCenter] removeObserver:cell]; + if([cell closeButtonTrackingTag] != 0){ + [self removeTrackingRect:[cell closeButtonTrackingTag]]; + } + if([cell cellTrackingTag] != 0){ + [self removeTrackingRect:[cell cellTrackingTag]]; + } + } + + // calculate number of cells to fit in control and cell widths + float availableWidth = [self availableCellWidth]; + NSMutableArray *newWidths = [NSMutableArray arrayWithCapacity:cellCount]; + int numberOfVisibleCells = 1; + float totalOccupiedWidth = 0.0; + NSMenu *overflowMenu = nil; + for(i = 0; i < cellCount; i++){ + PSMTabBarCell *cell = [_cells objectAtIndex:i]; + float width; + + // supress close button? + if (cellCount == 1 && [self canCloseOnlyTab] == NO) { + [cell setCloseButtonSuppressed:YES]; + } else { + [cell setCloseButtonSuppressed:NO]; + } + + // Determine cell width + if(_sizeCellsToFit){ + width = [cell desiredWidthOfCell]; + if (width > _cellMaxWidth) { + width = _cellMaxWidth; + } + } else { + width = _cellOptimumWidth; + } + + // too much? + totalOccupiedWidth += width; + if (totalOccupiedWidth >= availableWidth) { + numberOfVisibleCells = i; + if(_sizeCellsToFit){ + int neededWidth = width - (totalOccupiedWidth - availableWidth); + // can I squeeze it in without violating min cell width? + int widthIfAllMin = (numberOfVisibleCells + 1) * _cellMinWidth; + + if ((width + widthIfAllMin) <= availableWidth) { + // squeeze - distribute needed sacrifice among all cells + int q; + for(q = (i - 1); q >= 0; q--){ + int desiredReduction = (int)neededWidth/(q+1); + if(([[newWidths objectAtIndex:q] floatValue] - desiredReduction) < _cellMinWidth){ + int actualReduction = (int)[[newWidths objectAtIndex:q] floatValue] - _cellMinWidth; + [newWidths replaceObjectAtIndex:q withObject:[NSNumber numberWithFloat:_cellMinWidth]]; + neededWidth -= actualReduction; + } else { + int newCellWidth = (int)[[newWidths objectAtIndex:q] floatValue] - desiredReduction; + [newWidths replaceObjectAtIndex:q withObject:[NSNumber numberWithFloat:newCellWidth]]; + neededWidth -= desiredReduction; + } + } + // one cell left! + int thisWidth = width - neededWidth; + [newWidths addObject:[NSNumber numberWithFloat:thisWidth]]; + numberOfVisibleCells++; + } else { + // stretch - distribute leftover room among cells + int leftoverWidth = availableWidth - totalOccupiedWidth + width; + int q; + for(q = (i - 1); q >= 0; q--){ + int desiredAddition = (int)leftoverWidth/(q+1); + int newCellWidth = (int)[[newWidths objectAtIndex:q] floatValue] + desiredAddition; + [newWidths replaceObjectAtIndex:q withObject:[NSNumber numberWithFloat:newCellWidth]]; + leftoverWidth -= desiredAddition; + } + } + break; // done assigning widths; remaining cells go in overflow menu + } else { + int revisedWidth = availableWidth/(i + 1); + if(revisedWidth >= _cellMinWidth){ + int q; + totalOccupiedWidth = 0; + for(q = 0; q < [newWidths count]; q++){ + [newWidths replaceObjectAtIndex:q withObject:[NSNumber numberWithFloat:revisedWidth]]; + totalOccupiedWidth += revisedWidth; + } + // just squeezed this one in... + [newWidths addObject:[NSNumber numberWithFloat:revisedWidth]]; + totalOccupiedWidth += revisedWidth; + numberOfVisibleCells++; + } else { + // couldn't fit that last one... + break; + } + } + } else { + numberOfVisibleCells = cellCount; + [newWidths addObject:[NSNumber numberWithFloat:width]]; + } + } + + // Set up cells with frames and rects + NSRect cellRect = [self genericCellRect]; + for(i = 0; i < cellCount; i++){ + PSMTabBarCell *cell = [_cells objectAtIndex:i]; + int tabState = 0; + if (i < numberOfVisibleCells) { + // set cell frame + cellRect.size.width = [[newWidths objectAtIndex:i] floatValue]; + [cell setFrame:cellRect]; + NSTrackingRectTag tag; + + // close button tracking rect + if ([cell hasCloseButton]) { + tag = [self addTrackingRect:[cell closeButtonRectForFrame:cellRect] owner:cell userData:nil assumeInside:NO]; + [cell setCloseButtonTrackingTag:tag]; + } + + // entire tab tracking rect + tag = [self addTrackingRect:cellRect owner:cell userData:nil assumeInside:NO]; + [cell setCellTrackingTag:tag]; + [cell setEnabled:YES]; + + // selected? set tab states... + if([[cell representedObject] isEqualTo:[tabView selectedTabViewItem]]){ + [cell setState:NSOnState]; + tabState |= PSMTab_SelectedMask; + // previous cell + if(i > 0){ + [[_cells objectAtIndex:i-1] setTabState:([(PSMTabBarCell *)[_cells objectAtIndex:i-1] tabState] | PSMTab_RightIsSelectedMask)]; + } + // next cell - see below + } else { + [cell setState:NSOffState]; + // see if prev cell was selected + if(i > 0){ + if([[_cells objectAtIndex:i-1] state] == NSOnState){ + tabState |= PSMTab_LeftIsSelectedMask; + } + } + } + // more tab states + if(cellCount == 1){ + tabState |= PSMTab_PositionLeftMask | PSMTab_PositionRightMask | PSMTab_PositionSingleMask; + } else if(i == 0){ + tabState |= PSMTab_PositionLeftMask; + } else if(i-1 == cellCount){ + tabState |= PSMTab_PositionRightMask; + } + [cell setTabState:tabState]; + [cell setIsInOverflowMenu:NO]; + + // indicator + if(![[cell indicator] isHidden] && !_hideIndicators){ + [[cell indicator] setFrame:[cell indicatorRectForFrame:cellRect]]; + if(![[self subviews] containsObject:[cell indicator]]){ + [self addSubview:[cell indicator]]; + [[cell indicator] startAnimation:self]; + } + } + + // next... + cellRect.origin.x += [[newWidths objectAtIndex:i] floatValue]; + + } else { + // set up menu items + NSMenuItem *menuItem; + if(overflowMenu == nil){ + overflowMenu = [[[NSMenu alloc] initWithTitle:@"TITLE"] autorelease]; + [overflowMenu insertItemWithTitle:@"FIRST" action:nil keyEquivalent:@"" atIndex:0]; // Because the overflowPupUpButton is a pull down menu + } + menuItem = [[[NSMenuItem alloc] initWithTitle:[[cell attributedStringValue] string] action:@selector(overflowMenuAction:) keyEquivalent:@""] autorelease]; + [menuItem setTarget:self]; + [menuItem setRepresentedObject:[cell representedObject]]; + [cell setIsInOverflowMenu:YES]; + [[cell indicator] removeFromSuperview]; + if ([[cell representedObject] isEqualTo:[tabView selectedTabViewItem]]) + [menuItem setState:NSOnState]; + if([cell hasIcon]) + [menuItem setImage:[[[[cell representedObject] identifier] content] icon]]; + if([cell count] > 0) + [menuItem setTitle:[[menuItem title] stringByAppendingFormat:@" (%d)",[cell count]]]; + [overflowMenu addItem:menuItem]; + } + } + + + // Overflow menu + cellRect.origin.y = 0; + cellRect.size.height = kPSMTabBarControlHeight; + cellRect.size.width = [style rightMarginForTabBarControl]; + if (overflowMenu) { + cellRect.origin.x = [self frame].size.width - [style rightMarginForTabBarControl] + 1; + if(![[self subviews] containsObject:_overflowPopUpButton]){ + [self addSubview:_overflowPopUpButton]; + } + [_overflowPopUpButton setFrame:cellRect]; + [_overflowPopUpButton setMenu:overflowMenu]; + if ([_overflowPopUpButton isHidden]) [_overflowPopUpButton setHidden:NO]; + } else { + if (![_overflowPopUpButton isHidden]) [_overflowPopUpButton setHidden:YES]; + } + + // add tab button + if(!overflowMenu && _showAddTabButton){ + if(![[self subviews] containsObject:_addTabButton]) + [self addSubview:_addTabButton]; + if([_addTabButton isHidden] && _showAddTabButton) + [_addTabButton setHidden:NO]; + cellRect.size = [_addTabButton frame].size; + cellRect.origin.y = MARGIN_Y; + cellRect.origin.x += 2; + [_addTabButton setImage:[style addTabButtonImage]]; + [_addTabButton setFrame:cellRect]; + [_addTabButton setNeedsDisplay:YES]; + } else { + [_addTabButton setHidden:YES]; + [_addTabButton setNeedsDisplay:YES]; + } + + [self setNeedsDisplay:YES]; +} + +#pragma mark - +#pragma mark Mouse Tracking + +- (BOOL)mouseDownCanMoveWindow +{ + return NO; +} + +- (BOOL)acceptsFirstMouse:(NSEvent *)theEvent +{ + return YES; +} + +- (void)mouseDown:(NSEvent *)theEvent +{ + // keep for dragging + [self setLastMouseDownEvent:theEvent]; + // what cell? + NSPoint mousePt = [self convertPoint:[theEvent locationInWindow] fromView:nil]; + NSRect cellFrame; + PSMTabBarCell *cell = [self cellForPoint:mousePt cellFrame:&cellFrame]; + if(cell){ +#if 0 + NSRect iconRect = [cell closeButtonRectForFrame:cellFrame]; + if(NSMouseInRect(mousePt, iconRect,[self isFlipped])){ + [cell setCloseButtonPressed:YES]; + } else { + [cell setCloseButtonPressed:NO]; + } + [self setNeedsDisplay:YES]; +#else + // HACK! Let the tabs react on the mouse down instead of mouse up + NSRect iconRect = [cell closeButtonRectForFrame:cellFrame]; + if((NSMouseInRect(mousePt, iconRect,[self isFlipped]))){ + //[self performSelector:@selector(closeTabClick:) withObject:cell]; + [self closeTabClick:cell]; + } else if(NSMouseInRect(mousePt, cellFrame,[self isFlipped])){ + //[self performSelector:@selector(tabClick:) withObject:cell]; + [self tabClick:cell]; + } else { + //[self performSelector:@selector(tabNothing:) withObject:cell]; + [self tabNothing:cell]; + } +#endif + } +} + +- (void)mouseDragged:(NSEvent *)theEvent +{ + if([self lastMouseDownEvent] == nil){ + return; + } + + if ([_cells count] < 2) { + return; + } + + NSRect cellFrame; + NSPoint trackingStartPoint = [self convertPoint:[[self lastMouseDownEvent] locationInWindow] fromView:nil]; + PSMTabBarCell *cell = [self cellForPoint:trackingStartPoint cellFrame:&cellFrame]; + if (!cell) + return; + + NSPoint currentPoint = [self convertPoint:[theEvent locationInWindow] fromView:nil]; + float dx = fabs(currentPoint.x - trackingStartPoint.x); + float dy = fabs(currentPoint.y - trackingStartPoint.y); + float distance = sqrt(dx * dx + dy * dy); + if (distance < 10) + return; + + if(![[PSMTabDragAssistant sharedDragAssistant] isDragging]) { + [[PSMTabDragAssistant sharedDragAssistant] startDraggingCell:cell fromTabBar:self withMouseDownEvent:[self lastMouseDownEvent]]; + } +} + +- (void)mouseUp:(NSEvent *)theEvent +{ +#if 0 // HACK! Tabs react on mouse down instead of mouse up + // what cell? + NSPoint mousePt = [self convertPoint:[theEvent locationInWindow] fromView:nil]; + NSRect cellFrame, mouseDownCellFrame; + PSMTabBarCell *cell = [self cellForPoint:mousePt cellFrame:&cellFrame]; + PSMTabBarCell *mouseDownCell = [self cellForPoint:[self convertPoint:[[self lastMouseDownEvent] locationInWindow] fromView:nil] cellFrame:&mouseDownCellFrame]; + if(cell){ + NSRect iconRect = [mouseDownCell closeButtonRectForFrame:mouseDownCellFrame]; + if((NSMouseInRect(mousePt, iconRect,[self isFlipped])) && [mouseDownCell closeButtonPressed]){ + [self performSelector:@selector(closeTabClick:) withObject:cell]; + } else if(NSMouseInRect(mousePt, mouseDownCellFrame,[self isFlipped])){ + [mouseDownCell setCloseButtonPressed:NO]; + [self performSelector:@selector(tabClick:) withObject:cell]; + } else { + [mouseDownCell setCloseButtonPressed:NO]; + [self performSelector:@selector(tabNothing:) withObject:cell]; + } + } +#endif +} + +#pragma mark - +#pragma mark Drag and Drop + +- (BOOL)shouldDelayWindowOrderingForEvent:(NSEvent *)theEvent +{ + return YES; +} + +// NSDraggingSource +- (unsigned int)draggingSourceOperationMaskForLocal:(BOOL)isLocal +{ + return (isLocal ? NSDragOperationMove : NSDragOperationNone); +} + +- (BOOL)ignoreModifierKeysWhileDragging +{ + return YES; +} + +// NSDraggingDestination +- (NSDragOperation)draggingEntered:(id )sender +{ + if([[[sender draggingPasteboard] types] indexOfObject:@"PSMTabBarControlItemPBType"] != NSNotFound) { + + if ([sender draggingSource] != self && ![self allowsDragBetweenWindows]) + return NSDragOperationNone; + + [[PSMTabDragAssistant sharedDragAssistant] draggingEnteredTabBar:self atPoint:[self convertPoint:[sender draggingLocation] fromView:nil]]; + return NSDragOperationMove; + } + + return NSDragOperationNone; +} + +- (NSDragOperation)draggingUpdated:(id )sender +{ + if ([[[sender draggingPasteboard] types] indexOfObject:@"PSMTabBarControlItemPBType"] != NSNotFound) { + + if ([sender draggingSource] != self && ![self allowsDragBetweenWindows]) + return NSDragOperationNone; + + [[PSMTabDragAssistant sharedDragAssistant] draggingUpdatedInTabBar:self atPoint:[self convertPoint:[sender draggingLocation] fromView:nil]]; + return NSDragOperationMove; + } + + return NSDragOperationNone; +} + +- (void)draggingExited:(id )sender +{ + [[PSMTabDragAssistant sharedDragAssistant] draggingExitedTabBar:self]; +} + +- (BOOL)prepareForDragOperation:(id )sender +{ + return YES; +} + +- (BOOL)performDragOperation:(id )sender +{ +#if 1 + // HACK! Used below. + NSTabViewItem *tvi = [[[PSMTabDragAssistant sharedDragAssistant] draggedCell] representedObject]; +#endif + + [[PSMTabDragAssistant sharedDragAssistant] performDragOperation]; + +#if 1 + // HACK! Notify the delegate that a tab was dragged to a new position. + if (delegate && [delegate respondsToSelector:@selector(tabView:didDragTabViewItem:toIndex:)]) { + int idx = [[self representedTabViewItems] indexOfObject:tvi]; + if (NSNotFound != idx) { + [delegate tabView:[self tabView] didDragTabViewItem:tvi toIndex:idx]; + } + } +#endif + + return YES; +} + +- (void)draggedImage:(NSImage *)anImage endedAt:(NSPoint)aPoint operation:(NSDragOperation)operation +{ + [[PSMTabDragAssistant sharedDragAssistant] draggedImageEndedAt:aPoint operation:operation]; +} + +- (void)concludeDragOperation:(id )sender +{ + +} + +#pragma mark - +#pragma mark Actions + +- (void)overflowMenuAction:(id)sender +{ + [tabView selectTabViewItem:[sender representedObject]]; + [self update]; +} + +- (void)closeTabClick:(id)sender +{ + [sender retain]; + if(([_cells count] == 1) && (![self canCloseOnlyTab])) + return; + + if(([self delegate]) && ([[self delegate] respondsToSelector:@selector(tabView:shouldCloseTabViewItem:)])){ + if(![[self delegate] tabView:tabView shouldCloseTabViewItem:[sender representedObject]]){ + // fix mouse downed close button + [sender setCloseButtonPressed:NO]; + return; + } + } + + if(([self delegate]) && ([[self delegate] respondsToSelector:@selector(tabView:willCloseTabViewItem:)])){ + [[self delegate] tabView:tabView willCloseTabViewItem:[sender representedObject]]; + } + + [[sender representedObject] retain]; + [tabView removeTabViewItem:[sender representedObject]]; + + if(([self delegate]) && ([[self delegate] respondsToSelector:@selector(tabView:didCloseTabViewItem:)])){ + [[self delegate] tabView:tabView didCloseTabViewItem:[sender representedObject]]; + } + [[sender representedObject] release]; + [sender release]; +} + +- (void)tabClick:(id)sender +{ + [tabView selectTabViewItem:[sender representedObject]]; + [self update]; +} + +- (void)tabNothing:(id)sender +{ + [self update]; // takes care of highlighting based on state +} + +- (void)frameDidChange:(NSNotification *)notification +{ + [self update]; + // trying to address the drawing artifacts for the progress indicators - hackery follows + // this one fixes the "blanking" effect when the control hides and shows itself + NSEnumerator *e = [_cells objectEnumerator]; + PSMTabBarCell *cell; + while(cell = [e nextObject]){ + [[cell indicator] stopAnimation:self]; + [[cell indicator] startAnimation:self]; + } + [self setNeedsDisplay:YES]; +} + +- (void)viewWillStartLiveResize +{ + NSEnumerator *e = [_cells objectEnumerator]; + PSMTabBarCell *cell; + while(cell = [e nextObject]){ + [[cell indicator] stopAnimation:self]; + } + [self setNeedsDisplay:YES]; +} + +-(void)viewDidEndLiveResize +{ + NSEnumerator *e = [_cells objectEnumerator]; + PSMTabBarCell *cell; + while(cell = [e nextObject]){ + [[cell indicator] startAnimation:self]; + } + [self setNeedsDisplay:YES]; +} + +- (void)windowDidMove:(NSNotification *)aNotification +{ + [self setNeedsDisplay:YES]; +} + +- (void)windowStatusDidChange:(NSNotification *)notification +{ + // hide? must readjust things if I'm not supposed to be showing + // this block of code only runs when the app launches + if(_hideForSingleTab && ([_cells count] <= 1) && !_awakenedFromNib){ + // must adjust frames now before display + NSRect myFrame = [self frame]; + if(partnerView){ + NSRect partnerFrame = [partnerView frame]; + // above or below me? + if(([self frame].origin.y - 22) > [partnerView frame].origin.y){ + // partner is below me + [self setFrame:NSMakeRect(myFrame.origin.x, myFrame.origin.y + 21, myFrame.size.width, myFrame.size.height - 21)]; + [partnerView setFrame:NSMakeRect(partnerFrame.origin.x, partnerFrame.origin.y, partnerFrame.size.width, partnerFrame.size.height + 21)]; + } else { + // partner is above me + [self setFrame:NSMakeRect(myFrame.origin.x, myFrame.origin.y, myFrame.size.width, myFrame.size.height - 21)]; + [partnerView setFrame:NSMakeRect(partnerFrame.origin.x, partnerFrame.origin.y - 21, partnerFrame.size.width, partnerFrame.size.height + 21)]; + } + [partnerView setNeedsDisplay:YES]; + [self setNeedsDisplay:YES]; + } else { + // for window movement + NSRect windowFrame = [[self window] frame]; + [[self window] setFrame:NSMakeRect(windowFrame.origin.x, windowFrame.origin.y + 21, windowFrame.size.width, windowFrame.size.height - 21) display:YES]; + [self setFrame:NSMakeRect(myFrame.origin.x, myFrame.origin.y, myFrame.size.width, myFrame.size.height - 21)]; + } + _isHidden = YES; + [self setNeedsDisplay:YES]; + //[[self window] display]; + } + _awakenedFromNib = YES; + [self update]; +} + +#pragma mark - +#pragma mark NSTabView Delegate + +- (void)tabView:(NSTabView *)aTabView didSelectTabViewItem:(NSTabViewItem *)tabViewItem +{ + // here's a weird one - this message is sent before the "tabViewDidChangeNumberOfTabViewItems" + // message, thus I can end up updating when there are no cells, if no tabs were (yet) present + if([_cells count] > 0){ + [self update]; + } + if([self delegate]){ + if([[self delegate] respondsToSelector:@selector(tabView:didSelectTabViewItem:)]){ + [[self delegate] performSelector:@selector(tabView:didSelectTabViewItem:) withObject:aTabView withObject:tabViewItem]; + } + } +} + +- (BOOL)tabView:(NSTabView *)aTabView shouldSelectTabViewItem:(NSTabViewItem *)tabViewItem +{ + if([self delegate]){ + if([[self delegate] respondsToSelector:@selector(tabView:shouldSelectTabViewItem:)]){ + return (int)[[self delegate] performSelector:@selector(tabView:shouldSelectTabViewItem:) withObject:aTabView withObject:tabViewItem]; + } else { + return YES; + } + } else { + return YES; + } +} +- (void)tabView:(NSTabView *)aTabView willSelectTabViewItem:(NSTabViewItem *)tabViewItem +{ + if([self delegate]){ + if([[self delegate] respondsToSelector:@selector(tabView:willSelectTabViewItem:)]){ + [[self delegate] performSelector:@selector(tabView:willSelectTabViewItem:) withObject:aTabView withObject:tabViewItem]; + } + } +} + +- (void)tabViewDidChangeNumberOfTabViewItems:(NSTabView *)aTabView +{ + NSArray *tabItems = [tabView tabViewItems]; + // go through cells, remove any whose representedObjects are not in [tabView tabViewItems] + NSEnumerator *e = [_cells objectEnumerator]; + PSMTabBarCell *cell; + while(cell = [e nextObject]){ + if(![tabItems containsObject:[cell representedObject]]){ + [self removeTabForCell:cell]; + } + } + + // go through tab view items, add cell for any not present + NSMutableArray *cellItems = [self representedTabViewItems]; + NSEnumerator *ex = [tabItems objectEnumerator]; + NSTabViewItem *item; + while(item = [ex nextObject]){ + if(![cellItems containsObject:item]){ + [self addTabViewItem:item]; + } + } + +#if 0 + // HACK! Make sure '_cells' is ordered the same as 'tabItems'. + NSMutableArray *temp = [[NSMutableArray alloc] initWithArray:_cells]; + e = [_cells objectEnumerator]; + int count = [temp count]; + while ((cell = [e nextObject])) { + int idx = [tabItems indexOfObject:[cell representedObject]]; + if (NSNotFound != idx && idx < count) { + [temp replaceObjectAtIndex:idx withObject:cell]; + } + } + + [_cells release]; + _cells = temp; + + if ([_cells count] == [tabView numberOfTabViewItems]) { + [self update]; // don't update unless all are accounted for! + } +#endif + + // pass along for other delegate responses + if([self delegate]){ + if([[self delegate] respondsToSelector:@selector(tabViewDidChangeNumberOfTabViewItems:)]){ + [[self delegate] performSelector:@selector(tabViewDidChangeNumberOfTabViewItems:) withObject:aTabView]; + } + } +} + +#pragma mark - +#pragma mark Archiving + +- (void)encodeWithCoder:(NSCoder *)aCoder +{ + [super encodeWithCoder:aCoder]; + if ([aCoder allowsKeyedCoding]) { + [aCoder encodeObject:_cells forKey:@"PSMcells"]; + [aCoder encodeObject:tabView forKey:@"PSMtabView"]; + [aCoder encodeObject:_overflowPopUpButton forKey:@"PSMoverflowPopUpButton"]; + [aCoder encodeObject:_addTabButton forKey:@"PSMaddTabButton"]; + [aCoder encodeObject:style forKey:@"PSMstyle"]; + [aCoder encodeBool:_canCloseOnlyTab forKey:@"PSMcanCloseOnlyTab"]; + [aCoder encodeBool:_hideForSingleTab forKey:@"PSMhideForSingleTab"]; + [aCoder encodeBool:_showAddTabButton forKey:@"PSMshowAddTabButton"]; + [aCoder encodeBool:_sizeCellsToFit forKey:@"PSMsizeCellsToFit"]; + [aCoder encodeInt:_cellMinWidth forKey:@"PSMcellMinWidth"]; + [aCoder encodeInt:_cellMaxWidth forKey:@"PSMcellMaxWidth"]; + [aCoder encodeInt:_cellOptimumWidth forKey:@"PSMcellOptimumWidth"]; + [aCoder encodeInt:_currentStep forKey:@"PSMcurrentStep"]; + [aCoder encodeBool:_isHidden forKey:@"PSMisHidden"]; + [aCoder encodeBool:_hideIndicators forKey:@"PSMhideIndicators"]; + [aCoder encodeObject:partnerView forKey:@"PSMpartnerView"]; + [aCoder encodeBool:_awakenedFromNib forKey:@"PSMawakenedFromNib"]; + [aCoder encodeObject:_lastMouseDownEvent forKey:@"PSMlastMouseDownEvent"]; + [aCoder encodeObject:delegate forKey:@"PSMdelegate"]; + + } +} + +- (id)initWithCoder:(NSCoder *)aDecoder +{ + self = [super initWithCoder:aDecoder]; + if (self) { + if ([aDecoder allowsKeyedCoding]) { + _cells = [[aDecoder decodeObjectForKey:@"PSMcells"] retain]; + tabView = [[aDecoder decodeObjectForKey:@"PSMtabView"] retain]; + _overflowPopUpButton = [[aDecoder decodeObjectForKey:@"PSMoverflowPopUpButton"] retain]; + _addTabButton = [[aDecoder decodeObjectForKey:@"PSMaddTabButton"] retain]; + style = [[aDecoder decodeObjectForKey:@"PSMstyle"] retain]; + _canCloseOnlyTab = [aDecoder decodeBoolForKey:@"PSMcanCloseOnlyTab"]; + _hideForSingleTab = [aDecoder decodeBoolForKey:@"PSMhideForSingleTab"]; + _showAddTabButton = [aDecoder decodeBoolForKey:@"PSMshowAddTabButton"]; + _sizeCellsToFit = [aDecoder decodeBoolForKey:@"PSMsizeCellsToFit"]; + _cellMinWidth = [aDecoder decodeIntForKey:@"PSMcellMinWidth"]; + _cellMaxWidth = [aDecoder decodeIntForKey:@"PSMcellMaxWidth"]; + _cellOptimumWidth = [aDecoder decodeIntForKey:@"PSMcellOptimumWidth"]; + _currentStep = [aDecoder decodeIntForKey:@"PSMcurrentStep"]; + _isHidden = [aDecoder decodeBoolForKey:@"PSMisHidden"]; + _hideIndicators = [aDecoder decodeBoolForKey:@"PSMhideIndicators"]; + partnerView = [[aDecoder decodeObjectForKey:@"PSMpartnerView"] retain]; + _awakenedFromNib = [aDecoder decodeBoolForKey:@"PSMawakenedFromNib"]; + _lastMouseDownEvent = [[aDecoder decodeObjectForKey:@"PSMlastMouseDownEvent"] retain]; + delegate = [[aDecoder decodeObjectForKey:@"PSMdelegate"] retain]; + } + } + return self; +} + +#pragma mark - +#pragma mark IB Palette + +- (NSSize)minimumFrameSizeFromKnobPosition:(int)position +{ + return NSMakeSize(100.0, 22.0); +} + +- (NSSize)maximumFrameSizeFromKnobPosition:(int)knobPosition +{ + return NSMakeSize(10000.0, 22.0); +} + +- (void)placeView:(NSRect)newFrame +{ + // this is called any time the view is resized in IB + [self setFrame:newFrame]; + [self update]; +} + +#pragma mark - +#pragma mark Convenience + +- (NSMutableArray *)representedTabViewItems +{ + NSMutableArray *temp = [NSMutableArray arrayWithCapacity:[_cells count]]; + NSEnumerator *e = [_cells objectEnumerator]; + PSMTabBarCell *cell; + while(cell = [e nextObject]){ + [temp addObject:[cell representedObject]]; + } + return temp; +} + +- (id)cellForPoint:(NSPoint)point cellFrame:(NSRectPointer)outFrame +{ + NSRect aRect = [self genericCellRect]; + + if(!NSPointInRect(point,aRect)){ + return nil; + } + + int i, cnt = [_cells count]; + for(i = 0; i < cnt; i++){ + PSMTabBarCell *cell = [_cells objectAtIndex:i]; + float width = [cell width]; + aRect.size.width = width; + + if(NSPointInRect(point, aRect)){ + if(outFrame){ + *outFrame = aRect; + } + return cell; + } + aRect.origin.x += width; + } + return nil; +} + +- (PSMTabBarCell *)lastVisibleTab +{ + int i, cellCount = [_cells count]; + for(i = 0; i < cellCount; i++){ + if([[_cells objectAtIndex:i] isInOverflowMenu]) + return [_cells objectAtIndex:(i-1)]; + } + return [_cells objectAtIndex:(cellCount - 1)]; +} + +- (int)numberOfVisibleTabs +{ + int i, cellCount = [_cells count]; + for(i = 0; i < cellCount; i++){ + if([[_cells objectAtIndex:i] isInOverflowMenu]) + return i+1; + } + return cellCount; +} + + +@end diff --git a/PSMTabBarControl/source/PSMTabBarControlInspector.h b/PSMTabBarControl/source/PSMTabBarControlInspector.h new file mode 100644 index 0000000000..ba5d684b90 --- /dev/null +++ b/PSMTabBarControl/source/PSMTabBarControlInspector.h @@ -0,0 +1,23 @@ +// +// PSMTabBarControlInspector.h +// PSMTabBarControl +// +// Created by John Pannell on 12/21/05. +// Copyright Positive Spin Media 2005. All rights reserved. +// + +#import + +@interface PSMTabBarControlInspector : IBInspector +{ + IBOutlet NSPopUpButton *_stylePopUp; + IBOutlet NSButton *_canCloseOnlyTab; + IBOutlet NSButton *_hideForSingleTab; + IBOutlet NSButton *_showAddTab; + IBOutlet NSTextField *_cellMinWidth; + IBOutlet NSTextField *_cellMaxWidth; + IBOutlet NSTextField *_cellOptimumWidth; + IBOutlet NSButton *_sizeToFit; + IBOutlet NSButton *_allowsDragBetweenWindows; +} +@end diff --git a/PSMTabBarControl/source/PSMTabBarControlInspector.m b/PSMTabBarControl/source/PSMTabBarControlInspector.m new file mode 100644 index 0000000000..d9c5b91c4f --- /dev/null +++ b/PSMTabBarControl/source/PSMTabBarControlInspector.m @@ -0,0 +1,99 @@ +// +// PSMTabBarControlInspector.m +// PSMTabBarControl +// +// Created by John Pannell on 12/21/05. +// Copyright Positive Spin Media 2005 . All rights reserved. +// + +#import "PSMTabBarControlInspector.h" +#import "PSMTabBarControl.h" + +#define kPSMStyleTag 0 +#define kPSMCanCloseOnlyTabTag 1 +#define kPSMHideForSingleTabTag 2 +#define kPSMShowAddTabTag 3 +#define kPSMMinWidthTag 4 +#define kPSMMaxWidthTag 5 +#define kPSMOptimumWidthTag 6 +#define kPSMSizeToFitTag 7 +#define kPSMAllowsDragBetweenWindows 8 + +@implementation PSMTabBarControlInspector + +- (id)init +{ + self = [super init]; + [NSBundle loadNibNamed:@"PSMTabBarControlInspector" owner:self]; + return self; +} + +- (void)ok:(id)sender +{ + if([sender tag] == kPSMStyleTag){ + [[self object] setStyleNamed:[sender titleOfSelectedItem]]; + + } else if([sender tag] == kPSMCanCloseOnlyTabTag){ + [[self object] setCanCloseOnlyTab:[sender state]]; + + } else if([sender tag] == kPSMHideForSingleTabTag){ + [[self object] setHideForSingleTab:[sender state]]; + + } else if([sender tag] == kPSMShowAddTabTag){ + [[self object] setShowAddTabButton:[sender state]]; + + } else if([sender tag] == kPSMMinWidthTag){ + if([[self object] cellOptimumWidth] < [sender intValue]){ + [[self object] setCellMinWidth:[[self object] cellOptimumWidth]]; + [sender setIntValue:[[self object] cellOptimumWidth]]; + } else { + [[self object] setCellMinWidth:[sender intValue]]; + } + + } else if([sender tag] == kPSMMaxWidthTag){ + if([[self object] cellOptimumWidth] > [sender intValue]){ + [[self object] setCellMaxWidth:[[self object] cellOptimumWidth]]; + [sender setIntValue:[[self object] cellOptimumWidth]]; + } else { + [[self object] setCellMaxWidth:[sender intValue]]; + } + + } else if([sender tag] == kPSMOptimumWidthTag){ + if([[self object] cellMaxWidth] < [sender intValue]){ + [[self object] setCellOptimumWidth:[[self object] cellMaxWidth]]; + [sender setIntValue:[[self object] cellMaxWidth]]; + } else if([[self object] cellMinWidth] > [sender intValue]){ + [[self object] setCellOptimumWidth:[[self object] cellMinWidth]]; + [sender setIntValue:[[self object] cellMinWidth]]; + } else { + [[self object] setCellOptimumWidth:[sender intValue]]; + } + + } else if([sender tag] == kPSMSizeToFitTag){ + [[self object] setSizeCellsToFit:[sender state]]; + + } else if([sender tag] == kPSMAllowsDragBetweenWindows){ + [[self object] setAllowsDragBetweenWindows:[sender state]]; + + } + + + [super ok:sender]; +} + +- (void)revert:(id)sender +{ + [_stylePopUp selectItemWithTitle:[[self object] styleName]]; + [_canCloseOnlyTab setState:[[self object] canCloseOnlyTab]]; + [_hideForSingleTab setState:[[self object] hideForSingleTab]]; + [_showAddTab setState:[[self object] showAddTabButton]]; + [_cellMinWidth setIntValue:[[self object] cellMinWidth]]; + [_cellMaxWidth setIntValue:[[self object] cellMaxWidth]]; + [_cellOptimumWidth setIntValue:[[self object] cellOptimumWidth]]; + [_sizeToFit setState:[[self object] sizeCellsToFit]]; + [_allowsDragBetweenWindows setState:[[self object] allowsDragBetweenWindows]]; + + [super revert:sender]; +} + +@end diff --git a/PSMTabBarControl/source/PSMTabBarControlPalette.h b/PSMTabBarControl/source/PSMTabBarControlPalette.h new file mode 100644 index 0000000000..0feb9ad9d0 --- /dev/null +++ b/PSMTabBarControl/source/PSMTabBarControlPalette.h @@ -0,0 +1,21 @@ +// +// PSMTabBarControlPalette.h +// PSMTabBarControl +// +// Created by John Pannell on 12/21/05. +// Copyright Positive Spin Media 2005 . All rights reserved. +// + +#import +#import "PSMTabBarControl.h" + +@interface PSMTabBarControlPalette : IBPalette +{ + IBOutlet NSImageView *repImage; + PSMTabBarControl *_customControl; +} +@end + +@interface PSMTabBarControl (PSMTabBarControlPaletteInspector) +- (NSString *)inspectorClassName; +@end diff --git a/PSMTabBarControl/source/PSMTabBarControlPalette.m b/PSMTabBarControl/source/PSMTabBarControlPalette.m new file mode 100644 index 0000000000..bb5851aa18 --- /dev/null +++ b/PSMTabBarControl/source/PSMTabBarControlPalette.m @@ -0,0 +1,35 @@ +// +// PSMTabBarControlPalette.m +// PSMTabBarControl +// +// Created by John Pannell on 12/21/05. +// Copyright Positive Spin Media 2005 . All rights reserved. +// + +#import "PSMTabBarControlPalette.h" + +@implementation PSMTabBarControlPalette + +- (void)finishInstantiate +{ + // associate representative image with actual control + _customControl = [[PSMTabBarControl alloc] initWithFrame:NSMakeRect(0,0,180,22)]; + [self associateObject:_customControl ofType:IBViewPboardType withView:repImage]; +} + +- (void)dealloc +{ + [_customControl release]; + [super dealloc]; +} + +@end + +@implementation PSMTabBarControl (PSMTabBarControlPaletteInspector) + +- (NSString *)inspectorClassName +{ + return @"PSMTabBarControlInspector"; +} + +@end diff --git a/PSMTabBarControl/source/PSMTabBarControl_Prefix.pch b/PSMTabBarControl/source/PSMTabBarControl_Prefix.pch new file mode 100644 index 0000000000..65df9ffedb --- /dev/null +++ b/PSMTabBarControl/source/PSMTabBarControl_Prefix.pch @@ -0,0 +1,8 @@ +// +// Prefix header for all source files of the 'PSMTabBarControl' target in the 'PSMTabBarControl' project +// + +#ifdef __OBJC__ + #import + #import +#endif diff --git a/PSMTabBarControl/source/PSMTabDragAssistant.h b/PSMTabBarControl/source/PSMTabDragAssistant.h new file mode 100644 index 0000000000..e89692a7e3 --- /dev/null +++ b/PSMTabBarControl/source/PSMTabDragAssistant.h @@ -0,0 +1,84 @@ +// +// PSMTabDragAssistant.h +// PSMTabBarControl +// +// Created by John Pannell on 4/10/06. +// Copyright 2006 Positive Spin Media. All rights reserved. +// + +/* + This class is a sigleton that manages the details of a tab drag and drop. The details were beginning to overwhelm me when keeping all of this in the control and cells :-) + */ + +#import +#import "PSMTabBarControl.h" +@class PSMTabBarCell; +@class PSMTabDragWindow; + +#define kPSMTabDragAnimationSteps 8 +#define PI 3.1417 + +@interface PSMTabDragAssistant : NSObject { + PSMTabBarControl *_sourceTabBar; + PSMTabBarControl *_destinationTabBar; + NSMutableSet *_participatingTabBars; + PSMTabBarCell *_draggedCell; + int _draggedCellIndex; // for snap back + BOOL _isDragging; + + // Animation + NSTimer *_animationTimer; + NSMutableArray *_sineCurveWidths; + NSPoint _currentMouseLoc; + PSMTabBarCell *_targetCell; +} + +// Creation/destruction ++ (PSMTabDragAssistant *)sharedDragAssistant; + +// Accessors +- (PSMTabBarControl *)sourceTabBar; +- (void)setSourceTabBar:(PSMTabBarControl *)tabBar; +- (PSMTabBarControl *)destinationTabBar; +- (void)setDestinationTabBar:(PSMTabBarControl *)tabBar; +- (PSMTabBarCell *)draggedCell; +- (void)setDraggedCell:(PSMTabBarCell *)cell; +- (int)draggedCellIndex; +- (void)setDraggedCellIndex:(int)value; +- (BOOL)isDragging; +- (void)setIsDragging:(BOOL)value; +- (NSPoint)currentMouseLoc; +- (void)setCurrentMouseLoc:(NSPoint)point; +- (PSMTabBarCell *)targetCell; +- (void)setTargetCell:(PSMTabBarCell *)cell; + +// Functionality +- (void)startDraggingCell:(PSMTabBarCell *)cell fromTabBar:(PSMTabBarControl *)control withMouseDownEvent:(NSEvent *)event; +- (void)draggingEnteredTabBar:(PSMTabBarControl *)control atPoint:(NSPoint)mouseLoc; +- (void)draggingUpdatedInTabBar:(PSMTabBarControl *)control atPoint:(NSPoint)mouseLoc; +- (void)draggingExitedTabBar:(PSMTabBarControl *)control; +- (void)performDragOperation; +- (void)draggedImageEndedAt:(NSPoint)aPoint operation:(NSDragOperation)operation; +- (void)finishDrag; + +// Animation +- (void)animateDrag:(NSTimer *)timer; +- (void)calculateDragAnimationForTabBar:(PSMTabBarControl *)control; + +// Placeholder +- (void)distributePlaceholdersInTabBar:(PSMTabBarControl *)control withDraggedCell:(PSMTabBarCell *)cell; +- (void)distributePlaceholdersInTabBar:(PSMTabBarControl *)control; +- (void)removeAllPlaceholdersFromTabBar:(PSMTabBarControl *)control; + +@end + +@interface PSMTabBarControl (DragAccessors) + +- (id)style; +- (NSMutableArray *)cells; +- (void)setControlView:(id)view; +- (id)cellForPoint:(NSPoint)point cellFrame:(NSRectPointer)outFrame; +- (PSMTabBarCell *)lastVisibleTab; +- (int)numberOfVisibleTabs; + +@end diff --git a/PSMTabBarControl/source/PSMTabDragAssistant.m b/PSMTabBarControl/source/PSMTabDragAssistant.m new file mode 100644 index 0000000000..c5b937693c --- /dev/null +++ b/PSMTabBarControl/source/PSMTabDragAssistant.m @@ -0,0 +1,439 @@ +// +// PSMTabDragAssistant.m +// PSMTabBarControl +// +// Created by John Pannell on 4/10/06. +// Copyright 2006 Positive Spin Media. All rights reserved. +// + +#import "PSMTabDragAssistant.h" +#import "PSMTabBarCell.h" +#import "PSMTabStyle.h" + + +@implementation PSMTabDragAssistant + +static PSMTabDragAssistant *sharedDragAssistant = nil; + +#pragma mark - +#pragma mark Creation/Destruction + ++ (PSMTabDragAssistant *)sharedDragAssistant +{ + if (!sharedDragAssistant){ + sharedDragAssistant = [[PSMTabDragAssistant alloc] init]; + } + + return sharedDragAssistant; +} + +- (id)init +{ + if(self = [super init]){ + _sourceTabBar = nil; + _destinationTabBar = nil; + _participatingTabBars = [[NSMutableSet alloc] init]; + _draggedCell = nil; + _animationTimer = nil; + _sineCurveWidths = [[NSMutableArray alloc] initWithCapacity:kPSMTabDragAnimationSteps]; + _targetCell = nil; + _isDragging = NO; + } + + return self; +} + +- (void)dealloc +{ + [_sourceTabBar release]; + [_destinationTabBar release]; + [_participatingTabBars release]; + [_draggedCell release]; + [_animationTimer release]; + [_sineCurveWidths release]; + [_targetCell release]; + [super dealloc]; +} + +#pragma mark - +#pragma mark Accessors + +- (PSMTabBarControl *)sourceTabBar +{ + return _sourceTabBar; +} + +- (void)setSourceTabBar:(PSMTabBarControl *)tabBar +{ + [tabBar retain]; + [_sourceTabBar release]; + _sourceTabBar = tabBar; +} + +- (PSMTabBarControl *)destinationTabBar +{ + return _destinationTabBar; +} + +- (void)setDestinationTabBar:(PSMTabBarControl *)tabBar +{ + [tabBar retain]; + [_destinationTabBar release]; + _destinationTabBar = tabBar; +} + +- (PSMTabBarCell *)draggedCell +{ + return _draggedCell; +} + +- (void)setDraggedCell:(PSMTabBarCell *)cell +{ + [cell retain]; + [_draggedCell release]; + _draggedCell = cell; +} + +- (int)draggedCellIndex +{ + return _draggedCellIndex; +} + +- (void)setDraggedCellIndex:(int)value +{ + _draggedCellIndex = value; +} + +- (BOOL)isDragging +{ + return _isDragging; +} + +- (void)setIsDragging:(BOOL)value +{ + _isDragging = value; +} + +- (NSPoint)currentMouseLoc +{ + return _currentMouseLoc; +} + +- (void)setCurrentMouseLoc:(NSPoint)point +{ + _currentMouseLoc = point; +} + +- (PSMTabBarCell *)targetCell +{ + return _targetCell; +} + +- (void)setTargetCell:(PSMTabBarCell *)cell +{ + [cell retain]; + [_targetCell release]; + _targetCell = cell; +} + +#pragma mark - +#pragma mark Functionality + +- (void)startDraggingCell:(PSMTabBarCell *)cell fromTabBar:(PSMTabBarControl *)control withMouseDownEvent:(NSEvent *)event +{ + [self setIsDragging:YES]; + [self setSourceTabBar:control]; + [self setDestinationTabBar:control]; + [_participatingTabBars addObject:control]; + [self setDraggedCell:cell]; + [self setDraggedCellIndex:[[control cells] indexOfObject:cell]]; + + NSRect cellFrame = [cell frame]; + // list of widths for animation + int i; + float cellWidth = cellFrame.size.width; + for(i = 0; i < kPSMTabDragAnimationSteps; i++){ + int thisWidth; + thisWidth = (int)(cellWidth - ((cellWidth/2.0) + ((sin((PI/2.0) + ((float)i/(float)kPSMTabDragAnimationSteps)*PI) * cellWidth) / 2.0))); + [_sineCurveWidths addObject:[NSNumber numberWithInt:thisWidth]]; + } + + // hide UI buttons + [[control overflowPopUpButton] setHidden:YES]; + [[control addTabButton] setHidden:YES]; + + [[NSCursor closedHandCursor] set]; + + NSPasteboard *pboard = [NSPasteboard pasteboardWithName:NSDragPboard]; + NSImage *dragImage = [cell dragImageForRect:cellFrame]; + [[cell indicator] removeFromSuperview]; + [self distributePlaceholdersInTabBar:control withDraggedCell:cell]; + + if([control isFlipped]){ + cellFrame.origin.y += cellFrame.size.height; + } + [cell setHighlighted:NO]; + NSSize offset = NSZeroSize; + [pboard declareTypes:[NSArray arrayWithObjects:@"PSMTabBarControlItemPBType", nil] owner: nil]; + [pboard setString:[[NSNumber numberWithInt:[[control cells] indexOfObject:cell]] stringValue] forType:@"PSMTabBarControlItemPBType"]; + _animationTimer = [NSTimer scheduledTimerWithTimeInterval:(1.0/30.0) target:self selector:@selector(animateDrag:) userInfo:nil repeats:YES]; + [control dragImage:dragImage at:cellFrame.origin offset:offset event:event pasteboard:pboard source:control slideBack:YES]; +} + +- (void)draggingEnteredTabBar:(PSMTabBarControl *)control atPoint:(NSPoint)mouseLoc +{ + [self setDestinationTabBar:control]; + [self setCurrentMouseLoc:mouseLoc]; + // hide UI buttons + [[control overflowPopUpButton] setHidden:YES]; + [[control addTabButton] setHidden:YES]; + if(![[[control cells] objectAtIndex:0] isPlaceholder]) + [self distributePlaceholdersInTabBar:control]; + [_participatingTabBars addObject:control]; +} + +- (void)draggingUpdatedInTabBar:(PSMTabBarControl *)control atPoint:(NSPoint)mouseLoc +{ + if([self destinationTabBar] != control) + [self setDestinationTabBar:control]; + [self setCurrentMouseLoc:mouseLoc]; +} + +- (void)draggingExitedTabBar:(PSMTabBarControl *)control +{ + [self setDestinationTabBar:nil]; + [self setCurrentMouseLoc:NSMakePoint(-1.0, -1.0)]; +} + +- (void)performDragOperation +{ +#if 1 + // move cell + [[[self destinationTabBar] cells] replaceObjectAtIndex:[[[self destinationTabBar] cells] indexOfObject:[self targetCell]] withObject:[self draggedCell]]; + [[self draggedCell] setControlView:[self destinationTabBar]]; + // move actual NSTabViewItem + if([self sourceTabBar] != [self destinationTabBar]){ + [[[self sourceTabBar] tabView] removeTabViewItem:[[self draggedCell] representedObject]]; + [[[self destinationTabBar] tabView] addTabViewItem:[[self draggedCell] representedObject]]; + } + [self finishDrag]; +#else + unsigned idx = [[[self destinationTabBar] cells] indexOfObject:[self targetCell]]; + + // move cell + [[[self destinationTabBar] cells] replaceObjectAtIndex:idx withObject:[self draggedCell]]; + [[self draggedCell] setControlView:[self destinationTabBar]]; + // move actual NSTabViewItem + if([self sourceTabBar] != [self destinationTabBar]){ + [[[self sourceTabBar] tabView] removeTabViewItem:[[self draggedCell] representedObject]]; + idx = [[[self destinationTabBar] cells] indexOfObject:[self draggedCell]]; + NSLog(@"Inserting at index %d", idx); + [[[self destinationTabBar] tabView] insertTabViewItem:[[self draggedCell] representedObject] atIndex:idx]; + } + [self finishDrag]; +#endif +} + +- (void)draggedImageEndedAt:(NSPoint)aPoint operation:(NSDragOperation)operation +{ + if([self isDragging]){ // means there was not a successful drop (performDragOperation) + // put cell back + [[[self sourceTabBar] cells] insertObject:[self draggedCell] atIndex:[self draggedCellIndex]]; + [self finishDrag]; + } +} + +- (void)finishDrag +{ + [self setIsDragging:NO]; + [self removeAllPlaceholdersFromTabBar:[self sourceTabBar]]; + [self setSourceTabBar:nil]; + [self setDestinationTabBar:nil]; + NSEnumerator *e = [_participatingTabBars objectEnumerator]; + PSMTabBarControl *tabBar; + while(tabBar = [e nextObject]){ + [self removeAllPlaceholdersFromTabBar:tabBar]; + } + [_participatingTabBars removeAllObjects]; + [self setDraggedCell:nil]; + [_animationTimer invalidate]; + _animationTimer = nil; + [_sineCurveWidths removeAllObjects]; + [self setTargetCell:nil]; +} + +#pragma mark - +#pragma mark Animation + +- (void)animateDrag:(NSTimer *)timer +{ + NSEnumerator *e = [_participatingTabBars objectEnumerator]; + PSMTabBarControl *tabBar; + while(tabBar = [e nextObject]){ + [self calculateDragAnimationForTabBar:tabBar]; + [[NSRunLoop currentRunLoop] performSelector:@selector(display) target:tabBar argument:nil order:1 modes:[NSArray arrayWithObjects:@"NSEventTrackingRunLoopMode", @"NSDefaultRunLoopMode", nil]]; + } +} + +- (void)calculateDragAnimationForTabBar:(PSMTabBarControl *)control +{ + BOOL removeFlag = YES; + NSMutableArray *cells = [control cells]; + int i, cellCount = [cells count]; + float xPos = [[control style] leftMarginForTabBarControl]; + + // identify target cell + // mouse at beginning of tabs + NSPoint mouseLoc = [self currentMouseLoc]; + if([self destinationTabBar] == control){ + removeFlag = NO; + if(mouseLoc.x < [[control style] leftMarginForTabBarControl]){ + [self setTargetCell:[cells objectAtIndex:0]]; + goto layout; + } + + NSRect overCellRect; + PSMTabBarCell *overCell = [control cellForPoint:mouseLoc cellFrame:&overCellRect]; + if(overCell){ + // mouse among cells - placeholder + if([overCell isPlaceholder]){ + [self setTargetCell:overCell]; + goto layout; + } + + // non-placeholders + if(mouseLoc.x < (overCellRect.origin.x + (overCellRect.size.width / 2.0))){ + // mouse on left side of cell + [self setTargetCell:[cells objectAtIndex:([cells indexOfObject:overCell] - 1)]]; + goto layout; + } else { + // mouse on right side of cell + [self setTargetCell:[cells objectAtIndex:([cells indexOfObject:overCell] + 1)]]; + goto layout; + } + } else { + // out at end - must find proper cell (could be more in overflow menu) + [self setTargetCell:[control lastVisibleTab]]; + goto layout; + } + } else { + [self setTargetCell:nil]; + } + +layout: + for(i = 0; i < cellCount; i++){ + PSMTabBarCell *cell = [cells objectAtIndex:i]; + NSRect newRect = [cell frame]; + if(![cell isInOverflowMenu]){ + if([cell isPlaceholder]){ + if(cell == [self targetCell]){ + [cell setCurrentStep:([cell currentStep] + 1)]; + } else { + [cell setCurrentStep:([cell currentStep] - 1)]; + if([cell currentStep] > 0){ + removeFlag = NO; + } + } + newRect.size.width = [[_sineCurveWidths objectAtIndex:[cell currentStep]] intValue]; + } + } else { + break; + } + newRect.origin.x = xPos; + [cell setFrame:newRect]; + if([cell indicator]) + [[cell indicator] setFrame:[[control style] indicatorRectForTabCell:cell]]; + xPos += newRect.size.width; + } + if(removeFlag){ + [_participatingTabBars removeObject:control]; + [self removeAllPlaceholdersFromTabBar:control]; + } +} + +#pragma mark - +#pragma mark Placeholders + +- (void)distributePlaceholdersInTabBar:(PSMTabBarControl *)control withDraggedCell:(PSMTabBarCell *)cell +{ + // called upon first drag - must distribute placeholders + [self distributePlaceholdersInTabBar:control]; + // replace dragged cell with a placeholder, and clean up surrounding cells + int cellIndex = [[control cells] indexOfObject:cell]; + PSMTabBarCell *pc = [[[PSMTabBarCell alloc] initPlaceholderWithFrame:[[self draggedCell] frame] expanded:YES inControlView:control] autorelease]; + [[control cells] replaceObjectAtIndex:cellIndex withObject:pc]; + [[control cells] removeObjectAtIndex:(cellIndex + 1)]; + [[control cells] removeObjectAtIndex:(cellIndex - 1)]; + return; +} + +- (void)distributePlaceholdersInTabBar:(PSMTabBarControl *)control +{ + int i, numVisibleTabs = [control numberOfVisibleTabs]; + for(i = 0; i < numVisibleTabs; i++){ + PSMTabBarCell *pc = [[[PSMTabBarCell alloc] initPlaceholderWithFrame:[[self draggedCell] frame] expanded:NO inControlView:control] autorelease]; + [[control cells] insertObject:pc atIndex:(2 * i)]; + } + if(numVisibleTabs > 0){ + PSMTabBarCell *pc = [[[PSMTabBarCell alloc] initPlaceholderWithFrame:[[self draggedCell] frame] expanded:NO inControlView:control] autorelease]; + if([[control cells] count] > (2 * numVisibleTabs)){ + [[control cells] insertObject:pc atIndex:(2 * numVisibleTabs)]; + } else { + [[control cells] addObject:pc]; + } + } +} + +- (void)removeAllPlaceholdersFromTabBar:(PSMTabBarControl *)control +{ + int i, cellCount = [[control cells] count]; + for(i = (cellCount - 1); i >= 0; i--){ + PSMTabBarCell *cell = [[control cells] objectAtIndex:i]; + if([cell isPlaceholder]) + [[control cells] removeObject:cell]; + } + // redraw + [[NSRunLoop currentRunLoop] performSelector:@selector(update) target:control argument:nil order:1 modes:[NSArray arrayWithObjects:@"NSEventTrackingRunLoopMode", @"NSDefaultRunLoopMode", nil]]; + [[NSRunLoop currentRunLoop] performSelector:@selector(display) target:control argument:nil order:1 modes:[NSArray arrayWithObjects:@"NSEventTrackingRunLoopMode", @"NSDefaultRunLoopMode", nil]]; +} + +#pragma mark - +#pragma mark Archiving + +- (void)encodeWithCoder:(NSCoder *)aCoder { + //[super encodeWithCoder:aCoder]; + if ([aCoder allowsKeyedCoding]) { + [aCoder encodeObject:_sourceTabBar forKey:@"sourceTabBar"]; + [aCoder encodeObject:_destinationTabBar forKey:@"destinationTabBar"]; + [aCoder encodeObject:_participatingTabBars forKey:@"participatingTabBars"]; + [aCoder encodeObject:_draggedCell forKey:@"draggedCell"]; + [aCoder encodeInt:_draggedCellIndex forKey:@"draggedCellIndex"]; + [aCoder encodeBool:_isDragging forKey:@"isDragging"]; + [aCoder encodeObject:_animationTimer forKey:@"animationTimer"]; + [aCoder encodeObject:_sineCurveWidths forKey:@"sineCurveWidths"]; + [aCoder encodePoint:_currentMouseLoc forKey:@"currentMouseLoc"]; + [aCoder encodeObject:_targetCell forKey:@"targetCell"]; + } +} + +- (id)initWithCoder:(NSCoder *)aDecoder { + //self = [super initWithCoder:aDecoder]; + //if (self) { + if ([aDecoder allowsKeyedCoding]) { + _sourceTabBar = [[aDecoder decodeObjectForKey:@"sourceTabBar"] retain]; + _destinationTabBar = [[aDecoder decodeObjectForKey:@"destinationTabBar"] retain]; + _participatingTabBars = [[aDecoder decodeObjectForKey:@"participatingTabBars"] retain]; + _draggedCell = [[aDecoder decodeObjectForKey:@"draggedCell"] retain]; + _draggedCellIndex = [aDecoder decodeIntForKey:@"draggedCellIndex"]; + _isDragging = [aDecoder decodeBoolForKey:@"isDragging"]; + _animationTimer = [[aDecoder decodeObjectForKey:@"animationTimer"] retain]; + _sineCurveWidths = [[aDecoder decodeObjectForKey:@"sineCurveWidths"] retain]; + _currentMouseLoc = [aDecoder decodePointForKey:@"currentMouseLoc"]; + _targetCell = [[aDecoder decodeObjectForKey:@"targetCell"] retain]; + } + //} + return self; +} + + +@end diff --git a/PSMTabBarControl/source/PSMTabStyle.h b/PSMTabBarControl/source/PSMTabStyle.h new file mode 100644 index 0000000000..eedf7b7712 --- /dev/null +++ b/PSMTabBarControl/source/PSMTabStyle.h @@ -0,0 +1,52 @@ +// +// PSMTabStyle.h +// PSMTabBarControl +// +// Created by John Pannell on 2/17/06. +// Copyright 2006 Positive Spin Media. All rights reserved. +// + +/* +Protocol to be observed by all style delegate objects. These objects handle the drawing responsibilities for PSMTabBarCell; once the control has been assigned a style, the background and cells draw consistent with that style. Design pattern and implementation by David Smith, Seth Willits, and Chris Forsythe, all touch up and errors by John P. :-) +*/ + +#import "PSMTabBarCell.h" +#import "PSMTabBarControl.h" + +@protocol PSMTabStyle + +// identity +- (NSString *)name; + +// control specific parameters +- (float)leftMarginForTabBarControl; +- (float)rightMarginForTabBarControl; + +// add tab button +- (NSImage *)addTabButtonImage; +- (NSImage *)addTabButtonPressedImage; +- (NSImage *)addTabButtonRolloverImage; + +// cell specific parameters +- (NSRect)closeButtonRectForTabCell:(PSMTabBarCell *)cell; +- (NSRect)iconRectForTabCell:(PSMTabBarCell *)cell; +- (NSRect)indicatorRectForTabCell:(PSMTabBarCell *)cell; +- (NSRect)objectCounterRectForTabCell:(PSMTabBarCell *)cell; +- (float)minimumWidthOfTabCell:(PSMTabBarCell *)cell; +- (float)desiredWidthOfTabCell:(PSMTabBarCell *)cell; + +// cell values +- (NSAttributedString *)attributedObjectCountValueForTabCell:(PSMTabBarCell *)cell; +- (NSAttributedString *)attributedStringValueForTabCell:(PSMTabBarCell *)cell; + +// drawing +- (void)drawTabCell:(PSMTabBarCell *)cell; +- (void)drawTabBar:(PSMTabBarControl *)bar inRect:(NSRect)rect; + +@end + +@interface PSMTabBarControl (StyleAccessors) + +- (NSMutableArray *)cells; + +@end \ No newline at end of file diff --git a/PSMTabBarControl/source/PSMUnifiedTabStyle.h b/PSMTabBarControl/source/PSMUnifiedTabStyle.h new file mode 100644 index 0000000000..751956aaed --- /dev/null +++ b/PSMTabBarControl/source/PSMUnifiedTabStyle.h @@ -0,0 +1,24 @@ +// +// PSMUnifiedTabStyle.h +// -------------------- +// +// Created by Keith Blount on 30/04/2006. +// Copyright 2006 __MyCompanyName__. All rights reserved. +// + +#import +#import "PSMTabStyle.h" + +@interface PSMUnifiedTabStyle : NSObject +{ + NSImage *unifiedCloseButton; + NSImage *unifiedCloseButtonDown; + NSImage *unifiedCloseButtonOver; + NSImage *_addTabButtonImage; + NSImage *_addTabButtonPressedImage; + NSImage *_addTabButtonRolloverImage; + + float leftMargin; +} +- (void)setLeftMarginForTabBarControl:(float)margin; +@end diff --git a/PSMTabBarControl/source/PSMUnifiedTabStyle.m b/PSMTabBarControl/source/PSMUnifiedTabStyle.m new file mode 100644 index 0000000000..ea2910c6e2 --- /dev/null +++ b/PSMTabBarControl/source/PSMUnifiedTabStyle.m @@ -0,0 +1,529 @@ +// +// PSMUnifiedTabStyle.m +// -------------------- +// +// Created by Keith Blount on 30/04/2006. +// Copyright 2006 __MyCompanyName__. All rights reserved. +// + +#import "PSMUnifiedTabStyle.h" +#import "PSMTabBarCell.h" +#import "PSMTabBarControl.h" +#import "NSBezierPath_AMShading.h" + +#define kPSMUnifiedObjectCounterRadius 7.0 +#define kPSMUnifiedCounterMinWidth 20 + +@interface PSMUnifiedTabStyle (Private) +- (void)drawInteriorWithTabCell:(PSMTabBarCell *)cell inView:(NSView*)controlView; +@end + +@implementation PSMUnifiedTabStyle + +- (NSString *)name +{ + return @"Unified"; +} + +#pragma mark - +#pragma mark Creation/Destruction + +- (id) init +{ + if((self = [super init])) + { + NSLog(@"PSMUnifiedTabStyle init"); + + unifiedCloseButton = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"AquaTabClose_Front"]]; + unifiedCloseButtonDown = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"AquaTabClose_Front_Pressed"]]; + unifiedCloseButtonOver = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"AquaTabClose_Front_Rollover"]]; + + _addTabButtonImage = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"AquaTabNew"]]; + _addTabButtonPressedImage = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"AquaTabNewPressed"]]; + _addTabButtonRolloverImage = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"AquaTabNewRollover"]]; + + leftMargin = 5.0; + } + return self; +} + +- (void)dealloc +{ + [unifiedCloseButton release]; + [unifiedCloseButtonDown release]; + [unifiedCloseButtonOver release]; + [_addTabButtonImage release]; + [_addTabButtonPressedImage release]; + [_addTabButtonRolloverImage release]; + + [super dealloc]; +} + +#pragma mark - +#pragma mark Control Specific + +- (void)setLeftMarginForTabBarControl:(float)margin +{ + leftMargin = margin; +} + +- (float)leftMarginForTabBarControl +{ + return leftMargin; +} + +- (float)rightMarginForTabBarControl +{ + return 24.0f; +} + +#pragma mark - +#pragma mark Add Tab Button + +- (NSImage *)addTabButtonImage +{ + return _addTabButtonImage; +} + +- (NSImage *)addTabButtonPressedImage +{ + return _addTabButtonPressedImage; +} + +- (NSImage *)addTabButtonRolloverImage +{ + return _addTabButtonRolloverImage; +} + +#pragma mark - +#pragma mark Cell Specific + +- (NSRect) closeButtonRectForTabCell:(PSMTabBarCell *)cell +{ + NSRect cellFrame = [cell frame]; + + if ([cell hasCloseButton] == NO) { + return NSZeroRect; + } + + NSRect result; + result.size = [unifiedCloseButton size]; + result.origin.x = cellFrame.origin.x + MARGIN_X; + result.origin.y = cellFrame.origin.y + MARGIN_Y + 1.0; + + return result; +} + +- (NSRect)iconRectForTabCell:(PSMTabBarCell *)cell +{ + NSRect cellFrame = [cell frame]; + + if ([cell hasIcon] == NO) { + return NSZeroRect; + } + + NSRect result; + result.size = NSMakeSize(kPSMTabBarIconWidth, kPSMTabBarIconWidth); + result.origin.x = cellFrame.origin.x + MARGIN_X; + result.origin.y = cellFrame.origin.y + MARGIN_Y + 1.0; + + if([cell hasCloseButton] && ![cell isCloseButtonSuppressed]) + result.origin.x += [unifiedCloseButton size].width + kPSMTabBarCellPadding; + + return result; +} + +- (NSRect)indicatorRectForTabCell:(PSMTabBarCell *)cell +{ + NSRect cellFrame = [cell frame]; + + if ([[cell indicator] isHidden]) { + return NSZeroRect; + } + + NSRect result; + result.size = NSMakeSize(kPSMTabBarIndicatorWidth, kPSMTabBarIndicatorWidth); + result.origin.x = cellFrame.origin.x + cellFrame.size.width - MARGIN_X - kPSMTabBarIndicatorWidth; + result.origin.y = cellFrame.origin.y + MARGIN_Y - 1.0; + + return result; +} + +- (NSRect)objectCounterRectForTabCell:(PSMTabBarCell *)cell +{ + NSRect cellFrame = [cell frame]; + + if ([cell count] == 0) { + return NSZeroRect; + } + + float countWidth = [[self attributedObjectCountValueForTabCell:cell] size].width; + countWidth += (2 * kPSMUnifiedObjectCounterRadius - 6.0); + if(countWidth < kPSMUnifiedCounterMinWidth) + countWidth = kPSMUnifiedCounterMinWidth; + + NSRect result; + result.size = NSMakeSize(countWidth, 2 * kPSMUnifiedObjectCounterRadius); // temp + result.origin.x = cellFrame.origin.x + cellFrame.size.width - MARGIN_X - result.size.width; + result.origin.y = cellFrame.origin.y + MARGIN_Y + 1.0; + + if(![[cell indicator] isHidden]) + result.origin.x -= kPSMTabBarIndicatorWidth + kPSMTabBarCellPadding; + + return result; +} + + +- (float)minimumWidthOfTabCell:(PSMTabBarCell *)cell +{ + float resultWidth = 0.0; + + // left margin + resultWidth = MARGIN_X; + + // close button? + if([cell hasCloseButton] && ![cell isCloseButtonSuppressed]) + resultWidth += [unifiedCloseButton size].width + kPSMTabBarCellPadding; + + // icon? + if([cell hasIcon]) + resultWidth += kPSMTabBarIconWidth + kPSMTabBarCellPadding; + + // the label + resultWidth += kPSMMinimumTitleWidth; + + // object counter? + if([cell count] > 0) + resultWidth += [self objectCounterRectForTabCell:cell].size.width + kPSMTabBarCellPadding; + + // indicator? + if ([[cell indicator] isHidden] == NO) + resultWidth += kPSMTabBarCellPadding + kPSMTabBarIndicatorWidth; + + // right margin + resultWidth += MARGIN_X; + + return ceil(resultWidth); +} + +- (float)desiredWidthOfTabCell:(PSMTabBarCell *)cell +{ + float resultWidth = 0.0; + + // left margin + resultWidth = MARGIN_X; + + // close button? + if ([cell hasCloseButton] && ![cell isCloseButtonSuppressed]) + resultWidth += [unifiedCloseButton size].width + kPSMTabBarCellPadding; + + // icon? + if([cell hasIcon]) + resultWidth += kPSMTabBarIconWidth + kPSMTabBarCellPadding; + + // the label + resultWidth += [[cell attributedStringValue] size].width; + + // object counter? + if([cell count] > 0) + resultWidth += [self objectCounterRectForTabCell:cell].size.width + kPSMTabBarCellPadding; + + // indicator? + if ([[cell indicator] isHidden] == NO) + resultWidth += kPSMTabBarCellPadding + kPSMTabBarIndicatorWidth; + + // right margin + resultWidth += MARGIN_X; + + return ceil(resultWidth); +} + +#pragma mark - +#pragma mark Cell Values + +- (NSAttributedString *)attributedObjectCountValueForTabCell:(PSMTabBarCell *)cell +{ + NSMutableAttributedString *attrStr; + NSFontManager *fm = [NSFontManager sharedFontManager]; + NSNumberFormatter *nf = [[[NSNumberFormatter alloc] init] autorelease]; + [nf setLocalizesFormat:YES]; + [nf setFormat:@"0"]; + [nf setHasThousandSeparators:YES]; + NSString *contents = [nf stringFromNumber:[NSNumber numberWithInt:[cell count]]]; + attrStr = [[[NSMutableAttributedString alloc] initWithString:contents] autorelease]; + NSRange range = NSMakeRange(0, [contents length]); + + // Add font attribute + [attrStr addAttribute:NSFontAttributeName value:[fm convertFont:[NSFont fontWithName:@"Helvetica" size:11.0] toHaveTrait:NSBoldFontMask] range:range]; + [attrStr addAttribute:NSForegroundColorAttributeName value:[[NSColor whiteColor] colorWithAlphaComponent:0.85] range:range]; + + return attrStr; +} + +- (NSAttributedString *)attributedStringValueForTabCell:(PSMTabBarCell *)cell +{ + NSMutableAttributedString *attrStr; + NSString * contents = [cell stringValue]; + attrStr = [[[NSMutableAttributedString alloc] initWithString:contents] autorelease]; + NSRange range = NSMakeRange(0, [contents length]); + + [attrStr addAttribute:NSFontAttributeName value:[NSFont systemFontOfSize:11.0] range:range]; + + // Paragraph Style for Truncating Long Text + static NSMutableParagraphStyle *TruncatingTailParagraphStyle = nil; + if (!TruncatingTailParagraphStyle) { + TruncatingTailParagraphStyle = [[[NSParagraphStyle defaultParagraphStyle] mutableCopy] retain]; + [TruncatingTailParagraphStyle setLineBreakMode:NSLineBreakByTruncatingTail]; + } + [attrStr addAttribute:NSParagraphStyleAttributeName value:TruncatingTailParagraphStyle range:range]; + + return attrStr; +} + +#pragma mark - +#pragma mark ---- drawing ---- + +- (void)drawTabCell:(PSMTabBarCell *)cell +{ + NSRect cellFrame = [cell frame]; + NSColor * lineColor = nil; + NSBezierPath* bezier = [NSBezierPath bezierPath]; + lineColor = [NSColor colorWithCalibratedWhite:0.576 alpha:1.0]; + + if ([cell state] == NSOnState) + { + // selected tab + NSRect aRect = NSMakeRect(cellFrame.origin.x+0.5, cellFrame.origin.y-0.5, cellFrame.size.width-1.0, cellFrame.size.height); + aRect.size.height -= 0.5; + + aRect.size.height+=0.5; + + // frame + float radius = MIN(6.0, 0.5f * MIN(NSWidth(aRect), NSHeight(aRect))); + NSRect rect = NSInsetRect(aRect, radius, radius); + + [bezier appendBezierPathWithArcWithCenter:NSMakePoint(NSMinX(rect), NSMinY(rect)) radius:radius startAngle:180.0 endAngle:270.0]; + + [bezier appendBezierPathWithArcWithCenter:NSMakePoint(NSMaxX(rect), NSMinY(rect)) radius:radius startAngle:270.0 endAngle:360.0]; + + NSPoint cornerPoint = NSMakePoint(NSMaxX(aRect), NSMaxY(aRect)); + [bezier appendBezierPathWithPoints:&cornerPoint count:1]; + + cornerPoint = NSMakePoint(NSMinX(aRect), NSMaxY(aRect)); + [bezier appendBezierPathWithPoints:&cornerPoint count:1]; + + [bezier closePath]; + + //[[NSColor windowBackgroundColor] set]; + //[bezier fill]; + [bezier linearGradientFillWithStartColor:[NSColor colorWithCalibratedWhite:0.99 alpha:1.0] + endColor:[NSColor colorWithCalibratedWhite:0.941 alpha:1.0]]; + + [lineColor set]; + [bezier stroke]; + } + else + { + // unselected tab + NSRect aRect = NSMakeRect(cellFrame.origin.x, cellFrame.origin.y, cellFrame.size.width, cellFrame.size.height); + aRect.origin.y += 0.5; + aRect.origin.x += 1.5; + aRect.size.width -= 1; + + aRect.origin.x -= 1; + aRect.size.width += 1; + + // rollover + if ([cell isHighlighted]) + { + [[NSColor colorWithCalibratedWhite:0.0 alpha:0.1] set]; + NSRectFillUsingOperation(aRect, NSCompositeSourceAtop); + } + + // frame + + [lineColor set]; + [bezier moveToPoint:NSMakePoint(aRect.origin.x + aRect.size.width, aRect.origin.y-0.5)]; + if(!([cell tabState] & PSMTab_RightIsSelectedMask)){ + [bezier lineToPoint:NSMakePoint(NSMaxX(aRect), NSMaxY(aRect))]; + } + + [bezier stroke]; + + // Create a thin lighter line next to the dividing line for a bezel effect + if(!([cell tabState] & PSMTab_RightIsSelectedMask)){ + [[[NSColor whiteColor] colorWithAlphaComponent:0.5] set]; + [NSBezierPath strokeLineFromPoint:NSMakePoint(NSMaxX(aRect)+1.0, aRect.origin.y-0.5) + toPoint:NSMakePoint(NSMaxX(aRect)+1.0, NSMaxY(aRect)-2.5)]; + } + + // If this is the leftmost tab, we want to draw a line on the left, too + if ([cell tabState] & PSMTab_PositionLeftMask) + { + [lineColor set]; + [NSBezierPath strokeLineFromPoint:NSMakePoint(aRect.origin.x,aRect.origin.y-0.5) + toPoint:NSMakePoint(aRect.origin.x,NSMaxY(aRect)-2.5)]; + [[[NSColor whiteColor] colorWithAlphaComponent:0.5] set]; + [NSBezierPath strokeLineFromPoint:NSMakePoint(aRect.origin.x+1.0,aRect.origin.y-0.5) + toPoint:NSMakePoint(aRect.origin.x+1.0,NSMaxY(aRect)-2.5)]; + } + } + + [self drawInteriorWithTabCell:cell inView:[cell controlView]]; +} + + + +- (void)drawInteriorWithTabCell:(PSMTabBarCell *)cell inView:(NSView*)controlView +{ + NSRect cellFrame = [cell frame]; + float labelPosition = cellFrame.origin.x + MARGIN_X; + + // close button + if ([cell hasCloseButton] && ![cell isCloseButtonSuppressed]) { + NSSize closeButtonSize = NSZeroSize; + NSRect closeButtonRect = [cell closeButtonRectForFrame:cellFrame]; + NSImage * closeButton = nil; + + closeButton = unifiedCloseButton; + if ([cell closeButtonOver]) closeButton = unifiedCloseButtonOver; + if ([cell closeButtonPressed]) closeButton = unifiedCloseButtonDown; + + closeButtonSize = [closeButton size]; + if ([controlView isFlipped]) { + closeButtonRect.origin.y += closeButtonRect.size.height; + } + + [closeButton compositeToPoint:closeButtonRect.origin operation:NSCompositeSourceOver fraction:1.0]; + + // scoot label over + labelPosition += closeButtonSize.width + kPSMTabBarCellPadding; + } + + // icon + if([cell hasIcon]){ + NSRect iconRect = [self iconRectForTabCell:cell]; + NSImage *icon = [[[[cell representedObject] identifier] content] icon]; + if ([controlView isFlipped]) { + iconRect.origin.y = cellFrame.size.height - iconRect.origin.y; + } + [icon compositeToPoint:iconRect.origin operation:NSCompositeSourceOver fraction:1.0]; + + // scoot label over + labelPosition += iconRect.size.width + kPSMTabBarCellPadding; + } + + // object counter + if([cell count] > 0){ + [[NSColor colorWithCalibratedWhite:0.3 alpha:0.6] set]; + NSBezierPath *path = [NSBezierPath bezierPath]; + NSRect myRect = [self objectCounterRectForTabCell:cell]; + myRect.origin.y -= 1.0; + [path moveToPoint:NSMakePoint(myRect.origin.x + kPSMUnifiedObjectCounterRadius, myRect.origin.y)]; + [path lineToPoint:NSMakePoint(myRect.origin.x + myRect.size.width - kPSMUnifiedObjectCounterRadius, myRect.origin.y)]; + [path appendBezierPathWithArcWithCenter:NSMakePoint(myRect.origin.x + myRect.size.width - kPSMUnifiedObjectCounterRadius, myRect.origin.y + kPSMUnifiedObjectCounterRadius) radius:kPSMUnifiedObjectCounterRadius startAngle:270.0 endAngle:90.0]; + [path lineToPoint:NSMakePoint(myRect.origin.x + kPSMUnifiedObjectCounterRadius, myRect.origin.y + myRect.size.height)]; + [path appendBezierPathWithArcWithCenter:NSMakePoint(myRect.origin.x + kPSMUnifiedObjectCounterRadius, myRect.origin.y + kPSMUnifiedObjectCounterRadius) radius:kPSMUnifiedObjectCounterRadius startAngle:90.0 endAngle:270.0]; + [path fill]; + + // draw attributed string centered in area + NSRect counterStringRect; + NSAttributedString *counterString = [self attributedObjectCountValueForTabCell:cell]; + counterStringRect.size = [counterString size]; + counterStringRect.origin.x = myRect.origin.x + ((myRect.size.width - counterStringRect.size.width) / 2.0) + 0.25; + counterStringRect.origin.y = myRect.origin.y + ((myRect.size.height - counterStringRect.size.height) / 2.0) + 0.5; + [counterString drawInRect:counterStringRect]; + } + + // label rect + NSRect labelRect; + labelRect.origin.x = labelPosition; + labelRect.size.width = cellFrame.size.width - (labelRect.origin.x - cellFrame.origin.x) - kPSMTabBarCellPadding; + NSSize s = [[cell attributedStringValue] size]; + labelRect.origin.y = cellFrame.origin.y + (cellFrame.size.height-s.height)/2.0 - 1.0; + labelRect.size.height = s.height; + + if(![[cell indicator] isHidden]) + labelRect.size.width -= (kPSMTabBarIndicatorWidth + kPSMTabBarCellPadding); + + if([cell count] > 0) + labelRect.size.width -= ([self objectCounterRectForTabCell:cell].size.width + kPSMTabBarCellPadding); + + // label + [[cell attributedStringValue] drawInRect:labelRect]; +} + +- (void)drawTabBar:(PSMTabBarControl *)bar inRect:(NSRect)rect +{ + NSRect gradientRect = rect; + gradientRect.size.height -= 1.0; + NSBezierPath *path = [NSBezierPath bezierPathWithRect:gradientRect]; + [path linearGradientFillWithStartColor:[NSColor colorWithCalibratedWhite:0.918 alpha:1.0] + endColor:[NSColor colorWithCalibratedWhite:0.843 alpha:1.0]]; + [[NSColor colorWithCalibratedWhite:0.576 alpha:1.0] set]; + [NSBezierPath strokeLineFromPoint:NSMakePoint(rect.origin.x,NSMaxY(rect)-0.5) + toPoint:NSMakePoint(NSMaxX(rect),NSMaxY(rect)-0.5)]; + + // no tab view == not connected + if(![bar tabView]){ + NSRect labelRect = rect; + labelRect.size.height -= 4.0; + labelRect.origin.y += 4.0; + NSMutableAttributedString *attrStr; + NSString *contents = @"PSMTabBarControl"; + attrStr = [[[NSMutableAttributedString alloc] initWithString:contents] autorelease]; + NSRange range = NSMakeRange(0, [contents length]); + [attrStr addAttribute:NSFontAttributeName value:[NSFont systemFontOfSize:11.0] range:range]; + NSMutableParagraphStyle *centeredParagraphStyle = nil; + if (!centeredParagraphStyle) { + centeredParagraphStyle = [[[NSParagraphStyle defaultParagraphStyle] mutableCopy] retain]; + [centeredParagraphStyle setAlignment:NSCenterTextAlignment]; + } + [attrStr addAttribute:NSParagraphStyleAttributeName value:centeredParagraphStyle range:range]; + [attrStr drawInRect:labelRect]; + return; + } + + // draw cells + NSEnumerator *e = [[bar cells] objectEnumerator]; + PSMTabBarCell *cell; + while(cell = [e nextObject]){ + if(![cell isInOverflowMenu]){ + [cell drawWithFrame:[cell frame] inView:bar]; + } + } +} + +#pragma mark - +#pragma mark Archiving + +- (void)encodeWithCoder:(NSCoder *)aCoder +{ + //[super encodeWithCoder:aCoder]; + if ([aCoder allowsKeyedCoding]) { + [aCoder encodeObject:unifiedCloseButton forKey:@"unifiedCloseButton"]; + [aCoder encodeObject:unifiedCloseButtonDown forKey:@"unifiedCloseButtonDown"]; + [aCoder encodeObject:unifiedCloseButtonOver forKey:@"unifiedCloseButtonOver"]; + [aCoder encodeObject:_addTabButtonImage forKey:@"addTabButtonImage"]; + [aCoder encodeObject:_addTabButtonPressedImage forKey:@"addTabButtonPressedImage"]; + [aCoder encodeObject:_addTabButtonRolloverImage forKey:@"addTabButtonRolloverImage"]; + } +} + +- (id)initWithCoder:(NSCoder *)aDecoder +{ + // self = [super initWithCoder:aDecoder]; + //if (self) { + if ([aDecoder allowsKeyedCoding]) { + unifiedCloseButton = [[aDecoder decodeObjectForKey:@"unifiedCloseButton"] retain]; + unifiedCloseButtonDown = [[aDecoder decodeObjectForKey:@"unifiedCloseButtonDown"] retain]; + unifiedCloseButtonOver = [[aDecoder decodeObjectForKey:@"unifiedCloseButtonOver"] retain]; + _addTabButtonImage = [[aDecoder decodeObjectForKey:@"addTabButtonImage"] retain]; + _addTabButtonPressedImage = [[aDecoder decodeObjectForKey:@"addTabButtonPressedImage"] retain]; + _addTabButtonRolloverImage = [[aDecoder decodeObjectForKey:@"addTabButtonRolloverImage"] retain]; + } + //} + return self; +} + +@end diff --git a/PSMTabBarControl/source/WindowController.h b/PSMTabBarControl/source/WindowController.h new file mode 100644 index 0000000000..ae655b8bea --- /dev/null +++ b/PSMTabBarControl/source/WindowController.h @@ -0,0 +1,58 @@ +// +// WindowController.h +// PSMTabBarControl +// +// Created by John Pannell on 4/6/06. +// Copyright 2006 Positive Spin Media. All rights reserved. +// + +#import +@class PSMTabBarControl; + +@interface WindowController : NSWindowController { + IBOutlet NSTabView *tabView; + IBOutlet NSTextField *tabField; + IBOutlet NSDrawer *drawer; + + IBOutlet PSMTabBarControl *tabBar; + + IBOutlet NSButton *isProcessingButton; + IBOutlet NSTextField *objectCounterField; + IBOutlet NSPopUpButton *iconButton; +} + +// UI +- (IBAction)addNewTab:(id)sender; +- (IBAction)closeTab:(id)sender; +- (IBAction)stopProcessing:(id)sender; +- (IBAction)setIconNamed:(id)sender; +- (IBAction)setObjectCount:(id)sender; +- (IBAction)setTabLabel:(id)sender; + +// Actions +- (IBAction)isProcessingAction:(id)sender; + +// tab bar config +- (void)configStyle:(id)sender; +- (void)configCanCloseOnlyTab:(id)sender; +- (void)configHideForSingleTab:(id)sender; +- (void)configAddTabButton:(id)sender; +- (void)configTabMinWidth:(id)sender; +- (void)configTabMaxWidth:(id)sender; +- (void)configTabOptimumWidth:(id)sender; +- (void)configTabSizeToFit:(id)sender; + +// delegate +- (void)tabView:(NSTabView *)aTabView didSelectTabViewItem:(NSTabViewItem *)tabViewItem; +- (BOOL)tabView:(NSTabView *)aTabView shouldCloseTabViewItem:(NSTabViewItem *)tabViewItem; +- (void)tabView:(NSTabView *)aTabView willCloseTabViewItem:(NSTabViewItem *)tabViewItem; +- (void)tabView:(NSTabView *)aTabView didCloseTabViewItem:(NSTabViewItem *)tabViewItem; + +// toolbar +- (NSToolbarItem *)toolbar:(NSToolbar *)toolbar itemForItemIdentifier:(NSString *)itemIdentifier willBeInsertedIntoToolbar:(BOOL)flag; +- (NSArray *)toolbarDefaultItemIdentifiers:(NSToolbar*)toolbar; +- (NSArray *)toolbarAllowedItemIdentifiers:(NSToolbar*)toolbar; +- (IBAction)toggleToolbar:(id)sender; +- (BOOL)validateToolbarItem:(NSToolbarItem *)theItem; + +@end diff --git a/PSMTabBarControl/source/WindowController.m b/PSMTabBarControl/source/WindowController.m new file mode 100644 index 0000000000..07414dbdcf --- /dev/null +++ b/PSMTabBarControl/source/WindowController.m @@ -0,0 +1,280 @@ +// +// WindowController.m +// PSMTabBarControl +// +// Created by John Pannell on 4/6/06. +// Copyright 2006 Positive Spin Media. All rights reserved. +// + +#import "WindowController.h" +#import "FakeModel.h" +#import "PSMTabBarControl.h" + +@implementation WindowController + +- (void)awakeFromNib +{ + // toolbar + NSToolbar *toolbar = [[NSToolbar alloc] initWithIdentifier:@"DemoToolbar"]; + [toolbar setDelegate:self]; + [toolbar setAllowsUserCustomization:YES]; + [toolbar setAutosavesConfiguration:YES]; + /*SInt32 MacVersion; + if (Gestalt(gestaltSystemVersion, &MacVersion) == noErr){ + if (MacVersion >= 0x1040){ + // this call is Tiger only + [toolbar setShowsBaselineSeparator:NO]; + } + }*/ + [[self window] setToolbar:toolbar]; + + // hook up add tab button + [[tabBar addTabButton] setTarget:self]; + [[tabBar addTabButton] setAction:@selector(addNewTab:)]; + + // remove any tabs present in the nib + NSArray *existingItems = [tabView tabViewItems]; + NSEnumerator *e = [existingItems objectEnumerator]; + NSTabViewItem *item; + while(item = [e nextObject]){ + [tabView removeTabViewItem:item]; + } + + [self addNewTab:self]; + [self addNewTab:self]; + [self addNewTab:self]; + [[tabView tabViewItemAtIndex:0] setLabel:@"Tab"]; + [[tabView tabViewItemAtIndex:1] setLabel:@"Bar"]; + [[tabView tabViewItemAtIndex:2] setLabel:@"Control"]; + + // open drawer + //[drawer toggle:self]; +} + +- (IBAction)addNewTab:(id)sender +{ + FakeModel *newModel = [[FakeModel alloc] init]; + NSTabViewItem *newItem = [[[NSTabViewItem alloc] initWithIdentifier:[newModel controller]] autorelease]; + [newItem setLabel:@"Untitled"]; + [tabView addTabViewItem:newItem]; + [tabView selectTabViewItem:newItem]; // this is optional, but expected behavior + [newModel release]; +} + +- (IBAction)closeTab:(id)sender +{ + [tabView removeTabViewItem:[tabView selectedTabViewItem]]; +} + +- (void)stopProcessing:(id)sender +{ + [[[tabView selectedTabViewItem] identifier] setValue:[NSNumber numberWithBool:NO] forKeyPath:@"selection.isProcessing"]; +} + +- (void)setIconNamed:(id)sender +{ + NSString *iconName = [sender titleOfSelectedItem]; + if([iconName isEqualToString:@"None"]){ + [[[tabView selectedTabViewItem] identifier] setValue:nil forKeyPath:@"selection.icon"]; + [[[tabView selectedTabViewItem] identifier] setValue:@"None" forKeyPath:@"selection.iconName"]; + } else { + NSImage *newIcon = [NSImage imageNamed:iconName]; + [[[tabView selectedTabViewItem] identifier] setValue:newIcon forKeyPath:@"selection.icon"]; + [[[tabView selectedTabViewItem] identifier] setValue:iconName forKeyPath:@"selection.iconName"]; + } +} + +- (void)setObjectCount:(id)sender +{ + [[[tabView selectedTabViewItem] identifier] setValue:[NSNumber numberWithInt:[sender intValue]] forKeyPath:@"selection.objectCount"]; +} + +- (IBAction)isProcessingAction:(id)sender +{ + [[[tabView selectedTabViewItem] identifier] setValue:[NSNumber numberWithBool:[sender state]] forKeyPath:@"selection.isProcessing"]; +} + +- (IBAction)setTabLabel:(id)sender +{ + [[tabView selectedTabViewItem] setLabel:[sender stringValue]]; +} + +- (BOOL)validateMenuItem:(id )menuItem +{ + if([menuItem action] == @selector(closeTab:)){ + if(![tabBar canCloseOnlyTab] && ([tabView numberOfTabViewItems] <= 1)){ + return NO; + } + } + return YES; +} + +#pragma mark - +#pragma mark ---- tab bar config ---- + +- (void)configStyle:(id)sender +{ + [tabBar setStyleNamed:[sender titleOfSelectedItem]]; +} + +- (void)configCanCloseOnlyTab:(id)sender +{ + [tabBar setCanCloseOnlyTab:[sender state]]; +} + +- (void)configHideForSingleTab:(id)sender +{ + [tabBar setHideForSingleTab:[sender state]]; +} + +- (void)configAddTabButton:(id)sender +{ + [tabBar setShowAddTabButton:[sender state]]; +} + +- (void)configTabMinWidth:(id)sender +{ + if([tabBar cellOptimumWidth] < [sender intValue]){ + [tabBar setCellMinWidth:[tabBar cellOptimumWidth]]; + [sender setIntValue:[tabBar cellOptimumWidth]]; + return; + } + + [tabBar setCellMinWidth:[sender intValue]]; +} + +- (void)configTabMaxWidth:(id)sender +{ + if([tabBar cellOptimumWidth] > [sender intValue]){ + [tabBar setCellMaxWidth:[tabBar cellOptimumWidth]]; + [sender setIntValue:[tabBar cellOptimumWidth]]; + return; + } + + [tabBar setCellMaxWidth:[sender intValue]]; +} + +- (void)configTabOptimumWidth:(id)sender +{ + if([tabBar cellMaxWidth] < [sender intValue]){ + [tabBar setCellOptimumWidth:[tabBar cellMaxWidth]]; + [sender setIntValue:[tabBar cellMaxWidth]]; + return; + } + + if([tabBar cellMinWidth] > [sender intValue]){ + [tabBar setCellOptimumWidth:[tabBar cellMinWidth]]; + [sender setIntValue:[tabBar cellMinWidth]]; + return; + } + + [tabBar setCellOptimumWidth:[sender intValue]]; +} + +- (void)configTabSizeToFit:(id)sender +{ + [tabBar setSizeCellsToFit:[sender state]]; +} + +#pragma mark - +#pragma mark ---- delegate ---- + +- (void)tabView:(NSTabView *)aTabView didSelectTabViewItem:(NSTabViewItem *)tabViewItem +{ + // need to update bound values to match the selected tab + if([[tabViewItem identifier] respondsToSelector:@selector(content)]){ + if([[[tabViewItem identifier] content] respondsToSelector:@selector(objectCount)]){ + [objectCounterField setIntValue:[[[tabViewItem identifier] content] objectCount]]; + } + } + if([[tabViewItem identifier] respondsToSelector:@selector(content)]){ + if([[[tabViewItem identifier] content] respondsToSelector:@selector(isProcessing)]){ + [isProcessingButton setState:[[[tabViewItem identifier] content] isProcessing]]; + } + } + if([[tabViewItem identifier] respondsToSelector:@selector(content)]){ + if([[[tabViewItem identifier] content] respondsToSelector:@selector(iconName)]){ + NSString *newName = [[[tabViewItem identifier] content] iconName]; + if(newName){ + [iconButton selectItem:[[iconButton menu] itemWithTitle:newName]]; + } else { + [iconButton selectItem:[[iconButton menu] itemWithTitle:@"None"]]; + } + } + } +} + +- (BOOL)tabView:(NSTabView *)aTabView shouldCloseTabViewItem:(NSTabViewItem *)tabViewItem +{ + if([[tabViewItem label] isEqualToString:@"Drake"]){ + NSAlert *drakeAlert = [NSAlert alertWithMessageText:@"No Way!" defaultButton:@"OK" alternateButton:nil otherButton:nil informativeTextWithFormat:@"I refuse to close a tab named \"Drake\""]; + [drakeAlert beginSheetModalForWindow:[NSApp keyWindow] modalDelegate:nil didEndSelector:nil contextInfo:nil]; + return NO; + } + return YES; +} + +- (void)tabView:(NSTabView *)aTabView willCloseTabViewItem:(NSTabViewItem *)tabViewItem +{ + NSLog(@"willCloseTabViewItem: %@", [tabViewItem label]); +} + +- (void)tabView:(NSTabView *)aTabView didCloseTabViewItem:(NSTabViewItem *)tabViewItem +{ + NSLog(@"didCloseTabViewItem: %@", [tabViewItem label]); +} + +#pragma mark - +#pragma mark ---- toolbar ---- + +- (NSToolbarItem *)toolbar:(NSToolbar *)toolbar itemForItemIdentifier:(NSString *)itemIdentifier willBeInsertedIntoToolbar:(BOOL)flag +{ + NSToolbarItem *item = [[NSToolbarItem alloc] initWithItemIdentifier:itemIdentifier]; + + if([itemIdentifier isEqualToString:@"TabField"]){ + [item setPaletteLabel:@"Tab Label"]; + [item setLabel:@"Tab Label"]; + [item setView:tabField]; + [item setMinSize:NSMakeSize(100, [tabField frame].size.height)]; + [item setMaxSize:NSMakeSize(500, [tabField frame].size.height)]; + + } else if([itemIdentifier isEqualToString:@"DrawerItem"]){ + [item setPaletteLabel:@"Configuration"]; + [item setLabel:@"Configuration"]; + [item setToolTip:@"Configuration"]; + [item setImage:[NSImage imageNamed:@"32x32_log"]]; + [item setTarget:drawer]; + [item setAction:@selector(toggle:)]; + + } + + return [item autorelease]; +} + +- (NSArray *)toolbarDefaultItemIdentifiers:(NSToolbar*)toolbar +{ + return [NSArray arrayWithObjects:@"TabField", + NSToolbarFlexibleSpaceItemIdentifier, + @"DrawerItem", + nil]; +} + +- (NSArray *)toolbarAllowedItemIdentifiers:(NSToolbar*)toolbar +{ + return [NSArray arrayWithObjects:@"TabField", + NSToolbarFlexibleSpaceItemIdentifier, + @"DrawerItem", + nil]; +} + +- (IBAction)toggleToolbar:(id)sender +{ + [[[self window] toolbar] setVisible:![[[self window] toolbar] isVisible]]; +} + +- (BOOL)validateToolbarItem:(NSToolbarItem *)theItem +{ + return YES; +} + +@end diff --git a/PSMTabBarControl/source/main.m b/PSMTabBarControl/source/main.m new file mode 100644 index 0000000000..bcdabbe7b0 --- /dev/null +++ b/PSMTabBarControl/source/main.m @@ -0,0 +1,14 @@ +// +// main.m +// TabBarControl +// +// Created by John Pannell on 12/18/05. +// Copyright Positive Spin Media 2005. All rights reserved. +// + +#import + +int main(int argc, char *argv[]) +{ + return NSApplicationMain(argc, (const char **) argv); +} diff --git a/PSMTabBarControl/version.plist b/PSMTabBarControl/version.plist new file mode 100644 index 0000000000..df8c3dc7d1 --- /dev/null +++ b/PSMTabBarControl/version.plist @@ -0,0 +1,16 @@ + + + + + BuildVersion + 92 + CFBundleVersion + 1.0 + ProductBuildVersion + 7K571 + ProjectName + NibPBTemplates + SourceVersion + 1200000 + + diff --git a/README b/README new file mode 100644 index 0000000000..3cc2a23ba5 --- /dev/null +++ b/README @@ -0,0 +1,145 @@ +Compiling: + +- To build the project: + + open terminal, directory vimXX/src: type 'make' + this builds the Vim executable + + open MacVim.xcodeproj, choose 'Release' on pull-down menu 'Active Build + Configuration', click Build + this builds the PSMTabBarFramework, then MacVim.app (which can be found in + MacVim/build/Release) +- To install: + + copy MacVim.app to /Applications (or anywhere you want it) + + in ~/.profile add this line: + alias gvim='/Applications/MacVim.app/Contents/MacOS/Vim -g' +- To run: + + Double click MacVim icon + + with the above alias you can type 'gvim' in terminal to open MacVim + (if the -g switch is left out, then Vim is started in terminal mode) + + in terminal mode of Vim, type :gui and MacVim will start +- Technical notes: + + to build a universal binary, the compiler AND linker needs the flags + '-isysroot /Developer/SDKs/MacOSX10.4u.sdk -arch ppc -arch i386' + + vim runtime files are copied to + 'MacVim.app/Contents/Resources/vim/runtime/' + +Weirdness: + +- When the text system (Cocoa) comes across multi byte characters it + automatically chooses a font for those characters; this font may not be the + same height as the one set on the text storage and hence the program must + account for the fact that lines may have differing heights. + We get around this problem by resizing the window to fit the text storage + after the layout manager has performed layout. As a side-effect the user + sees how the window resizes when certain multi byte characters are being + displayed. +- Remember to set 'inputReceived = YES' in MMBackend + handlePortMessage:, otherwise Vim will not inform MMVimController of + changes it makes (e.g. in response to a key down event). +- The way delegate messages from the tab bar are handled are based on lots of + assumptions on how the code works. See comments in tabView:... delegate + messages in MMWindowController. +- The insertion point is automatically moved to wherever changes are made in + the text storage. To set the position manually (via setSelectedRange:), + first call endEditing on the text storage. +- Delegate messages from the tab view need to be able to differentiate whether + the message was sent due to the user clicking a tab with the mouse, or if the + vim task initiated the change. To facilitate this, flags must be set + whenever the vim task does something that results in these delegate messages + being sent. See comments in the tabView:...Item: messages in + MMWindowController. +- In Vim the first tab has index 1, in the gui the first tab has index 0. This + is compensated for in MMBackend.m. +- The PSMTabBarControl does not reorder the NSTabView when a user drags tabs + around, so we must rely on [PSMTabBarControl representedItems] to get the + correct order of tabs (the order which the user can 'see'). WARNING! This + means that the code cannot rely on calls like + [NSTabView selectTabViewItemAtIndex:] etc. since the NSTabView has the + 'wrong' order. +- The MMVimController is added to the NSEventTrackingRunLoopMode, otherwise + updates from Vim would not reach the MMVimController while the user + resizes the window using the mouse. + + +Design decisions: + +- Output is queued and sent to the MMVimController only when + [MMBackend flushQueue] is called in order to minimize the amount of + messages sent back and forth between the task and gui. (This does not apply + to all messages sent to the gui though.) +- Drawing commands are stored in a buffer (drawData) and put on the output + queue whenever [MMBackend flush] is called. This buffer might no + longer be needed now that there is a general output queue. However, the + existing code works, so why change it? +- The gui listens for tasks on a named port whose name is derived from + CFBundleIdentifier (which is defined inside Info.plist of the app bundle). + In order to run two different copies of MacVim at the same time, they need to + have differing bundle identifiers; otherwise one copy will not be able to + create the named listening port and all tasks will connect to the first copy. +- All tabs share one text view and its associated text storage. There used to + be one text view per tab, but this only complicated the code since Vim has no + concept of different views (as in NSView). + + +Keyboard stuff: + +- input ends up in one of the following methods + (1) insertText: + (2) doCommandBySelector: + (3) performKeyEquivalent: + +- (1) handles: printable keys (a, Space, 1, ...) and (also ). + if Ctrl+Option is held [NSEvents characters] will translate the input to + control characters; note that if the translation fails, then Shift and Option + modifiers are NOT includeded in [NSEvent characters], but they are included + in [NSEvent charactersIgnoringModifiers]. e.g. given , characters + returns 1, charactersIgnoringModifiers returns . +- (2) handles: Ctrl+key, enter, backspace, escape. + same note on translation of Ctrl+key as above holds true. +- (3) handles: Cmd+key, arrow keys, function keys +- and are two different characters (the former is 0xa0) + + +Bugs: + +- Using NSString initWithBytesNoCopy:::: causes crash when trying to set window + title. +- NSTabViewItem setInitialFirstResponder: seems to have no effect, so we + manually set the first responder when the tab item selection changes. + + +Features (!supp indicates that a feature is not supported): + +- Multiple top-level windows: each window runs its own vim process (they are + completely independent) +- Tabs: uses PSMTabBarControl to show tabs, can reorder tabs by dragging them, + has overflow menu, new tab button on tabline +- Menubar: accelerators !supp, actext hint displayed as tool tip + instead of on menu, each window has its own menu, key equivalents !supp +- Toolbar: toolbariconsize supported (tiny&small equiv to 24x24 px, + medium&large equiv to 32x32 px), toolbar supports 'icons' and 'text' options + (but not 'tooltip' which is always on), each window has its own toolbar, + custom toolbar items +- Cocoa input protocols: input managers, character palette input etc. + supported, marked text !supp, cocoa key bindings (DefaultKeyBinding.dict) + !supp +- Mouse: resize (vim) windows, selection, different mouse cursors !supp, + autoscrolling whilst selecting works poorly +- Drag and Drop: drag files onto dock icon to open in tabs, drag to text view + !supp +- Zoom: Command-click to zoom height only, otherwise maximize witdh as well, + hold down Option to zoom all windows +- Resize: live resize (although terribly slow), :set lines will not make window + higher than can fit the screen (no such restrictions on width at the moment) +- Pasteboard: star-register works with the mac os x pasteboard +- Open/Save dialog: use with :browse +- Fonts: bold/italic/underline traits supported, font changes !supp +- File type associations: add more associations by editing Info.plist +- Start GUI from terminal, type :gui +- Scroll bars: !supp +- Wide characters: !supp +- Printing: !supp +- Find/Replace dialog: !supp +- Gui dialogs: !supp +- External editor protocol: !supp +- Services menu: !supp +- Encodings: !supp (enc, tenc always set to utf-8) diff --git a/SpecialKeys.plist b/SpecialKeys.plist new file mode 100644 index 0000000000..8d91cccc37 --- /dev/null +++ b/SpecialKeys.plist @@ -0,0 +1,62 @@ + + + + +  + KA +  + kB +  + kb +  + ku + ïœ + kd +  + kl +  + kr +  + k1 +  + k2 +  + k3 +  + k4 +  + k5 +  + k6 +  + k7 +  + k8 +  + k9 + ïœ + k; +  + F1 + ïœ + F2 + ïœ + F3 +  + F4 +  + F5 +  + F6 +  + kD +  + kh +  + @7 +  + kP +  + kN + + diff --git a/TODO b/TODO new file mode 100644 index 0000000000..94559a0894 --- /dev/null +++ b/TODO @@ -0,0 +1,114 @@ +Active: + +- proper font handling +- font selection dialog (:set gfn=*) +- check for memory leaks +- startup is a bit flakey (up until openWindowWithRows:columns:) +- i8n +- services menu +- don't clear the text storage on setMaxRows:: so that display does not go + blank when dragging to resize +- gui dialogs (FEAT_GUI_DIALOG) +- find/replace toolbar item (FIND_REPLACE_DIALOG) +- main menu +- menu key equivalents +- add menu options with key equiv: + Cmd+Option+Left/Right to change tab, Cmd+x/c/v cut/copy/paste, + Cmd+z/Z undo/redo, Cmd+o open, Cmd+w/W close tab/window, + Cmd+Option+T special characters, + etc. +- popup menus +- encoding -- convert strings from vim to utf-8 +- change building procedure so that the Makefile compiles and links VimTask and + then calls pbxbuild to build MacVim (and put MacVim.app) in the src folder +- icons for all built in toolbar items +- hide baseline separator when tabbar is visible (and make sure clicking the + hide/show toolbar button in the top right of the corner does not show it + again) +- use DO to communicate between GUI and Vim (only for two-way communication, + one-way communication should still use mach ports) +- window title is never set when starting with terminal vim and typing :gui +- forking doesn't work with :gui (i think) +- make sure [NSMutableData appendByte:length:] is never called with 0 length + (this will lead to a crash) +- wide characters are badly supported: they render as too wide +- update speed whilst resizing with mouse is excruciatingly slow +- drag and drop inside view (FEAT_GUI_DND, gui_handle_drop()) +- window count should be typeset nicely in tab +- put marked text in status line (?) +- track pad scrolling is jerky +- memory leak with text view? (need to release text storage) +- sanity check all input in handlePortMessage: etc. +- cursor in replace mode +- nice looking cursors (both the block and in insert mode) +- support project builder external editor + http://www.codingmonkeys.de/techpubs/externaleditor/pbxexternaleditor.html +- dock icon menu +- horizontal scrolling with trackpad does not work +- got this error when clicking to close second last tab: + 2007-07-23 08:19:29.398 MacVim[335] *** Assertion failure in -[PSMTabBarControl lockFocus], AppKit.subproj/NSView.m:3248 + 2007-07-23 08:19:29.410 MacVim[335] lockFocus sent to a view whose window is deferred and does not yet have a corresponding platform window + + +Pending: + +- make scrollbar inactive if it is too small to display properly +- make vertical scrollbars cover command line as well +- setting font in .gvimrc has no effect since textStorage has not been init'ed +- fonts +- scroll bars +- Make MacVim project depend on PSMTabBarControl project +- Change Makefile so that it builds a vim executable and copy this into the + MacVim.app from the MacVim project +- warning before closing modified buffer +- On quitting, warn user if modified files are open +- An untitled window should not open when the GUI is started from the terminal + (figure out how to pass '-nowindow yes' option when launching GUI) +- support using VimTask as a standalone terminal app, with support for :gui +- path is set to / when not starting from command line, set it to $HOME instead + + +Done: + +- input of wide characters does not work +- tab completion doesn't work on iMac +- close icons on tabs don't appear on iMac +- toolbar +- copy runtime files to bundle properly (only works for debug at the moment) +- don't resize to make window bigger than what can fit on screen +- window resizing using mouse & zoom +- cmd-click to maximize window, :tabnew...the text view overlaps the tabline +- colorscheme changes are buggy (open two tabs, change colorscheme, open new + tab; the new tab has wrong color on first and last lines.) +- tab selection bug: open three tabs, selct middle, drag last tab so it becomes + middle without selecting it, select middle tab...selects middle, then last +- tab selection bug #2: :tabnew, drag tab #2 to pos #1, press enter. tab #2 is + selected. +- this stuffs up the display: set go-=e; :tabnew +- with 2 tabs: closing one tab using mouse makes screen flash (does not happen + if tab is closed using :q) +- resize to fit every draw update +- insertion point +- copy/paste +- compute text storage size based on actual content +- color changes (:colorscheme) +- set text storage dimensions properly when creating text view +- text dimension changes +- notify vim task when user closes/selects tabs +- mouse handling in text view +- file type associations (Info.plist) +- drag and drop onto app icon +- remove tab update hack when flushing (edit vim code to call update) +- crash when typing :browse e $vim (but not :browse e $vim/) +- maintain queue of messages to send from task (to ensure they are passed in + the same order they arrive) +- do not include shift flag in chars that are already shifted (%, A, etc.) +- open file(s) in tab(s) (never open in new window?) +- key handling: + works, does not + clean up dispatchKeyEvent +- reordering tab pages (gui tabs must have same order as vim tabs) +- make sure tab is wide enough to fit label +- encoding (did_set_string_option, option.c, line 5675) + in init: + set_option_value((char_u *)"termencoding", 0L, (char_u *)"utf-8", 0); diff --git a/Toolbar/Attention.png b/Toolbar/Attention.png new file mode 100644 index 0000000000000000000000000000000000000000..704cf4ba5ea90bbfcd9bd07528478840d2a475f4 GIT binary patch literal 1931 zcmV;62Xy#}P)5851PiPNsY0Ijn+i8MFj*39k$uGd*?3i`<`?B@ZMo7LxJd<{J-3D&a?cV z|MQ%4#V>wt0dS5PKj%P*D}U1?Z!#zQTZ&UKUiS^!w`68EFvHjPXAqBd-t;*Dnp-@U z_4c%moj)7B`_|FnKb^jb!_{PZJ3!u=djKB0>yBmTy6;>x1Uz_47UZo5(9yMZ$+InU z4NKRxvvd3Wmw?(^F{HJ=xdTZIEiLL>o9^j`$q|r}-rZe|zx(5>kDuu0zy}V9YZ$41 zO5GX*>$mORv@h@_rc{JdfuK3d1G^S}6KK9!V>cZ@+oH^~YrDFr44)xMEH19Vct72H zdsx~m4wej*43umYW@bbckPf&}#1-!D+S#>DxG|z)f=d!?5H2|=1)3&8wo1Kj*PxK>^REh#w zlGuubkpcL}zv-A?re}5VG|(_p_LCxm41EZ_6v1V{K~tl8rmOc(;tMA+Qi6?9wv3b( zmlQ7r;0#eQrgHi?@mPd2z)(MXceJV7YT2&@TnoSa%j9*t;I1t@*X*egqeSHjew?6O zjPDFtPoRXkv~%nR7z;_!0Xb7P3DoE?n7tiG=C*0q&bM2;_ zxqu?V^9;U7@TEh00zWPzO6M;IptMIemj)n38U!9NmC)E2(Yqn{5U~D+8EBm!erL_f z1w>;5c*@~PgZ30kB&g9dcq0|0yQBdrBD^rYUIo+7Hvw8feu7=yjm*h#u$Vx>TnV*h z)|Jj<%f9;`So>&OeHj;(&|0G~=wd&5_#7&VkvV}F`a7I{4UYT-as2m4TS4k71Cr`x zFClVdnmwW^*ZH?o@f!%ve1L(=T2OT^&AqT@`5fZnBsvqKl5uqZG1SNiLP^L5kjoHF z6c{f=jO9zj6Gf=WKp3R$q|~Ka2nqQDAKTo>ie{d_nr+q70!pT^iYFf2v+5JG>Jvn% zgc>@DH#m$?4niM-0Q?YyAnAUb-0oKi)_oNt$I$)nKoC}iP|ZqK6`6oHOOljmJ@$Tl zxH05Ntp~NMX2tx>SkjX-jC0OfF6+oRk$ym;v7hGCDOj4L=8A29yWIF=$=~L@;t3)GQDch>H-FAew?o5lSU4j%^L) zisHb}riTAHLL6@@a4wiKSPM1t z!PluDYtq6vn`R$HU~DQ1W6?DZ9g#hJ-sKOE^OoA)Dr)ZD+V;xg%%t{IDq`&cp@N(b zxoj16P*)GLXG47p)HcJM&eVBLLn=_ugHVGfz!*>oCcG^9o9xzQHD6i7>P^D zSg8@R1V(}K2r~*_{{j;@CV45b RP-6f9002ovPDHLkV1jFGhMxcc literal 0 HcmV?d00001 diff --git a/Toolbar/Copy.png b/Toolbar/Copy.png new file mode 100644 index 0000000000000000000000000000000000000000..8df8201ec9748822200f737fc52eb925382b0809 GIT binary patch literal 1075 zcmV-31kC%1P)F4XY$#51Tv%gLs5t!G=w?gLnvd05%ymjJ$&pBL##A z$}rOxw=c2NZJ9WZ9ox98>aei8V>_M8ke;%R&d$fFREnok zb7_jbfuOa9QW{z-+~$*W&OOholu9K_+!`IgU@&;QP$>M6&1M&s(y?=hMi4}V+t!p$ z&*AaoZ@vTY#hm~EKuTpusSpIgjq?n{xRXDnR0;sD1=!u)Wov6|831{uR1N?et?uUK z-KC`Cc{ByU7~|P&Hn+b1-ulMI`x_4*e*S4bpR4%3-`LvP{+2Q0Ev3|*oWITx0PyJ1 zmtP$m{Px+>($c&6d_FfnpJw5N^Yae&_xEqD>%9P0S64Q-x3@kD0tuxQdc8h?Q9b+p z9;B3SCVB{Pc=*@f0B#gmSpU1$__Y9R+p?6>Fbw0`07(OcUIYMCtJPAw-5zE#nYlQj zg`JgX2F89E0QkON_kF*~Iggz;GJ@90Sm-kX2!i0$b=_mm`BbX)#P`uhCt?~D6@iUY zs~pF63g=Mgzw6mzoHI3#3x1=(mN1Ma(^TV8jAAj$;z0SG}^bibA0P#uyMa(8M5&_jx@! zoB&|V0An1B3ybi5uhnX`{t!Yi07$3P^Ut6E`e!V_ix)>n{eC|R&KO57mjmYv;oA~L zt2DqE0~Z{Eb1=q00D|EVoo*Lrt=7Q1xHx5w zvxDX3<(v#8h%}^9;Eay~2?5Rp0K)L!A=>RW{DyyCtJNB=>sD>sa*9sTtksU)X0v(R z?RJle$S0!MH{L55==FMyhVR!lKitd>g8%?QN{Mc#Lw?O`SE`j0$9Bq=ZMo(v(=1oY zcEk58gTcTD&?2H?T%ha56#yc-*xTFtT}rulczAeZS*GQ>rDC;ODSDn)?)7>efHn~& ta#*-h0ss&~yrZ>dM07?($)Cq2#(#k4+4%v4qPzeA002ovPDHLkV1jDD`{Doq literal 0 HcmV?d00001 diff --git a/Toolbar/Cut.png b/Toolbar/Cut.png new file mode 100644 index 0000000000000000000000000000000000000000..514bd97c273a2ab2f85222a0113d5aff45297b5b GIT binary patch literal 1379 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 RO|<|3002ovPDHLkV1mTjV!HqU literal 0 HcmV?d00001 diff --git a/Toolbar/FindNext.png b/Toolbar/FindNext.png new file mode 100644 index 0000000000000000000000000000000000000000..e260865a1750443c56892fb86c3aeb4b9d982ba4 GIT binary patch literal 1596 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 tqZ zdvH|s70187``o>|n|)c$wY4+q z*r`QjYEi_#w6sMT0p$^#@JKK~APF&Vl594c>~8jX_jT|6^$#=}j3{HzUw7`@bH1N@ z&iVa*=SL`|_%>Ekd6y&FjL>QPa-hH`P#~2;Dv?HyU&VDRR{;jc^!FO22q!hPJh%DCUw1XV+CJny*dBCGepP(# za^lb3P`2rnU#@#WpKE6k9R&4t14$J`1r&vWj)4CalFMeEhedq5&L3z%a~3=eE6| zZ*K<4D~7^2@%p}wKfS!C`SH_K`;yqK8Q67i?e_J{%Nh_H1w3OQz948?L5lE*F%l9G z5Y$BY(@unX2EYgcBvC|0Mh2`lJ9O{A1`LjZDioY6hDVl{{aD9yCIA~Q)nYz-xch-$ z69Cv!QSi|Hi{~^T;RVLVfQbM!MMH?{;Z{s=2Pxd6LG+D8(AzhPqsLC*N%$d%)#U=CVS6qL)=cFme za}EwkgOMaa83xG70?Eq5CqBb?<4e1%o1!t#j1mY8tr~sj`Lk;uxaXE-4Qs6Djvd3` zPy!3$9t1fHJW&FVH;g^~ftC}&^lGte(MHYhK9Y*drwPEs<8jI79e4E{KUy8m)UUg* z#9pIvCb$F&NlO9~eo#?FiNlb+>c;Y)19)NvfEpZ6oZahb*Z^8R3`cN!plXxroux4!y8c22gDPzn$huKXMnuKGTX zNZIJwx7Rz882iMirD}q$dtW>ekA^R;Whmw!|>?8`r z;vjMqS&~&>J~!tM0KL;qXvr&_?{sB3jFKK81OO0@L=c~v0BZowwj6vT(fQGD4s{)W zdp7Y)K!O5r;($A{-Q$nZsKP=83!*51EJK8hsySJ=POpL+s_(Il2UTy>>*>`=`sqM1 zSw=`sps%fMMD|Y}W`M8U%`UYzO2huNda%=<=t-qCq`(27Ks*7c3CwY3T(^MXBmiK< z(!~;qP05zfs7PYL=^zP)N1QMi?>>JXz+fw-$~OhTMLG9qB-yRXaj3}zAcuiS5J*Ik zp%+~G{CV>MfD1RhnRE!6SkSahNBaK`XcAO=5uncnAJUK<9&{7nYfrUHjRjCfM56oJ6hR5Gom7?$H00BH4H==1ufIsq2o zc@P5V7!AD0qQoqg=?E#hQUD#t6%So}^%qI22iUQ@Pc!www^@n~GNpMtfe}t&ciNtE>*E0|x0+S4t6y#GrD# zn3@EGMXf2IrR^u-0FQou7Az`HMR{i9+okm_=;VW$ClCxR!NhoVh{;Q^xr zFbvEj4s(Wpe7nf6pKE)uK;+g}5W>$Uo@>qe!PVE@+-&VW{J~ne?anG~2rB}IQ1RA} z(6r@AOnmSUU}6wQ_wH?JefM9RO=We4oQ7vzGX|2?F8lJ=*Ol)za8b};7$g!wlJXc= z3^n+5E!p)&wuiGE2ElG*k;z0s zr~+Baz-dDnQnq4jefz*q-GSI)+p1rfAz4~x09;E5dHj}ZUu&$hJxrA-5D0?A6G&?e ze2fJn4bNjjZ^fj?gUR7xZ#W!w>juv&wxRx_>yv|4o5jFMMgbO`1`CxzKtc5)V6%Z3 zocP`G_v$J_CB;V%Y?m20%ddI%pO%U~r;&jJvS=Q1h?a z(&^4GYJRDyTGHu}WoF}sXV%=bb75)0RcdA!B&~s|Z-AKrGUgN_l}aO(PJwa)f`K7u z1x^%*#)|<61tlz~PK0JOfi>9C+#MKt=AZi?O({zErFye=_5M)w*b=>X-_IVp_l=cH z=2v6h0w^{Yh^m5N7>J?(Q4|0Gip7RR(LBHiXkbA(7MdV}k&K{J!0rRBr=Q=k=doxa z*?Q*Uk^S`m0Ps;fd9Ko6eXw;nx@Fzw#q}jX1_+=k3Mc>qfaQ54SP^Pr88oX1jpe}# zI)>m{A({JRnB<}oo1op_B)rZxZ}YM%L0{?>gJcrxHO&VNsqhqS=Lklb`s#6P~`lfzH7Z&&e32eF6|Zbs6C+0sw$o zPGHljqH&qICD7aQQbAuBET@C)_b92@IDj+BjL~joO;)oS^7&ij;1$mb bU$p-L(h)?sbJ0m{00000NkvXXu0mjfTsooG literal 0 HcmV?d00001 diff --git a/Toolbar/LoadSesn.png b/Toolbar/LoadSesn.png new file mode 100644 index 0000000000000000000000000000000000000000..f762a24bcbb70ca2226d1d7bddaac49eea957e62 GIT binary patch literal 1757 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 literal 0 HcmV?d00001 diff --git a/Toolbar/Open.png b/Toolbar/Open.png new file mode 100644 index 0000000000000000000000000000000000000000..e3528f02c939db2a07723980076767c367605454 GIT binary patch literal 1365 zcmV-b1*-aqP)em6veIk|M#5#Kew(? zRjyae&d&N%Q&Y7#j%T(^PuE4<&WY;euH}_%_YFIDeXw)O#Ovn25SX2v^=q|SEso=v zTCG;M*6yg)YP*avH&?6Gok0-X7)9lJISi)-FYKgBY?X4!@Y#3gP98mU>m$K9fTvEK zx~X2TKNg1Jo=T;1^TC4$Z;Ya-9t6R35Coy```3JcN zRKS=%byO6q*MWeD5XUhh4r2^T4rB!kfB{uNu0sZlG5r$ci&dmZb*4E1Pm4JOoco^% zj2y3;*V`$^fB@DCz7bsR!tn^Wf_6`Q=4xTD2}7Q45pa?dP!*gL@IXYzCor6WK_Y{$ z7#wd!u&Q_p&bqurx=8}P3=D^=_Oqd?p!w=m6z2rzz=|LueKDqX6D8QV29%x%MIp0- zIEx{-qg7=kb(<$Joa(_6^j%;I5elT41r>||&p1O4?5l%P*ga{_6Wky)F! zTm!y=rLG`ub1slRKoRRX!C6OU9k#HcZ=jng%c~i>NgGZLzZ>3|^3^L@mge9#7hx6RPbI0zG)}w>*@BphYF>3N2=-Pzx4M;?AgW}Emw1FWJo@q7{ zU=c`w3NT5Y{)s{14U2HSOei2uQ70G`d=wAJ>>4&a(`=^u8;ykmd>TkqwY-t@!yvFR zh9C&=yk*yCMPFpwU*O` zg@yCYpS!LV1&iPO(w=X}(n`b_Bl2+&n0MAAuma2jk;zGvC!&Z_skEjD(=>H)9G{z; zn>+o{haaB)_Uo^{KL69t^W1*?>H2{!TNjtpwh2mQKUseF!pleB>wPzpz?o)KfM54F z8Y_Mf+;(Mg@z;|lPP~8k@ZsBc@7YsdU0r2)d6`zLb*|g(e%@}kKe5)Ho|&0x&dkiD z$BrN8t~>82n=q(9yd?c2HU-g~^MyB~k_&tHE0e(vK}z8p1ftle;& X7MP!rkhXXe00000NkvXXu0mjfYNeO3 literal 0 HcmV?d00001 diff --git a/Toolbar/Paste.png b/Toolbar/Paste.png new file mode 100644 index 0000000000000000000000000000000000000000..8906e80f7e2c57bfca05f524105a861fb278f127 GIT binary patch literal 1550 zcmV+p2J!icP)Z zON?Ac6^6gMkDi&HmuH3{cCa1C5i$-ASb!Hiy~2vbB5?!~!crozEFo-1EV2P10Y)s5 zOyaFq2nn%r5=Fcw1PhE5p(KdN3ZB@;cKlF0_B`F)_jc7ehsC|!Gd-T^9wUxa-Kthq zoxlEb&VQ<%nbFJ6zW(ay%)I;qlTpLO;hdNyX_7qo%)zJM>UlsnGqaxKxkFEV>)Q1j zccw4>$1c2o(WWn6vWr)5+xNeF@CO^&-)$rQ)@`uxZyZc%%0@?tElJJ@1Kl=HRkk|WtR#OQ%8a%3k`lg*b zef;JZ55M$qb)cVmBeTDpe&P00U;WAfb7`z1s2MJbQB{(Gv4KDS>C9GO;{ZlC4L&w7 zF!|BB+4GnRSL)+@>A=&NX>lcNEN|SyH*-|g?fu%Zhnxzn40_}DFEdg5H<+M}jJ~vQ z=ZnW&^!zE)o&a7v>LSyJDp`FFHO0h}#ltk*AXlzkEmk_vE4K?kKwRku91hs=$aeC+ zNy6fJ(14lYAO-q>MsEfjP7Oj3R0K06%W?**1I*4X;N0qM4r6 zYt?-_*971IHA8|FF&8Dt?~>K;v2X9=0Bx%2sM=!ExVK1JzlBLCK$xsv*n z&B@QAD$CRX&Ola#W!KIF+ve`o-v04VPAEX+AWhRW&-1ehLqNfR z2%^SK9p`+sgLm?ep_MAvD?9k5dyYJK%zLESKz)O=7iv8Ji&qHE20mXN&8$JA-k`o> z0AyL-0VrBIX~o|}n9&j5OCRHEbqAN01_)6#J`4?# zY^vf#!3*jIR51lrL#_8Px&Tnql7&*!MaVT~bMrF$?@lpVt>A{MB%_0%hBX5g6hkp9 z1gqOn5llM)EKBi<5EOD-NUV9!pZ(`~W!JOVNR`AHttPAsbu0)d%M^Esx2?fIM-oyB zk(K~rZE`Mrj^FHkf%ws3;wJbofCSJgcyXn3EqaBmKEBhmT(>R&Z8w@imc1w+EID@n z^S7k$c)UTzCXzG-RYU+&CMFY96zx$0rnWYKLO_acC#}vWikjo#&|h&rM^#wLglzXW z`Oe`Zgy4&Y?;K4rLND)>6|ibqrx3N= zf`Kxl%l6yK3EGKSmfQwzyxL5AFi_lDmKi7?9?Q%~sd)Ftazg;t*w+G3q_5FV!gd+1 zEJ;-iEA*oKV|Ptc({;+w;Y20NvkcV;6UEeF8lffSh(pD-<@Eo{fDz-e*WUd5tJ{(& z8MC%tm7fOAj6Aq>%O`agX3_r&fOSG3J3o>A4zf25Mpz-ytsWmogzK}(-ix@X~9r$$i}FD@*6I6XZ*)q0fv7xf+NY*jU-p8x;=07*qoM6N<$g1$ZV AnE(I) literal 0 HcmV?d00001 diff --git a/Toolbar/Print.png b/Toolbar/Print.png new file mode 100644 index 0000000000000000000000000000000000000000..bbbac94c15b45ab65c0148ddd5169d196eada9bf GIT binary patch literal 1482 zcmV;*1vUDKP)ewjJ6sGxv2~E~f9!RB4TF{3YL=`jiPjpG z(A(SFS5;M&7D9^kHbN>swhYD?b6qc(p8jKSczC$HBdv8=>Fetwmo8nJ(OPSz^p?@x z-F^J>Sv zLMl3{6xotwvu}P@k>O?p{w@4ZpdtazIbyMx+^&OIET#ts2P^uiXsEBRXSQu`sQ*`m zX_`29?tDdiMFJljJC+HBLiL<)or9DThG9fbocNHvGJ#OYumdhEr7D*2U!qis$~biB z(4O0OZkMg&HI3-}`3vUcgwv{$&(*>OLNH5Uhu`4b8T&HE!V43RlEJb_ob8uB_!I~+6JXm>D^ib zq~xfitF=BiC5R(da!()r@~HdMPd=VlL!hUpr)O~Rt81~CjhBT2 zz8<;=-}k{NgVH6Bgb+~1KxruxOTS7gXlN*UvakN*DS zhi}~Y_WLz|K{A<4QcB>u9t!z9cJFRLYfBpe4+}+B9TmPSOazSyQ&GLP)dP-KyZ#nj~*hO&cL!P z5K0gUM_}7ggu`J(!V!4B2O%VE+eS@o9fS~2QleNaqEN`gaaG=va~sV%JoLMaFcT+am$I84)o9|Z7R2cGM} z_kB37gTN2qxh|}zjl*xh1E7?FSS(h%hQO(T0ovT$+)OA12tYvaa()4v2arlZ2m!$b zgy7(ugL47FIh0Zmk|Xc~2q7V*gcJf&Do9n*xd`CR2XGt*=}ZQcQe-ljJ*Nf+=;xk`hv> z(wJ0GYL&hyQb}m3AeDkv3PMVFu7ibz1sI_a7$Gn%YsbjQ2wl#A;}qH4+>3131ed7iOo4*Sp!Ndy(5#h z48uTsYYXvLZVu0r!33$($v({k;~-@TmK+ii>axpxtiLVz2$tBZN=Gawl$SX+1mqp1*>u7-6LHc?HzAPDZMh!yfPSL kk^4X0A0Ga0_|AIUpYQdhxg}6*(*OVf07*qoM6N<$f{dBDfdBvi literal 0 HcmV?d00001 diff --git a/Toolbar/Redo.png b/Toolbar/Redo.png new file mode 100644 index 0000000000000000000000000000000000000000..8a065ddae632b026c5d6c8876e0bc34a7eaf2c5c GIT binary patch literal 1236 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 Tjwl_{00000NkvXXu0mjf+=+ts literal 0 HcmV?d00001 diff --git a/Toolbar/RunCtags.png b/Toolbar/RunCtags.png new file mode 100644 index 0000000000000000000000000000000000000000..08d186924b16be71ab62e9b48c7d649249493b9a GIT binary patch literal 1225 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 literal 0 HcmV?d00001 diff --git a/Toolbar/SaveSesn.png b/Toolbar/SaveSesn.png new file mode 100644 index 0000000000000000000000000000000000000000..d8b3d7e2cdcbea34abe8a93b4c650555ecfe071a GIT binary patch literal 2039 zcmV)7U^`df1RrRe%ph6%ZwM9ThBq)g+Y%osj#P-@=uh-tQd(N4eKJ0PgfCHG7 zzMVNbbN=7=|K>k4=Ll;p>-`NCgfs@Wb|t>)`}*vGpN7v26@(lZv}WDGthJvAPd=pX zwsXIdxNJ-gN`j zNr>v8YY^2STmloZ>-sN!^Z1l6Du@jUmrL4mnLF?N%J=r+pM@v{;Q$U;8RsEEy6oO_+t&_1;2x_6 z(Xk-pO#eY!`mp%ITFb$H(VFzQG@VZNWHXt|v$o3Ib);I?V>Qiq;h^=! z-+$I}|GvJPf0Ay_=aT76QYO=&T#y2+1`~pgzyuIg8)PflpMwM&x55KA2QmrLi|^Zp zYqce!YRS}=X8pyf;n^2nfBD-=NpV?wbMpp~Nq{avWg0LsYz)zWh%;XiAe{5W=bZ4N zR&I>9tHKxyMx%t1nN+sP@tT?hqD#Gfru3NmkEeR~?cQ^1s&gY!Mqp|&2{EyV`#RQS z8(>9aeBX)&j6Fw)(V*kLo5O@2rPKe5UO4&2<8yxWnoE!wN&#U2LdJDq*ATGc0$>DIhP*uaFPfYbUM)cwSbAl^{P?lp$a|B2p7x`|uEQ8G zGcag_m6r$~IO8eaIaypDeDV0ZPy4e|mPj?$d1PYP^UxNwiQDtnBl8lKaR_oX%65TT z=<{;9WS$+H_~W!69(E<~0W&~Eyr3Bvv}ULvd|=XZU}VleXx=)dZ@tpo)zs`NR`0Dg z{=2||^Zo8?ZzPdTV4VoRX%XSW+ZBJj*kb=0lTQx}+F&KzxvhAW6O*39J0o-cZ(kjq zevK%KGhKx>9cc6&&qJjhq$dbeKwZ?BH+DQGFRms(=fG+aD^5s>cBQCeX%JlC0NncG zHp)SXn)Si6;DT@kQRX;%)m|2YMXJ#f`KHaZwRY`#=;Zv1wJ4bU;Xb)w>(G{M6W8q6 zb+=gSrF5tu+)%UOj_vv9uIy^xgM5QIJ;~=divULm^ ztIb6OSWJ`S^rWTmh|IZpZwP5zcrrnAE<-AxLIf7SQm0-INTpIZVVd#b7MKWkpd{DqpK}Z8mPB}XyG%9|@0Y`ywA=GTyw3X+cc!dpSN8{L# zpfPl`x03ElbGCDWsI^X2mU-rH$4QfA?9^B#a2KC8bx4||=u$BNJAlvFVThJDgtspZj&n@uw?DWL(YUN1L=%Z3_%9B(8Iit%%#6;wQCT=T zW%LnX)D_GCv%oSSl^|oGcv?pzj#c-dK}vy?5`jQTg@A1Q%!dmA94lbHZWor%mcsv( zW?!1r(Q{TXssvLs_VF?ht=KtK5Wav#S5U0`b<)NqB&2R?gi%0!IY0>9Mx|Wn!UqHh zkXA5vq+I%uu{3MJxRT7o#EU>MFla9bva*d26-1Cprs?WxqeJ)MSO+IkHk^qC}c>@M20+8JR0mMXLh76mvAr|j3PegHq**1zC0T4i# z4oLcdZn-1FdbJC1d6$y{3)?Mh1(IQy^*2=N1P8pOB2v6itGrG89enEjsOTC zW>$M#vG6DB`R_aRfjBAtge#2N;PEnbn_Xk_TYBJqby`cfXt|8_}aVxT^T?C z;ck#Dle&Nr|8PhAzW{fH**4scc$U8aCFrpLfB?eZBwHnq!x5lj8|Dax`M~x-0-mPt z1*AF#0{{dN;YR6N6>QO=fZ_-Spd<9wB#_e{00}c{{G$1@b|X>!=K+D82m zGz|a*5EBC>;J6#K0{ee~4Bg-o6(E2p3jui2S}(xx?~efqA@G6WPtOIA-2edw0M|-X U+z62-7ytkO07*qoM6N<$g0Hg5i~s-t literal 0 HcmV?d00001 diff --git a/Toolbar/Undo.png b/Toolbar/Undo.png new file mode 100644 index 0000000000000000000000000000000000000000..0cbd408ba50b973c21e370a0475f74dd4a206623 GIT binary patch literal 1178 zcmV;L1ZDe)P)iVSyYX91L7MTnvvNJ=S2b0y^RVWsU#{AVxT= z9cVc-!#rUfVFnFP4T2hu_%Epr001vPt@-PvuMFQde`8?y0(3+Nd5!=GAV!8-pyf=!^sNu%`H>NZ7lC*a$TdJm^pNfd zfB<4-sKOI>F+ePbCbkBMZ{bjXlOdjAEjXKgAvR3_1P}|u3kGY3_Y5jPAMgRSAQGh> zLkq)g1|9}+G#v^+d=-=k7?v?SV>k~Cy+6Q&`yXuKZiWj$niU$g_#IFT4*7b300Jpw zgO+X_D2Xx)=vQq9GloDcnil}^3!sxvGh{LxXE*`m{e)Wh3mOGK@H!w5nCh4q>VOe- z4IqF(KK=(a;2SjPAXt|{nBfD1GdOL4z#k;63dHw-4(DZXW#DJn&u||Y_zVmmp=RLD zl4%Tz4CcVJ@*fygAX~37)B^+%EXe;u9fH7Oz?kM`C;`h#LX*{Bq~ry1#C@P6*cqaL zA*ITo#PFEm1~5_}`cXkLFdU5;DnVroP*wq~;w>B*e+*B6UU>+lF9LOgk}p3nsBIzDDiF&+)xT#r#;}T^8kCX%0*DcBLa}6! z0tVVCU}#7)1VK{^F7OnJK@Ry06_bYQQHILx0jH9Cz#_aD7y@@dq5uKJNU*4O239@d z3>$$y;AL|P0j!T#7IJ&!3s`P+Q5t{ z&kzZW3VWc4GKNZ!rQaDY11&xZEU*p$tpoY?1Jqfcp^*a5DF6Y)NMekFvMnbxCGbK0 z&yLo#`wuNGejt@AU!i3UMjZhVK#XKmKa5a^utL)~GZu6HK^^f6S}^^?Wf(vJF%ER! s5FmgCyk7tiKm+aofB+hB2LJ>Z0O33%qw0R97ytkO07*qoM6N<$f-3UAfB*mh literal 0 HcmV?d00001 diff --git a/VimColorList.clr b/VimColorList.clr new file mode 100644 index 0000000000..1d6aaabe53 --- /dev/null +++ b/VimColorList.clr @@ -0,0 +1,803 @@ +802 +0 0.0000 0.0000 0.0000 1.0 Black +0 0.5020 0.5020 0.5020 1.0 darkgray +0 0.5020 0.5020 0.5020 1.0 darkgrey +0 0.7529 0.7529 0.7529 1.0 Gray +0 0.7529 0.7529 0.7529 1.0 Grey +0 0.8784 0.8784 0.8784 1.0 lightgray +0 0.8784 0.8784 0.8784 1.0 lightgrey +0 0.1020 0.1020 0.1020 1.0 gray10 +0 0.1020 0.1020 0.1020 1.0 grey10 +0 0.2000 0.2000 0.2000 1.0 gray20 +0 0.2000 0.2000 0.2000 1.0 grey20 +0 0.3020 0.3020 0.3020 1.0 gray30 +0 0.3020 0.3020 0.3020 1.0 grey30 +0 0.4000 0.4000 0.4000 1.0 gray40 +0 0.4000 0.4000 0.4000 1.0 grey40 +0 0.4980 0.4980 0.4980 1.0 gray50 +0 0.4980 0.4980 0.4980 1.0 grey50 +0 0.6000 0.6000 0.6000 1.0 gray60 +0 0.6000 0.6000 0.6000 1.0 grey60 +0 0.7020 0.7020 0.7020 1.0 gray70 +0 0.7020 0.7020 0.7020 1.0 grey70 +0 0.8000 0.8000 0.8000 1.0 gray80 +0 0.8000 0.8000 0.8000 1.0 grey80 +0 0.8980 0.8980 0.8980 1.0 gray90 +0 0.8980 0.8980 0.8980 1.0 grey90 +0 1.0000 1.0000 1.0000 1.0 white +0 0.5020 0.0000 0.0000 1.0 darkred +0 0.8667 0.0314 0.0235 1.0 red +0 1.0000 0.6275 0.6275 1.0 lightred +0 0.0000 0.0000 0.5020 1.0 DarkBlue +0 0.0000 0.0000 0.8314 1.0 Blue +0 0.6275 0.6275 1.0000 1.0 lightblue +0 0.0000 0.5020 0.0000 1.0 DarkGreen +0 0.0000 0.3922 0.0667 1.0 Green +0 0.6275 1.0000 0.6275 1.0 lightgreen +0 0.0000 0.5020 0.5020 1.0 DarkCyan +0 0.0078 0.6706 0.9176 1.0 cyan +0 0.6275 1.0000 1.0000 1.0 lightcyan +0 0.5020 0.0000 0.5020 1.0 darkmagenta +0 0.9490 0.0314 0.5176 1.0 magenta +0 0.9412 0.6275 0.9412 1.0 lightmagenta +0 0.5020 0.2510 0.2510 1.0 brown +0 0.9882 0.9529 0.0196 1.0 yellow +0 1.0000 1.0000 0.6275 1.0 lightyellow +0 0.7333 0.7333 0.0000 1.0 darkyellow +0 0.1804 0.5451 0.3412 1.0 SeaGreen +0 0.9882 0.5020 0.0000 1.0 orange +0 0.6275 0.1255 0.9412 1.0 Purple +0 0.4157 0.3529 0.8039 1.0 SlateBlue +0 0.5529 0.2196 0.7882 1.0 Violet +0 1.0000 0.9804 0.9804 1.0 snow +0 0.9725 0.9725 1.0000 1.0 ghost white +0 0.9725 0.9725 1.0000 1.0 GhostWhite +0 0.9608 0.9608 0.9608 1.0 white smoke +0 0.9608 0.9608 0.9608 1.0 WhiteSmoke +0 0.8627 0.8627 0.8627 1.0 gainsboro +0 1.0000 0.9804 0.9412 1.0 floral white +0 1.0000 0.9804 0.9412 1.0 FloralWhite +0 0.9922 0.9608 0.9020 1.0 old lace +0 0.9922 0.9608 0.9020 1.0 OldLace +0 0.9804 0.9412 0.9020 1.0 linen +0 0.9804 0.9216 0.8431 1.0 antique white +0 0.9804 0.9216 0.8431 1.0 AntiqueWhite +0 1.0000 0.9373 0.8353 1.0 papaya whip +0 1.0000 0.9373 0.8353 1.0 PapayaWhip +0 1.0000 0.9216 0.8039 1.0 blanched almond +0 1.0000 0.9216 0.8039 1.0 BlanchedAlmond +0 1.0000 0.8941 0.7686 1.0 bisque +0 1.0000 0.8549 0.7255 1.0 peach puff +0 1.0000 0.8549 0.7255 1.0 PeachPuff +0 1.0000 0.8706 0.6784 1.0 navajo white +0 1.0000 0.8706 0.6784 1.0 NavajoWhite +0 1.0000 0.8941 0.7098 1.0 moccasin +0 1.0000 0.9725 0.8627 1.0 cornsilk +0 1.0000 1.0000 0.9412 1.0 ivory +0 1.0000 0.9804 0.8039 1.0 lemon chiffon +0 1.0000 0.9804 0.8039 1.0 LemonChiffon +0 1.0000 0.9608 0.9333 1.0 seashell +0 0.9412 1.0000 0.9412 1.0 honeydew +0 0.9608 1.0000 0.9804 1.0 mint cream +0 0.9608 1.0000 0.9804 1.0 MintCream +0 0.9412 1.0000 1.0000 1.0 azure +0 0.9412 0.9725 1.0000 1.0 alice blue +0 0.9412 0.9725 1.0000 1.0 AliceBlue +0 0.9020 0.9020 0.9804 1.0 lavender +0 1.0000 0.9412 0.9608 1.0 lavender blush +0 1.0000 0.9412 0.9608 1.0 LavenderBlush +0 1.0000 0.8941 0.8824 1.0 misty rose +0 1.0000 0.8941 0.8824 1.0 MistyRose +0 1.0000 1.0000 1.0000 1.0 white +0 0.0000 0.0000 0.0000 1.0 black +0 0.1843 0.3098 0.3098 1.0 dark slate gray +0 0.1843 0.3098 0.3098 1.0 DarkSlateGray +0 0.1843 0.3098 0.3098 1.0 dark slate grey +0 0.1843 0.3098 0.3098 1.0 DarkSlateGrey +0 0.4118 0.4118 0.4118 1.0 dim gray +0 0.4118 0.4118 0.4118 1.0 DimGray +0 0.4118 0.4118 0.4118 1.0 dim grey +0 0.4118 0.4118 0.4118 1.0 DimGrey +0 0.4392 0.5020 0.5647 1.0 slate gray +0 0.4392 0.5020 0.5647 1.0 SlateGray +0 0.4392 0.5020 0.5647 1.0 slate grey +0 0.4392 0.5020 0.5647 1.0 SlateGrey +0 0.4667 0.5333 0.6000 1.0 light slate gray +0 0.4667 0.5333 0.6000 1.0 LightSlateGray +0 0.4667 0.5333 0.6000 1.0 light slate grey +0 0.4667 0.5333 0.6000 1.0 LightSlateGrey +0 0.7451 0.7451 0.7451 1.0 gray +0 0.7451 0.7451 0.7451 1.0 grey +0 0.8275 0.8275 0.8275 1.0 light grey +0 0.8275 0.8275 0.8275 1.0 LightGrey +0 0.8275 0.8275 0.8275 1.0 light gray +0 0.8275 0.8275 0.8275 1.0 LightGray +0 0.0980 0.0980 0.4392 1.0 midnight blue +0 0.0980 0.0980 0.4392 1.0 MidnightBlue +0 0.0000 0.0000 0.5020 1.0 navy +0 0.0000 0.0000 0.5020 1.0 navy blue +0 0.0000 0.0000 0.5020 1.0 NavyBlue +0 0.3922 0.5843 0.9294 1.0 cornflower blue +0 0.3922 0.5843 0.9294 1.0 CornflowerBlue +0 0.2824 0.2392 0.5451 1.0 dark slate blue +0 0.2824 0.2392 0.5451 1.0 DarkSlateBlue +0 0.4157 0.3529 0.8039 1.0 slate blue +0 0.4157 0.3529 0.8039 1.0 SlateBlue +0 0.4824 0.4078 0.9333 1.0 medium slate blue +0 0.4824 0.4078 0.9333 1.0 MediumSlateBlue +0 0.5176 0.4392 1.0000 1.0 light slate blue +0 0.5176 0.4392 1.0000 1.0 LightSlateBlue +0 0.0000 0.0000 0.8039 1.0 medium blue +0 0.0000 0.0000 0.8039 1.0 MediumBlue +0 0.2549 0.4118 0.8824 1.0 royal blue +0 0.2549 0.4118 0.8824 1.0 RoyalBlue +0 0.0000 0.0000 1.0000 1.0 blue +0 0.1176 0.5647 1.0000 1.0 dodger blue +0 0.1176 0.5647 1.0000 1.0 DodgerBlue +0 0.0000 0.7490 1.0000 1.0 deep sky blue +0 0.0000 0.7490 1.0000 1.0 DeepSkyBlue +0 0.5294 0.8078 0.9216 1.0 sky blue +0 0.5294 0.8078 0.9216 1.0 SkyBlue +0 0.5294 0.8078 0.9804 1.0 light sky blue +0 0.5294 0.8078 0.9804 1.0 LightSkyBlue +0 0.2745 0.5098 0.7059 1.0 steel blue +0 0.2745 0.5098 0.7059 1.0 SteelBlue +0 0.6902 0.7686 0.8706 1.0 light steel blue +0 0.6902 0.7686 0.8706 1.0 LightSteelBlue +0 0.6784 0.8471 0.9020 1.0 light blue +0 0.6784 0.8471 0.9020 1.0 LightBlue +0 0.6902 0.8784 0.9020 1.0 powder blue +0 0.6902 0.8784 0.9020 1.0 PowderBlue +0 0.6863 0.9333 0.9333 1.0 pale turquoise +0 0.6863 0.9333 0.9333 1.0 PaleTurquoise +0 0.0000 0.8078 0.8196 1.0 dark turquoise +0 0.0000 0.8078 0.8196 1.0 DarkTurquoise +0 0.2824 0.8196 0.8000 1.0 medium turquoise +0 0.2824 0.8196 0.8000 1.0 MediumTurquoise +0 0.2510 0.8784 0.8157 1.0 turquoise +0 0.0000 1.0000 1.0000 1.0 cyan +0 0.8784 1.0000 1.0000 1.0 light cyan +0 0.8784 1.0000 1.0000 1.0 LightCyan +0 0.3725 0.6196 0.6275 1.0 cadet blue +0 0.3725 0.6196 0.6275 1.0 CadetBlue +0 0.4000 0.8039 0.6667 1.0 medium aquamarine +0 0.4000 0.8039 0.6667 1.0 MediumAquamarine +0 0.4980 1.0000 0.8314 1.0 aquamarine +0 0.0000 0.3922 0.0000 1.0 dark green +0 0.0000 0.3922 0.0000 1.0 DarkGreen +0 0.3333 0.4196 0.1843 1.0 dark olive green +0 0.3333 0.4196 0.1843 1.0 DarkOliveGreen +0 0.5608 0.7373 0.5608 1.0 dark sea green +0 0.5608 0.7373 0.5608 1.0 DarkSeaGreen +0 0.1804 0.5451 0.3412 1.0 sea green +0 0.1804 0.5451 0.3412 1.0 SeaGreen +0 0.2353 0.7020 0.4431 1.0 medium sea green +0 0.2353 0.7020 0.4431 1.0 MediumSeaGreen +0 0.1255 0.6980 0.6667 1.0 light sea green +0 0.1255 0.6980 0.6667 1.0 LightSeaGreen +0 0.5961 0.9843 0.5961 1.0 pale green +0 0.5961 0.9843 0.5961 1.0 PaleGreen +0 0.0000 1.0000 0.4980 1.0 spring green +0 0.0000 1.0000 0.4980 1.0 SpringGreen +0 0.4863 0.9882 0.0000 1.0 lawn green +0 0.4863 0.9882 0.0000 1.0 LawnGreen +0 0.0000 1.0000 0.0000 1.0 green +0 0.4980 1.0000 0.0000 1.0 chartreuse +0 0.0000 0.9804 0.6039 1.0 medium spring green +0 0.0000 0.9804 0.6039 1.0 MediumSpringGreen +0 0.6784 1.0000 0.1843 1.0 green yellow +0 0.6784 1.0000 0.1843 1.0 GreenYellow +0 0.1961 0.8039 0.1961 1.0 lime green +0 0.1961 0.8039 0.1961 1.0 LimeGreen +0 0.6039 0.8039 0.1961 1.0 yellow green +0 0.6039 0.8039 0.1961 1.0 YellowGreen +0 0.1333 0.5451 0.1333 1.0 forest green +0 0.1333 0.5451 0.1333 1.0 ForestGreen +0 0.4196 0.5569 0.1373 1.0 olive drab +0 0.4196 0.5569 0.1373 1.0 OliveDrab +0 0.7412 0.7176 0.4196 1.0 dark khaki +0 0.7412 0.7176 0.4196 1.0 DarkKhaki +0 0.9412 0.9020 0.5490 1.0 khaki +0 0.9333 0.9098 0.6667 1.0 pale goldenrod +0 0.9333 0.9098 0.6667 1.0 PaleGoldenrod +0 0.9804 0.9804 0.8235 1.0 light goldenrod yellow +0 0.9804 0.9804 0.8235 1.0 LightGoldenrodYellow +0 1.0000 1.0000 0.8784 1.0 light yellow +0 1.0000 1.0000 0.8784 1.0 LightYellow +0 1.0000 1.0000 0.0000 1.0 yellow +0 1.0000 0.8431 0.0000 1.0 gold +0 0.9333 0.8667 0.5098 1.0 light goldenrod +0 0.9333 0.8667 0.5098 1.0 LightGoldenrod +0 0.8549 0.6471 0.1255 1.0 goldenrod +0 0.7216 0.5255 0.0431 1.0 dark goldenrod +0 0.7216 0.5255 0.0431 1.0 DarkGoldenrod +0 0.7373 0.5608 0.5608 1.0 rosy brown +0 0.7373 0.5608 0.5608 1.0 RosyBrown +0 0.8039 0.3608 0.3608 1.0 indian red +0 0.8039 0.3608 0.3608 1.0 IndianRed +0 0.5451 0.2706 0.0745 1.0 saddle brown +0 0.5451 0.2706 0.0745 1.0 SaddleBrown +0 0.6275 0.3216 0.1765 1.0 sienna +0 0.8039 0.5216 0.2471 1.0 peru +0 0.8706 0.7216 0.5294 1.0 burlywood +0 0.9608 0.9608 0.8627 1.0 beige +0 0.9608 0.8706 0.7020 1.0 wheat +0 0.9569 0.6431 0.3765 1.0 sandy brown +0 0.9569 0.6431 0.3765 1.0 SandyBrown +0 0.8235 0.7059 0.5490 1.0 tan +0 0.8235 0.4118 0.1176 1.0 chocolate +0 0.6980 0.1333 0.1333 1.0 firebrick +0 0.6471 0.1647 0.1647 1.0 brown +0 0.9137 0.5882 0.4784 1.0 dark salmon +0 0.9137 0.5882 0.4784 1.0 DarkSalmon +0 0.9804 0.5020 0.4471 1.0 salmon +0 1.0000 0.6275 0.4784 1.0 light salmon +0 1.0000 0.6275 0.4784 1.0 LightSalmon +0 1.0000 0.6471 0.0000 1.0 orange +0 1.0000 0.5490 0.0000 1.0 dark orange +0 1.0000 0.5490 0.0000 1.0 DarkOrange +0 1.0000 0.4980 0.3137 1.0 coral +0 0.9412 0.5020 0.5020 1.0 light coral +0 0.9412 0.5020 0.5020 1.0 LightCoral +0 1.0000 0.3882 0.2784 1.0 tomato +0 1.0000 0.2706 0.0000 1.0 orange red +0 1.0000 0.2706 0.0000 1.0 OrangeRed +0 1.0000 0.0000 0.0000 1.0 red +0 1.0000 0.4118 0.7059 1.0 hot pink +0 1.0000 0.4118 0.7059 1.0 HotPink +0 1.0000 0.0784 0.5765 1.0 deep pink +0 1.0000 0.0784 0.5765 1.0 DeepPink +0 1.0000 0.7529 0.7961 1.0 pink +0 1.0000 0.7137 0.7569 1.0 light pink +0 1.0000 0.7137 0.7569 1.0 LightPink +0 0.8588 0.4392 0.5765 1.0 pale violet red +0 0.8588 0.4392 0.5765 1.0 PaleVioletRed +0 0.6902 0.1882 0.3765 1.0 maroon +0 0.7804 0.0824 0.5216 1.0 medium violet red +0 0.7804 0.0824 0.5216 1.0 MediumVioletRed +0 0.8157 0.1255 0.5647 1.0 violet red +0 0.8157 0.1255 0.5647 1.0 VioletRed +0 1.0000 0.0000 1.0000 1.0 magenta +0 0.9333 0.5098 0.9333 1.0 violet +0 0.8667 0.6275 0.8667 1.0 plum +0 0.8549 0.4392 0.8392 1.0 orchid +0 0.7294 0.3333 0.8275 1.0 medium orchid +0 0.7294 0.3333 0.8275 1.0 MediumOrchid +0 0.6000 0.1961 0.8000 1.0 dark orchid +0 0.6000 0.1961 0.8000 1.0 DarkOrchid +0 0.5804 0.0000 0.8275 1.0 dark violet +0 0.5804 0.0000 0.8275 1.0 DarkViolet +0 0.5412 0.1686 0.8863 1.0 blue violet +0 0.5412 0.1686 0.8863 1.0 BlueViolet +0 0.6275 0.1255 0.9412 1.0 purple +0 0.5765 0.4392 0.8588 1.0 medium purple +0 0.5765 0.4392 0.8588 1.0 MediumPurple +0 0.8471 0.7490 0.8471 1.0 thistle +0 1.0000 0.9804 0.9804 1.0 snow1 +0 0.9333 0.9137 0.9137 1.0 snow2 +0 0.8039 0.7882 0.7882 1.0 snow3 +0 0.5451 0.5373 0.5373 1.0 snow4 +0 1.0000 0.9608 0.9333 1.0 seashell1 +0 0.9333 0.8980 0.8706 1.0 seashell2 +0 0.8039 0.7725 0.7490 1.0 seashell3 +0 0.5451 0.5255 0.5098 1.0 seashell4 +0 1.0000 0.9373 0.8588 1.0 AntiqueWhite1 +0 0.9333 0.8745 0.8000 1.0 AntiqueWhite2 +0 0.8039 0.7529 0.6902 1.0 AntiqueWhite3 +0 0.5451 0.5137 0.4706 1.0 AntiqueWhite4 +0 1.0000 0.8941 0.7686 1.0 bisque1 +0 0.9333 0.8353 0.7176 1.0 bisque2 +0 0.8039 0.7176 0.6196 1.0 bisque3 +0 0.5451 0.4902 0.4196 1.0 bisque4 +0 1.0000 0.8549 0.7255 1.0 PeachPuff1 +0 0.9333 0.7961 0.6784 1.0 PeachPuff2 +0 0.8039 0.6863 0.5843 1.0 PeachPuff3 +0 0.5451 0.4667 0.3961 1.0 PeachPuff4 +0 1.0000 0.8706 0.6784 1.0 NavajoWhite1 +0 0.9333 0.8118 0.6314 1.0 NavajoWhite2 +0 0.8039 0.7020 0.5451 1.0 NavajoWhite3 +0 0.5451 0.4745 0.3686 1.0 NavajoWhite4 +0 1.0000 0.9804 0.8039 1.0 LemonChiffon1 +0 0.9333 0.9137 0.7490 1.0 LemonChiffon2 +0 0.8039 0.7882 0.6471 1.0 LemonChiffon3 +0 0.5451 0.5373 0.4392 1.0 LemonChiffon4 +0 1.0000 0.9725 0.8627 1.0 cornsilk1 +0 0.9333 0.9098 0.8039 1.0 cornsilk2 +0 0.8039 0.7843 0.6941 1.0 cornsilk3 +0 0.5451 0.5333 0.4706 1.0 cornsilk4 +0 1.0000 1.0000 0.9412 1.0 ivory1 +0 0.9333 0.9333 0.8784 1.0 ivory2 +0 0.8039 0.8039 0.7569 1.0 ivory3 +0 0.5451 0.5451 0.5137 1.0 ivory4 +0 0.9412 1.0000 0.9412 1.0 honeydew1 +0 0.8784 0.9333 0.8784 1.0 honeydew2 +0 0.7569 0.8039 0.7569 1.0 honeydew3 +0 0.5137 0.5451 0.5137 1.0 honeydew4 +0 1.0000 0.9412 0.9608 1.0 LavenderBlush1 +0 0.9333 0.8784 0.8980 1.0 LavenderBlush2 +0 0.8039 0.7569 0.7725 1.0 LavenderBlush3 +0 0.5451 0.5137 0.5255 1.0 LavenderBlush4 +0 1.0000 0.8941 0.8824 1.0 MistyRose1 +0 0.9333 0.8353 0.8235 1.0 MistyRose2 +0 0.8039 0.7176 0.7098 1.0 MistyRose3 +0 0.5451 0.4902 0.4824 1.0 MistyRose4 +0 0.9412 1.0000 1.0000 1.0 azure1 +0 0.8784 0.9333 0.9333 1.0 azure2 +0 0.7569 0.8039 0.8039 1.0 azure3 +0 0.5137 0.5451 0.5451 1.0 azure4 +0 0.5137 0.4353 1.0000 1.0 SlateBlue1 +0 0.4784 0.4039 0.9333 1.0 SlateBlue2 +0 0.4118 0.3490 0.8039 1.0 SlateBlue3 +0 0.2784 0.2353 0.5451 1.0 SlateBlue4 +0 0.2824 0.4627 1.0000 1.0 RoyalBlue1 +0 0.2627 0.4314 0.9333 1.0 RoyalBlue2 +0 0.2275 0.3725 0.8039 1.0 RoyalBlue3 +0 0.1529 0.2510 0.5451 1.0 RoyalBlue4 +0 0.0000 0.0000 1.0000 1.0 blue1 +0 0.0000 0.0000 0.9333 1.0 blue2 +0 0.0000 0.0000 0.8039 1.0 blue3 +0 0.0000 0.0000 0.5451 1.0 blue4 +0 0.1176 0.5647 1.0000 1.0 DodgerBlue1 +0 0.1098 0.5255 0.9333 1.0 DodgerBlue2 +0 0.0941 0.4549 0.8039 1.0 DodgerBlue3 +0 0.0627 0.3059 0.5451 1.0 DodgerBlue4 +0 0.3882 0.7216 1.0000 1.0 SteelBlue1 +0 0.3608 0.6745 0.9333 1.0 SteelBlue2 +0 0.3098 0.5804 0.8039 1.0 SteelBlue3 +0 0.2118 0.3922 0.5451 1.0 SteelBlue4 +0 0.0000 0.7490 1.0000 1.0 DeepSkyBlue1 +0 0.0000 0.6980 0.9333 1.0 DeepSkyBlue2 +0 0.0000 0.6039 0.8039 1.0 DeepSkyBlue3 +0 0.0000 0.4078 0.5451 1.0 DeepSkyBlue4 +0 0.5294 0.8078 1.0000 1.0 SkyBlue1 +0 0.4941 0.7529 0.9333 1.0 SkyBlue2 +0 0.4235 0.6510 0.8039 1.0 SkyBlue3 +0 0.2902 0.4392 0.5451 1.0 SkyBlue4 +0 0.6902 0.8863 1.0000 1.0 LightSkyBlue1 +0 0.6431 0.8275 0.9333 1.0 LightSkyBlue2 +0 0.5529 0.7137 0.8039 1.0 LightSkyBlue3 +0 0.3765 0.4824 0.5451 1.0 LightSkyBlue4 +0 0.7765 0.8863 1.0000 1.0 SlateGray1 +0 0.7255 0.8275 0.9333 1.0 SlateGray2 +0 0.6235 0.7137 0.8039 1.0 SlateGray3 +0 0.4235 0.4824 0.5451 1.0 SlateGray4 +0 0.7922 0.8824 1.0000 1.0 LightSteelBlue1 +0 0.7373 0.8235 0.9333 1.0 LightSteelBlue2 +0 0.6353 0.7098 0.8039 1.0 LightSteelBlue3 +0 0.4314 0.4824 0.5451 1.0 LightSteelBlue4 +0 0.7490 0.9373 1.0000 1.0 LightBlue1 +0 0.6980 0.8745 0.9333 1.0 LightBlue2 +0 0.6039 0.7529 0.8039 1.0 LightBlue3 +0 0.4078 0.5137 0.5451 1.0 LightBlue4 +0 0.8784 1.0000 1.0000 1.0 LightCyan1 +0 0.8196 0.9333 0.9333 1.0 LightCyan2 +0 0.7059 0.8039 0.8039 1.0 LightCyan3 +0 0.4784 0.5451 0.5451 1.0 LightCyan4 +0 0.7333 1.0000 1.0000 1.0 PaleTurquoise1 +0 0.6824 0.9333 0.9333 1.0 PaleTurquoise2 +0 0.5882 0.8039 0.8039 1.0 PaleTurquoise3 +0 0.4000 0.5451 0.5451 1.0 PaleTurquoise4 +0 0.5961 0.9608 1.0000 1.0 CadetBlue1 +0 0.5569 0.8980 0.9333 1.0 CadetBlue2 +0 0.4784 0.7725 0.8039 1.0 CadetBlue3 +0 0.3255 0.5255 0.5451 1.0 CadetBlue4 +0 0.0000 0.9608 1.0000 1.0 turquoise1 +0 0.0000 0.8980 0.9333 1.0 turquoise2 +0 0.0000 0.7725 0.8039 1.0 turquoise3 +0 0.0000 0.5255 0.5451 1.0 turquoise4 +0 0.0000 1.0000 1.0000 1.0 cyan1 +0 0.0000 0.9333 0.9333 1.0 cyan2 +0 0.0000 0.8039 0.8039 1.0 cyan3 +0 0.0000 0.5451 0.5451 1.0 cyan4 +0 0.5922 1.0000 1.0000 1.0 DarkSlateGray1 +0 0.5529 0.9333 0.9333 1.0 DarkSlateGray2 +0 0.4745 0.8039 0.8039 1.0 DarkSlateGray3 +0 0.3216 0.5451 0.5451 1.0 DarkSlateGray4 +0 0.4980 1.0000 0.8314 1.0 aquamarine1 +0 0.4627 0.9333 0.7765 1.0 aquamarine2 +0 0.4000 0.8039 0.6667 1.0 aquamarine3 +0 0.2706 0.5451 0.4549 1.0 aquamarine4 +0 0.7569 1.0000 0.7569 1.0 DarkSeaGreen1 +0 0.7059 0.9333 0.7059 1.0 DarkSeaGreen2 +0 0.6078 0.8039 0.6078 1.0 DarkSeaGreen3 +0 0.4118 0.5451 0.4118 1.0 DarkSeaGreen4 +0 0.3294 1.0000 0.6235 1.0 SeaGreen1 +0 0.3059 0.9333 0.5804 1.0 SeaGreen2 +0 0.2627 0.8039 0.5020 1.0 SeaGreen3 +0 0.1804 0.5451 0.3412 1.0 SeaGreen4 +0 0.6039 1.0000 0.6039 1.0 PaleGreen1 +0 0.5647 0.9333 0.5647 1.0 PaleGreen2 +0 0.4863 0.8039 0.4863 1.0 PaleGreen3 +0 0.3294 0.5451 0.3294 1.0 PaleGreen4 +0 0.0000 1.0000 0.4980 1.0 SpringGreen1 +0 0.0000 0.9333 0.4627 1.0 SpringGreen2 +0 0.0000 0.8039 0.4000 1.0 SpringGreen3 +0 0.0000 0.5451 0.2706 1.0 SpringGreen4 +0 0.0000 1.0000 0.0000 1.0 green1 +0 0.0000 0.9333 0.0000 1.0 green2 +0 0.0000 0.8039 0.0000 1.0 green3 +0 0.0000 0.5451 0.0000 1.0 green4 +0 0.4980 1.0000 0.0000 1.0 chartreuse1 +0 0.4627 0.9333 0.0000 1.0 chartreuse2 +0 0.4000 0.8039 0.0000 1.0 chartreuse3 +0 0.2706 0.5451 0.0000 1.0 chartreuse4 +0 0.7529 1.0000 0.2431 1.0 OliveDrab1 +0 0.7020 0.9333 0.2275 1.0 OliveDrab2 +0 0.6039 0.8039 0.1961 1.0 OliveDrab3 +0 0.4118 0.5451 0.1333 1.0 OliveDrab4 +0 0.7922 1.0000 0.4392 1.0 DarkOliveGreen1 +0 0.7373 0.9333 0.4078 1.0 DarkOliveGreen2 +0 0.6353 0.8039 0.3529 1.0 DarkOliveGreen3 +0 0.4314 0.5451 0.2392 1.0 DarkOliveGreen4 +0 1.0000 0.9647 0.5608 1.0 khaki1 +0 0.9333 0.9020 0.5216 1.0 khaki2 +0 0.8039 0.7765 0.4510 1.0 khaki3 +0 0.5451 0.5255 0.3059 1.0 khaki4 +0 1.0000 0.9255 0.5451 1.0 LightGoldenrod1 +0 0.9333 0.8627 0.5098 1.0 LightGoldenrod2 +0 0.8039 0.7451 0.4392 1.0 LightGoldenrod3 +0 0.5451 0.5059 0.2980 1.0 LightGoldenrod4 +0 1.0000 1.0000 0.8784 1.0 LightYellow1 +0 0.9333 0.9333 0.8196 1.0 LightYellow2 +0 0.8039 0.8039 0.7059 1.0 LightYellow3 +0 0.5451 0.5451 0.4784 1.0 LightYellow4 +0 1.0000 1.0000 0.0000 1.0 yellow1 +0 0.9333 0.9333 0.0000 1.0 yellow2 +0 0.8039 0.8039 0.0000 1.0 yellow3 +0 0.5451 0.5451 0.0000 1.0 yellow4 +0 1.0000 0.8431 0.0000 1.0 gold1 +0 0.9333 0.7882 0.0000 1.0 gold2 +0 0.8039 0.6784 0.0000 1.0 gold3 +0 0.5451 0.4588 0.0000 1.0 gold4 +0 1.0000 0.7569 0.1451 1.0 goldenrod1 +0 0.9333 0.7059 0.1333 1.0 goldenrod2 +0 0.8039 0.6078 0.1137 1.0 goldenrod3 +0 0.5451 0.4118 0.0784 1.0 goldenrod4 +0 1.0000 0.7255 0.0588 1.0 DarkGoldenrod1 +0 0.9333 0.6784 0.0549 1.0 DarkGoldenrod2 +0 0.8039 0.5843 0.0471 1.0 DarkGoldenrod3 +0 0.5451 0.3961 0.0314 1.0 DarkGoldenrod4 +0 1.0000 0.7569 0.7569 1.0 RosyBrown1 +0 0.9333 0.7059 0.7059 1.0 RosyBrown2 +0 0.8039 0.6078 0.6078 1.0 RosyBrown3 +0 0.5451 0.4118 0.4118 1.0 RosyBrown4 +0 1.0000 0.4157 0.4157 1.0 IndianRed1 +0 0.9333 0.3882 0.3882 1.0 IndianRed2 +0 0.8039 0.3333 0.3333 1.0 IndianRed3 +0 0.5451 0.2275 0.2275 1.0 IndianRed4 +0 1.0000 0.5098 0.2784 1.0 sienna1 +0 0.9333 0.4745 0.2588 1.0 sienna2 +0 0.8039 0.4078 0.2235 1.0 sienna3 +0 0.5451 0.2784 0.1490 1.0 sienna4 +0 1.0000 0.8275 0.6078 1.0 burlywood1 +0 0.9333 0.7725 0.5686 1.0 burlywood2 +0 0.8039 0.6667 0.4902 1.0 burlywood3 +0 0.5451 0.4510 0.3333 1.0 burlywood4 +0 1.0000 0.9059 0.7294 1.0 wheat1 +0 0.9333 0.8471 0.6824 1.0 wheat2 +0 0.8039 0.7294 0.5882 1.0 wheat3 +0 0.5451 0.4941 0.4000 1.0 wheat4 +0 1.0000 0.6471 0.3098 1.0 tan1 +0 0.9333 0.6039 0.2863 1.0 tan2 +0 0.8039 0.5216 0.2471 1.0 tan3 +0 0.5451 0.3529 0.1686 1.0 tan4 +0 1.0000 0.4980 0.1412 1.0 chocolate1 +0 0.9333 0.4627 0.1294 1.0 chocolate2 +0 0.8039 0.4000 0.1137 1.0 chocolate3 +0 0.5451 0.2706 0.0745 1.0 chocolate4 +0 1.0000 0.1882 0.1882 1.0 firebrick1 +0 0.9333 0.1725 0.1725 1.0 firebrick2 +0 0.8039 0.1490 0.1490 1.0 firebrick3 +0 0.5451 0.1020 0.1020 1.0 firebrick4 +0 1.0000 0.2510 0.2510 1.0 brown1 +0 0.9333 0.2314 0.2314 1.0 brown2 +0 0.8039 0.2000 0.2000 1.0 brown3 +0 0.5451 0.1373 0.1373 1.0 brown4 +0 1.0000 0.5490 0.4118 1.0 salmon1 +0 0.9333 0.5098 0.3843 1.0 salmon2 +0 0.8039 0.4392 0.3294 1.0 salmon3 +0 0.5451 0.2980 0.2235 1.0 salmon4 +0 1.0000 0.6275 0.4784 1.0 LightSalmon1 +0 0.9333 0.5843 0.4471 1.0 LightSalmon2 +0 0.8039 0.5059 0.3843 1.0 LightSalmon3 +0 0.5451 0.3412 0.2588 1.0 LightSalmon4 +0 1.0000 0.6471 0.0000 1.0 orange1 +0 0.9333 0.6039 0.0000 1.0 orange2 +0 0.8039 0.5216 0.0000 1.0 orange3 +0 0.5451 0.3529 0.0000 1.0 orange4 +0 1.0000 0.4980 0.0000 1.0 DarkOrange1 +0 0.9333 0.4627 0.0000 1.0 DarkOrange2 +0 0.8039 0.4000 0.0000 1.0 DarkOrange3 +0 0.5451 0.2706 0.0000 1.0 DarkOrange4 +0 1.0000 0.4471 0.3373 1.0 coral1 +0 0.9333 0.4157 0.3137 1.0 coral2 +0 0.8039 0.3569 0.2706 1.0 coral3 +0 0.5451 0.2431 0.1843 1.0 coral4 +0 1.0000 0.3882 0.2784 1.0 tomato1 +0 0.9333 0.3608 0.2588 1.0 tomato2 +0 0.8039 0.3098 0.2235 1.0 tomato3 +0 0.5451 0.2118 0.1490 1.0 tomato4 +0 1.0000 0.2706 0.0000 1.0 OrangeRed1 +0 0.9333 0.2510 0.0000 1.0 OrangeRed2 +0 0.8039 0.2157 0.0000 1.0 OrangeRed3 +0 0.5451 0.1451 0.0000 1.0 OrangeRed4 +0 1.0000 0.0000 0.0000 1.0 red1 +0 0.9333 0.0000 0.0000 1.0 red2 +0 0.8039 0.0000 0.0000 1.0 red3 +0 0.5451 0.0000 0.0000 1.0 red4 +0 1.0000 0.0784 0.5765 1.0 DeepPink1 +0 0.9333 0.0706 0.5373 1.0 DeepPink2 +0 0.8039 0.0627 0.4627 1.0 DeepPink3 +0 0.5451 0.0392 0.3137 1.0 DeepPink4 +0 1.0000 0.4314 0.7059 1.0 HotPink1 +0 0.9333 0.4157 0.6549 1.0 HotPink2 +0 0.8039 0.3765 0.5647 1.0 HotPink3 +0 0.5451 0.2275 0.3843 1.0 HotPink4 +0 1.0000 0.7098 0.7725 1.0 pink1 +0 0.9333 0.6627 0.7216 1.0 pink2 +0 0.8039 0.5686 0.6196 1.0 pink3 +0 0.5451 0.3882 0.4235 1.0 pink4 +0 1.0000 0.6824 0.7255 1.0 LightPink1 +0 0.9333 0.6353 0.6784 1.0 LightPink2 +0 0.8039 0.5490 0.5843 1.0 LightPink3 +0 0.5451 0.3725 0.3961 1.0 LightPink4 +0 1.0000 0.5098 0.6706 1.0 PaleVioletRed1 +0 0.9333 0.4745 0.6235 1.0 PaleVioletRed2 +0 0.8039 0.4078 0.5373 1.0 PaleVioletRed3 +0 0.5451 0.2784 0.3647 1.0 PaleVioletRed4 +0 1.0000 0.2039 0.7020 1.0 maroon1 +0 0.9333 0.1882 0.6549 1.0 maroon2 +0 0.8039 0.1608 0.5647 1.0 maroon3 +0 0.5451 0.1098 0.3843 1.0 maroon4 +0 1.0000 0.2431 0.5882 1.0 VioletRed1 +0 0.9333 0.2275 0.5490 1.0 VioletRed2 +0 0.8039 0.1961 0.4706 1.0 VioletRed3 +0 0.5451 0.1333 0.3216 1.0 VioletRed4 +0 1.0000 0.0000 1.0000 1.0 magenta1 +0 0.9333 0.0000 0.9333 1.0 magenta2 +0 0.8039 0.0000 0.8039 1.0 magenta3 +0 0.5451 0.0000 0.5451 1.0 magenta4 +0 1.0000 0.5137 0.9804 1.0 orchid1 +0 0.9333 0.4784 0.9137 1.0 orchid2 +0 0.8039 0.4118 0.7882 1.0 orchid3 +0 0.5451 0.2784 0.5373 1.0 orchid4 +0 1.0000 0.7333 1.0000 1.0 plum1 +0 0.9333 0.6824 0.9333 1.0 plum2 +0 0.8039 0.5882 0.8039 1.0 plum3 +0 0.5451 0.4000 0.5451 1.0 plum4 +0 0.8784 0.4000 1.0000 1.0 MediumOrchid1 +0 0.8196 0.3725 0.9333 1.0 MediumOrchid2 +0 0.7059 0.3216 0.8039 1.0 MediumOrchid3 +0 0.4784 0.2157 0.5451 1.0 MediumOrchid4 +0 0.7490 0.2431 1.0000 1.0 DarkOrchid1 +0 0.6980 0.2275 0.9333 1.0 DarkOrchid2 +0 0.6039 0.1961 0.8039 1.0 DarkOrchid3 +0 0.4078 0.1333 0.5451 1.0 DarkOrchid4 +0 0.6078 0.1882 1.0000 1.0 purple1 +0 0.5686 0.1725 0.9333 1.0 purple2 +0 0.4902 0.1490 0.8039 1.0 purple3 +0 0.3333 0.1020 0.5451 1.0 purple4 +0 0.6706 0.5098 1.0000 1.0 MediumPurple1 +0 0.6235 0.4745 0.9333 1.0 MediumPurple2 +0 0.5373 0.4078 0.8039 1.0 MediumPurple3 +0 0.3647 0.2784 0.5451 1.0 MediumPurple4 +0 1.0000 0.8824 1.0000 1.0 thistle1 +0 0.9333 0.8235 0.9333 1.0 thistle2 +0 0.8039 0.7098 0.8039 1.0 thistle3 +0 0.5451 0.4824 0.5451 1.0 thistle4 +0 0.0000 0.0000 0.0000 1.0 gray0 +0 0.0000 0.0000 0.0000 1.0 grey0 +0 0.0118 0.0118 0.0118 1.0 gray1 +0 0.0118 0.0118 0.0118 1.0 grey1 +0 0.0196 0.0196 0.0196 1.0 gray2 +0 0.0196 0.0196 0.0196 1.0 grey2 +0 0.0314 0.0314 0.0314 1.0 gray3 +0 0.0314 0.0314 0.0314 1.0 grey3 +0 0.0392 0.0392 0.0392 1.0 gray4 +0 0.0392 0.0392 0.0392 1.0 grey4 +0 0.0510 0.0510 0.0510 1.0 gray5 +0 0.0510 0.0510 0.0510 1.0 grey5 +0 0.0588 0.0588 0.0588 1.0 gray6 +0 0.0588 0.0588 0.0588 1.0 grey6 +0 0.0706 0.0706 0.0706 1.0 gray7 +0 0.0706 0.0706 0.0706 1.0 grey7 +0 0.0784 0.0784 0.0784 1.0 gray8 +0 0.0784 0.0784 0.0784 1.0 grey8 +0 0.0902 0.0902 0.0902 1.0 gray9 +0 0.0902 0.0902 0.0902 1.0 grey9 +0 0.1020 0.1020 0.1020 1.0 gray10 +0 0.1020 0.1020 0.1020 1.0 grey10 +0 0.1098 0.1098 0.1098 1.0 gray11 +0 0.1098 0.1098 0.1098 1.0 grey11 +0 0.1216 0.1216 0.1216 1.0 gray12 +0 0.1216 0.1216 0.1216 1.0 grey12 +0 0.1294 0.1294 0.1294 1.0 gray13 +0 0.1294 0.1294 0.1294 1.0 grey13 +0 0.1412 0.1412 0.1412 1.0 gray14 +0 0.1412 0.1412 0.1412 1.0 grey14 +0 0.1490 0.1490 0.1490 1.0 gray15 +0 0.1490 0.1490 0.1490 1.0 grey15 +0 0.1608 0.1608 0.1608 1.0 gray16 +0 0.1608 0.1608 0.1608 1.0 grey16 +0 0.1686 0.1686 0.1686 1.0 gray17 +0 0.1686 0.1686 0.1686 1.0 grey17 +0 0.1804 0.1804 0.1804 1.0 gray18 +0 0.1804 0.1804 0.1804 1.0 grey18 +0 0.1882 0.1882 0.1882 1.0 gray19 +0 0.1882 0.1882 0.1882 1.0 grey19 +0 0.2000 0.2000 0.2000 1.0 gray20 +0 0.2000 0.2000 0.2000 1.0 grey20 +0 0.2118 0.2118 0.2118 1.0 gray21 +0 0.2118 0.2118 0.2118 1.0 grey21 +0 0.2196 0.2196 0.2196 1.0 gray22 +0 0.2196 0.2196 0.2196 1.0 grey22 +0 0.2314 0.2314 0.2314 1.0 gray23 +0 0.2314 0.2314 0.2314 1.0 grey23 +0 0.2392 0.2392 0.2392 1.0 gray24 +0 0.2392 0.2392 0.2392 1.0 grey24 +0 0.2510 0.2510 0.2510 1.0 gray25 +0 0.2510 0.2510 0.2510 1.0 grey25 +0 0.2588 0.2588 0.2588 1.0 gray26 +0 0.2588 0.2588 0.2588 1.0 grey26 +0 0.2706 0.2706 0.2706 1.0 gray27 +0 0.2706 0.2706 0.2706 1.0 grey27 +0 0.2784 0.2784 0.2784 1.0 gray28 +0 0.2784 0.2784 0.2784 1.0 grey28 +0 0.2902 0.2902 0.2902 1.0 gray29 +0 0.2902 0.2902 0.2902 1.0 grey29 +0 0.3020 0.3020 0.3020 1.0 gray30 +0 0.3020 0.3020 0.3020 1.0 grey30 +0 0.3098 0.3098 0.3098 1.0 gray31 +0 0.3098 0.3098 0.3098 1.0 grey31 +0 0.3216 0.3216 0.3216 1.0 gray32 +0 0.3216 0.3216 0.3216 1.0 grey32 +0 0.3294 0.3294 0.3294 1.0 gray33 +0 0.3294 0.3294 0.3294 1.0 grey33 +0 0.3412 0.3412 0.3412 1.0 gray34 +0 0.3412 0.3412 0.3412 1.0 grey34 +0 0.3490 0.3490 0.3490 1.0 gray35 +0 0.3490 0.3490 0.3490 1.0 grey35 +0 0.3608 0.3608 0.3608 1.0 gray36 +0 0.3608 0.3608 0.3608 1.0 grey36 +0 0.3686 0.3686 0.3686 1.0 gray37 +0 0.3686 0.3686 0.3686 1.0 grey37 +0 0.3804 0.3804 0.3804 1.0 gray38 +0 0.3804 0.3804 0.3804 1.0 grey38 +0 0.3882 0.3882 0.3882 1.0 gray39 +0 0.3882 0.3882 0.3882 1.0 grey39 +0 0.4000 0.4000 0.4000 1.0 gray40 +0 0.4000 0.4000 0.4000 1.0 grey40 +0 0.4118 0.4118 0.4118 1.0 gray41 +0 0.4118 0.4118 0.4118 1.0 grey41 +0 0.4196 0.4196 0.4196 1.0 gray42 +0 0.4196 0.4196 0.4196 1.0 grey42 +0 0.4314 0.4314 0.4314 1.0 gray43 +0 0.4314 0.4314 0.4314 1.0 grey43 +0 0.4392 0.4392 0.4392 1.0 gray44 +0 0.4392 0.4392 0.4392 1.0 grey44 +0 0.4510 0.4510 0.4510 1.0 gray45 +0 0.4510 0.4510 0.4510 1.0 grey45 +0 0.4588 0.4588 0.4588 1.0 gray46 +0 0.4588 0.4588 0.4588 1.0 grey46 +0 0.4706 0.4706 0.4706 1.0 gray47 +0 0.4706 0.4706 0.4706 1.0 grey47 +0 0.4784 0.4784 0.4784 1.0 gray48 +0 0.4784 0.4784 0.4784 1.0 grey48 +0 0.4902 0.4902 0.4902 1.0 gray49 +0 0.4902 0.4902 0.4902 1.0 grey49 +0 0.4980 0.4980 0.4980 1.0 gray50 +0 0.4980 0.4980 0.4980 1.0 grey50 +0 0.5098 0.5098 0.5098 1.0 gray51 +0 0.5098 0.5098 0.5098 1.0 grey51 +0 0.5216 0.5216 0.5216 1.0 gray52 +0 0.5216 0.5216 0.5216 1.0 grey52 +0 0.5294 0.5294 0.5294 1.0 gray53 +0 0.5294 0.5294 0.5294 1.0 grey53 +0 0.5412 0.5412 0.5412 1.0 gray54 +0 0.5412 0.5412 0.5412 1.0 grey54 +0 0.5490 0.5490 0.5490 1.0 gray55 +0 0.5490 0.5490 0.5490 1.0 grey55 +0 0.5608 0.5608 0.5608 1.0 gray56 +0 0.5608 0.5608 0.5608 1.0 grey56 +0 0.5686 0.5686 0.5686 1.0 gray57 +0 0.5686 0.5686 0.5686 1.0 grey57 +0 0.5804 0.5804 0.5804 1.0 gray58 +0 0.5804 0.5804 0.5804 1.0 grey58 +0 0.5882 0.5882 0.5882 1.0 gray59 +0 0.5882 0.5882 0.5882 1.0 grey59 +0 0.6000 0.6000 0.6000 1.0 gray60 +0 0.6000 0.6000 0.6000 1.0 grey60 +0 0.6118 0.6118 0.6118 1.0 gray61 +0 0.6118 0.6118 0.6118 1.0 grey61 +0 0.6196 0.6196 0.6196 1.0 gray62 +0 0.6196 0.6196 0.6196 1.0 grey62 +0 0.6314 0.6314 0.6314 1.0 gray63 +0 0.6314 0.6314 0.6314 1.0 grey63 +0 0.6392 0.6392 0.6392 1.0 gray64 +0 0.6392 0.6392 0.6392 1.0 grey64 +0 0.6510 0.6510 0.6510 1.0 gray65 +0 0.6510 0.6510 0.6510 1.0 grey65 +0 0.6588 0.6588 0.6588 1.0 gray66 +0 0.6588 0.6588 0.6588 1.0 grey66 +0 0.6706 0.6706 0.6706 1.0 gray67 +0 0.6706 0.6706 0.6706 1.0 grey67 +0 0.6784 0.6784 0.6784 1.0 gray68 +0 0.6784 0.6784 0.6784 1.0 grey68 +0 0.6902 0.6902 0.6902 1.0 gray69 +0 0.6902 0.6902 0.6902 1.0 grey69 +0 0.7020 0.7020 0.7020 1.0 gray70 +0 0.7020 0.7020 0.7020 1.0 grey70 +0 0.7098 0.7098 0.7098 1.0 gray71 +0 0.7098 0.7098 0.7098 1.0 grey71 +0 0.7216 0.7216 0.7216 1.0 gray72 +0 0.7216 0.7216 0.7216 1.0 grey72 +0 0.7294 0.7294 0.7294 1.0 gray73 +0 0.7294 0.7294 0.7294 1.0 grey73 +0 0.7412 0.7412 0.7412 1.0 gray74 +0 0.7412 0.7412 0.7412 1.0 grey74 +0 0.7490 0.7490 0.7490 1.0 gray75 +0 0.7490 0.7490 0.7490 1.0 grey75 +0 0.7608 0.7608 0.7608 1.0 gray76 +0 0.7608 0.7608 0.7608 1.0 grey76 +0 0.7686 0.7686 0.7686 1.0 gray77 +0 0.7686 0.7686 0.7686 1.0 grey77 +0 0.7804 0.7804 0.7804 1.0 gray78 +0 0.7804 0.7804 0.7804 1.0 grey78 +0 0.7882 0.7882 0.7882 1.0 gray79 +0 0.7882 0.7882 0.7882 1.0 grey79 +0 0.8000 0.8000 0.8000 1.0 gray80 +0 0.8000 0.8000 0.8000 1.0 grey80 +0 0.8118 0.8118 0.8118 1.0 gray81 +0 0.8118 0.8118 0.8118 1.0 grey81 +0 0.8196 0.8196 0.8196 1.0 gray82 +0 0.8196 0.8196 0.8196 1.0 grey82 +0 0.8314 0.8314 0.8314 1.0 gray83 +0 0.8314 0.8314 0.8314 1.0 grey83 +0 0.8392 0.8392 0.8392 1.0 gray84 +0 0.8392 0.8392 0.8392 1.0 grey84 +0 0.8510 0.8510 0.8510 1.0 gray85 +0 0.8510 0.8510 0.8510 1.0 grey85 +0 0.8588 0.8588 0.8588 1.0 gray86 +0 0.8588 0.8588 0.8588 1.0 grey86 +0 0.8706 0.8706 0.8706 1.0 gray87 +0 0.8706 0.8706 0.8706 1.0 grey87 +0 0.8784 0.8784 0.8784 1.0 gray88 +0 0.8784 0.8784 0.8784 1.0 grey88 +0 0.8902 0.8902 0.8902 1.0 gray89 +0 0.8902 0.8902 0.8902 1.0 grey89 +0 0.8980 0.8980 0.8980 1.0 gray90 +0 0.8980 0.8980 0.8980 1.0 grey90 +0 0.9098 0.9098 0.9098 1.0 gray91 +0 0.9098 0.9098 0.9098 1.0 grey91 +0 0.9216 0.9216 0.9216 1.0 gray92 +0 0.9216 0.9216 0.9216 1.0 grey92 +0 0.9294 0.9294 0.9294 1.0 gray93 +0 0.9294 0.9294 0.9294 1.0 grey93 +0 0.9412 0.9412 0.9412 1.0 gray94 +0 0.9412 0.9412 0.9412 1.0 grey94 +0 0.9490 0.9490 0.9490 1.0 gray95 +0 0.9490 0.9490 0.9490 1.0 grey95 +0 0.9608 0.9608 0.9608 1.0 gray96 +0 0.9608 0.9608 0.9608 1.0 grey96 +0 0.9686 0.9686 0.9686 1.0 gray97 +0 0.9686 0.9686 0.9686 1.0 grey97 +0 0.9804 0.9804 0.9804 1.0 gray98 +0 0.9804 0.9804 0.9804 1.0 grey98 +0 0.9882 0.9882 0.9882 1.0 gray99 +0 0.9882 0.9882 0.9882 1.0 grey99 +0 1.0000 1.0000 1.0000 1.0 gray100 +0 1.0000 1.0000 1.0000 1.0 grey100 +0 0.6627 0.6627 0.6627 1.0 dark grey +0 0.6627 0.6627 0.6627 1.0 DarkGrey +0 0.6627 0.6627 0.6627 1.0 dark gray +0 0.6627 0.6627 0.6627 1.0 DarkGray +0 0.0000 0.0000 0.5451 1.0 dark blue +0 0.0000 0.0000 0.5451 1.0 DarkBlue +0 0.0000 0.5451 0.5451 1.0 dark cyan +0 0.0000 0.5451 0.5451 1.0 DarkCyan +0 0.5451 0.0000 0.5451 1.0 dark magenta +0 0.5451 0.0000 0.5451 1.0 DarkMagenta +0 0.5451 0.0000 0.0000 1.0 dark red +0 0.5451 0.0000 0.0000 1.0 DarkRed +0 0.5647 0.9333 0.5647 1.0 light green +0 0.5647 0.9333 0.5647 1.0 LightGreen diff --git a/doc-bm-c.icns b/doc-bm-c.icns new file mode 100644 index 0000000000000000000000000000000000000000..335f8bfa3f7420f5f89618c8b108a7728a5d1873 GIT binary patch literal 39682 zcmeI52S60p+Wu!NEQlxyih`OL>@kVv#)jsmc-5#$?ibTE-WXGj#uSa%nb|@IL7D|r zY)BEj3RDx_TVhIu61V*cXpW*C9EGH2{X;qzvSauwNG0WkQ{0*fvhrk#Wb#Mr8 zr&d*#5*WR)0d#PTR$EhD39(Hrq*P-=eO)zV(b9%ttyoKQb5mm-l-owMGF!-_hBMgc zs%F@uYKA?kW@y-1HC0qKLqo_|RyFt$H-wrRqN=Hu!y&vGGc-h1Q$6zzjG~O`HFuD&7fmx^z+;%c^br0IpM#Fq zbRBnu&h2^J;XS>_`Hqf-y^c5ZI{vWd@ry0Jjz5Ou7u^MR^mifN^MNQ!h{CeiJ&H;q`-Chi2AcJ5 zu)pB;&8yCy4}+m7ZwRu=C33KAA`9ybBc9Jj8786rNJw}R8y$K7ZlJ{5&Bf___@g@z z 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 Kly0|u-~Rz``Z@0a literal 0 HcmV?d00001 diff --git a/doc-bm-html.icns b/doc-bm-html.icns new file mode 100644 index 0000000000000000000000000000000000000000..4b15485ad0e5f3b4a40b6b1fc7ac751a5bf796e4 GIT binary patch literal 40619 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 literal 0 HcmV?d00001 diff --git a/doc-bm-pl.icns b/doc-bm-pl.icns new file mode 100644 index 0000000000000000000000000000000000000000..5d09ccca6b0f2114b89bad07586bef29590b7083 GIT binary patch literal 39845 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 literal 0 HcmV?d00001 diff --git a/doc-bm-txt.icns b/doc-bm-txt.icns new file mode 100644 index 0000000000000000000000000000000000000000..2219e2ce99a31bcd9c4c7b9e0b3c8bd3033b6d36 GIT binary patch literal 40106 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%0A4b?85|D zmAdT1Q~NXA=Rih%2-~o(+%}9R4`mx>SR)M(83Cp3Zx>eWrnE1B&J^ZYY{E)%n=lBe zfY1mytlS*(G~m$8?CxVkyqjA!Cb-Ez^jNWcpVKXE9wd!33;`hj*#{^ zyMmPvZ4Gt>n{9sUgR#1T4`A}TmWGrJFnNVuP#U8vcqZivhE`8M2jumXHZ;G}6+9a9 zx{$e!as|T|n6AO(^%wZz^)Zmwg-j*N6}%c+x}S0d!w+M11vAlf$`y=TO}T>MJ2J=O z3Wl%O#I9fiW%vQRf)B$F1G<7qa2XHp3PxP4J<}2n3o;r{#m{ehM;FT|jRGHrG3GU{uU@xxj&s{b9ao6}&rf9N)R^X`v zS%KkI+Q>b?(+2ba3y|ix*ngSoDynGg_TNP-HGA5BWq_4mN2~4fMi1iutp@+^)Wtph zzlspntktX@{$C@&x;_2Bu*HFkb(H?!{}f@x#$RJ7oZrj%dlF;K;k>^m;TZ#ae|Z2_ z`S4fJ3YPRPunKxDlp&ObzpEI$(2Yv?>zLuoN&v3*1*`ul`>*0ubrkkrV*t_r?e^cH zs45+(>VK{Mmq%HK6}A744yumW{o5O=K704?e(KAx{|=jR?;DNIWOG#2CuwL*9{Ei} zLt~P_|+@ony09i2I|XJ}1PS5acp$5H^iP*t9! z)${AKNBnb3sbs^*#Kfhw@z%$6NPyx>(zaj-Zll%%4@NDu^+wq7F zrOzn;hzodD`JsRj9m$?q{*IOr74YoxcQk#DdtjIsr_V5dN7KgHQ#h=l3wW0KJE|7V z)KF#)`QrGQ=I^-ug0|YwBk*kVH@!PolQU!oJlp&o7Z*(*x&xkZ{g>NT|HhZ+Ou`>X8tnG0+rQ~m9gU$@ zfM=cmy%m3L{>>}r{-y2T^4I5|tTeR|6e=*Ci;J(|NqMM zcVhlc%)g2GH~0&HXMO&exc(-tzlrN_;`;lmUjI+5KNIWE#QHO_{!FYt1NXqh`44~o zYaBlRG|*?F;IWDQXJY@E*ncMWpMh6j@WWG|Kb=^A23bDG{P4v3JF)&wtiKcM@5K5$ za1TuEKNIKwiPt}4_WuleP8r$fKmOAE&8 z^c@>snhl?S8+`wT??ef>(*sy8ymMvSy>$YXf z=1m*kczyYNE%l*ofinNGj_%TzUR^o9w^v_Us;i?l2|j>5#Pq|jKu6)f9)VGNuFmY4 z+M4Rh!+Zc87cdI{`S4D4Y*1I_ut(qyr_mTp7Msmh8s8fzvPR~Pr{NoY{BM+QzjNRJ E0WqikivR!s literal 0 HcmV?d00001 diff --git a/doc-bm.icns b/doc-bm.icns new file mode 100644 index 0000000000000000000000000000000000000000..984d11d0473483bec2d9f13d06296b21e82e8714 GIT binary patch literal 42287 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 pgHVUlXz +#import "MMBackend.h" +#import "MacVim.h" +#import "vim.h" + + + +// -- Initialization -------------------------------------------------------- + +/* + * Parse the GUI related command-line arguments. Any arguments used are + * deleted from argv, and *argc is decremented accordingly. This is called + * when vim is started, whether or not the GUI has been started. + */ + void +gui_mch_prepare(int *argc, char **argv) +{ + //NSLog(@"gui_mch_prepare(argc=%d)", *argc); + + // Set environment variables $VIM and $VIMRUNTIME + // NOTE! If vim_getenv is called with one of these as parameters before + // they have been set here, they will most likely end up with the wrong + // values! + // + // TODO: + // - ensure this is called first to avoid above problem + // - encoding + + NSString *path = [[[NSBundle mainBundle] resourcePath] + stringByAppendingPathComponent:@"vim"]; + vim_setenv((char_u*)"VIM", (char_u*)[path UTF8String]); + + path = [path stringByAppendingPathComponent:@"runtime"]; + vim_setenv((char_u*)"VIMRUNTIME", (char_u*)[path UTF8String]); +} + + +/* + * Check if the GUI can be started. Called before gvimrc is sourced. + * Return OK or FAIL. + */ + int +gui_mch_init_check(void) +{ + //NSLog(@"gui_mch_init_check()"); + return OK; +} + + +/* + * Initialise the GUI. Create all the windows, set up all the call-backs etc. + * Returns OK for success, FAIL when the GUI can't be started. + */ + int +gui_mch_init(void) +{ + //NSLog(@"gui_mch_init()"); + + if (![[MMBackend sharedInstance] checkin]) + return FAIL; + + // HACK! Force the 'termencoding to utf-8. For the moment also force + // 'encoding', although this will change in the future. The user can still + // change 'encoding'; doing so WILL crash the program. + set_option_value((char_u *)"termencoding", 0L, (char_u *)"utf-8", 0); + set_option_value((char_u *)"encoding", 0L, (char_u *)"utf-8", 0); + + // Set values so that pixels and characters are in one-to-one + // correspondence (assuming all characters have the same dimensions). + gui.scrollbar_width = gui.scrollbar_height = 0; + + gui.char_height = 1; + gui.char_width = 1; + gui.char_ascent = 0; + + // Default foreground and background colors are black and white. + gui.def_norm_pixel = gui.norm_pixel = 0; + gui.def_back_pixel = gui.back_pixel = 0xffffff; + + [[MMBackend sharedInstance] + setDefaultColorsBackground:gui.back_pixel foreground:gui.norm_pixel]; + [[MMBackend sharedInstance] setBackgroundColor:gui.back_pixel]; + [[MMBackend sharedInstance] setForegroundColor:gui.norm_pixel]; + + // NOTE: If this call is left out the cursor is opaque. + highlight_gui_started(); + + return OK; +} + + + + void +gui_mch_exit(int rc) +{ + //NSLog(@"gui_mch_exit(rc=%d)", rc); + + [[MMBackend sharedInstance] exit]; +} + + +/* + * Open the GUI window which was created by a call to gui_mch_init(). + */ + int +gui_mch_open(void) +{ + //NSLog(@"gui_mch_open()"); + + return [[MMBackend sharedInstance] + openVimWindowWithRows:gui.num_rows columns:gui.num_cols]; +} + + +// -- Updating -------------------------------------------------------------- + + +/* + * Catch up with any queued X events. This may put keyboard input into the + * input buffer, call resize call-backs, trigger timers etc. If there is + * nothing in the X event queue (& no timers pending), then we return + * immediately. + */ + void +gui_mch_update(void) +{ + // HACK! Nothing to do here since we tend to the run loop (which holds + // incoming events) in gui_mch_wait_for_chars(). +} + + +/* Flush any output to the screen */ + void +gui_mch_flush(void) +{ + // HACK! This function is called so often that draw performance suffers. + // Instead of actually flushing the output it is placed on a queue and + // flushed in gui_mch_wait_for_chars(), which makes the program feel much + // more responsive. This might have unintended side effects though; if + // so, another solution might have to be found. + + //[[MMBackend sharedInstance] flush]; +} + + +/* + * GUI input routine called by gui_wait_for_chars(). Waits for a character + * from the keyboard. + * wtime == -1 Wait forever. + * wtime == 0 This should never happen. + * wtime > 0 Wait wtime milliseconds for a character. + * Returns OK if a character was found to be available within the given time, + * or FAIL otherwise. + */ + int +gui_mch_wait_for_chars(int wtime) +{ + // HACK! See comment in gui_mch_flush(). + [[MMBackend sharedInstance] flushQueue]; + + return [[MMBackend sharedInstance] waitForInput:wtime]; +} + + +// -- Drawing --------------------------------------------------------------- + + +/* + * Clear the whole text window. + */ + void +gui_mch_clear_all(void) +{ + [[MMBackend sharedInstance] clearAll]; +} + + +/* + * Clear a rectangular region of the screen from text pos (row1, col1) to + * (row2, col2) inclusive. + */ + void +gui_mch_clear_block(int row1, int col1, int row2, int col2) +{ + [[MMBackend sharedInstance] clearBlockFromRow:row1 column:col1 + toRow:row2 column:col2]; +} + + +/* + * Delete the given number of lines from the given row, scrolling up any + * text further down within the scroll region. + */ + void +gui_mch_delete_lines(int row, int num_lines) +{ + [[MMBackend sharedInstance] deleteLinesFromRow:row count:num_lines + scrollBottom:gui.scroll_region_bot + left:gui.scroll_region_left + right:gui.scroll_region_right]; +} + + + void +gui_mch_draw_string(int row, int col, char_u *s, int len, int flags) +{ + [[MMBackend sharedInstance] replaceString:(char*)s length:len + row:row column:col flags:flags]; +} + + + int +gui_macvim_draw_string(int row, int col, char_u *s, int len, int flags) +{ +#if 0 + NSString *string = [[NSString alloc] + initWithBytesNoCopy:(void*)s + length:len + encoding:NSUTF8StringEncoding + freeWhenDone:NO]; + int cells = [string length]; + [string release]; + + NSLog(@"gui_macvim_draw_string(row=%d, col=%d, len=%d, cells=%d, flags=%d)", + row, col, len, cells, flags); + + [[MMBackend sharedInstance] replaceString:(char*)s length:len + row:row column:col flags:flags]; + + return cells; +#elif 0 + int c; + int cn; + int cl; + int i; + BOOL wide = NO; + int start = 0; + int endcol = col; + int startcol = col; + MMBackend *backend = [MMBackend sharedInstance]; + + for (i = 0; i < len; i += cl) { + c = utf_ptr2char(s + i); + cl = utf_ptr2len(s + i); + cn = utf_char2cells(c); + comping = utf_iscomposing(c); + + if (!comping) + endcol += cn; + + if (cn > 1 && !wide) { + // Start of wide characters. + wide = YES; + + // Output non-wide characters. + if (start > i) { + NSLog(@"Outputting %d non-wide chars (%d bytes)", + endcol-startcol, start-i); + [backend replaceString:(char*)(s+start) length:start-i + row:row column:startcol flags:flags]; + startcol = endcol; + start = i; + } + } else if (cn <= 1 && !comping && wide) { + // End of wide characters. + wide = NO; + + // Output wide characters. + if (start > i) { + NSLog(@"Outputting %d wide chars (%d bytes)", + endcol-startcol, start-i); + [backend replaceString:(char*)(s+start) length:start-i + row:row column:startcol flags:(flags|0x80)]; + startcol = endcol; + start = i; + } + } + } + + // Output remaining characters. + flags = wide ? flags|0x80 : flags; + NSLog(@"Outputting %d %s chars (%d bytes)", endcol-startcol, wide ? "wide" + : "non-wide", len-start); + [backend replaceString:(char*)(s+start) length:len-start + row:row column:startcol flags:flags]; + + return endcol - col; +#elif 1 + // + // Output chars until a wide char found. If a wide char is found, output a + // zero-width space after it so that a wide char looks like two chars to + // MMTextStorage. This way 1 char corresponds to 1 column. + // + + int c; + int cn; + int cl; + int i; + int start = 0; + int endcol = col; + int startcol = col; + BOOL outPad = NO; + MMBackend *backend = [MMBackend sharedInstance]; + static char ZeroWidthSpace[] = { 0xe2, 0x80, 0x8b }; + + for (i = 0; i < len; i += cl) { + c = utf_ptr2char(s + i); + cl = utf_ptr2len(s + i); + cn = utf_char2cells(c); + + if (!utf_iscomposing(c)) { + if (outPad) { + outPad = NO; +#if 0 + NSString *string = [[NSString alloc] + initWithBytesNoCopy:(void*)(s+start) + length:i-start + encoding:NSUTF8StringEncoding + freeWhenDone:NO]; + NSLog(@"Flushing string=%@ len=%d row=%d col=%d end=%d", + string, i-start, row, startcol, endcol); + [string release]; +#endif + [backend replaceString:(char*)(s+start) length:i-start + row:row column:startcol flags:flags]; + start = i; + startcol = endcol; +#if 0 + NSLog(@"Padding len=%d row=%d col=%d", sizeof(ZeroWidthSpace), + row, endcol-1); +#endif + [backend replaceString:ZeroWidthSpace + length:sizeof(ZeroWidthSpace) + row:row column:endcol-1 flags:flags]; + } + + endcol += cn; + } + + if (cn > 1) { +#if 0 + NSLog(@"Wide char detected! (char=%C hex=%x cells=%d)", c, c, cn); +#endif + outPad = YES; + } + } + +#if 0 + if (row < 1) { + NSString *string = [[NSString alloc] + initWithBytesNoCopy:(void*)(s+start) + length:len-start + encoding:NSUTF8StringEncoding + freeWhenDone:NO]; + NSLog(@"Output string=%@ len=%d row=%d col=%d", string, len-start, row, + startcol); + [string release]; + } +#endif + + // Output remaining characters. + [backend replaceString:(char*)(s+start) length:len-start + row:row column:startcol flags:flags]; + + if (outPad) { +#if 0 + NSLog(@"Padding len=%d row=%d col=%d", sizeof(ZeroWidthSpace), row, + endcol-1); +#endif + [backend replaceString:ZeroWidthSpace + length:sizeof(ZeroWidthSpace) + row:row column:endcol-1 flags:flags]; + } + + return endcol - col; +#else + // This will fail abysmally when wide or composing characters are used. + [[MMBackend sharedInstance] + replaceString:(char*)s length:len row:row column:col flags:flags]; + + int i, c, cl, cn, cells = 0; + for (i = 0; i < len; i += cl) { + c = utf_ptr2char(s + i); + cl = utf_ptr2len(s + i); + cn = utf_char2cells(c); + + if (!utf_iscomposing(c)) + cells += cn; + } + + return cells; +#endif +} + + +/* + * Insert the given number of lines before the given row, scrolling down any + * following text within the scroll region. + */ + void +gui_mch_insert_lines(int row, int num_lines) +{ + [[MMBackend sharedInstance] insertLinesFromRow:row count:num_lines + scrollBottom:gui.scroll_region_bot + left:gui.scroll_region_left + right:gui.scroll_region_right]; +} + + +// -- Tab line -------------------------------------------------------------- + + +/* + * Set the current tab to "nr". First tab is 1. + */ + void +gui_mch_set_curtab(int nr) +{ + //NSLog(@"gui_mch_set_curtab(nr=%d)", nr); + [[MMBackend sharedInstance] selectTab:nr]; +} + + +/* + * Return TRUE when tabline is displayed. + */ + int +gui_mch_showing_tabline(void) +{ + //NSLog(@"gui_mch_showing_tabline()"); + return [[MMBackend sharedInstance] tabBarVisible]; +} + +/* + * Update the labels of the tabline. + */ + void +gui_mch_update_tabline(void) +{ + //NSLog(@"gui_mch_update_tabline()"); + [[MMBackend sharedInstance] updateTabBar]; +} + +/* + * Show or hide the tabline. + */ + void +gui_mch_show_tabline(int showit) +{ + //NSLog(@"gui_mch_show_tabline(showit=%d)", showit); + [[MMBackend sharedInstance] showTabBar:showit]; +} + + +// -- Clipboard ------------------------------------------------------------- + + + void +clip_mch_lose_selection(VimClipboard *cbd) +{ +} + + + int +clip_mch_own_selection(VimClipboard *cbd) +{ + return 0; +} + + + void +clip_mch_request_selection(VimClipboard *cbd) +{ + NSPasteboard *pb = [NSPasteboard generalPasteboard]; + NSString *type = [pb availableTypeFromArray: + [NSArray arrayWithObject:NSStringPboardType]]; + if (type) { + NSMutableString *string = + [[pb stringForType:NSStringPboardType] mutableCopy]; + + // Replace unrecognized end-of-line sequences with \x0a (line feed). + NSRange range = { 0, [string length] }; + unsigned n = [string replaceOccurrencesOfString:@"\x0d\x0a" + withString:@"\x0a" options:0 + range:range]; + if (0 == n) { + n = [string replaceOccurrencesOfString:@"\x0d" withString:@"\x0a" + options:0 range:range]; + } + + // Scan for newline character to decide whether the string should be + // pasted linewise or characterwise. + int type = MCHAR; + if (0 < n || NSNotFound != [string rangeOfString:@"\n"].location) + type = MLINE; + + const char *utf8chars = [string UTF8String]; + clip_yank_selection(type, (char_u*)utf8chars, strlen(utf8chars), cbd); + } +} + + +/* + * Send the current selection to the clipboard. + */ + void +clip_mch_set_selection(VimClipboard *cbd) +{ + // If the '*' register isn't already filled in, fill it in now. + cbd->owned = TRUE; + clip_get_selection(cbd); + cbd->owned = FALSE; + + // Get the text to put on the pasteboard. + long_u len = 0; char_u *str = 0; + int type = clip_convert_selection(&str, &len, cbd); + if (type < 0) + return; + + NSString *string = [[NSString alloc] initWithBytes:str length:len + encoding:NSUTF8StringEncoding]; + + NSPasteboard *pb = [NSPasteboard generalPasteboard]; + [pb declareTypes:[NSArray arrayWithObject:NSStringPboardType] owner:nil]; + [pb setString:string forType:NSStringPboardType]; + + [string release]; + vim_free(str); +} + + +// -- Menu ------------------------------------------------------------------ + + +/* + * Add a sub menu to the menu bar. + */ + void +gui_mch_add_menu(vimmenu_T *menu, int idx) +{ + //NSLog(@"gui_mch_add_menu(name=%s, idx=%d)", menu->name, idx); + + // HACK! If menu has no parent, then we set the parent tag to the type of + // menu it is. This will not mix up tag and type because pointers can not + // take values close to zero (and the tag is simply the value of the + // pointer). + int parent = (int)menu->parent; + if (!parent) { + parent = menu_is_popup(menu->name) ? MenuPopupType : + menu_is_toolbar(menu->name) ? MenuToolbarType : + MenuMenubarType; + } + + [[MMBackend sharedInstance] + addMenuWithTag:(int)menu parent:parent name:(char*)menu->dname + atIndex:idx]; +} + + +/* + * Add a menu item to a menu + */ + void +gui_mch_add_menu_item(vimmenu_T *menu, int idx) +{ + //NSLog(@"gui_mch_add_menu_item(name=%s, accel=%s idx=%d)", menu->dname, + // menu->actext, idx); + + // NOTE! If 'iconfile' is not set but 'iconidx' is, use the name of the + // menu item. (Should correspond to a stock item.) + char *icon = menu->iconfile ? (char*)menu->iconfile : + menu->iconidx >= 0 ? (char*)menu->dname : + NULL; + char *name = menu_is_separator(menu->name) ? NULL : (char*)menu->dname; + char *tip = menu->strings[MENU_INDEX_TIP] + ? (char*)menu->strings[MENU_INDEX_TIP] : (char*)menu->actext; + + [[MMBackend sharedInstance] + addMenuItemWithTag:(int)menu parent:(int)menu->parent name:name + tip:tip icon:(char*)icon atIndex:idx]; +} + + +/* + * Destroy the machine specific menu widget. + */ + void +gui_mch_destroy_menu(vimmenu_T *menu) +{ + //NSLog(@"gui_mch_destroy_menu(name=%s)", menu->name); + + [[MMBackend sharedInstance] removeMenuItemWithTag:(int)menu]; +} + + +/* + * Make a menu either grey or not grey. + */ + void +gui_mch_menu_grey(vimmenu_T *menu, int grey) +{ + //NSLog(@"gui_mch_menu_grey(name=%s, grey=%d)", menu->name, grey); + [[MMBackend sharedInstance] + enableMenuItemWithTag:(int)menu state:!grey]; +} + + +/* + * Make menu item hidden or not hidden + */ + void +gui_mch_menu_hidden(vimmenu_T *menu, int hidden) +{ + //NSLog(@"gui_mch_menu_hidden(name=%s, hidden=%d)", menu->name, hidden); + + // HACK! There is no (obvious) way to hide a menu item, so simply + // enable/disable it instead. + [[MMBackend sharedInstance] + enableMenuItemWithTag:(int)menu state:!hidden]; +} + + + void +gui_mch_show_popupmenu(vimmenu_T *menu) +{ + //NSLog(@"gui_mch_show_popupmenu(name=%s)", menu->name); +} + + +/* + * This is called after setting all the menus to grey/hidden or not. + */ + void +gui_mch_draw_menubar(void) +{ + // The (main) menu draws itself in Mac OS X. +} + + + void +gui_mch_enable_menu(int flag) +{ + // The (main) menu is always enabled in Mac OS X. +} + + +#if 0 + void +gui_mch_set_menu_pos(int x, int y, int w, int h) +{ + // The (main) menu cannot be moved in Mac OS X. +} +#endif + + + void +gui_mch_show_toolbar(int showit) +{ + int flags = 0; + if (toolbar_flags & TOOLBAR_TEXT) flags |= ToolbarLabelFlag; + if (toolbar_flags & TOOLBAR_ICONS) flags |= ToolbarIconFlag; + if (tbis_flags & (TBIS_MEDIUM|TBIS_LARGE)) flags |= ToolbarSizeRegularFlag; + + //NSLog(@"gui_mch_show_toolbar(showit=%d, flags=%d)", showit, flags); + + [[MMBackend sharedInstance] showToolbar:showit flags:flags]; +} + + + + +// -- Fonts ----------------------------------------------------------------- + + +/* + * If a font is not going to be used, free its structure. + */ + void +gui_mch_free_font(font) + GuiFont font; +{ +#if 0 + static GuiFont last_font = -1; + if (last_font != font) { + NSLog(@"gui_mch_free_font(font=%d)", font); + last_font = font; + } +#endif +} + + +/* + * Get a font structure for highlighting. + */ + GuiFont +gui_mch_get_font(char_u *name, int giveErrorIfMissing) +{ + //NSLog(@"gui_mch_get_font(name=%s, giveErrorIfMissing=%d)", name, + // giveErrorIfMissing); + return 0; +} + + +#if defined(FEAT_EVAL) || defined(PROTO) +/* + * Return the name of font "font" in allocated memory. + * Don't know how to get the actual name, thus use the provided name. + */ + char_u * +gui_mch_get_fontname(GuiFont font, char_u *name) +{ + //NSLog(@"gui_mch_get_fontname(font=%d, name=%s)", font, name); + return 0; +} +#endif + + +/* + * Initialise vim to use the font with the given name. Return FAIL if the font + * could not be loaded, OK otherwise. + */ + int +gui_mch_init_font(char_u *font_name, int fontset) +{ + //NSLog(@"gui_mch_init_font(font_name=%s, fontset=%d)", font_name, fontset); + + // HACK! This gets called whenever the user types :set gfn=fontname, so + // for now we set the font here. + // TODO! Proper font handling, the way Vim expects it. + return [[MMBackend sharedInstance] + setFontWithName:(char*)font_name]; +} + + +/* + * Set the current text font. + */ + void +gui_mch_set_font(GuiFont font) +{ +#if 0 + static GuiFont last_font = -1; + if (last_font != font) { + NSLog(@"gui_mch_set_font(font=%d)", font); + last_font = font; + } +#endif +} + + + + +// -- Scrollbars ------------------------------------------------------------ + + + void +gui_mch_create_scrollbar( + scrollbar_T *sb, + int orient) /* SBAR_VERT or SBAR_HORIZ */ +{ + //NSLog(@"gui_mch_create_scrollbar(id=%d, orient=%d, type=%d)", + // sb->ident, orient, sb->type); + + [[MMBackend sharedInstance] + createScrollbarWithIdentifier:sb->ident type:sb->type]; +} + + + void +gui_mch_destroy_scrollbar(scrollbar_T *sb) +{ + //NSLog(@"gui_mch_destroy_scrollbar(id=%d)", sb->ident); + + [[MMBackend sharedInstance] + destroyScrollbarWithIdentifier:sb->ident]; +} + + + void +gui_mch_enable_scrollbar( + scrollbar_T *sb, + int flag) +{ + //NSLog(@"gui_mch_enable_scrollbar(id=%d, flag=%d)", sb->ident, flag); + + [[MMBackend sharedInstance] + showScrollbarWithIdentifier:sb->ident state:flag]; +} + + + void +gui_mch_set_scrollbar_pos( + scrollbar_T *sb, + int x, + int y, + int w, + int h) +{ + //NSLog(@"gui_mch_set_scrollbar_pos(id=%d, x=%d, y=%d, w=%d, h=%d)", + // sb->ident, x, y, w, h); + + int pos = y; + int len = h; + if (SBAR_BOTTOM == sb->type) { + pos = x; + len = w; + } + + [[MMBackend sharedInstance] + setScrollbarPosition:pos length:len identifier:sb->ident]; +} + + + void +gui_mch_set_scrollbar_thumb( + scrollbar_T *sb, + long val, + long size, + long max) +{ + //NSLog(@"gui_mch_set_scrollbar_thumb(id=%d, val=%d, size=%d, max=%d)", + // sb->ident, val, size, max); + +#if 0 + float value = max-size+1 > 0 ? (float)val/(max-size+1) : 0; + float prop = (float)size/(max+1); + if (value < 0) value = 0; + else if (value > 1.0f) value = 1.0f; + if (prop < 0) prop = 0; + else if (prop > 1.0f) prop = 1.0f; + + [[MMBackend sharedInstance] + setScrollbarThumbValue:value proportion:prop identifier:sb->ident]; +#else + [[MMBackend sharedInstance] + setScrollbarThumbValue:val size:size max:max identifier:sb->ident]; +#endif +} + + + + + +// -- Unsorted -------------------------------------------------------------- + + +/* + * Adjust gui.char_height (after 'linespace' was changed). + */ + int +gui_mch_adjust_charheight(void) +{ + return 0; +} + + + void +gui_mch_beep(void) +{ +} + + + +#ifdef FEAT_BROWSE +/* + * Pop open a file browser and return the file selected, in allocated memory, + * or NULL if Cancel is hit. + * saving - TRUE if the file will be saved to, FALSE if it will be opened. + * title - Title message for the file browser dialog. + * dflt - Default name of file. + * ext - Default extension to be added to files without extensions. + * initdir - directory in which to open the browser (NULL = current dir) + * filter - Filter for matched files to choose from. + * Has a format like this: + * "C Files (*.c)\0*.c\0" + * "All Files\0*.*\0\0" + * If these two strings were concatenated, then a choice of two file + * filters will be selectable to the user. Then only matching files will + * be shown in the browser. If NULL, the default allows all files. + * + * *NOTE* - the filter string must be terminated with TWO nulls. + */ + char_u * +gui_mch_browse( + int saving, + char_u *title, + char_u *dflt, + char_u *ext, + char_u *initdir, + char_u *filter) +{ + //NSLog(@"gui_mch_browse(saving=%d, title=%s, dflt=%s, ext=%s, initdir=%s," + // " filter=%s", saving, title, dflt, ext, initdir, filter); + + char_u *s = (char_u*)[[MMBackend sharedInstance] + browseForFileInDirectory:(char*)initdir title:(char*)title + saving:saving]; + + return s; +} +#endif /* FEAT_BROWSE */ + + + + int +gui_mch_dialog( + int type, + char_u *title, + char_u *message, + char_u *buttons, + int dfltbutton, + char_u *textfield) +{ + return 0; +} + + +/* + * Draw a cursor without focus. + */ + void +gui_mch_draw_hollow_cursor(guicolor_T color) +{ +} + + +/* + * Draw part of a cursor, only w pixels wide, and h pixels high. + */ + void +gui_mch_draw_part_cursor(int w, int h, guicolor_T color) +{ +} + + + void +gui_mch_flash(int msec) +{ +} + + +/* + * Return the Pixel value (color) for the given color name. This routine was + * pretty much taken from example code in the Silicon Graphics OSF/Motif + * Programmer's Guide. + * Return INVALCOLOR when failed. + */ + guicolor_T +gui_mch_get_color(char_u *name) +{ + NSString *key = [NSString stringWithUTF8String:(char*)name]; + return [[MMBackend sharedInstance] lookupColorWithKey:key]; +} + + +/* + * Return the RGB value of a pixel as long. + */ + long_u +gui_mch_get_rgb(guicolor_T pixel) +{ + // This is only implemented so that vim can guess the correct value for + // 'background' (which otherwise defaults to 'dark'); it is not used for + // anything else (as far as I know). + // The implementation is simple since colors are stored in an int as + // "rrggbb". + return pixel; +} + + +/* + * Get the screen dimensions. + * Allow 10 pixels for horizontal borders, 40 for vertical borders. + * Is there no way to find out how wide the borders really are? + * TODO: Add live udate of those value on suspend/resume. + */ + void +gui_mch_get_screen_dimensions(int *screen_w, int *screen_h) +{ + //NSLog(@"gui_mch_get_screen_dimensions()"); + *screen_w = Columns; + *screen_h = Rows; +} + + +/* + * Get the position of the top left corner of the window. + */ + int +gui_mch_get_winpos(int *x, int *y) +{ + *x = *y = 0; + return OK; +} + + +/* + * Get current mouse coordinates in text window. + */ + void +gui_mch_getmouse(int *x, int *y) +{ +} + + +/* + * Return OK if the key with the termcap name "name" is supported. + */ + int +gui_mch_haskey(char_u *name) +{ + NSLog(@"gui_mch_haskey(name=%s)", name); + return 0; +} + + +/* + * Iconify the GUI window. + */ + void +gui_mch_iconify(void) +{ +} + + +/* + * Invert a rectangle from row r, column c, for nr rows and nc columns. + */ + void +gui_mch_invert_rectangle(int r, int c, int nr, int nc) +{ +} + + +/* + * Called when the foreground or background color has been changed. + */ + void +gui_mch_new_colors(void) +{ + gui.def_back_pixel = gui.back_pixel; + gui.def_norm_pixel = gui.norm_pixel; + + //NSLog(@"gui_mch_new_colors(back=%x, norm=%x)", gui.def_back_pixel, + // gui.def_norm_pixel); + + [[MMBackend sharedInstance] + setDefaultColorsBackground:gui.def_back_pixel + foreground:gui.def_norm_pixel]; +} + + +/* + * Set the current text background color. + */ + void +gui_mch_set_bg_color(guicolor_T color) +{ + [[MMBackend sharedInstance] setBackgroundColor:color]; +} + + +/* + * Cursor blink functions. + * + * This is a simple state machine: + * BLINK_NONE not blinking at all + * BLINK_OFF blinking, cursor is not shown + * BLINK_ON blinking, cursor is shown + */ + void +gui_mch_set_blinking(long wait, long on, long off) +{ +} + + +/* + * Set the current text foreground color. + */ + void +gui_mch_set_fg_color(guicolor_T color) +{ + [[MMBackend sharedInstance] setForegroundColor:color]; +} + + +#if defined(FEAT_EVAL) || defined(PROTO) +/* + * Bring the Vim window to the foreground. + */ + void +gui_mch_set_foreground(void) +{ +} +#endif + + + + void +gui_mch_set_shellsize( + int width, + int height, + int min_width, + int min_height, + int base_width, + int base_height, + int direction) +{ + //NSLog(@"gui_mch_set_shellsize(width=%d, height=%d, min_width=%d," + // " min_height=%d, base_width=%d, base_height=%d, direction=%d)", + // width, height, min_width, min_height, base_width, base_height, + // direction); + [[MMBackend sharedInstance] setRows:height columns:width]; +} + + +/* + * Set the current text special color. + */ + void +gui_mch_set_sp_color(guicolor_T color) +{ +} + + + void +gui_mch_set_text_area_pos(int x, int y, int w, int h) +{ +} + +/* + * Set the position of the top left corner of the window to the given + * coordinates. + */ + void +gui_mch_set_winpos(int x, int y) +{ +} + + + void +gui_mch_setmouse(int x, int y) +{ +} + + +#ifdef FEAT_TITLE +/* + * Set the window title and icon. + * (The icon is not taken care of). + */ + void +gui_mch_settitle(char_u *title, char_u *icon) +{ + //NSLog(@"gui_mch_settitle(title=%s, icon=%s)", title, icon); + + [[MMBackend sharedInstance] setVimWindowTitle:(char*)title]; +} +#endif + + +/* + * Start the cursor blinking. If it was already blinking, this restarts the + * waiting time and shows the cursor. + */ + void +gui_mch_start_blink(void) +{ +} + + +/* + * Stop the cursor blinking. Show the cursor if it wasn't shown. + */ + void +gui_mch_stop_blink(void) +{ +} + + + void +gui_mch_toggle_tearoffs(int enable) +{ +} + + + void +mch_set_mouse_shape(int shape) +{ +} diff --git a/main.m b/main.m new file mode 100644 index 0000000000..5d5346169c --- /dev/null +++ b/main.m @@ -0,0 +1,16 @@ +/* vi:set ts=8 sts=4 sw=4 ft=objc: + * + * VIM - Vi IMproved by Bram Moolenaar + * MacVim GUI port by Bjorn Winckler + * + * Do ":help uganda" in Vim to read copying and usage conditions. + * Do ":help credits" in Vim to see a list of people who contributed. + * See README.txt for an overview of the Vim source code. + */ + +#import + +int main(int argc, char *argv[]) +{ + return NSApplicationMain(argc, (const char **) argv); +} diff --git a/vim_gloss.icns b/vim_gloss.icns new file mode 100644 index 0000000000000000000000000000000000000000..f2d922bc94e3936303d941fc6ebe92b9cf3808b1 GIT binary patch literal 55320 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 literal 0 HcmV?d00001