logo       

Mac tabpages patch: msg#00039

editors.vim.mac

Subject: Mac tabpages patch


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>
Google Custom Search

News | FAQ | advertise