|
Mac tabpages patch: msg#00039editors.vim.mac
I have applied the patch from Nicolas Weber to add GUI support to tab pages. I have cleaned it up a bit, it is included below. Changes are mostly to make it look like the Vim standard formatting and avoiding C++ syntax. Made quite a few things "static". There are still a few C++ things in there, I don't think it compiles with anything but gcc. A few things I noticed on a quick try: - There are no tab pages labels, there is a new window with them. Takes a lot of screen space. Can't we have labels like on other systems, so that they really look like tab pages? - Maximizing with the green "+" button only changes the height. Don't know if this was already so. - Using ":set columns=999" doesn't fit the window to the screen size. Don't know if this was already so. I would like to have feedback on this before I send this patch out. *** ../vim-7.0.216/src/feature.h Wed Nov 1 18:10:36 2006 --- src/feature.h Thu Mar 15 19:02:15 2007 *************** *** 756,761 **** --- 756,762 ---- #if defined(FEAT_WINDOWS) && defined(FEAT_NORMAL) \ && (defined(FEAT_GUI_GTK) \ || (defined(FEAT_GUI_MOTIF) && defined(HAVE_XM_NOTEBOOK_H)) \ + || defined(FEAT_GUI_MAC) \ || (defined(FEAT_GUI_MSWIN) && (!defined(_MSC_VER) || _MSC_VER > 1020))) # define FEAT_GUI_TABLINE #endif *** ../vim-7.0.216/src/gui.c Tue Oct 10 17:36:50 2006 --- src/gui.c Thu Mar 15 19:02:15 2007 *************** *** 1159,1165 **** #endif # if defined(FEAT_GUI_TABLINE) && (defined(FEAT_GUI_MSWIN) \ ! || defined(FEAT_GUI_MOTIF)) if (gui_has_tabline()) text_area_y += gui.tabline_height; #endif --- 1159,1165 ---- #endif # if defined(FEAT_GUI_TABLINE) && (defined(FEAT_GUI_MSWIN) \ ! || defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_MAC)) if (gui_has_tabline()) text_area_y += gui.tabline_height; #endif *************** *** 2714,2720 **** } /* ! * Fill buffer with mouse coordinates encoded for check_termcode(). */ static void fill_mouse_coord(p, col, row) --- 2714,2720 ---- } /* ! * Fill p[4] with mouse coordinates encoded for check_termcode(). */ static void fill_mouse_coord(p, col, row) *** ../vim-7.0.216/src/gui.h Thu Apr 27 01:52:33 2006 --- src/gui.h Thu Mar 15 19:02:15 2007 *************** *** 71,76 **** --- 71,80 ---- # define ALWAYS_USE_GUI #endif + /* + * On some systems scrolling needs to be done right away instead of in the + * main loop. + */ #if defined(FEAT_GUI_MSWIN) || defined(FEAT_GUI_MAC) || defined(HAVE_GTK2) # define USE_ON_FLY_SCROLL #endif *************** *** 421,427 **** #endif /* FEAT_GUI_GTK */ #if defined(FEAT_GUI_TABLINE) \ ! && (defined(FEAT_GUI_W32) || defined(FEAT_GUI_MOTIF)) int tabline_height; #endif --- 425,432 ---- #endif /* FEAT_GUI_GTK */ #if defined(FEAT_GUI_TABLINE) \ ! && (defined(FEAT_GUI_W32) || defined(FEAT_GUI_MOTIF) \ ! || defined(FEAT_GUI_MAC)) int tabline_height; #endif *** ../vim-7.0.216/src/gui_mac.c Thu Mar 8 20:39:02 2007 --- src/gui_mac.c Thu Mar 15 20:20:44 2007 *************** *** 4,10 **** * GUI/Motif support by Robert Webb * Macintosh port by Dany St-Amant * and Axel Kielhorn ! * Port to MPW by Bernhard Pr?mmer * Initial Carbon port by Ammon Skidmore * * Do ":help uganda" in Vim to read copying and usage conditions. --- 4,10 ---- * GUI/Motif support by Robert Webb * Macintosh port by Dany St-Amant * and Axel Kielhorn ! * Port to MPW by Bernhard Pruemmer * Initial Carbon port by Ammon Skidmore * * Do ":help uganda" in Vim to read copying and usage conditions. *************** *** 28,38 **** * */ ! /* TODO (Jussi) ! * * Clipboard does not work (at least some cases) ! * * ATSU font rendering has some problems ! * * Investigate and remove dead code (there is still lots of that) ! */ #include <Devices.h> /* included first to avoid CR problems */ #include "vim.h" --- 28,38 ---- * */ ! /* TODO (Jussi) ! * * Clipboard does not work (at least some cases) ! * * ATSU font rendering has some problems ! * * Investigate and remove dead code (there is still lots of that) ! */ #include <Devices.h> /* included first to avoid CR problems */ #include "vim.h" *************** *** 260,265 **** --- 260,269 ---- OSErr HandleUnusedParms(const AppleEvent *theAEvent); #endif + #ifdef FEAT_GUI_TABLINE + static void initialise_tabline(void); + #endif + /* * ------------------------------------------------------------ * Conversion Utility *************** *** 499,507 **** /* Get number of files in list */ *error = AECountItems(theList, numFiles); if (*error) ! { ! return(fnames); ! } /* Allocate the pointer list */ fnames = (char_u **) alloc(*numFiles * sizeof(char_u *)); --- 503,509 ---- /* Get number of files in list */ *error = AECountItems(theList, numFiles); if (*error) ! return fnames; /* Allocate the pointer list */ fnames = (char_u **) alloc(*numFiles * sizeof(char_u *)); *************** *** 521,527 **** { /* Caller is able to clean up */ /* TODO: Should be clean up or not? For safety. */ ! return(fnames); } /* Convert the FSSpec to a pathname */ --- 523,529 ---- { /* Caller is able to clean up */ /* TODO: Should be clean up or not? For safety. */ ! return fnames; } /* Convert the FSSpec to a pathname */ *************** *** 584,598 **** error = AEGetParamPtr(theAEvent, keyDirectObject, typeChar, &typeCode, (Ptr) &SearchData, sizeof(WindowSearch), &actualSize); if (error) ! { ! return(error); ! } error = HandleUnusedParms(theAEvent); if (error) ! { ! return(error); ! } for (buf = firstbuf; buf != NULL; buf = buf->b_next) if (buf->b_ml.ml_mfp != NULL --- 586,596 ---- error = AEGetParamPtr(theAEvent, keyDirectObject, typeChar, &typeCode, (Ptr) &SearchData, sizeof(WindowSearch), &actualSize); if (error) ! return error; error = HandleUnusedParms(theAEvent); if (error) ! return error; for (buf = firstbuf; buf != NULL; buf = buf->b_next) if (buf->b_ml.ml_mfp != NULL *************** *** 663,671 **** error = HandleUnusedParms(theAEvent); if (error) ! { ! return(error); ! } /* Send the reply */ /* replyObject.descriptorType = typeNull; --- 661,667 ---- error = HandleUnusedParms(theAEvent); if (error) ! return error; /* Send the reply */ /* replyObject.descriptorType = typeNull; *************** *** 674,682 **** /* AECreateDesc(typeChar, (Ptr)&title[1], title[0], &data) */ error = AECreateList(nil, 0, false, &replyList); if (error) ! { ! return(error); ! } #if 0 error = AECountItems(&replyList, &numFiles); --- 670,676 ---- /* AECreateDesc(typeChar, (Ptr)&title[1], title[0], &data) */ error = AECreateList(nil, 0, false, &replyList); if (error) ! return error; #if 0 error = AECountItems(&replyList, &numFiles); *************** *** 770,778 **** error = AEGetParamPtr(theAEvent, keyDirectObject, typeChar, &typeCode, (Ptr) &GetTextData, sizeof(GetTextData), &actualSize); if (error) ! { ! return(error); ! } for (buf = firstbuf; buf != NULL; buf = buf->b_next) if (buf->b_ml.ml_mfp != NULL) --- 764,770 ---- error = AEGetParamPtr(theAEvent, keyDirectObject, typeChar, &typeCode, (Ptr) &GetTextData, sizeof(GetTextData), &actualSize); if (error) ! return error; for (buf = firstbuf; buf != NULL; buf = buf->b_next) if (buf->b_ml.ml_mfp != NULL) *************** *** 821,832 **** } error = HandleUnusedParms(theAEvent); - if (error) - { - return(error); - } ! return(error); } /* --- 813,820 ---- } error = HandleUnusedParms(theAEvent); ! return error; } /* *************** *** 1012,1020 **** /* the direct object parameter is the list of aliases to files (one or more) */ error = AEGetParamDesc(theAEvent, keyDirectObject, typeAEList, &theList); if (error) ! { ! return(error); ! } error = AEGetParamPtr(theAEvent, keyAEPosition, typeChar, &typeCode, (Ptr) &thePosition, sizeof(SelectionRange), &actualSize); --- 1000,1006 ---- /* the direct object parameter is the list of aliases to files (one or more) */ error = AEGetParamDesc(theAEvent, keyDirectObject, typeAEList, &theList); if (error) ! return error; error = AEGetParamPtr(theAEvent, keyAEPosition, typeChar, &typeCode, (Ptr) &thePosition, sizeof(SelectionRange), &actualSize); *************** *** 1023,1031 **** if (error == errAEDescNotFound) error = noErr; if (error) ! { ! return(error); ! } /* error = AEGetParamDesc(theAEvent, keyAEPosition, typeChar, &thePosition); --- 1009,1015 ---- if (error == errAEDescNotFound) error = noErr; if (error) ! return error; /* error = AEGetParamDesc(theAEvent, keyAEPosition, typeChar, &thePosition); *************** *** 1129,1143 **** /* Fake mouse event to wake from stall */ PostEvent(mouseUp, 0); ! finished: AEDisposeDesc(&theList); /* dispose what we allocated */ error = HandleUnusedParms(theAEvent); ! if (error) ! { ! return(error); ! } ! return(error); } /* --- 1113,1123 ---- /* Fake mouse event to wake from stall */ PostEvent(mouseUp, 0); ! finished: AEDisposeDesc(&theList); /* dispose what we allocated */ error = HandleUnusedParms(theAEvent); ! return error; } /* *************** *** 1153,1164 **** OSErr error = noErr; error = HandleUnusedParms(theAEvent); ! if (error) ! { ! return(error); ! } ! ! return(error); } /* --- 1133,1139 ---- OSErr error = noErr; error = HandleUnusedParms(theAEvent); ! return error; } /* *************** *** 1175,1188 **** error = HandleUnusedParms(theAEvent); if (error) ! { ! return(error); ! } /* Need to fake a :confirm qa */ do_cmdline_cmd((char_u *)"confirm qa"); ! return(error); } /* --- 1150,1161 ---- error = HandleUnusedParms(theAEvent); if (error) ! return error; /* Need to fake a :confirm qa */ do_cmdline_cmd((char_u *)"confirm qa"); ! return error; } /* *************** *** 1198,1209 **** OSErr error = noErr; error = HandleUnusedParms(theAEvent); - if (error) - { - return(error); - } ! return(error); } /* --- 1171,1178 ---- OSErr error = noErr; error = HandleUnusedParms(theAEvent); ! return error; } /* *************** *** 1220,1231 **** OSErr error = noErr; error = HandleUnusedParms(theAEvent); - if (error) - { - return(error); - } ! return(error); } --- 1189,1196 ---- OSErr error = noErr; error = HandleUnusedParms(theAEvent); ! return error; } *************** *** 2357,2362 **** --- 2322,2334 ---- thePart = FindWindow(theEvent->where, &whichWindow); + #ifdef FEAT_GUI_TABLINE + /* prevent that the vim window size changes if it's activated by a + click into the tab pane */ + if (whichWindow != gui.VimWindow) + return; + #endif + switch (thePart) { case (inDesk): *************** *** 2505,2511 **** return noErr; ! bail: /* * when we fail give any additional callback handler a chance to perform * it's actions --- 2477,2483 ---- return noErr; ! bail: /* * when we fail give any additional callback handler a chance to perform * it's actions *************** *** 2895,2901 **** #endif static OSErr ! receiveHandler(WindowRef theWindow, void* handlerRefCon, DragRef theDrag) { int x, y; int_u modifiers; --- 2867,2873 ---- #endif static OSErr ! receiveHandler(WindowRef theWindow, void *handlerRefCon, DragRef theDrag) { int x, y; int_u modifiers; *************** *** 3097,3102 **** --- 3069,3081 ---- #endif */ + #ifdef FEAT_GUI_TABLINE + /* + * Create the tabline + */ + initialise_tabline(); + #endif + /* TODO: Load bitmap if using TOOLBAR */ return OK; } *************** *** 4963,4969 **** SetControl32BitMaximum (sb->id, max); SetControl32BitMinimum (sb->id, 0); SetControl32BitValue (sb->id, val); ! SetControlViewSize (sb->id, size); #ifdef DEBUG_MAC_SB printf("thumb_sb (%x) %x, %x,%x\n",sb->id, val, size, max); #endif --- 4942,4948 ---- SetControl32BitMaximum (sb->id, max); SetControl32BitMinimum (sb->id, 0); SetControl32BitValue (sb->id, val); ! SetControlViewSize (sb->id, size); #ifdef DEBUG_MAC_SB printf("thumb_sb (%x) %x, %x,%x\n",sb->id, val, size, max); #endif *************** *** 5895,5901 **** theCPB.dirInfo.ioFDirIndex = 0; theCPB.dirInfo.ioNamePtr = file.name; theCPB.dirInfo.ioVRefNum = file.vRefNum; ! /*theCPB.hFileInfo.ioDirID = 0;*/ theCPB.dirInfo.ioDrDirID = file.parID; /* As ioFDirIndex = 0, get the info of ioNamePtr, --- 5874,5880 ---- theCPB.dirInfo.ioFDirIndex = 0; theCPB.dirInfo.ioNamePtr = file.name; theCPB.dirInfo.ioVRefNum = file.vRefNum; ! /*theCPB.hFileInfo.ioDirID = 0;*/ theCPB.dirInfo.ioDrDirID = file.parID; /* As ioFDirIndex = 0, get the info of ioNamePtr, *************** *** 6093,6096 **** --- 6072,6479 ---- return (script != smRoman && script == GetScriptManagerVariable(smSysScript)) ? 1 : 0; } + #endif /* defined(USE_IM_CONTROL) || defined(PROTO) */ + + + + + #if defined(FEAT_GUI_TABLINE) || defined(PROTO) + static MenuRef contextMenu = NULL; + enum + { + kTabContextMenuId = 42, + }; + + // the caller has to CFRelease() the returned string + static CFStringRef + getTabLabel(tabpage_T *page) + { + get_tabline_label(page, FALSE); + #ifdef MACOS_CONVERT + return mac_enc_to_cfstring(NameBuff, STRLEN(NameBuff)); + #else + // TODO: check internal encoding? + return CFStringCreateWithCString(kCFAllocatorDefault, (char *)NameBuff, + kCFStringEncodingMacRoman); + #endif + } + + + #define DRAWER_SIZE 150 + #define DRAWER_INSET 16 + + // drawer implementation + static WindowRef drawer = NULL; // TODO: put into gui.h + static ControlRef dataBrowser = NULL; + + // when the tabline is hidden, vim doesn't call update_tabline(). When + // the tabline is shown again, show_tabline() is called before upate_tabline(), + // and because of this, the tab labels and vims internal tabs are out of sync + // for a very short time. to prevent inconsistent state, we store the labels + // of the tabs, not pointers to the tabs (which are invalid for a short time). + static CFStringRef *tabLabels = NULL; + static int tabLabelsSize = 0; + + enum + { + kTabsColumn = 'Tabs' + }; + + static int + getTabCount(void) + { + tabpage_T *tp; + int numTabs = 0; + + for (tp = first_tabpage; tp != NULL; tp = tp->tp_next) + ++numTabs; + return numTabs; + } + + // data browser item display callback + static OSStatus + dbItemDataCallback(ControlRef browser, + DataBrowserItemID itemID, + DataBrowserPropertyID property /* column id */, + DataBrowserItemDataRef itemData, + Boolean changeValue) + { + OSStatus status = noErr; + + // assert(property == kTabsColumn); // why is this violated?? + + // changeValue is true if we have a modifieable list and data was changed. + // In our case, it's always false. + // (that is: if (changeValue) updateInternalData(); else return + // internalData(); + if (!changeValue) + { + CFStringRef str; + + assert(itemID - 1 >= 0 && itemID - 1 < tabLabelsSize); + str = tabLabels[itemID - 1]; + status = SetDataBrowserItemDataText(itemData, str); + } + else + status = errDataBrowserPropertyNotSupported; + + return status; + } + + // data browser action callback + static void + dbItemNotificationCallback(ControlRef browser, + DataBrowserItemID item, + DataBrowserItemNotification message) + { + switch (message) + { + case kDataBrowserItemSelected: + send_tabline_event(item); + break; + } + } + + // callbacks needed for contextual menu: + static void + dbGetContextualMenuCallback(ControlRef browser, + MenuRef *menu, + UInt32 *helpType, + CFStringRef *helpItemString, + AEDesc *selection) + { + // on mac os 9: kCMHelpItemNoHelp, but it's not the same + *helpType = kCMHelpItemRemoveHelp; // OS X only ;-) + *helpItemString = NULL; + + *menu = contextMenu; + } + + static void + dbSelectContextualMenuCallback(ControlRef browser, + MenuRef menu, + UInt32 selectionType, + SInt16 menuID, + MenuItemIndex menuItem) + { + if (selectionType == kCMMenuItemSelected) + { + MenuCommand command; + GetMenuItemCommandID(menu, menuItem, &command); + + // get tab that was selected when the context menu appeared + // (there is always one tab selected). TODO: check if the context menu + // isn't opened on an item but on empty space (has to be possible some + // way, the finder does it too ;-) ) + Handle items = NewHandle(0); + if (items != NULL) + { + int numItems; + + GetDataBrowserItems(browser, kDataBrowserNoItem, false, + kDataBrowserItemIsSelected, items); + numItems = GetHandleSize(items) / sizeof(DataBrowserItemID); + if (numItems > 0) + { + int idx; + DataBrowserItemID *itemsPtr; + + HLock(items); + itemsPtr = (DataBrowserItemID *)*items; + idx = itemsPtr[0]; + HUnlock(items); + send_tabline_menu_event(idx, command); + } + DisposeHandle(items); + } + } + } + + // focus callback of the data browser to always leave focus in vim + static OSStatus + dbFocusCallback(EventHandlerCallRef handler, EventRef event, void *data) + { + assert(GetEventClass(event) == kEventClassControl + && GetEventKind(event) == kEventControlSetFocusPart); + + return paramErr; + } + + + // drawer callback to resize data browser to drawer size + static OSStatus + drawerCallback(EventHandlerCallRef handler, EventRef event, void *data) + { + switch (GetEventKind(event)) + { + case kEventWindowBoundsChanged: // move or resize + { + UInt32 attribs; + GetEventParameter(event, kEventParamAttributes, typeUInt32, + NULL, sizeof(attribs), NULL, &attribs); + if (attribs & kWindowBoundsChangeSizeChanged) // resize + { + Rect r; + GetWindowBounds(drawer, kWindowContentRgn, &r); + SetRect(&r, 0, 0, r.right - r.left, r.bottom - r.top); + SetControlBounds(dataBrowser, &r); + SetDataBrowserTableViewNamedColumnWidth(dataBrowser, + kTabsColumn, r.right); + } + } + break; + } + + return eventNotHandledErr; + } + + // Load DataBrowserChangeAttributes() dynamically on tiger (and better). + // This way the code works on 10.2 and 10.3 as well (it doesn't have the + // blue highlights in the list view on these systems, though. Oh well.) + + + #import <mach-o/dyld.h> + + enum { kMyDataBrowserAttributeListViewAlternatingRowColors = (1 << 1) }; + + static OSStatus + myDataBrowserChangeAttributes(ControlRef inDataBrowser, + OptionBits inAttributesToSet, + OptionBits inAttributesToClear) + { + long osVersion; + char *symbolName; + NSSymbol symbol = NULL; + OSStatus (*dataBrowserChangeAttributes)(ControlRef inDataBrowser, + OptionBits inAttributesToSet, OptionBits inAttributesToClear); + + Gestalt(gestaltSystemVersion, &osVersion); + if (osVersion < 0x1040) // only supported for 10.4 (and up) + return noErr; + + // C name mangling... + symbolName = "_DataBrowserChangeAttributes"; + if (!NSIsSymbolNameDefined(symbolName) + || (symbol = NSLookupAndBindSymbol(symbolName)) == NULL) + return noErr; + + dataBrowserChangeAttributes = NSAddressOfSymbol(symbol); + if (dataBrowserChangeAttributes == NULL) + return noErr; // well... + return dataBrowserChangeAttributes(inDataBrowser, + inAttributesToSet, inAttributesToClear); + } + + static void + initialise_tabline(void) + { + Rect drawerRect = { 0, 0, 0, DRAWER_SIZE }; + DataBrowserCallbacks dbCallbacks; + EventTypeSpec focusEvent = {kEventClassControl, kEventControlSetFocusPart}; + EventTypeSpec resizeEvent = {kEventClassWindow, kEventWindowBoundsChanged}; + DataBrowserListViewColumnDesc colDesc; + + // drawers have to have compositing enabled + CreateNewWindow(kDrawerWindowClass, + kWindowStandardHandlerAttribute + | kWindowCompositingAttribute + | kWindowResizableAttribute + | kWindowLiveResizeAttribute, + &drawerRect, &drawer); + + SetThemeWindowBackground(drawer, kThemeBrushDrawerBackground, true); + SetDrawerParent(drawer, gui.VimWindow); + SetDrawerOffsets(drawer, kWindowOffsetUnchanged, DRAWER_INSET); + + + // create list view embedded in drawer + CreateDataBrowserControl(drawer, &drawerRect, kDataBrowserListView, + &dataBrowser); + + dbCallbacks.version = kDataBrowserLatestCallbacks; + InitDataBrowserCallbacks(&dbCallbacks); + dbCallbacks.u.v1.itemDataCallback = + NewDataBrowserItemDataUPP(dbItemDataCallback); + dbCallbacks.u.v1.itemNotificationCallback = + NewDataBrowserItemNotificationUPP(dbItemNotificationCallback); + dbCallbacks.u.v1.getContextualMenuCallback = + NewDataBrowserGetContextualMenuUPP(dbGetContextualMenuCallback); + dbCallbacks.u.v1.selectContextualMenuCallback = + NewDataBrowserSelectContextualMenuUPP(dbSelectContextualMenuCallback); + + SetDataBrowserCallbacks(dataBrowser, &dbCallbacks); + + SetDataBrowserListViewHeaderBtnHeight(dataBrowser, 0); // no header + SetDataBrowserHasScrollBars(dataBrowser, false, true); // only vertical + SetDataBrowserSelectionFlags(dataBrowser, + kDataBrowserSelectOnlyOne | kDataBrowserNeverEmptySelectionSet); + SetDataBrowserTableViewHiliteStyle(dataBrowser, + kDataBrowserTableViewFillHilite); + Boolean b = false; + SetControlData(dataBrowser, kControlEntireControl, + kControlDataBrowserIncludesFrameAndFocusTag, sizeof(b), &b); + + // enable blue background in data browser (this is only in 10.4 and vim + // has to support older osx versions as well, so we have to load this + // function dynamically) + myDataBrowserChangeAttributes(dataBrowser, + kMyDataBrowserAttributeListViewAlternatingRowColors, 0); + + // install callback that keeps focus in vim and away from the data browser + InstallControlEventHandler(dataBrowser, dbFocusCallback, 1, &focusEvent, + NULL, NULL); + + // install callback that keeps data browser at the size of the drawer + InstallWindowEventHandler(drawer, drawerCallback, 1, &resizeEvent, + NULL, NULL); + + // add "tabs" column to data browser + colDesc.propertyDesc.propertyID = kTabsColumn; + colDesc.propertyDesc.propertyType = kDataBrowserTextType; + + // add if items can be selected (?): kDataBrowserListViewSelectionColumn + colDesc.propertyDesc.propertyFlags = kDataBrowserDefaultPropertyFlags; + + colDesc.headerBtnDesc.version = kDataBrowserListViewLatestHeaderDesc; + colDesc.headerBtnDesc.minimumWidth = 100; + colDesc.headerBtnDesc.maximumWidth = 150; + colDesc.headerBtnDesc.titleOffset = 0; + colDesc.headerBtnDesc.titleString = CFSTR("Tabs"); + colDesc.headerBtnDesc.initialOrder = kDataBrowserOrderIncreasing; + colDesc.headerBtnDesc.btnFontStyle.flags = 0; // use default font + colDesc.headerBtnDesc.btnContentInfo.contentType = kControlContentTextOnly; + + AddDataBrowserListViewColumn(dataBrowser, &colDesc, 0); + + // create tabline popup menu required by vim docs (see :he tabline-menu) + CreateNewMenu(kTabContextMenuId, 0, &contextMenu); + AppendMenuItemTextWithCFString(contextMenu, CFSTR("Close"), 0, + TABLINE_MENU_CLOSE, NULL); + AppendMenuItemTextWithCFString(contextMenu, CFSTR("New Tab"), 0, + TABLINE_MENU_NEW, NULL); + AppendMenuItemTextWithCFString(contextMenu, CFSTR("Open Tab..."), 0, + TABLINE_MENU_OPEN, NULL); + } + + + /* + * Show or hide the tabline. + */ + void + gui_mch_show_tabline(int showit) + { + if (showit == 0) + CloseDrawer(drawer, true); + else + OpenDrawer(drawer, kWindowEdgeRight, true); + } + + /* + * Return TRUE when tabline is displayed. + */ + int + gui_mch_showing_tabline(void) + { + WindowDrawerState state = GetDrawerState(drawer); + + return state == kWindowDrawerOpen || state == kWindowDrawerOpening; + } + + /* + * Update the labels of the tabline. + */ + void + gui_mch_update_tabline(void) + { + tabpage_T *tp; + int numTabs = getTabCount(); + int nr = 1; + int curtabidx = 1; + + // adjust data browser + if (tabLabels != NULL) + { + int i; + + for (i = 0; i < tabLabelsSize; ++i) + CFRelease(tabLabels[i]); + free(tabLabels); + } + tabLabels = (CFStringRef *)malloc(numTabs * sizeof(CFStringRef)); + tabLabelsSize = numTabs; + + for (tp = first_tabpage; tp != NULL; tp = tp->tp_next, ++nr) + { + if (tp == curtab) + curtabidx = nr; + tabLabels[nr-1] = getTabLabel(tp); + } + + RemoveDataBrowserItems(dataBrowser, kDataBrowserNoItem, 0, NULL, + kDataBrowserItemNoProperty); + // data browser uses ids 1, 2, 3, ... numTabs per default, so we + // can pass NULL for the id array + AddDataBrowserItems(dataBrowser, kDataBrowserNoItem, numTabs, NULL, + kDataBrowserItemNoProperty); + + DataBrowserItemID item = curtabidx; + SetDataBrowserSelectedItems(dataBrowser, 1, &item, kDataBrowserItemsAssign); + } + + /* + * Set the current tab to "nr". First tab is 1. + */ + void + gui_mch_set_curtab(nr) + int nr; + { + DataBrowserItemID item = nr; + SetDataBrowserSelectedItems(dataBrowser, 1, &item, kDataBrowserItemsAssign); + + // TODO: call something like this?: (or restore scroll position, or...) + RevealDataBrowserItem(dataBrowser, item, kTabsColumn, + kDataBrowserRevealOnly); + } + + #endif // FEAT_GUI_TABLINE *** ../vim-7.0.216/src/proto/gui_mac.pro Tue Mar 28 23:01:02 2006 --- src/proto/gui_mac.pro Thu Mar 15 20:23:42 2007 *************** *** 84,89 **** --- 84,93 ---- int gui_mch_dialog __ARGS((int type, char_u *title, char_u *message, char_u *buttons, int dfltbutton, char_u *textfield)); char_u *gui_mch_browse __ARGS((int saving, char_u *title, char_u *dflt, char_u *ext, char_u *initdir, char_u *filter)); void gui_mch_set_foreground __ARGS((void)); + void gui_mch_show_tabline __ARGS((int showit)); + int gui_mch_showing_tabline __ARGS((void)); + void gui_mch_update_tabline __ARGS((void)); + void gui_mch_set_curtab __ARGS((int nr)); char_u *C2Pascal_save __ARGS((char_u *Cstring)); char_u *C2Pascal_save_and_remove_backslash __ARGS((char_u *Cstring)); -- [clop clop] MORTICIAN: Who's that then? CUSTOMER: I don't know. MORTICIAN: Must be a king. CUSTOMER: Why? MORTICIAN: He hasn't got shit all over him. The Quest for the Holy Grail (Monty Python) /// Bram Moolenaar -- Bram-+95IjRO79B4xsqv6Oivclw@xxxxxxxxxxxxxxxx -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ download, build and distribute -- http://www.A-A-P.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org /// |
|
| <Prev in Thread] | Current Thread | [Next in Thread> |
|---|---|---|
| Previous by Date: | Re: Xcode project for OS X Vim?: 00039, Arnaud BARRÉ |
|---|---|
| Next by Date: | Re: Mac tabpages patch: 00039, Bem Jones-Bey |
| Previous by Thread: | system menu bar not responsei: 00039, Leira Hua |
| Next by Thread: | Re: Mac tabpages patch: 00039, Bem Jones-Bey |
| Indexes: | [Date] [Thread] [Top] [All Lists] |
| News | FAQ | advertise |