зеркало из https://github.com/mozilla/pjs.git
3701 строка
102 KiB
C
3701 строка
102 KiB
C
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
|
*
|
|
* The contents of this file are subject to the Netscape Public License
|
|
* Version 1.0 (the "NPL"); you may not use this file except in
|
|
* compliance with the NPL. You may obtain a copy of the NPL at
|
|
* http://www.mozilla.org/NPL/
|
|
*
|
|
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
|
* for the specific language governing rights and limitations under the
|
|
* NPL.
|
|
*
|
|
* The Initial Developer of this code under the NPL is Netscape
|
|
* Communications Corporation. Portions created by Netscape are
|
|
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
|
* Reserved.
|
|
*/
|
|
|
|
/*
|
|
* The following source code is part of the Microline Widget Library.
|
|
* The Microline widget library is made available to Mozilla developers
|
|
* under the Netscape Public License (NPL) by Neuron Data. To learn
|
|
* more about Neuron Data, please visit the Neuron Data Home Page at
|
|
* http://www.neurondata.com.
|
|
*/
|
|
|
|
#include "FolderP.h"
|
|
#include <X11/StringDefs.h>
|
|
#include <Xm/DrawnB.h>
|
|
#include <Xm/Label.h>
|
|
#include <Xm/Form.h>
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
#ifdef SUNOS4
|
|
int fprintf(FILE *, char *, ...);
|
|
#endif
|
|
|
|
/* Create and Destroy */
|
|
static void ClassInitialize();
|
|
static void Initialize(Widget req, Widget newW,
|
|
ArgList args, Cardinal *nargs);
|
|
static void Destroy(Widget w);
|
|
|
|
/* Geometry, Drawing, Entry and Picking */
|
|
static void Realize(Widget w, XtValueMask *valueMask,
|
|
XSetWindowAttributes *attr);
|
|
static void Redisplay(Widget w, XExposeEvent *event, Region region);
|
|
static void Layout(XmLFolderWidget f, int resizeIfNeeded);
|
|
static void LayoutTopBottom(XmLFolderWidget f, int resizeIfNeeded);
|
|
static void LayoutLeftRight(XmLFolderWidget f, int resizeIfNeeded);
|
|
static void Resize(Widget w);
|
|
static XtGeometryResult GeometryManager(Widget w, XtWidgetGeometry *request,
|
|
XtWidgetGeometry *);
|
|
static void ChangeManaged(Widget w);
|
|
static void ConstraintInitialize(Widget, Widget w,
|
|
ArgList args, Cardinal *nargs);
|
|
static void ConstraintDestroy(Widget w);
|
|
static void SetActiveTab(XmLFolderWidget f, Widget w, XEvent *event,
|
|
Boolean notify);
|
|
static void DrawTabPixmap(XmLFolderWidget f, Widget tab, int active);
|
|
static void DrawManagerShadowLeftRight(XmLFolderWidget f, XRectangle *rect);
|
|
static void DrawManagerShadowTopBottom(XmLFolderWidget f, XRectangle *rect);
|
|
static void DrawTabHighlight(XmLFolderWidget f, Widget w);
|
|
static void SetTabPlacement(XmLFolderWidget f, Widget tab);
|
|
static void GetTabRect(XmLFolderWidget f, Widget tab, XRectangle *rect,
|
|
int includeShadow);
|
|
static void DrawTabShadowArcTopBottom(XmLFolderWidget f, Widget w);
|
|
static void DrawTabShadowArcLeftRight(XmLFolderWidget f, Widget w);
|
|
static void DrawTabShadowLineTopBottom(XmLFolderWidget f, Widget w);
|
|
static void DrawTabShadowLineLeftRight(XmLFolderWidget f, Widget w);
|
|
static void DrawTabShadowNoneTopBottom(XmLFolderWidget f, Widget w);
|
|
static void DrawTabShadowNoneLeftRight(XmLFolderWidget f, Widget w);
|
|
static void SetGC(XmLFolderWidget f, int type);
|
|
|
|
/* Getting and Setting Values */
|
|
static Boolean SetValues(Widget curW, Widget reqW, Widget newW,
|
|
ArgList args, Cardinal *nargs);
|
|
static Boolean ConstraintSetValues(Widget curW, Widget, Widget newW,
|
|
ArgList, Cardinal *);
|
|
static void CopyFontList(XmLFolderWidget f);
|
|
static Boolean CvtStringToCornerStyle(Display *dpy, XrmValuePtr args,
|
|
Cardinal *numArgs, XrmValuePtr fromVal, XrmValuePtr toVal,
|
|
XtPointer *data);
|
|
static Boolean CvtStringToFolderResizePolicy(Display *dpy, XrmValuePtr args,
|
|
Cardinal *numArgs, XrmValuePtr fromVal, XrmValuePtr toVal,
|
|
XtPointer *data);
|
|
static Boolean CvtStringToTabPlacement(Display *dpy, XrmValuePtr args,
|
|
Cardinal *numArgs, XrmValuePtr fromVal, XrmValuePtr toVal,
|
|
XtPointer *data);
|
|
|
|
/* Utility */
|
|
static void GetCoreBackground(Widget w, int, XrmValue *value);
|
|
static void GetDefaultTabWidgetClass(Widget w, int, XrmValue *value);
|
|
static void GetManagerForeground(Widget w, int, XrmValue *value);
|
|
static Boolean ServerDrawsArcsLarge(Display *dpy, int debug);
|
|
|
|
/* Actions, Callbacks and Handlers */
|
|
static void Activate(Widget w, XEvent *event, String *, Cardinal *);
|
|
static void PrimActivate(Widget w, XtPointer, XtPointer);
|
|
static void PrimFocusIn(Widget w, XEvent *event, String *, Cardinal *);
|
|
static void PrimFocusOut(Widget w, XEvent *event, String *, Cardinal *);
|
|
|
|
static XtActionsRec actions[] =
|
|
{
|
|
{ "XmLFolderActivate", Activate },
|
|
{ "XmLFolderPrimFocusIn", PrimFocusIn },
|
|
{ "XmLFolderPrimFocusOut", PrimFocusOut },
|
|
};
|
|
|
|
#define MAX_TAB_ROWS 64
|
|
|
|
#define GC_SHADOWBOT 0
|
|
#define GC_SHADOWTOP 1
|
|
#define GC_BLANK 2
|
|
#define GC_UNSET 3
|
|
|
|
/* Folder Translations */
|
|
|
|
static char translations[] =
|
|
"<Btn1Down>: XmLFolderActivate()\n\
|
|
<EnterWindow>: ManagerEnter()\n\
|
|
<LeaveWindow>: ManagerLeave()\n\
|
|
<FocusOut>: ManagerFocusOut()\n\
|
|
<FocusIn>: ManagerFocusIn()";
|
|
|
|
/* Primitive Child Translations */
|
|
|
|
static char primTranslations[] =
|
|
"<FocusIn>: XmLFolderPrimFocusIn() PrimitiveFocusIn()\n\
|
|
<FocusOut>: XmLFolderPrimFocusOut() PrimitiveFocusOut()";
|
|
|
|
static XtResource resources[] =
|
|
{
|
|
/* Folder Resources */
|
|
{
|
|
XmNtabWidgetClass, XmCTabWidgetClass,
|
|
XmRWidgetClass, sizeof(WidgetClass),
|
|
XtOffset(XmLFolderWidget, folder.tabWidgetClass),
|
|
XmRCallProc, (XtPointer)GetDefaultTabWidgetClass,
|
|
},
|
|
{
|
|
XmNactivateCallback, XmCCallback,
|
|
XmRCallback, sizeof(XtCallbackList),
|
|
XtOffset(XmLFolderWidget, folder.activateCallback),
|
|
XmRImmediate, (XtPointer)0,
|
|
},
|
|
{
|
|
XmNactiveTab, XmCActiveTab,
|
|
XmRInt, sizeof(int),
|
|
XtOffset(XmLFolderWidget, folder.activeTab),
|
|
XmRImmediate, (XtPointer)-1,
|
|
},
|
|
{
|
|
XmNautoSelect, XmCAutoSelect,
|
|
XmRBoolean, sizeof(Boolean),
|
|
XtOffset(XmLFolderWidget, folder.autoSelect),
|
|
XmRImmediate, (XtPointer)True,
|
|
},
|
|
{
|
|
XmNblankBackground, XmCBlankBackground,
|
|
XmRPixel, sizeof(Pixel),
|
|
XtOffset(XmLFolderWidget, folder.blankBg),
|
|
XmRCallProc, (XtPointer)GetCoreBackground,
|
|
},
|
|
{
|
|
XmNblankBackgroundPixmap, XmCBlankBackgroundPixmap,
|
|
XmRManForegroundPixmap, sizeof(Pixmap),
|
|
XtOffset(XmLFolderWidget, folder.blankPix),
|
|
XmRImmediate, (XtPointer)XmUNSPECIFIED_PIXMAP,
|
|
},
|
|
{
|
|
XmNcornerDimension, XmCCornerDimension,
|
|
XmRDimension, sizeof(Dimension),
|
|
XtOffset(XmLFolderWidget, folder.cornerDimension),
|
|
XmRImmediate, (XtPointer)2,
|
|
},
|
|
{
|
|
XmNcornerStyle, XmCCornerStyle,
|
|
XmRCornerStyle, sizeof(unsigned char),
|
|
XtOffset(XmLFolderWidget, folder.cornerStyle),
|
|
XmRImmediate, (XtPointer)XmCORNER_ARC,
|
|
},
|
|
{
|
|
XmNfontList, XmCFontList,
|
|
XmRFontList, sizeof(XmFontList),
|
|
XtOffset(XmLFolderWidget, folder.fontList),
|
|
XmRImmediate, (XtPointer)0,
|
|
},
|
|
{
|
|
XmNhighlightThickness, XmCHighlightThickness,
|
|
XmRDimension, sizeof(Dimension),
|
|
XtOffset(XmLFolderWidget, folder.highlightThickness),
|
|
XmRImmediate, (XtPointer)2,
|
|
},
|
|
{
|
|
XmNinactiveBackground, XmCInactiveBackground,
|
|
XmRPixel, sizeof(Pixel),
|
|
XtOffset(XmLFolderWidget, folder.inactiveBg),
|
|
XmRCallProc, (XtPointer)GetCoreBackground,
|
|
},
|
|
{
|
|
XmNinactiveForeground, XmCInactiveForeground,
|
|
XmRPixel, sizeof(Pixel),
|
|
XtOffset(XmLFolderWidget, folder.inactiveFg),
|
|
XmRCallProc, (XtPointer)GetManagerForeground,
|
|
},
|
|
{
|
|
XmNmarginHeight, XmCMarginHeight,
|
|
XmRDimension, sizeof(Dimension),
|
|
XtOffset(XmLFolderWidget, folder.marginHeight),
|
|
XmRImmediate, (XtPointer)0,
|
|
},
|
|
{
|
|
XmNmarginWidth, XmCMarginWidth,
|
|
XmRDimension, sizeof(Dimension),
|
|
XtOffset(XmLFolderWidget, folder.marginWidth),
|
|
XmRImmediate, (XtPointer)0,
|
|
},
|
|
{
|
|
XmNpixmapMargin, XmCPixmapMargin,
|
|
XmRDimension, sizeof(Dimension),
|
|
XtOffset(XmLFolderWidget, folder.pixmapMargin),
|
|
XmRImmediate, (XtPointer)2,
|
|
},
|
|
{
|
|
XmNresizePolicy, XmCFolderResizePolicy,
|
|
XmRFolderResizePolicy, sizeof(unsigned char),
|
|
XtOffset(XmLFolderWidget, folder.resizePolicy),
|
|
XmRImmediate, (XtPointer)XmRESIZE_STATIC,
|
|
},
|
|
{
|
|
XmNrotateWhenLeftRight, XmCRotateWhenLeftRight,
|
|
XmRBoolean, sizeof(Boolean),
|
|
XtOffset(XmLFolderWidget, folder.allowRotate),
|
|
XmRImmediate, (XtPointer)True,
|
|
},
|
|
{
|
|
XmNspacing, XmCSpacing,
|
|
XmRDimension, sizeof(Dimension),
|
|
XtOffset(XmLFolderWidget, folder.spacing),
|
|
XmRImmediate, (XtPointer)0,
|
|
},
|
|
{
|
|
XmNtabBarHeight, XmCTabBarHeight,
|
|
XmRDimension, sizeof(Dimension),
|
|
XtOffset(XmLFolderWidget, folder.tabBarHeight),
|
|
XmRImmediate, (XtPointer)0,
|
|
},
|
|
{
|
|
XmNtabCount, XmCTabCount,
|
|
XmRInt, sizeof(int),
|
|
XtOffset(XmLFolderWidget, folder.tabCount),
|
|
XmRImmediate, (XtPointer)0,
|
|
},
|
|
{
|
|
XmNtabPlacement, XmCTabPlacement,
|
|
XmRTabPlacement, sizeof(unsigned char),
|
|
XtOffset(XmLFolderWidget, folder.tabPlacement),
|
|
XmRImmediate, (XtPointer)XmFOLDER_TOP,
|
|
},
|
|
{
|
|
XmNtabsPerRow, XmCTabsPerRow,
|
|
XmRInt, sizeof(int),
|
|
XtOffset(XmLFolderWidget, folder.tabsPerRow),
|
|
XmRImmediate, (XtPointer)0,
|
|
},
|
|
{
|
|
XmNtabWidgetList, XmCReadOnly,
|
|
XmRPointer, sizeof(XtPointer),
|
|
XtOffset(XmLFolderWidget, folder.tabs),
|
|
XmRImmediate, (XtPointer)0,
|
|
},
|
|
{
|
|
XmNtabTranslations, XmCTranslations,
|
|
XmRTranslationTable, sizeof(XtTranslations),
|
|
XtOffset(XmLFolderWidget, folder.primTrans),
|
|
XmRString, (XtPointer)primTranslations,
|
|
},
|
|
{
|
|
XmNdebugLevel, XmCDebugLevel,
|
|
XmRInt, sizeof(int),
|
|
XtOffset(XmLFolderWidget, folder.debugLevel),
|
|
XmRImmediate, (XtPointer)0,
|
|
},
|
|
/* Overridden inherited resources */
|
|
{
|
|
XmNshadowThickness, XmCShadowThickness,
|
|
XmRHorizontalDimension, sizeof(Dimension),
|
|
XtOffset(XmLFolderWidget, manager.shadow_thickness),
|
|
XmRImmediate, (XtPointer)2,
|
|
},
|
|
};
|
|
|
|
static XtResource constraint_resources[] =
|
|
{
|
|
/* Folder Constraint Resources */
|
|
{
|
|
XmNtabFreePixmaps, XmCTabFreePixmaps,
|
|
XmRBoolean, sizeof(Boolean),
|
|
XtOffset(XmLFolderConstraintPtr, folder.freePix),
|
|
XmRImmediate, (XtPointer)False,
|
|
},
|
|
{
|
|
XmNtabInactivePixmap, XmCTabInactivePixmap,
|
|
XmRPrimForegroundPixmap, sizeof(Pixmap),
|
|
XtOffset(XmLFolderConstraintPtr, folder.inactPix),
|
|
XmRImmediate, (XtPointer)XmUNSPECIFIED_PIXMAP,
|
|
},
|
|
{
|
|
XmNtabManagedName, XmCTabManagedName,
|
|
XmRString, sizeof(char *),
|
|
XtOffset(XmLFolderConstraintPtr, folder.managedName),
|
|
XmRImmediate, (XtPointer)0,
|
|
},
|
|
{
|
|
XmNtabManagedWidget, XmCTabManagedWidget,
|
|
XmRWidget, sizeof(Widget),
|
|
XtOffset(XmLFolderConstraintPtr, folder.managedW),
|
|
XmRImmediate, (XtPointer)0,
|
|
},
|
|
{
|
|
XmNtabPixmap, XmCTabPixmap,
|
|
XmRPrimForegroundPixmap, sizeof(Pixmap),
|
|
XtOffset(XmLFolderConstraintPtr, folder.pix),
|
|
XmRImmediate, (XtPointer)XmUNSPECIFIED_PIXMAP,
|
|
},
|
|
};
|
|
|
|
XmLFolderClassRec xmlFolderClassRec =
|
|
{
|
|
{ /* core_class */
|
|
(WidgetClass)&xmManagerClassRec, /* superclass */
|
|
"XmLFolder", /* class_name */
|
|
sizeof(XmLFolderRec), /* widget_size */
|
|
ClassInitialize, /* class_init */
|
|
0, /* class_part_init */
|
|
FALSE, /* class_inited */
|
|
(XtInitProc)Initialize, /* initialize */
|
|
0, /* initialize_hook */
|
|
(XtRealizeProc)Realize, /* realize */
|
|
(XtActionList)actions, /* actions */
|
|
(Cardinal)XtNumber(actions), /* num_actions */
|
|
resources, /* resources */
|
|
XtNumber(resources), /* num_resources */
|
|
NULLQUARK, /* xrm_class */
|
|
TRUE, /* compress_motion */
|
|
XtExposeCompressMultiple, /* compress_exposure */
|
|
TRUE, /* compress_enterlv */
|
|
TRUE, /* visible_interest */
|
|
(XtWidgetProc)Destroy, /* destroy */
|
|
(XtWidgetProc)Resize, /* resize */
|
|
(XtExposeProc)Redisplay, /* expose */
|
|
(XtSetValuesFunc)SetValues, /* set_values */
|
|
0, /* set_values_hook */
|
|
XtInheritSetValuesAlmost, /* set_values_almost */
|
|
0, /* get_values_hook */
|
|
0, /* accept_focus */
|
|
XtVersion, /* version */
|
|
0, /* callback_private */
|
|
translations, /* tm_table */
|
|
0, /* query_geometry */
|
|
0, /* display_acceleratr */
|
|
0, /* extension */
|
|
},
|
|
{ /* composite_class */
|
|
(XtGeometryHandler)GeometryManager, /* geometry_manager */
|
|
(XtWidgetProc)ChangeManaged, /* change_managed */
|
|
XtInheritInsertChild, /* insert_child */
|
|
XtInheritDeleteChild, /* delete_child */
|
|
0, /* extension */
|
|
},
|
|
{ /* constraint_class */
|
|
constraint_resources, /* subresources */
|
|
XtNumber(constraint_resources), /* subresource_count */
|
|
sizeof(XmLFolderConstraintRec), /* constraint_size */
|
|
(XtInitProc)ConstraintInitialize, /* initialize */
|
|
(XtWidgetProc)ConstraintDestroy, /* destroy */
|
|
(XtSetValuesFunc)ConstraintSetValues, /* set_values */
|
|
0, /* extension */
|
|
},
|
|
{ /* manager_class */
|
|
XtInheritTranslations, /* translations */
|
|
0, /* syn resources */
|
|
0, /* num syn_resources */
|
|
0, /* get_cont_resources */
|
|
0, /* num_get_cont_resrc */
|
|
XmInheritParentProcess, /* parent_process */
|
|
0, /* extension */
|
|
},
|
|
{ /* folder_class */
|
|
0, /* unused */
|
|
}
|
|
};
|
|
|
|
WidgetClass xmlFolderWidgetClass = (WidgetClass)&xmlFolderClassRec;
|
|
|
|
/*
|
|
Create and Destroy
|
|
*/
|
|
|
|
static void
|
|
ClassInitialize(void)
|
|
{
|
|
XmLInitialize();
|
|
|
|
XtSetTypeConverter(XmRString, XmRCornerStyle,
|
|
CvtStringToCornerStyle, 0, 0, XtCacheNone, 0);
|
|
XtSetTypeConverter(XmRString, XmRFolderResizePolicy,
|
|
CvtStringToFolderResizePolicy, 0, 0, XtCacheNone, 0);
|
|
XtSetTypeConverter(XmRString, XmRTabPlacement,
|
|
CvtStringToTabPlacement, 0, 0, XtCacheNone, 0);
|
|
}
|
|
|
|
static void
|
|
Initialize(Widget req,
|
|
Widget newW,
|
|
ArgList args,
|
|
Cardinal *narg)
|
|
{
|
|
Display *dpy;
|
|
/* Window root;*/
|
|
XmLFolderWidget f, request;
|
|
|
|
f = (XmLFolderWidget)newW;
|
|
dpy = XtDisplay((Widget)f);
|
|
request = (XmLFolderWidget)req;
|
|
|
|
if (f->core.width <= 0)
|
|
f->core.width = 100;
|
|
if (f->core.height <= 0)
|
|
f->core.height = 100;
|
|
|
|
f->folder.gc = 0;
|
|
|
|
f->folder.tabAllocCount = 32;
|
|
f->folder.tabs = (Widget *)malloc(sizeof(Widget) * 32);
|
|
f->folder.tabHeight = 0;
|
|
f->folder.tabWidth = 0;
|
|
f->folder.activeW = 0;
|
|
f->folder.focusW = 0;
|
|
f->folder.allowLayout = 1;
|
|
f->folder.activeRow = -1;
|
|
CopyFontList(f);
|
|
|
|
if (f->folder.tabBarHeight)
|
|
{
|
|
XmLWarning((Widget)f, "Initialize() - can't set tabBarHeight");
|
|
f->folder.tabBarHeight = 0;
|
|
}
|
|
if (f->folder.tabCount)
|
|
{
|
|
XmLWarning((Widget)f, "Initialize() - can't set tabCount");
|
|
f->folder.tabCount = 0;
|
|
}
|
|
if (f->folder.activeTab != -1)
|
|
{
|
|
XmLWarning((Widget)f, "Initialize() - can't set activeTab");
|
|
f->folder.activeTab = -1;
|
|
}
|
|
if (f->folder.cornerDimension < 1)
|
|
{
|
|
XmLWarning((Widget)f, "Initialize() - cornerDimension can't be < 1");
|
|
f->folder.cornerDimension = 1;
|
|
}
|
|
f->folder.serverDrawsArcsLarge = ServerDrawsArcsLarge(dpy,
|
|
f->folder.debugLevel);
|
|
}
|
|
|
|
static void
|
|
Destroy(Widget w)
|
|
{
|
|
XmLFolderWidget f;
|
|
Display *dpy;
|
|
|
|
f = (XmLFolderWidget)w;
|
|
dpy = XtDisplay(w);
|
|
if (f->folder.debugLevel)
|
|
fprintf(stderr, "Folder destroy: \n");
|
|
if (f->folder.tabs)
|
|
free((char *)f->folder.tabs);
|
|
if (f->folder.gc)
|
|
XFreeGC(dpy, f->folder.gc);
|
|
XmFontListFree(f->folder.fontList);
|
|
}
|
|
|
|
/*
|
|
Geometry, Drawing, Entry and Picking
|
|
*/
|
|
|
|
static void
|
|
Realize(Widget w,
|
|
XtValueMask *valueMask,
|
|
XSetWindowAttributes *attr)
|
|
{
|
|
XmLFolderWidget f;
|
|
Display *dpy;
|
|
WidgetClass superClass;
|
|
XtRealizeProc realize;
|
|
XGCValues values;
|
|
XtGCMask mask;
|
|
|
|
f = (XmLFolderWidget)w;
|
|
dpy = XtDisplay(f);
|
|
superClass = xmlFolderWidgetClass->core_class.superclass;
|
|
realize = superClass->core_class.realize;
|
|
(*realize)(w, valueMask, attr);
|
|
|
|
if (!f->folder.gc)
|
|
{
|
|
values.foreground = f->manager.foreground;
|
|
mask = GCForeground;
|
|
f->folder.gc = XCreateGC(dpy, XtWindow(f), mask, &values);
|
|
if (f->folder.autoSelect == True && f->folder.tabCount)
|
|
XmLFolderSetActiveTab(w, 0, False);
|
|
}
|
|
}
|
|
|
|
static void
|
|
Redisplay(Widget w,
|
|
XExposeEvent *event,
|
|
Region region)
|
|
{
|
|
Display *dpy;
|
|
Window win;
|
|
XmLFolderWidget f;
|
|
XmLFolderConstraintRec *fc;
|
|
XRectangle eRect, rRect, rect;
|
|
/* XSegment *topSeg, *botSeg; */
|
|
/* int tCount, bCount; */
|
|
Widget tab;
|
|
int i, st, ht; /*, x, y; */
|
|
|
|
f = (XmLFolderWidget)w;
|
|
if (!XtIsRealized(w))
|
|
return;
|
|
if (!f->core.visible)
|
|
return;
|
|
dpy = XtDisplay(f);
|
|
win = XtWindow(f);
|
|
st = f->manager.shadow_thickness;
|
|
ht = f->folder.highlightThickness;
|
|
|
|
if (event)
|
|
{
|
|
eRect.x = event->x;
|
|
eRect.y = event->y;
|
|
eRect.width = event->width;
|
|
eRect.height = event->height;
|
|
if (f->folder.debugLevel > 1)
|
|
fprintf(stderr, "XmLFolder: Redisplay x %d y %d w %d h %d\n",
|
|
event->x, event->y, event->width, event->height);
|
|
}
|
|
else
|
|
{
|
|
eRect.x = 0;
|
|
eRect.y = 0;
|
|
eRect.width = f->core.width;
|
|
eRect.height = f->core.height;
|
|
}
|
|
if (!eRect.width || !eRect.height)
|
|
return;
|
|
|
|
if (f->folder.tabPlacement == XmFOLDER_TOP)
|
|
{
|
|
rRect.x = 0;
|
|
rRect.y = f->folder.tabHeight;
|
|
rRect.width = f->core.width;
|
|
rRect.height = f->core.height - f->folder.tabHeight;
|
|
}
|
|
else if (f->folder.tabPlacement == XmFOLDER_BOTTOM)
|
|
{
|
|
rRect.x = 0;
|
|
rRect.y = 0;
|
|
rRect.width = f->core.width;
|
|
rRect.height = f->core.height - f->folder.tabHeight;
|
|
}
|
|
if (f->folder.tabPlacement == XmFOLDER_LEFT)
|
|
{
|
|
rRect.x = f->folder.tabWidth;
|
|
rRect.y = 0;
|
|
rRect.width = f->core.width - f->folder.tabWidth;
|
|
rRect.height = f->core.height;
|
|
}
|
|
if (f->folder.tabPlacement == XmFOLDER_RIGHT)
|
|
{
|
|
rRect.x = 0;
|
|
rRect.y = 0;
|
|
rRect.width = f->core.width - f->folder.tabWidth;
|
|
rRect.height = f->core.height;
|
|
}
|
|
if (XmLRectIntersect(&eRect, &rRect) != XmLRectOutside)
|
|
{
|
|
if (f->folder.tabPlacement == XmFOLDER_TOP ||
|
|
f->folder.tabPlacement == XmFOLDER_BOTTOM)
|
|
DrawManagerShadowTopBottom(f, &rRect);
|
|
else
|
|
DrawManagerShadowLeftRight(f, &rRect);
|
|
}
|
|
|
|
if (!f->folder.tabCount)
|
|
return;
|
|
|
|
rRect.x = 0;
|
|
rRect.y = 0;
|
|
rRect.width = 0;
|
|
rRect.height = 0;
|
|
|
|
/* Draw tabs */
|
|
for (i = 0; i < f->folder.tabCount; i++)
|
|
{
|
|
tab = f->folder.tabs[i];
|
|
if (!XtIsManaged(tab))
|
|
continue;
|
|
fc = (XmLFolderConstraintRec *)(tab->core.constraints);
|
|
GetTabRect(f, tab, &rRect, 0);
|
|
|
|
/* include spacing in intersect test */
|
|
rect = rRect;
|
|
if (f->folder.tabPlacement == XmFOLDER_TOP ||
|
|
f->folder.tabPlacement == XmFOLDER_BOTTOM)
|
|
rect.width += f->folder.spacing;
|
|
else
|
|
rect.height += f->folder.spacing;
|
|
|
|
/* include indent in intersect test */
|
|
if (f->folder.tabsPerRow)
|
|
{
|
|
if (rRect.x == 2)
|
|
rect.x = 0;
|
|
if (rRect.y == 2)
|
|
rect.y = 0;
|
|
if (rRect.x + rRect.width == f->core.width - 2)
|
|
rect.width += 2;
|
|
if (rRect.y + rRect.height == f->core.height - 2)
|
|
rect.height += 2;
|
|
}
|
|
|
|
if (XmLRectIntersect(&eRect, &rect) == XmLRectOutside)
|
|
continue;
|
|
if (event && XRectInRegion(region, rect.x, rect.y,
|
|
rect.width, rect.height) == RectangleOut)
|
|
continue;
|
|
|
|
if (f->folder.debugLevel > 1)
|
|
fprintf(stderr, "XmLFolder: Redisplay tab for widget %d\n", i);
|
|
if (tab == f->folder.activeW)
|
|
{
|
|
XtVaSetValues(tab,
|
|
XmNbackground, f->core.background_pixel,
|
|
XmNforeground, f->manager.foreground,
|
|
NULL);
|
|
}
|
|
else
|
|
{
|
|
XSetForeground(dpy, f->folder.gc, f->folder.inactiveBg);
|
|
XFillRectangle(dpy, win, f->folder.gc,
|
|
rRect.x, rRect.y, rRect.width, rRect.height);
|
|
XtVaSetValues(tab,
|
|
XmNbackground, f->folder.inactiveBg,
|
|
XmNforeground, f->folder.inactiveFg,
|
|
NULL);
|
|
}
|
|
|
|
if (f->folder.tabPlacement == XmFOLDER_TOP ||
|
|
f->folder.tabPlacement == XmFOLDER_BOTTOM)
|
|
{
|
|
if (f->folder.cornerStyle == XmCORNER_LINE)
|
|
DrawTabShadowLineTopBottom(f, tab);
|
|
else if (f->folder.cornerStyle == XmCORNER_ARC)
|
|
DrawTabShadowArcTopBottom(f, tab);
|
|
else
|
|
DrawTabShadowNoneTopBottom(f, tab);
|
|
}
|
|
else
|
|
{
|
|
if (f->folder.cornerStyle == XmCORNER_LINE)
|
|
DrawTabShadowLineLeftRight(f, tab);
|
|
else if (f->folder.cornerStyle == XmCORNER_ARC)
|
|
DrawTabShadowArcLeftRight(f, tab);
|
|
else
|
|
DrawTabShadowNoneLeftRight(f, tab);
|
|
}
|
|
|
|
if (f->folder.focusW == tab)
|
|
DrawTabHighlight(f, tab);
|
|
|
|
if (tab == f->folder.activeW &&
|
|
fc->folder.pix != XmUNSPECIFIED_PIXMAP &&
|
|
(fc->folder.maxPixWidth || fc->folder.maxPixHeight))
|
|
DrawTabPixmap(f, tab, 1);
|
|
else if (tab != f->folder.activeW &&
|
|
fc->folder.inactPix != XmUNSPECIFIED_PIXMAP &&
|
|
(fc->folder.maxPixWidth || fc->folder.maxPixHeight))
|
|
DrawTabPixmap(f, tab, 0);
|
|
|
|
SetGC(f, GC_BLANK);
|
|
|
|
/* draw indent */
|
|
if (f->folder.tabsPerRow)
|
|
{
|
|
if (rRect.x == 2)
|
|
{
|
|
rect = rRect;
|
|
rect.x = 0;
|
|
rect.width = 2;
|
|
XFillRectangle(dpy, win, f->folder.gc, rect.x, rect.y,
|
|
rect.width, rect.height);
|
|
}
|
|
if (rRect.y == 2)
|
|
{
|
|
rect = rRect;
|
|
rect.y = 0;
|
|
rect.height = 2;
|
|
XFillRectangle(dpy, win, f->folder.gc, rect.x, rect.y,
|
|
rect.width, rect.height);
|
|
}
|
|
if (rRect.x + rRect.width == f->core.width - 2)
|
|
{
|
|
rect = rRect;
|
|
rect.x = f->core.width - 2;
|
|
rect.width = 2;
|
|
XFillRectangle(dpy, win, f->folder.gc, rect.x, rect.y,
|
|
rect.width, rect.height);
|
|
}
|
|
if (rRect.y + rRect.height == f->core.height - 2)
|
|
{
|
|
rect = rRect;
|
|
rect.y = f->core.height - 2;
|
|
rect.height = 2;
|
|
XFillRectangle(dpy, win, f->folder.gc, rect.x, rect.y,
|
|
rect.width, rect.height);
|
|
}
|
|
}
|
|
|
|
if (f->folder.spacing)
|
|
{
|
|
if (f->folder.tabPlacement == XmFOLDER_TOP ||
|
|
f->folder.tabPlacement == XmFOLDER_BOTTOM)
|
|
XFillRectangle(dpy, win, f->folder.gc, rRect.x + rRect.width,
|
|
rRect.y, f->folder.spacing, rRect.height);
|
|
else
|
|
XFillRectangle(dpy, win, f->folder.gc, rRect.x,
|
|
rRect.y + rRect.height, rRect.width, f->folder.spacing);
|
|
}
|
|
|
|
SetGC(f, GC_UNSET);
|
|
}
|
|
|
|
/* Draw empty area */
|
|
if (!f->folder.tabsPerRow)
|
|
{
|
|
if (f->folder.tabPlacement == XmFOLDER_TOP ||
|
|
f->folder.tabPlacement == XmFOLDER_BOTTOM)
|
|
{
|
|
rRect.x += rRect.width + f->folder.spacing;
|
|
if ((int)f->core.width > rRect.x)
|
|
{
|
|
if (f->folder.tabPlacement == XmFOLDER_TOP)
|
|
rRect.y = 0;
|
|
else
|
|
rRect.y = f->core.height - f->folder.tabHeight;
|
|
rRect.width = f->core.width - rRect.x;
|
|
rRect.height = f->folder.tabHeight;
|
|
SetGC(f, GC_BLANK);
|
|
XFillRectangle(dpy, win, f->folder.gc,
|
|
rRect.x, rRect.y, rRect.width, rRect.height);
|
|
SetGC(f, GC_UNSET);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
rRect.y += rRect.height + f->folder.spacing;
|
|
if ((int)f->core.height > rRect.y)
|
|
{
|
|
if (f->folder.tabPlacement == XmFOLDER_LEFT)
|
|
rRect.x = 0;
|
|
else
|
|
rRect.x = f->core.width - f->folder.tabWidth;
|
|
rRect.width = f->folder.tabWidth;
|
|
rRect.height = f->core.height - rRect.y;
|
|
SetGC(f, GC_BLANK);
|
|
XFillRectangle(dpy, win, f->folder.gc,
|
|
rRect.x, rRect.y, rRect.width, rRect.height);
|
|
SetGC(f, GC_UNSET);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
Layout(XmLFolderWidget f,
|
|
int resizeIfNeeded)
|
|
{
|
|
/* Window win;*/
|
|
|
|
if (!f->folder.allowLayout)
|
|
return;
|
|
f->folder.allowLayout = 0;
|
|
if (f->folder.tabPlacement == XmFOLDER_LEFT ||
|
|
f->folder.tabPlacement == XmFOLDER_RIGHT)
|
|
LayoutLeftRight(f, resizeIfNeeded);
|
|
else
|
|
LayoutTopBottom(f, resizeIfNeeded);
|
|
if (XtIsRealized((Widget)f) && f->core.visible)
|
|
XClearArea(XtDisplay(f), XtWindow(f), 0, 0, 0, 0, True);
|
|
f->folder.allowLayout = 1;
|
|
}
|
|
|
|
static void
|
|
LayoutTopBottom(XmLFolderWidget f,
|
|
int resizeIfNeeded)
|
|
{
|
|
Display *dpy;
|
|
Window root;
|
|
int i, tabNum, x, y, w, h, pad1, pad2;
|
|
int rowNum, numRows, rowHeight, rowX, rowY;
|
|
WidgetList children;
|
|
Widget tab, child;
|
|
XmLFolderConstraintRec *fc;
|
|
XtGeometryResult result;
|
|
unsigned int inactPixHeight, pixHeight;
|
|
unsigned int inactPixWidth, pixWidth;
|
|
unsigned int pixBW, pixDepth;
|
|
Dimension height, minHeight;
|
|
Dimension width, minWidth, borderWidth;
|
|
Dimension co;
|
|
int st, ht;
|
|
Boolean map, isManaged;
|
|
struct
|
|
{
|
|
int width, height, numTabs, y;
|
|
} rows[MAX_TAB_ROWS];
|
|
|
|
dpy = XtDisplay(f);
|
|
children = f->composite.children;
|
|
st = f->manager.shadow_thickness;
|
|
ht = f->folder.highlightThickness;
|
|
|
|
/* calculate corner offset */
|
|
if (f->folder.cornerStyle == XmCORNER_LINE)
|
|
co = (Dimension)((double)f->folder.cornerDimension * .5 + .99);
|
|
else if (f->folder.cornerStyle == XmCORNER_ARC)
|
|
co = (Dimension)((double)f->folder.cornerDimension * .3 + .99);
|
|
else
|
|
co = 0;
|
|
|
|
/* caculate tabHeight, minWidth, minHeight, row y positions, */
|
|
/* row heights and tab pixmap dimensions */
|
|
rowX = 0;
|
|
rowY = 0;
|
|
rowHeight = 0;
|
|
rowNum = 0;
|
|
tabNum = 0;
|
|
minWidth = 0;
|
|
for (i = 0; i < f->folder.tabCount; i++)
|
|
{
|
|
tab = f->folder.tabs[i];
|
|
if (!XtIsManaged(tab))
|
|
continue;
|
|
fc = (XmLFolderConstraintRec *)(tab->core.constraints);
|
|
|
|
/* check for start of a new row */
|
|
fc->folder.firstInRow = False;
|
|
if (!tabNum)
|
|
fc->folder.firstInRow = True;
|
|
if (f->folder.tabsPerRow && tabNum == f->folder.tabsPerRow)
|
|
{
|
|
fc->folder.firstInRow = True;
|
|
|
|
/* store prev row values and start next row */
|
|
if (rowX)
|
|
rowX -= f->folder.spacing;
|
|
rows[rowNum].y = rowY;
|
|
rows[rowNum].width = rowX;
|
|
rows[rowNum].height = rowHeight;
|
|
rows[rowNum].numTabs = tabNum;
|
|
if (f->folder.debugLevel)
|
|
{
|
|
fprintf(stderr, "XmLFolder: Layout: ");
|
|
fprintf(stderr, "row %d: y %d w %d h %d numTabs %d\n",
|
|
rowNum, rowY, rowX, rowHeight, tabNum);
|
|
}
|
|
rowY += rowHeight;
|
|
rowHeight = 0;
|
|
if (rowX > (int)minWidth)
|
|
minWidth = rowX;
|
|
rowX = 0;
|
|
tabNum = 0;
|
|
rowNum++;
|
|
if (rowNum == MAX_TAB_ROWS - 1)
|
|
{
|
|
XmLWarning((Widget)f, "Layout ERROR - too many rows\n");
|
|
return;
|
|
}
|
|
}
|
|
|
|
/* make sure row height > maximum tab height */
|
|
height = co + st + tab->core.height + tab->core.border_width * 2 +
|
|
f->folder.marginHeight * 2 + ht * 2;
|
|
if ((int)height > rowHeight)
|
|
rowHeight = height;
|
|
|
|
/* calc pixmap dimensions/maximum pixmap height */
|
|
fc->folder.pixWidth = 0;
|
|
fc->folder.pixHeight = 0;
|
|
fc->folder.inactPixWidth = 0;
|
|
fc->folder.inactPixHeight = 0;
|
|
fc->folder.maxPixWidth = 0;
|
|
fc->folder.maxPixHeight = 0;
|
|
if (fc->folder.pix != XmUNSPECIFIED_PIXMAP)
|
|
{
|
|
XGetGeometry(dpy, fc->folder.pix, &root,
|
|
&x, &y, &pixWidth, &pixHeight, &pixBW, &pixDepth);
|
|
fc->folder.pixWidth = pixWidth;
|
|
fc->folder.maxPixWidth = pixWidth;
|
|
fc->folder.pixHeight = pixHeight;
|
|
fc->folder.maxPixHeight = pixHeight;
|
|
height = co + st + pixHeight + f->folder.marginHeight * 2 + ht * 2;
|
|
if ((int)height > rowHeight)
|
|
rowHeight = height;
|
|
}
|
|
if (fc->folder.inactPix != XmUNSPECIFIED_PIXMAP)
|
|
{
|
|
XGetGeometry(dpy, fc->folder.inactPix, &root, &x, &y,
|
|
&inactPixWidth, &inactPixHeight, &pixBW, &pixDepth);
|
|
fc->folder.inactPixWidth = inactPixWidth;
|
|
if (inactPixWidth > fc->folder.maxPixWidth)
|
|
fc->folder.maxPixWidth = inactPixWidth;
|
|
fc->folder.inactPixHeight = inactPixHeight;
|
|
if (inactPixHeight > fc->folder.maxPixHeight)
|
|
fc->folder.maxPixHeight = inactPixHeight;
|
|
height = co + st + inactPixHeight +
|
|
f->folder.marginHeight * 2 + ht * 2;
|
|
if ((int)height > rowHeight)
|
|
rowHeight = height;
|
|
}
|
|
|
|
/* increment rowX to move on to the next tab */
|
|
rowX += st * 2 + co * 2 + f->folder.marginWidth * 2 + ht * 2 +
|
|
XtWidth(tab) + tab->core.border_width * 2;
|
|
if (fc->folder.maxPixWidth)
|
|
rowX += fc->folder.maxPixWidth + f->folder.pixmapMargin;
|
|
rowX += f->folder.spacing;
|
|
|
|
tabNum++;
|
|
fc->folder.row = rowNum;
|
|
}
|
|
|
|
/* complete calcuations for last row */
|
|
if (rowX)
|
|
rowX -= f->folder.spacing;
|
|
rows[rowNum].y = rowY;
|
|
rows[rowNum].width = rowX;
|
|
rows[rowNum].height = rowHeight;
|
|
rows[rowNum].numTabs = tabNum;
|
|
numRows = rowNum + 1;
|
|
if (f->folder.debugLevel)
|
|
{
|
|
fprintf(stderr, "XmLFolder: Layout: ");
|
|
fprintf(stderr, "row %d: y %d w %d h %d numTabs %d\n",
|
|
rowNum, rowY, rowX, rowHeight, tabNum);
|
|
}
|
|
f->folder.tabHeight = rowY + rowHeight;
|
|
f->folder.tabBarHeight = f->folder.tabHeight;
|
|
minHeight = f->folder.tabHeight;
|
|
if ((int)minWidth < rowX)
|
|
minWidth = rowX;
|
|
|
|
/* add space for indent of upper rows */
|
|
if (f->folder.tabsPerRow && minWidth)
|
|
minWidth += 4;
|
|
|
|
if (f->folder.debugLevel)
|
|
{
|
|
fprintf(stderr, "XmLFolder: Layout: ");
|
|
fprintf(stderr, "tab bar minimum w %d h %d\n",
|
|
(int)minWidth, (int)minHeight);
|
|
}
|
|
|
|
/* calculate width and height of non-tab children ensure */
|
|
/* minWidth > width and minHeight > height */
|
|
for (i = 0; i < f->composite.num_children; i++)
|
|
{
|
|
child = children[i];
|
|
if (XtIsSubclass(child, xmPrimitiveWidgetClass))
|
|
continue;
|
|
|
|
height = XtHeight(child) + f->folder.tabHeight + st * 2;
|
|
if (XtIsWidget(child))
|
|
height += child->core.border_width * 2;
|
|
if (height > minHeight)
|
|
minHeight = height;
|
|
|
|
width = XtWidth(child) + st * 2;
|
|
if (XtIsWidget(child))
|
|
width += child->core.border_width * 2;
|
|
if (width > minWidth)
|
|
minWidth = width;
|
|
}
|
|
|
|
if (f->folder.debugLevel)
|
|
{
|
|
fprintf(stderr, "XmLFolder: Layout: ");
|
|
fprintf(stderr, "with non-tabs minimum w %d h %d\n",
|
|
(int)minWidth, (int)minHeight);
|
|
}
|
|
|
|
/* Resize folder if needed */
|
|
if (resizeIfNeeded && f->folder.resizePolicy != XmRESIZE_NONE)
|
|
{
|
|
if (minWidth <= 0)
|
|
minWidth = 1;
|
|
if (minHeight <= 0)
|
|
minHeight = 1;
|
|
result = XtMakeResizeRequest((Widget)f, minWidth, minHeight,
|
|
&width, &height);
|
|
if (result == XtGeometryAlmost)
|
|
XtMakeResizeRequest((Widget)f, width, height, NULL, NULL);
|
|
}
|
|
|
|
/* move active row to bottom */
|
|
tab = f->folder.activeW;
|
|
if (tab)
|
|
{
|
|
fc = (XmLFolderConstraintRec *)(tab->core.constraints);
|
|
rowNum = fc->folder.row;
|
|
f->folder.activeRow = rowNum;
|
|
rows[rowNum].y = f->folder.tabHeight - rows[rowNum].height;
|
|
for (i = rowNum + 1; i < numRows; i++)
|
|
rows[i].y -= rows[rowNum].height;
|
|
}
|
|
else
|
|
f->folder.activeRow = -1;
|
|
|
|
/* configure tab children */
|
|
for (i = 0; i < f->folder.tabCount; i++)
|
|
{
|
|
tab = f->folder.tabs[i];
|
|
if (!XtIsManaged(tab))
|
|
continue;
|
|
fc = (XmLFolderConstraintRec *)(tab->core.constraints);
|
|
rowNum = fc->folder.row;
|
|
|
|
/* calculate tab x */
|
|
if (fc->folder.firstInRow == True)
|
|
{
|
|
if (f->folder.tabsPerRow && rowNum != f->folder.activeRow)
|
|
x = 2;
|
|
else
|
|
x = 0;
|
|
}
|
|
fc->folder.x = x;
|
|
x += st + co + f->folder.marginWidth + ht;
|
|
if (fc->folder.maxPixWidth)
|
|
x += fc->folder.maxPixWidth + f->folder.pixmapMargin;
|
|
|
|
/* calculate tab y and tab height */
|
|
fc->folder.height = rows[rowNum].height;
|
|
if (f->folder.tabPlacement == XmFOLDER_TOP)
|
|
{
|
|
fc->folder.y = rows[rowNum].y;
|
|
y = fc->folder.y + fc->folder.height - f->folder.marginHeight -
|
|
ht - XtHeight(tab) - tab->core.border_width * 2;
|
|
}
|
|
else
|
|
{
|
|
fc->folder.y = f->core.height - rows[rowNum].y -
|
|
rows[rowNum].height;
|
|
y = fc->folder.y + f->folder.marginHeight + ht;
|
|
}
|
|
|
|
/* calculate tab padding */
|
|
pad1 = 0;
|
|
pad2 = 0;
|
|
w = f->core.width - rows[rowNum].width;
|
|
if (rowNum != f->folder.activeRow)
|
|
w -= 4;
|
|
if (f->folder.tabsPerRow && w > 0)
|
|
{
|
|
pad1 = w / (rows[rowNum].numTabs * 2);
|
|
pad2 = pad1;
|
|
if (fc->folder.firstInRow == True)
|
|
pad2 += w - (pad1 * rows[rowNum].numTabs * 2);
|
|
}
|
|
x += pad1;
|
|
|
|
/* move tab widget into place */
|
|
XtMoveWidget(tab, x, y);
|
|
|
|
/* calculate tab width and move to next tab */
|
|
x += pad2 + XtWidth(tab) + tab->core.border_width * 2 + ht +
|
|
f->folder.marginWidth + co + st;
|
|
fc->folder.width = x - fc->folder.x;
|
|
x += f->folder.spacing;
|
|
}
|
|
|
|
/* configure non-tab children */
|
|
for (i = 0; i < f->composite.num_children; i++)
|
|
{
|
|
child = children[i];
|
|
if (XtIsSubclass(child, xmPrimitiveWidgetClass))
|
|
continue;
|
|
if (f->folder.resizePolicy == XmRESIZE_NONE)
|
|
continue;
|
|
|
|
w = (int)f->core.width - st * 2;
|
|
h = (int)f->core.height - (int)f->folder.tabHeight - st * 2;
|
|
if (h <= 0 || w <= 0)
|
|
continue;
|
|
/* manager widgets will not configure correctly unless they */
|
|
/* are managed, so manage then unmapped if they are unmanaged */
|
|
isManaged = True;
|
|
if (!XtIsManaged(child))
|
|
{
|
|
XtVaGetValues(child,
|
|
XmNmappedWhenManaged, &map,
|
|
NULL);
|
|
XtVaSetValues(child,
|
|
XmNmappedWhenManaged, False,
|
|
NULL);
|
|
XtManageChild(child);
|
|
isManaged = False;
|
|
}
|
|
x = st;
|
|
if (f->folder.tabPlacement == XmFOLDER_TOP)
|
|
y = f->folder.tabHeight + st;
|
|
else
|
|
y = st;
|
|
width = w;
|
|
height = h;
|
|
borderWidth = 0;
|
|
if (XtIsWidget(child))
|
|
borderWidth = child->core.border_width;
|
|
XtConfigureWidget(child, x, y, width, height, borderWidth);
|
|
if (isManaged == False)
|
|
{
|
|
XtUnmanageChild(child);
|
|
XtVaSetValues(child, XmNmappedWhenManaged, map, NULL);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
LayoutLeftRight(XmLFolderWidget f,
|
|
int resizeIfNeeded)
|
|
{
|
|
Display *dpy;
|
|
Window root;
|
|
int i, tabNum, x, y, w, h, pad1, pad2;
|
|
int rowNum, numRows, rowWidth, rowX, rowY;
|
|
WidgetList children;
|
|
Widget tab, child;
|
|
XmLFolderConstraintRec *fc;
|
|
XtGeometryResult result;
|
|
unsigned int inactPixHeight, pixHeight;
|
|
unsigned int inactPixWidth, pixWidth;
|
|
unsigned int pixBW, pixDepth;
|
|
Dimension height, minHeight;
|
|
Dimension width, minWidth, borderWidth;
|
|
Dimension co;
|
|
int st, ht;
|
|
Boolean map, isManaged;
|
|
struct
|
|
{
|
|
int width, height, numTabs, x;
|
|
} rows[MAX_TAB_ROWS];
|
|
|
|
dpy = XtDisplay(f);
|
|
children = f->composite.children;
|
|
st = f->manager.shadow_thickness;
|
|
ht = f->folder.highlightThickness;
|
|
|
|
/* calculate corner offset */
|
|
if (f->folder.cornerStyle == XmCORNER_LINE)
|
|
co = (Dimension)((double)f->folder.cornerDimension * .5 + .99);
|
|
else if (f->folder.cornerStyle == XmCORNER_ARC)
|
|
co = (Dimension)((double)f->folder.cornerDimension * .3 + .99);
|
|
else
|
|
co = 0;
|
|
|
|
/* caculate tabWidth, minWidth, minHeight, row x positions, */
|
|
/* row widths and tab pixmap dimensions */
|
|
rowX = 0;
|
|
rowY = 0;
|
|
rowWidth = 0;
|
|
rowNum = 0;
|
|
tabNum = 0;
|
|
minHeight = 0;
|
|
for (i = 0; i < f->folder.tabCount; i++)
|
|
{
|
|
tab = f->folder.tabs[i];
|
|
if (!XtIsManaged(tab))
|
|
continue;
|
|
fc = (XmLFolderConstraintRec *)(tab->core.constraints);
|
|
|
|
/* check for start of a new row */
|
|
fc->folder.firstInRow = False;
|
|
if (!tabNum)
|
|
fc->folder.firstInRow = True;
|
|
if (f->folder.tabsPerRow && tabNum == f->folder.tabsPerRow)
|
|
{
|
|
fc->folder.firstInRow = True;
|
|
|
|
/* store prev row values and start next row */
|
|
if (rowY)
|
|
rowY -= f->folder.spacing;
|
|
rows[rowNum].x = rowX;
|
|
rows[rowNum].height = rowY;
|
|
rows[rowNum].width = rowWidth;
|
|
rows[rowNum].numTabs = tabNum;
|
|
if (f->folder.debugLevel)
|
|
{
|
|
fprintf(stderr, "XmLFolder: Layout: ");
|
|
fprintf(stderr, "row %d: x %d w %d h %d numTabs %d\n",
|
|
rowNum, rowX, rowWidth, rowY, tabNum);
|
|
}
|
|
rowX += rowWidth;
|
|
rowWidth = 0;
|
|
if (rowY > (int)minHeight)
|
|
minHeight = rowY;
|
|
rowY = 0;
|
|
tabNum = 0;
|
|
rowNum++;
|
|
if (rowNum == MAX_TAB_ROWS - 1)
|
|
{
|
|
XmLWarning((Widget)f, "Layout ERROR - too many rows\n");
|
|
return;
|
|
}
|
|
}
|
|
|
|
/* make sure row width > maximum tab width */
|
|
width = co + st + tab->core.width + tab->core.border_width * 2 +
|
|
f->folder.marginHeight * 2 + ht * 2;
|
|
if ((int)width > rowWidth)
|
|
rowWidth = width;
|
|
|
|
/* calc pixmap dimensions/maximum pixmap width */
|
|
pixWidth = 0;
|
|
pixHeight = 0;
|
|
fc->folder.pixWidth = 0;
|
|
fc->folder.pixHeight = 0;
|
|
fc->folder.inactPixWidth = 0;
|
|
fc->folder.inactPixHeight = 0;
|
|
fc->folder.maxPixWidth = 0;
|
|
fc->folder.maxPixHeight = 0;
|
|
if (fc->folder.pix != XmUNSPECIFIED_PIXMAP)
|
|
{
|
|
XGetGeometry(dpy, fc->folder.pix, &root,
|
|
&x, &y, &pixWidth, &pixHeight, &pixBW, &pixDepth);
|
|
fc->folder.pixWidth = pixWidth;
|
|
fc->folder.maxPixWidth = pixWidth;
|
|
fc->folder.pixHeight = pixHeight;
|
|
fc->folder.maxPixHeight = pixHeight;
|
|
width = co + st + pixWidth + f->folder.marginHeight * 2 + ht * 2;
|
|
if ((int)width > rowWidth)
|
|
rowWidth = width;
|
|
}
|
|
if (fc->folder.inactPix != XmUNSPECIFIED_PIXMAP)
|
|
{
|
|
XGetGeometry(dpy, fc->folder.inactPix, &root, &x, &y,
|
|
&inactPixWidth, &inactPixHeight, &pixBW, &pixDepth);
|
|
fc->folder.inactPixWidth = inactPixWidth;
|
|
if (inactPixWidth > fc->folder.maxPixWidth)
|
|
fc->folder.maxPixWidth = inactPixWidth;
|
|
fc->folder.inactPixHeight = inactPixHeight;
|
|
if (inactPixHeight > fc->folder.maxPixHeight)
|
|
fc->folder.maxPixHeight = inactPixHeight;
|
|
width = co + st + inactPixWidth +
|
|
f->folder.marginHeight * 2 + ht * 2;
|
|
if ((int)width > rowWidth)
|
|
rowWidth = width;
|
|
}
|
|
|
|
/* increment rowY to move on to the next tab */
|
|
rowY += st * 2 + co * 2 + f->folder.marginWidth * 2 + ht * 2 +
|
|
XtHeight(tab) + tab->core.border_width * 2;
|
|
|
|
if (fc->folder.maxPixHeight)
|
|
rowY += fc->folder.maxPixHeight + f->folder.pixmapMargin;
|
|
rowY += f->folder.spacing;
|
|
|
|
tabNum++;
|
|
fc->folder.row = rowNum;
|
|
}
|
|
|
|
/* complete calcuations for last row */
|
|
if (rowY)
|
|
rowY -= f->folder.spacing;
|
|
rows[rowNum].x = rowX;
|
|
rows[rowNum].height = rowY;
|
|
rows[rowNum].width = rowWidth;
|
|
rows[rowNum].numTabs = tabNum;
|
|
numRows = rowNum + 1;
|
|
if (f->folder.debugLevel)
|
|
{
|
|
fprintf(stderr, "XmLFolder: Layout: ");
|
|
fprintf(stderr, "row %d: x %d w %d h %d numTabs %d\n",
|
|
rowNum, rowX, rowWidth, rowY, tabNum);
|
|
}
|
|
f->folder.tabWidth = rowX + rowWidth;
|
|
f->folder.tabBarHeight = f->folder.tabWidth;
|
|
minWidth = f->folder.tabWidth;
|
|
if ((int)minHeight < rowY)
|
|
minHeight = rowY;
|
|
|
|
/* add space for indent of upper rows */
|
|
if (f->folder.tabsPerRow && minHeight)
|
|
minHeight += 4;
|
|
|
|
if (f->folder.debugLevel)
|
|
{
|
|
fprintf(stderr, "XmLFolder: Layout: ");
|
|
fprintf(stderr, "tab bar minimum w %d h %d\n",
|
|
(int)minWidth, (int)minHeight);
|
|
}
|
|
|
|
/* calculate width and height of non-tab children ensure */
|
|
/* minWidth > width and minHeight > height */
|
|
for (i = 0; i < f->composite.num_children; i++)
|
|
{
|
|
child = children[i];
|
|
if (XtIsSubclass(child, xmPrimitiveWidgetClass))
|
|
continue;
|
|
|
|
height = XtHeight(child) + st * 2;
|
|
if (XtIsWidget(child))
|
|
height += f->core.border_width * 2;
|
|
if (height > minHeight)
|
|
minHeight = height;
|
|
|
|
width = XtWidth(child) + f->folder.tabWidth + st * 2;
|
|
if (XtIsWidget(child))
|
|
width += f->core.border_width * 2;
|
|
if (width > minWidth)
|
|
minWidth = width;
|
|
}
|
|
|
|
if (f->folder.debugLevel)
|
|
{
|
|
fprintf(stderr, "XmLFolder: Layout: ");
|
|
fprintf(stderr, "with non-tabs minimum w %d h %d\n",
|
|
(int)minWidth, (int)minHeight);
|
|
}
|
|
|
|
/* Resize folder if needed */
|
|
if (resizeIfNeeded && f->folder.resizePolicy != XmRESIZE_NONE)
|
|
{
|
|
if (minWidth <= 0)
|
|
minWidth = 1;
|
|
if (minHeight <= 0)
|
|
minHeight = 1;
|
|
result = XtMakeResizeRequest((Widget)f, minWidth, minHeight,
|
|
&width, &height);
|
|
if (result == XtGeometryAlmost)
|
|
XtMakeResizeRequest((Widget)f, width, height, NULL, NULL);
|
|
}
|
|
/* move active row to bottom */
|
|
tab = f->folder.activeW;
|
|
if (tab)
|
|
{
|
|
fc = (XmLFolderConstraintRec *)(tab->core.constraints);
|
|
rowNum = fc->folder.row;
|
|
f->folder.activeRow = rowNum;
|
|
rows[rowNum].x = f->folder.tabWidth - rows[rowNum].width;
|
|
for (i = rowNum + 1; i < numRows; i++)
|
|
rows[i].x -= rows[rowNum].width;
|
|
}
|
|
else
|
|
f->folder.activeRow = -1;
|
|
|
|
/* configure tab children */
|
|
for (i = 0; i < f->folder.tabCount; i++)
|
|
{
|
|
tab = f->folder.tabs[i];
|
|
if (!XtIsManaged(tab))
|
|
continue;
|
|
fc = (XmLFolderConstraintRec *)(tab->core.constraints);
|
|
rowNum = fc->folder.row;
|
|
|
|
/* calculate tab x */
|
|
if (fc->folder.firstInRow == True)
|
|
{
|
|
if (f->folder.tabsPerRow && rowNum != f->folder.activeRow)
|
|
y = 2;
|
|
else
|
|
y = 0;
|
|
}
|
|
fc->folder.y = y;
|
|
y += st + co + f->folder.marginWidth + ht;
|
|
if (fc->folder.maxPixHeight)
|
|
y += fc->folder.maxPixHeight + f->folder.pixmapMargin;
|
|
|
|
/* calculate tab x and tab width */
|
|
fc->folder.width = rows[rowNum].width;
|
|
if (f->folder.tabPlacement == XmFOLDER_LEFT)
|
|
{
|
|
fc->folder.x = rows[rowNum].x;
|
|
x = fc->folder.x + fc->folder.width - f->folder.marginHeight -
|
|
ht - XtWidth(tab) - tab->core.border_width * 2;
|
|
}
|
|
else
|
|
{
|
|
fc->folder.x = f->core.width - rows[rowNum].x -
|
|
rows[rowNum].width;
|
|
x = fc->folder.x + f->folder.marginHeight + ht;
|
|
}
|
|
|
|
/* calculate tab padding */
|
|
pad1 = 0;
|
|
pad2 = 0;
|
|
h = f->core.height - rows[rowNum].height;
|
|
if (rowNum != f->folder.activeRow)
|
|
h -= 4;
|
|
if (f->folder.tabsPerRow && h > 0)
|
|
{
|
|
pad1 = h / (rows[rowNum].numTabs * 2);
|
|
pad2 = pad1;
|
|
if (fc->folder.firstInRow == True)
|
|
pad2 += h - (pad1 * rows[rowNum].numTabs * 2);
|
|
}
|
|
y += pad1;
|
|
|
|
/* move tab widget into place */
|
|
XtMoveWidget(tab, x, y);
|
|
|
|
/* calculate tab height and move to next tab */
|
|
y += pad2 + XtHeight(tab) + tab->core.border_width * 2 + ht +
|
|
f->folder.marginWidth + co + st;
|
|
fc->folder.height = y - fc->folder.y;
|
|
y += f->folder.spacing;
|
|
}
|
|
|
|
/* configure non-tab children */
|
|
for (i = 0; i < f->composite.num_children; i++)
|
|
{
|
|
child = children[i];
|
|
if (XtIsSubclass(child, xmPrimitiveWidgetClass))
|
|
continue;
|
|
if (f->folder.resizePolicy == XmRESIZE_NONE)
|
|
continue;
|
|
|
|
w = (int)f->core.width - (int)f->folder.tabWidth - st * 2;
|
|
h = (int)f->core.height - st * 2;
|
|
if (h <= 0 || w <= 0)
|
|
continue;
|
|
/* manager widgets will not configure correctly unless they */
|
|
/* are managed, so manage then unmapped if they are unmanaged */
|
|
isManaged = True;
|
|
if (!XtIsManaged(child))
|
|
{
|
|
XtVaGetValues(child,
|
|
XmNmappedWhenManaged, &map,
|
|
NULL);
|
|
XtVaSetValues(child,
|
|
XmNmappedWhenManaged, False,
|
|
NULL);
|
|
XtManageChild(child);
|
|
isManaged = False;
|
|
}
|
|
y = st;
|
|
if (f->folder.tabPlacement == XmFOLDER_LEFT)
|
|
x = f->folder.tabWidth + st;
|
|
else
|
|
x = st;
|
|
width = w;
|
|
height = h;
|
|
borderWidth = 0;
|
|
if (XtIsWidget(child))
|
|
borderWidth = child->core.border_width;
|
|
XtConfigureWidget(child, x, y, width, height, borderWidth);
|
|
if (isManaged == False)
|
|
{
|
|
XtUnmanageChild(child);
|
|
XtVaSetValues(child, XmNmappedWhenManaged, map, NULL);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
Resize(Widget w)
|
|
{
|
|
XmLFolderWidget f;
|
|
|
|
f = (XmLFolderWidget)w;
|
|
Layout(f, 0);
|
|
}
|
|
|
|
static XtGeometryResult
|
|
GeometryManager(Widget w,
|
|
XtWidgetGeometry *request,
|
|
XtWidgetGeometry *allow)
|
|
{
|
|
XmLFolderWidget f;
|
|
|
|
f = (XmLFolderWidget)XtParent(w);
|
|
if (f->folder.resizePolicy != XmRESIZE_STATIC ||
|
|
XtIsSubclass(w, xmPrimitiveWidgetClass))
|
|
{
|
|
if (request->request_mode & CWWidth)
|
|
w->core.width = request->width;
|
|
if (request->request_mode & CWHeight)
|
|
w->core.height = request->height;
|
|
if (request->request_mode & CWX)
|
|
w->core.x = request->x;
|
|
if (request->request_mode & CWY)
|
|
w->core.y = request->y;
|
|
if (request->request_mode & CWBorderWidth)
|
|
w->core.border_width = request->border_width;
|
|
Layout(f, 1);
|
|
return XtGeometryYes;
|
|
}
|
|
return XtGeometryNo;
|
|
}
|
|
|
|
static void
|
|
ChangeManaged(Widget w)
|
|
{
|
|
XmLFolderWidget f;
|
|
|
|
f = (XmLFolderWidget)w;
|
|
Layout(f, 1);
|
|
_XmNavigChangeManaged(w);
|
|
}
|
|
|
|
static void
|
|
ConstraintInitialize(Widget req,
|
|
Widget w,
|
|
ArgList args,
|
|
Cardinal *narg)
|
|
{
|
|
XmLFolderWidget f;
|
|
XmLFolderConstraintRec *fc;
|
|
|
|
if (!XtIsRectObj(w))
|
|
return;
|
|
f = (XmLFolderWidget)XtParent(w);
|
|
if (f->folder.debugLevel)
|
|
fprintf(stderr, "XmLFolder: Constraint Init\n");
|
|
fc = (XmLFolderConstraintRec *)(w->core.constraints);
|
|
fc->folder.x = 0;
|
|
fc->folder.y = 0;
|
|
fc->folder.width = 0;
|
|
fc->folder.height = 0;
|
|
fc->folder.maxPixWidth = 0;
|
|
fc->folder.maxPixHeight = 0;
|
|
fc->folder.row = -1;
|
|
fc->folder.firstInRow = False;
|
|
if (fc->folder.managedName)
|
|
fc->folder.managedName = (char *)strdup(fc->folder.managedName);
|
|
if (XtIsSubclass(w, xmPrimitiveWidgetClass))
|
|
{
|
|
XtOverrideTranslations(w, f->folder.primTrans);
|
|
XtAddCallback(w, XmNactivateCallback, PrimActivate, 0);
|
|
XtVaSetValues(w,
|
|
XmNhighlightThickness, 0,
|
|
XmNshadowThickness, 0,
|
|
NULL);
|
|
if (XtIsSubclass(w, xmLabelWidgetClass))
|
|
XtVaSetValues(w, XmNfillOnArm, False, NULL);
|
|
|
|
/* add child to tabs list */
|
|
if (f->folder.tabAllocCount < f->folder.tabCount + 1)
|
|
{
|
|
f->folder.tabAllocCount *= 2;
|
|
f->folder.tabs = (Widget *)realloc((char *)f->folder.tabs,
|
|
sizeof(Widget) * f->folder.tabAllocCount);
|
|
}
|
|
f->folder.tabs[f->folder.tabCount++] = w;
|
|
|
|
}
|
|
if (XmIsDrawnButton(w))
|
|
SetTabPlacement(f, w);
|
|
|
|
#ifdef XmLEVAL
|
|
if (f->folder.tabCount > 6)
|
|
{
|
|
fprintf(stderr, "XmL: evaluation version only supports <= 6 tabs\n");
|
|
exit(0);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
static void
|
|
ConstraintDestroy(Widget w)
|
|
{
|
|
XmLFolderWidget f;
|
|
XmLFolderConstraintRec *fc;
|
|
int i, j, activePos;
|
|
|
|
if (!XtIsRectObj(w))
|
|
return;
|
|
f = (XmLFolderWidget)XtParent(w);
|
|
if (f->folder.debugLevel)
|
|
fprintf(stderr, "XmLFolder: Constraint Destroy\n");
|
|
if (f->folder.focusW == w)
|
|
f->folder.focusW = 0;
|
|
fc = (XmLFolderConstraintRec *)(w->core.constraints);
|
|
if (fc->folder.managedName)
|
|
free((char *)fc->folder.managedName);
|
|
if (fc->folder.freePix == True)
|
|
{
|
|
if (fc->folder.pix != XmUNSPECIFIED_PIXMAP)
|
|
XFreePixmap(XtDisplay(w), fc->folder.pix);
|
|
if (fc->folder.inactPix != XmUNSPECIFIED_PIXMAP)
|
|
XFreePixmap(XtDisplay(w), fc->folder.inactPix);
|
|
}
|
|
if (XtIsSubclass(w, xmPrimitiveWidgetClass))
|
|
{
|
|
XtRemoveCallback(w, XmNactivateCallback, PrimActivate, 0);
|
|
|
|
/* remove child from tabs list and calculate active pos */
|
|
activePos = -1;
|
|
j = 0;
|
|
for (i = 0; i < f->folder.tabCount; i++)
|
|
if (f->folder.tabs[i] != w)
|
|
{
|
|
if (f->folder.activeW == f->folder.tabs[i])
|
|
activePos = j;
|
|
f->folder.tabs[j++] = f->folder.tabs[i];
|
|
}
|
|
if (j != f->folder.tabCount - 1)
|
|
XmLWarning((Widget)f, "ConstraintDestroy() - bad child list");
|
|
f->folder.tabCount = j;
|
|
f->folder.activeTab = activePos;
|
|
if (activePos == -1)
|
|
f->folder.activeW = 0;
|
|
}
|
|
}
|
|
|
|
static void
|
|
DrawTabPixmap(XmLFolderWidget f,
|
|
Widget tab,
|
|
int active)
|
|
{
|
|
Display *dpy;
|
|
Window win;
|
|
int x, y;
|
|
Pixmap pixmap;
|
|
Dimension pixWidth, pixHeight, ht;
|
|
XmLFolderConstraintRec *fc;
|
|
|
|
x = 0;
|
|
y = 0;
|
|
dpy = XtDisplay(f);
|
|
win = XtWindow(f);
|
|
fc = (XmLFolderConstraintRec *)(tab->core.constraints);
|
|
ht = f->folder.highlightThickness;
|
|
if (active)
|
|
{
|
|
pixWidth = fc->folder.pixWidth;
|
|
pixHeight = fc->folder.pixHeight;
|
|
pixmap = fc->folder.pix;
|
|
}
|
|
else
|
|
{
|
|
pixWidth = fc->folder.inactPixWidth;
|
|
pixHeight = fc->folder.inactPixHeight;
|
|
pixmap = fc->folder.inactPix;
|
|
}
|
|
if (f->folder.tabPlacement == XmFOLDER_TOP)
|
|
{
|
|
x = tab->core.x - pixWidth - ht - f->folder.pixmapMargin;
|
|
y = tab->core.y + tab->core.height - pixHeight;
|
|
}
|
|
else if (f->folder.tabPlacement == XmFOLDER_BOTTOM)
|
|
{
|
|
x = tab->core.x - fc->folder.pixWidth - ht - f->folder.pixmapMargin;
|
|
y = tab->core.y;
|
|
}
|
|
else if (f->folder.tabPlacement == XmFOLDER_LEFT)
|
|
{
|
|
x = tab->core.x + tab->core.width - pixWidth;
|
|
y = tab->core.y - pixHeight - f->folder.pixmapMargin - ht;
|
|
}
|
|
else if (f->folder.tabPlacement == XmFOLDER_RIGHT)
|
|
{
|
|
x = tab->core.x;
|
|
y = tab->core.y - pixHeight - f->folder.pixmapMargin - ht;
|
|
}
|
|
XCopyArea(dpy, pixmap, win, f->folder.gc, 0, 0, pixWidth, pixHeight, x, y);
|
|
}
|
|
|
|
static void
|
|
DrawManagerShadowTopBottom(XmLFolderWidget f,
|
|
XRectangle *rect)
|
|
{
|
|
Display *dpy;
|
|
Window win;
|
|
XmLFolderConstraintRec *fc;
|
|
XSegment *topSeg, *botSeg;
|
|
int i, bCount, tCount, st, botOff;
|
|
|
|
dpy = XtDisplay(f);
|
|
win = XtWindow(f);
|
|
st = f->manager.shadow_thickness;
|
|
if (!st)
|
|
return;
|
|
botOff = f->core.height - f->folder.tabHeight - 1;
|
|
|
|
topSeg = (XSegment *)malloc(sizeof(XSegment) * st * 2);
|
|
botSeg = (XSegment *)malloc(sizeof(XSegment) * st * 2);
|
|
|
|
/* top shadow */
|
|
fc = 0;
|
|
if (f->folder.activeW)
|
|
fc = (XmLFolderConstraintRec *)(f->folder.activeW->core.constraints);
|
|
tCount = 0;
|
|
if (fc)
|
|
for (i = 0; i < st; i++)
|
|
{
|
|
topSeg[tCount].x1 = rect->x + i;
|
|
topSeg[tCount].y1 = rect->y + i;
|
|
topSeg[tCount].x2 = fc->folder.x + i;
|
|
topSeg[tCount].y2 = rect->y + i;
|
|
if (rect->x != fc->folder.x)
|
|
tCount++;
|
|
topSeg[tCount].x1 = rect->x + fc->folder.x +
|
|
fc->folder.width - i - 1;
|
|
topSeg[tCount].y1 = rect->y + i;
|
|
topSeg[tCount].x2 = rect->x + rect->width - i - 1;
|
|
topSeg[tCount].y2 = rect->y + i;
|
|
if (fc->folder.x + fc->folder.width != rect->width)
|
|
tCount++;
|
|
}
|
|
else
|
|
for (i = 0; i < st; i++)
|
|
{
|
|
topSeg[tCount].x1 = rect->x + i;
|
|
topSeg[tCount].y1 = rect->y + i;
|
|
topSeg[tCount].x2 = rect->x + rect->width - i - 1;
|
|
topSeg[tCount].y2 = rect->y + i;
|
|
tCount++;
|
|
}
|
|
if (f->folder.tabPlacement == XmFOLDER_BOTTOM)
|
|
for (i = 0 ; i < tCount; i++)
|
|
{
|
|
topSeg[i].y1 = botOff - topSeg[i].y1;
|
|
topSeg[i].y2 = botOff - topSeg[i].y2;
|
|
}
|
|
if (tCount)
|
|
{
|
|
if (f->folder.tabPlacement == XmFOLDER_BOTTOM)
|
|
SetGC(f, GC_SHADOWBOT);
|
|
else
|
|
SetGC(f, GC_SHADOWTOP);
|
|
XDrawSegments(dpy, win, f->folder.gc, topSeg, tCount);
|
|
SetGC(f, GC_UNSET);
|
|
}
|
|
|
|
/* left shadow */
|
|
tCount = 0;
|
|
for (i = 0; i < st; i++)
|
|
{
|
|
topSeg[tCount].x1 = rect->x + i;
|
|
topSeg[tCount].y1 = rect->y + i;
|
|
topSeg[tCount].x2 = rect->x + i;
|
|
topSeg[tCount].y2 = rect->y + rect->height - i - 1;
|
|
tCount++;
|
|
}
|
|
if (tCount)
|
|
{
|
|
SetGC(f, GC_SHADOWTOP);
|
|
XDrawSegments(dpy, win, f->folder.gc, topSeg, tCount);
|
|
SetGC(f, GC_UNSET);
|
|
}
|
|
|
|
/* right shadow */
|
|
bCount = 0;
|
|
for (i = 0; i < st; i++)
|
|
{
|
|
botSeg[bCount].x1 = rect->x + rect->width - i - 1;
|
|
botSeg[bCount].y1 = rect->y + i;
|
|
botSeg[bCount].x2 = rect->x + rect->width - i - 1;
|
|
botSeg[bCount].y2 = rect->y + rect->height - i - 1;
|
|
bCount++;
|
|
}
|
|
if (bCount)
|
|
{
|
|
SetGC(f, GC_SHADOWBOT);
|
|
XDrawSegments(dpy, win, f->folder.gc, botSeg, bCount);
|
|
SetGC(f, GC_UNSET);
|
|
}
|
|
|
|
/* bottom shadow */
|
|
bCount = 0;
|
|
for (i = 0; i < st; i++)
|
|
{
|
|
botSeg[bCount].x1 = rect->x + i;
|
|
botSeg[bCount].y1 = rect->y + rect->height - i - 1;
|
|
botSeg[bCount].x2 = rect->x + rect->width - i - 1;
|
|
botSeg[bCount].y2 = rect->y + rect->height - i - 1;
|
|
if (f->folder.tabPlacement == XmFOLDER_BOTTOM)
|
|
{
|
|
botSeg[bCount].y1 = botOff - botSeg[bCount].y1;
|
|
botSeg[bCount].y2 = botOff - botSeg[bCount].y2;
|
|
}
|
|
bCount++;
|
|
}
|
|
if (bCount)
|
|
{
|
|
if (f->folder.tabPlacement == XmFOLDER_TOP)
|
|
SetGC(f, GC_SHADOWBOT);
|
|
else
|
|
SetGC(f, GC_SHADOWTOP);
|
|
XDrawSegments(dpy, win, f->folder.gc, botSeg, bCount);
|
|
SetGC(f, GC_UNSET);
|
|
}
|
|
free((char *)topSeg);
|
|
free((char *)botSeg);
|
|
}
|
|
|
|
static void
|
|
DrawManagerShadowLeftRight(XmLFolderWidget f,
|
|
XRectangle *rect)
|
|
{
|
|
Display *dpy;
|
|
Window win;
|
|
XmLFolderConstraintRec *fc;
|
|
XSegment *topSeg, *botSeg;
|
|
int i, bCount, tCount, st, rightOff;
|
|
|
|
dpy = XtDisplay(f);
|
|
win = XtWindow(f);
|
|
st = f->manager.shadow_thickness;
|
|
if (!st)
|
|
return;
|
|
rightOff = f->core.width - f->folder.tabWidth - 1;
|
|
|
|
topSeg = (XSegment *)malloc(sizeof(XSegment) * st * 2);
|
|
botSeg = (XSegment *)malloc(sizeof(XSegment) * st * 2);
|
|
|
|
/* left shadow */
|
|
fc = 0;
|
|
if (f->folder.activeW)
|
|
fc = (XmLFolderConstraintRec *)(f->folder.activeW->core.constraints);
|
|
tCount = 0;
|
|
if (fc)
|
|
for (i = 0; i < st; i++)
|
|
{
|
|
topSeg[tCount].x1 = rect->x + i;
|
|
topSeg[tCount].y1 = rect->y + i;
|
|
topSeg[tCount].x2 = rect->x + i;
|
|
topSeg[tCount].y2 = fc->folder.y + i;
|
|
if (rect->y != fc->folder.y)
|
|
tCount++;
|
|
topSeg[tCount].x1 = rect->x + i;
|
|
topSeg[tCount].y1 = rect->y + fc->folder.y +
|
|
fc->folder.height - i - 1;
|
|
topSeg[tCount].x2 = rect->x + i;
|
|
topSeg[tCount].y2 = rect->y + rect->height - i - 1;
|
|
if (fc->folder.y + fc->folder.height != rect->height)
|
|
tCount++;
|
|
}
|
|
else
|
|
for (i = 0; i < st; i++)
|
|
{
|
|
topSeg[tCount].x1 = rect->x + i;
|
|
topSeg[tCount].y1 = rect->y + i;
|
|
topSeg[tCount].x2 = rect->x + i;
|
|
topSeg[tCount].y2 = rect->y + rect->height - i - 1;
|
|
tCount++;
|
|
}
|
|
if (f->folder.tabPlacement == XmFOLDER_RIGHT)
|
|
for (i = 0 ; i < tCount; i++)
|
|
{
|
|
topSeg[i].x1 = rightOff - topSeg[i].x1;
|
|
topSeg[i].x2 = rightOff - topSeg[i].x2;
|
|
}
|
|
if (tCount)
|
|
{
|
|
if (f->folder.tabPlacement == XmFOLDER_RIGHT)
|
|
SetGC(f, GC_SHADOWBOT);
|
|
else
|
|
SetGC(f, GC_SHADOWTOP);
|
|
XDrawSegments(dpy, win, f->folder.gc, topSeg, tCount);
|
|
SetGC(f, GC_UNSET);
|
|
}
|
|
|
|
/* top shadow */
|
|
tCount = 0;
|
|
for (i = 0; i < st; i++)
|
|
{
|
|
topSeg[tCount].x1 = rect->x + i;
|
|
topSeg[tCount].y1 = rect->y + i;
|
|
topSeg[tCount].x2 = rect->x + rect->width - i - 1;
|
|
topSeg[tCount].y2 = rect->y + i;
|
|
tCount++;
|
|
}
|
|
if (tCount)
|
|
{
|
|
SetGC(f, GC_SHADOWTOP);
|
|
XDrawSegments(dpy, win, f->folder.gc, topSeg, tCount);
|
|
SetGC(f, GC_UNSET);
|
|
}
|
|
|
|
/* bottom shadow */
|
|
bCount = 0;
|
|
for (i = 0; i < st; i++)
|
|
{
|
|
botSeg[bCount].x1 = rect->x + i;
|
|
botSeg[bCount].y1 = rect->y + rect->height - i - 1;
|
|
botSeg[bCount].x2 = rect->x + rect->width - i - 1;
|
|
botSeg[bCount].y2 = rect->y + rect->height - i - 1;
|
|
bCount++;
|
|
}
|
|
if (bCount)
|
|
{
|
|
SetGC(f, GC_SHADOWBOT);
|
|
XDrawSegments(dpy, win, f->folder.gc, botSeg, bCount);
|
|
SetGC(f, GC_UNSET);
|
|
}
|
|
|
|
/* right shadow */
|
|
bCount = 0;
|
|
for (i = 0; i < st; i++)
|
|
{
|
|
botSeg[bCount].x1 = rect->x + rect->width - i - 1;
|
|
botSeg[bCount].y1 = rect->y + i;
|
|
botSeg[bCount].x2 = rect->x + rect->width - i - 1;
|
|
botSeg[bCount].y2 = rect->y + rect->height - i - 1;
|
|
if (f->folder.tabPlacement == XmFOLDER_RIGHT)
|
|
{
|
|
botSeg[bCount].x1 = rightOff - botSeg[bCount].x1;
|
|
botSeg[bCount].x2 = rightOff - botSeg[bCount].x2;
|
|
}
|
|
bCount++;
|
|
}
|
|
if (bCount)
|
|
{
|
|
if (f->folder.tabPlacement == XmFOLDER_LEFT)
|
|
SetGC(f, GC_SHADOWBOT);
|
|
else
|
|
SetGC(f, GC_SHADOWTOP);
|
|
XDrawSegments(dpy, win, f->folder.gc, botSeg, bCount);
|
|
SetGC(f, GC_UNSET);
|
|
}
|
|
free((char *)topSeg);
|
|
free((char *)botSeg);
|
|
}
|
|
|
|
static void
|
|
DrawTabShadowArcTopBottom(XmLFolderWidget f,
|
|
Widget w)
|
|
{
|
|
XmLFolderConstraintRec *fc;
|
|
Display *dpy;
|
|
Window win;
|
|
XSegment *topSeg, *botSeg;
|
|
XRectangle rect, rect2;
|
|
XArc arc;
|
|
int tCount, bCount;
|
|
int i, st, cd, botOff;
|
|
|
|
dpy = XtDisplay(f);
|
|
win = XtWindow(f);
|
|
fc = (XmLFolderConstraintRec *)(w->core.constraints);
|
|
botOff = 2 * fc->folder.y + fc->folder.height - 1;
|
|
st = f->manager.shadow_thickness;
|
|
if (!st)
|
|
return;
|
|
cd = f->folder.cornerDimension;
|
|
|
|
tCount = 0;
|
|
bCount = 0;
|
|
topSeg = (XSegment *)malloc(sizeof(XSegment) * st);
|
|
botSeg = (XSegment *)malloc(sizeof(XSegment) * st);
|
|
for (i = 0; i < st; i++)
|
|
{
|
|
/* left tab shadow */
|
|
topSeg[tCount].x1 = fc->folder.x + i;
|
|
topSeg[tCount].y1 = fc->folder.y + cd + st;
|
|
topSeg[tCount].x2 = fc->folder.x + i;
|
|
topSeg[tCount].y2 = fc->folder.y + fc->folder.height - 1;
|
|
if (w == f->folder.activeW)
|
|
topSeg[tCount].y2 += i;
|
|
if (f->folder.tabPlacement == XmFOLDER_BOTTOM)
|
|
{
|
|
topSeg[tCount].y1 = botOff - topSeg[tCount].y1;
|
|
topSeg[tCount].y2 = botOff - topSeg[tCount].y2;
|
|
}
|
|
tCount++;
|
|
|
|
/* right tab shadow */
|
|
botSeg[bCount].x1 = fc->folder.x + fc->folder.width - i - 1;
|
|
botSeg[bCount].y1 = fc->folder.y + cd + st;
|
|
botSeg[bCount].x2 = fc->folder.x + fc->folder.width - i - 1;
|
|
botSeg[bCount].y2 = fc->folder.y + fc->folder.height - 1;
|
|
if (w == f->folder.activeW)
|
|
botSeg[bCount].y2 += i;
|
|
if (f->folder.tabPlacement == XmFOLDER_BOTTOM)
|
|
{
|
|
botSeg[bCount].y1 = botOff - botSeg[bCount].y1;
|
|
botSeg[bCount].y2 = botOff - botSeg[bCount].y2;
|
|
}
|
|
bCount++;
|
|
}
|
|
if (tCount)
|
|
{
|
|
SetGC(f, GC_SHADOWTOP);
|
|
XDrawSegments(dpy, win, f->folder.gc, topSeg, tCount);
|
|
SetGC(f, GC_UNSET);
|
|
}
|
|
if (bCount)
|
|
{
|
|
SetGC(f, GC_SHADOWBOT);
|
|
XDrawSegments(dpy, win, f->folder.gc, botSeg, bCount);
|
|
SetGC(f, GC_UNSET);
|
|
}
|
|
tCount = 0;
|
|
for (i = 0; i < st; i++)
|
|
{
|
|
/* top tab shadow */
|
|
topSeg[tCount].x1 = fc->folder.x + cd + st;
|
|
topSeg[tCount].y1 = fc->folder.y + i;
|
|
topSeg[tCount].x2 = fc->folder.x + fc->folder.width - cd - st - 1;
|
|
topSeg[tCount].y2 = fc->folder.y + i;
|
|
if (f->folder.tabPlacement == XmFOLDER_BOTTOM)
|
|
{
|
|
topSeg[tCount].y1 = botOff - topSeg[tCount].y1;
|
|
topSeg[tCount].y2 = botOff - topSeg[tCount].y2;
|
|
}
|
|
tCount++;
|
|
}
|
|
if (tCount)
|
|
{
|
|
if (f->folder.tabPlacement == XmFOLDER_BOTTOM)
|
|
SetGC(f, GC_SHADOWBOT);
|
|
else
|
|
SetGC(f, GC_SHADOWTOP);
|
|
XDrawSegments(dpy, win, f->folder.gc, topSeg, tCount);
|
|
SetGC(f, GC_UNSET);
|
|
}
|
|
free((char *)topSeg);
|
|
free((char *)botSeg);
|
|
|
|
/* left corner blank background */
|
|
rect.x = fc->folder.x;
|
|
rect.y = fc->folder.y;
|
|
rect.width = cd + st;
|
|
rect.height = cd + st;
|
|
if (f->folder.tabPlacement == XmFOLDER_BOTTOM)
|
|
rect.y = fc->folder.y + fc->folder.height - rect.height;
|
|
SetGC(f, GC_BLANK);
|
|
XFillRectangle(dpy, win, f->folder.gc, rect.x, rect.y,
|
|
rect.width, rect.height);
|
|
SetGC(f, GC_UNSET);
|
|
|
|
/* left arc */
|
|
/* various X Servers have problems drawing arcs - so set clip rect */
|
|
/* and draw two circles, one smaller than the other, for corner */
|
|
XSetClipRectangles(dpy, f->folder.gc, 0, 0, &rect, 1, Unsorted);
|
|
arc.x = rect.x;
|
|
arc.y = rect.y;
|
|
arc.width = rect.width * 2;
|
|
arc.height = rect.height * 2;
|
|
if (f->folder.serverDrawsArcsLarge == True)
|
|
{
|
|
arc.width -= 1;
|
|
arc.height -= 1;
|
|
}
|
|
arc.angle1 = 0 * 64;
|
|
arc.angle2 = 360 * 64;
|
|
if (f->folder.tabPlacement == XmFOLDER_BOTTOM)
|
|
arc.y = fc->folder.y + fc->folder.height - arc.height;
|
|
SetGC(f, GC_SHADOWTOP);
|
|
XFillArc(dpy, win, f->folder.gc, arc.x, arc.y, arc.width, arc.height,
|
|
arc.angle1, arc.angle2);
|
|
XDrawArc(dpy, win, f->folder.gc, arc.x, arc.y, arc.width, arc.height,
|
|
arc.angle1, arc.angle2);
|
|
SetGC(f, GC_UNSET);
|
|
|
|
rect2 = rect;
|
|
rect2.x += st;
|
|
rect2.width -= st;
|
|
rect2.height -= st;
|
|
if (f->folder.tabPlacement == XmFOLDER_TOP)
|
|
rect2.y += st;
|
|
XSetClipRectangles(dpy, f->folder.gc, 0, 0, &rect2, 1, Unsorted);
|
|
if (w == f->folder.activeW)
|
|
XSetForeground(dpy, f->folder.gc, f->core.background_pixel);
|
|
else
|
|
XSetForeground(dpy, f->folder.gc, f->folder.inactiveBg);
|
|
arc.x += st;
|
|
arc.y += st;
|
|
arc.width -= st * 2;
|
|
arc.height -= st * 2;
|
|
XFillArc(dpy, win, f->folder.gc, arc.x, arc.y, arc.width, arc.height,
|
|
arc.angle1, arc.angle2);
|
|
XDrawArc(dpy, win, f->folder.gc, arc.x, arc.y, arc.width, arc.height,
|
|
arc.angle1, arc.angle2);
|
|
XSetClipMask(dpy, f->folder.gc, None);
|
|
|
|
/* right corner blank background */
|
|
rect.x = fc->folder.x + fc->folder.width - cd - st;
|
|
SetGC(f, GC_BLANK);
|
|
XFillRectangle(dpy, win, f->folder.gc, rect.x, rect.y,
|
|
rect.width, rect.height);
|
|
SetGC(f, GC_UNSET);
|
|
|
|
/* right arc */
|
|
XSetClipRectangles(dpy, f->folder.gc, 0, 0, &rect, 1, Unsorted);
|
|
arc.x = rect.x - cd - st;
|
|
arc.y = rect.y;
|
|
arc.width = rect.width * 2;
|
|
arc.height = rect.height * 2;
|
|
if (f->folder.serverDrawsArcsLarge == True)
|
|
{
|
|
arc.width -= 1;
|
|
arc.height -= 1;
|
|
}
|
|
arc.angle1 = 0 * 64;
|
|
arc.angle2 = 360 * 64;
|
|
if (f->folder.tabPlacement == XmFOLDER_BOTTOM)
|
|
arc.y = fc->folder.y + fc->folder.height - arc.height;
|
|
SetGC(f, GC_SHADOWBOT);
|
|
XFillArc(dpy, win, f->folder.gc, arc.x, arc.y, arc.width, arc.height,
|
|
arc.angle1, arc.angle2);
|
|
XDrawArc(dpy, win, f->folder.gc, arc.x, arc.y, arc.width, arc.height,
|
|
arc.angle1, arc.angle2);
|
|
SetGC(f, GC_UNSET);
|
|
|
|
rect2 = rect;
|
|
rect2.width -= st;
|
|
rect2.height -= st;
|
|
if (f->folder.tabPlacement == XmFOLDER_TOP)
|
|
rect2.y += st;
|
|
XSetClipRectangles(dpy, f->folder.gc, 0, 0, &rect2, 1, Unsorted);
|
|
if (w == f->folder.activeW)
|
|
XSetForeground(dpy, f->folder.gc, f->core.background_pixel);
|
|
else
|
|
XSetForeground(dpy, f->folder.gc, f->folder.inactiveBg);
|
|
arc.x += st;
|
|
arc.y += st;
|
|
arc.width -= st * 2;
|
|
arc.height -= st * 2;
|
|
XFillArc(dpy, win, f->folder.gc, arc.x, arc.y, arc.width, arc.height,
|
|
arc.angle1, arc.angle2);
|
|
XDrawArc(dpy, win, f->folder.gc, arc.x, arc.y, arc.width, arc.height,
|
|
arc.angle1, arc.angle2);
|
|
XSetClipMask(dpy, f->folder.gc, None);
|
|
}
|
|
|
|
static void
|
|
DrawTabShadowArcLeftRight(XmLFolderWidget f,
|
|
Widget w)
|
|
{
|
|
XmLFolderConstraintRec *fc;
|
|
Display *dpy;
|
|
Window win;
|
|
XSegment *topSeg, *botSeg;
|
|
XRectangle rect, rect2;
|
|
XArc arc;
|
|
int tCount, bCount;
|
|
int i, st, cd, rightOff;
|
|
|
|
dpy = XtDisplay(f);
|
|
win = XtWindow(f);
|
|
fc = (XmLFolderConstraintRec *)(w->core.constraints);
|
|
rightOff = 2 * fc->folder.x + fc->folder.width - 1;
|
|
st = f->manager.shadow_thickness;
|
|
if (!st)
|
|
return;
|
|
cd = f->folder.cornerDimension;
|
|
|
|
tCount = 0;
|
|
bCount = 0;
|
|
topSeg = (XSegment *)malloc(sizeof(XSegment) * st);
|
|
botSeg = (XSegment *)malloc(sizeof(XSegment) * st);
|
|
for (i = 0; i < st; i++)
|
|
{
|
|
/* top tab shadow */
|
|
topSeg[tCount].x1 = fc->folder.x + cd + st;
|
|
topSeg[tCount].y1 = fc->folder.y + i;
|
|
topSeg[tCount].x2 = fc->folder.x + fc->folder.width - 1;
|
|
if (w == f->folder.activeW)
|
|
topSeg[tCount].x2 += i;
|
|
topSeg[tCount].y2 = fc->folder.y + i;
|
|
if (f->folder.tabPlacement == XmFOLDER_RIGHT)
|
|
{
|
|
topSeg[tCount].x1 = rightOff - topSeg[tCount].x1;
|
|
topSeg[tCount].x2 = rightOff - topSeg[tCount].x2;
|
|
}
|
|
tCount++;
|
|
|
|
/* bottom tab shadow */
|
|
botSeg[bCount].x1 = fc->folder.x + cd + st;
|
|
botSeg[bCount].y1 = fc->folder.y + fc->folder.height - i - 1;
|
|
botSeg[bCount].x2 = fc->folder.x + fc->folder.width - 1;
|
|
if (w == f->folder.activeW)
|
|
botSeg[bCount].x2 += i;
|
|
botSeg[bCount].y2 = fc->folder.y + fc->folder.height - i - 1;
|
|
if (f->folder.tabPlacement == XmFOLDER_RIGHT)
|
|
{
|
|
botSeg[bCount].x1 = rightOff - botSeg[bCount].x1;
|
|
botSeg[bCount].x2 = rightOff - botSeg[bCount].x2;
|
|
}
|
|
bCount++;
|
|
}
|
|
if (tCount)
|
|
{
|
|
SetGC(f, GC_SHADOWTOP);
|
|
XDrawSegments(dpy, win, f->folder.gc, topSeg, tCount);
|
|
SetGC(f, GC_UNSET);
|
|
}
|
|
if (bCount)
|
|
{
|
|
SetGC(f, GC_SHADOWBOT);
|
|
XDrawSegments(dpy, win, f->folder.gc, botSeg, bCount);
|
|
SetGC(f, GC_UNSET);
|
|
}
|
|
tCount = 0;
|
|
for (i = 0; i < st; i++)
|
|
{
|
|
/* left tab shadow */
|
|
topSeg[tCount].x1 = fc->folder.x + i;
|
|
topSeg[tCount].y1 = fc->folder.y + cd + st;
|
|
topSeg[tCount].x2 = fc->folder.x + i;
|
|
topSeg[tCount].y2 = fc->folder.y + fc->folder.height - cd - st - 1;
|
|
if (f->folder.tabPlacement == XmFOLDER_RIGHT)
|
|
{
|
|
topSeg[tCount].x1 = rightOff - topSeg[tCount].x1;
|
|
topSeg[tCount].x2 = rightOff - topSeg[tCount].x2;
|
|
}
|
|
tCount++;
|
|
}
|
|
if (tCount)
|
|
{
|
|
if (f->folder.tabPlacement == XmFOLDER_RIGHT)
|
|
SetGC(f, GC_SHADOWBOT);
|
|
else
|
|
SetGC(f, GC_SHADOWTOP);
|
|
XDrawSegments(dpy, win, f->folder.gc, topSeg, tCount);
|
|
SetGC(f, GC_UNSET);
|
|
}
|
|
free((char *)topSeg);
|
|
free((char *)botSeg);
|
|
|
|
/* top corner blank background */
|
|
rect.x = fc->folder.x;
|
|
rect.y = fc->folder.y;
|
|
rect.width = cd + st;
|
|
rect.height = cd + st;
|
|
if (f->folder.tabPlacement == XmFOLDER_RIGHT)
|
|
rect.x = fc->folder.x + fc->folder.width - rect.width;
|
|
SetGC(f, GC_BLANK);
|
|
XFillRectangle(dpy, win, f->folder.gc, rect.x, rect.y,
|
|
rect.width, rect.height);
|
|
SetGC(f, GC_UNSET);
|
|
|
|
/* top arc */
|
|
XSetClipRectangles(dpy, f->folder.gc, 0, 0, &rect, 1, Unsorted);
|
|
arc.x = rect.x;
|
|
arc.y = rect.y;
|
|
arc.width = rect.width * 2;
|
|
arc.height = rect.height * 2;
|
|
if (f->folder.serverDrawsArcsLarge == True)
|
|
{
|
|
arc.width -= 1;
|
|
arc.height -= 1;
|
|
}
|
|
arc.angle1 = 0 * 64;
|
|
arc.angle2 = 360 * 64;
|
|
if (f->folder.tabPlacement == XmFOLDER_RIGHT)
|
|
arc.x = fc->folder.x + fc->folder.width - arc.width;
|
|
SetGC(f, GC_SHADOWTOP);
|
|
XFillArc(dpy, win, f->folder.gc, arc.x, arc.y, arc.width, arc.height,
|
|
arc.angle1, arc.angle2);
|
|
XDrawArc(dpy, win, f->folder.gc, arc.x, arc.y, arc.width, arc.height,
|
|
arc.angle1, arc.angle2);
|
|
SetGC(f, GC_UNSET);
|
|
|
|
rect2 = rect;
|
|
rect2.width -= st;
|
|
rect2.height -= st;
|
|
rect2.y += st;
|
|
if (f->folder.tabPlacement == XmFOLDER_LEFT)
|
|
rect2.x += st;
|
|
XSetClipRectangles(dpy, f->folder.gc, 0, 0, &rect2, 1, Unsorted);
|
|
if (w == f->folder.activeW)
|
|
XSetForeground(dpy, f->folder.gc, f->core.background_pixel);
|
|
else
|
|
XSetForeground(dpy, f->folder.gc, f->folder.inactiveBg);
|
|
arc.x += st;
|
|
arc.y += st;
|
|
arc.width -= st * 2;
|
|
arc.height -= st * 2;
|
|
XFillArc(dpy, win, f->folder.gc, arc.x, arc.y, arc.width, arc.height,
|
|
arc.angle1, arc.angle2);
|
|
XDrawArc(dpy, win, f->folder.gc, arc.x, arc.y, arc.width, arc.height,
|
|
arc.angle1, arc.angle2);
|
|
XSetClipMask(dpy, f->folder.gc, None);
|
|
|
|
/* bottom corner blank background */
|
|
rect.y = fc->folder.y + fc->folder.height - cd - st;
|
|
SetGC(f, GC_BLANK);
|
|
XFillRectangle(dpy, win, f->folder.gc, rect.x, rect.y,
|
|
rect.width, rect.height);
|
|
SetGC(f, GC_UNSET);
|
|
|
|
/* bottom arc */
|
|
XSetClipRectangles(dpy, f->folder.gc, 0, 0, &rect, 1, Unsorted);
|
|
arc.x = rect.x;
|
|
arc.y = rect.y - cd - st;
|
|
arc.width = rect.width * 2;
|
|
arc.height = rect.height * 2;
|
|
if (f->folder.serverDrawsArcsLarge == True)
|
|
{
|
|
arc.width -= 1;
|
|
arc.height -= 1;
|
|
}
|
|
arc.angle1 = 0 * 64;
|
|
arc.angle2 = 360 * 64;
|
|
if (f->folder.tabPlacement == XmFOLDER_RIGHT)
|
|
arc.x = fc->folder.x + fc->folder.width - arc.width;
|
|
SetGC(f, GC_SHADOWBOT);
|
|
XFillArc(dpy, win, f->folder.gc, arc.x, arc.y, arc.width, arc.height,
|
|
arc.angle1, arc.angle2);
|
|
XDrawArc(dpy, win, f->folder.gc, arc.x, arc.y, arc.width, arc.height,
|
|
arc.angle1, arc.angle2);
|
|
SetGC(f, GC_UNSET);
|
|
|
|
rect2 = rect;
|
|
rect2.width -= st;
|
|
rect2.height -= st;
|
|
if (f->folder.tabPlacement == XmFOLDER_LEFT)
|
|
rect2.x += st;
|
|
XSetClipRectangles(dpy, f->folder.gc, 0, 0, &rect2, 1, Unsorted);
|
|
if (w == f->folder.activeW)
|
|
XSetForeground(dpy, f->folder.gc, f->core.background_pixel);
|
|
else
|
|
XSetForeground(dpy, f->folder.gc, f->folder.inactiveBg);
|
|
arc.x += st;
|
|
arc.y += st;
|
|
arc.width -= st * 2;
|
|
arc.height -= st * 2;
|
|
XFillArc(dpy, win, f->folder.gc, arc.x, arc.y, arc.width, arc.height,
|
|
arc.angle1, arc.angle2);
|
|
XDrawArc(dpy, win, f->folder.gc, arc.x, arc.y, arc.width, arc.height,
|
|
arc.angle1, arc.angle2);
|
|
XSetClipMask(dpy, f->folder.gc, None);
|
|
}
|
|
|
|
static void
|
|
DrawTabShadowLineTopBottom(XmLFolderWidget f,
|
|
Widget w)
|
|
{
|
|
XmLFolderConstraintRec *fc;
|
|
Display *dpy;
|
|
Window win;
|
|
XSegment *topSeg, *botSeg;
|
|
XPoint points[4];
|
|
int tCount, bCount, botOff, i, st, cd, y;
|
|
|
|
dpy = XtDisplay(f);
|
|
win = XtWindow(f);
|
|
fc = (XmLFolderConstraintRec *)(w->core.constraints);
|
|
botOff = 2 * fc->folder.y + fc->folder.height - 1;
|
|
st = f->manager.shadow_thickness;
|
|
if (!st)
|
|
return;
|
|
cd = f->folder.cornerDimension;
|
|
|
|
tCount = 0;
|
|
bCount = 0;
|
|
topSeg = (XSegment *)malloc(sizeof(XSegment) * st);
|
|
botSeg = (XSegment *)malloc(sizeof(XSegment) * st);
|
|
for (i = 0; i < st; i++)
|
|
{
|
|
/* left tab shadow */
|
|
topSeg[tCount].x1 = fc->folder.x + i;
|
|
topSeg[tCount].y1 = fc->folder.y + cd + st;
|
|
topSeg[tCount].x2 = fc->folder.x + i;
|
|
topSeg[tCount].y2 = fc->folder.y + fc->folder.height - 1;
|
|
if (w == f->folder.activeW)
|
|
topSeg[tCount].y2 += i;
|
|
if (f->folder.tabPlacement == XmFOLDER_BOTTOM)
|
|
{
|
|
topSeg[tCount].y1 = botOff - topSeg[tCount].y1;
|
|
topSeg[tCount].y2 = botOff - topSeg[tCount].y2;
|
|
}
|
|
tCount++;
|
|
/* right tab shadow */
|
|
botSeg[bCount].x1 = fc->folder.x + fc->folder.width - i - 1;
|
|
botSeg[bCount].y1 = fc->folder.y + cd + st;
|
|
botSeg[bCount].x2 = fc->folder.x + fc->folder.width - i - 1;
|
|
botSeg[bCount].y2 = fc->folder.y + fc->folder.height - 1;
|
|
if (w == f->folder.activeW)
|
|
botSeg[bCount].y2 += i;
|
|
if (f->folder.tabPlacement == XmFOLDER_BOTTOM)
|
|
{
|
|
botSeg[bCount].y1 = botOff - botSeg[bCount].y1;
|
|
botSeg[bCount].y2 = botOff - botSeg[bCount].y2;
|
|
}
|
|
bCount++;
|
|
}
|
|
if (tCount)
|
|
{
|
|
SetGC(f, GC_SHADOWTOP);
|
|
XDrawSegments(dpy, win, f->folder.gc, topSeg, tCount);
|
|
SetGC(f, GC_UNSET);
|
|
}
|
|
if (bCount)
|
|
{
|
|
SetGC(f, GC_SHADOWBOT);
|
|
XDrawSegments(dpy, win, f->folder.gc, botSeg, bCount);
|
|
SetGC(f, GC_UNSET);
|
|
}
|
|
tCount = 0;
|
|
for (i = 0; i < st; i++)
|
|
{
|
|
/* top tab shadow */
|
|
topSeg[tCount].x1 = fc->folder.x + cd + st;
|
|
topSeg[tCount].y1 = fc->folder.y + i;
|
|
topSeg[tCount].x2 = fc->folder.x + fc->folder.width - cd - st - 1;
|
|
topSeg[tCount].y2 = fc->folder.y + i;
|
|
if (f->folder.tabPlacement == XmFOLDER_BOTTOM)
|
|
{
|
|
topSeg[tCount].y1 = botOff - topSeg[tCount].y1;
|
|
topSeg[tCount].y2 = botOff - topSeg[tCount].y2;
|
|
}
|
|
tCount++;
|
|
}
|
|
if (tCount)
|
|
{
|
|
if (f->folder.tabPlacement == XmFOLDER_TOP)
|
|
SetGC(f, GC_SHADOWTOP);
|
|
else
|
|
SetGC(f, GC_SHADOWBOT);
|
|
XDrawSegments(dpy, win, f->folder.gc, topSeg, tCount);
|
|
SetGC(f, GC_UNSET);
|
|
}
|
|
free((char *)topSeg);
|
|
free((char *)botSeg);
|
|
|
|
/* left top line */
|
|
points[0].x = fc->folder.x;
|
|
points[0].y = fc->folder.y + cd + st - 1;
|
|
points[1].x = fc->folder.x + cd + st - 1;
|
|
points[1].y = fc->folder.y;
|
|
points[2].x = fc->folder.x + cd + st - 1;
|
|
points[2].y = fc->folder.y + cd + st - 1;
|
|
if (f->folder.tabPlacement == XmFOLDER_BOTTOM)
|
|
{
|
|
points[0].y = botOff - points[0].y;
|
|
points[1].y = botOff - points[1].y;
|
|
points[2].y = botOff - points[2].y;
|
|
}
|
|
y = fc->folder.y;
|
|
if (f->folder.tabPlacement == XmFOLDER_BOTTOM)
|
|
y = fc->folder.y + fc->folder.height - cd - st;
|
|
SetGC(f, GC_BLANK);
|
|
XFillRectangle(dpy, win, f->folder.gc, fc->folder.x, y, cd + st, cd + st);
|
|
SetGC(f, GC_UNSET);
|
|
SetGC(f, GC_SHADOWTOP);
|
|
XFillPolygon(dpy, win, f->folder.gc, points, 3, Nonconvex,
|
|
CoordModeOrigin);
|
|
points[3].x = points[0].x;
|
|
points[3].y = points[0].y;
|
|
XDrawLines(dpy, win, f->folder.gc, points, 4, CoordModeOrigin);
|
|
SetGC(f, GC_UNSET);
|
|
if (w == f->folder.activeW)
|
|
XSetForeground(dpy, f->folder.gc, f->core.background_pixel);
|
|
else
|
|
XSetForeground(dpy, f->folder.gc, f->folder.inactiveBg);
|
|
points[0].x += st;
|
|
points[1].y += st;
|
|
if (f->folder.tabPlacement == XmFOLDER_BOTTOM)
|
|
points[1].y -= st * 2;
|
|
XFillPolygon(dpy, win, f->folder.gc, points, 3,
|
|
Nonconvex, CoordModeOrigin);
|
|
points[3].x = points[0].x;
|
|
points[3].y = points[0].y;
|
|
XDrawLines(dpy, win, f->folder.gc, points, 4, CoordModeOrigin);
|
|
|
|
/* right top line */
|
|
points[0].x = fc->folder.x + fc->folder.width - 1;
|
|
points[0].y = fc->folder.y + cd + st - 1;
|
|
points[1].x = fc->folder.x + fc->folder.width - cd - st;
|
|
points[1].y = fc->folder.y;
|
|
points[2].x = fc->folder.x + fc->folder.width - cd - st;
|
|
points[2].y = fc->folder.y + cd + st - 1;
|
|
if (f->folder.tabPlacement == XmFOLDER_BOTTOM)
|
|
{
|
|
points[0].y = botOff - points[0].y;
|
|
points[1].y = botOff - points[1].y;
|
|
points[2].y = botOff - points[2].y;
|
|
}
|
|
y = fc->folder.y;
|
|
if (f->folder.tabPlacement == XmFOLDER_BOTTOM)
|
|
y = fc->folder.y + fc->folder.height - cd - st;
|
|
SetGC(f, GC_BLANK);
|
|
XFillRectangle(dpy, win, f->folder.gc, fc->folder.x + fc->folder.width -
|
|
cd - st, y, cd + st, cd + st);
|
|
SetGC(f, GC_UNSET);
|
|
if (f->folder.tabPlacement == XmFOLDER_TOP)
|
|
SetGC(f, GC_SHADOWTOP);
|
|
else
|
|
SetGC(f, GC_SHADOWBOT);
|
|
XFillPolygon(dpy, win, f->folder.gc, points, 3, Nonconvex,
|
|
CoordModeOrigin);
|
|
points[3].x = points[0].x;
|
|
points[3].y = points[0].y;
|
|
XDrawLines(dpy, win, f->folder.gc, points, 4, CoordModeOrigin);
|
|
SetGC(f, GC_UNSET);
|
|
if (w == f->folder.activeW)
|
|
XSetForeground(dpy, f->folder.gc, f->core.background_pixel);
|
|
else
|
|
XSetForeground(dpy, f->folder.gc, f->folder.inactiveBg);
|
|
points[0].x -= st;
|
|
points[1].y += st;
|
|
if (f->folder.tabPlacement == XmFOLDER_BOTTOM)
|
|
points[1].y -= st * 2;
|
|
XFillPolygon(dpy, win, f->folder.gc, points, 3, Nonconvex,
|
|
CoordModeOrigin);
|
|
points[3].x = points[0].x;
|
|
points[3].y = points[0].y;
|
|
XDrawLines(dpy, win, f->folder.gc, points, 4, CoordModeOrigin);
|
|
}
|
|
|
|
static void
|
|
DrawTabShadowLineLeftRight(XmLFolderWidget f,
|
|
Widget w)
|
|
{
|
|
XmLFolderConstraintRec *fc;
|
|
Display *dpy;
|
|
Window win;
|
|
XSegment *topSeg, *botSeg;
|
|
XPoint points[4];
|
|
int tCount, bCount, rightOff, i, st, cd, x;
|
|
|
|
dpy = XtDisplay(f);
|
|
win = XtWindow(f);
|
|
fc = (XmLFolderConstraintRec *)(w->core.constraints);
|
|
rightOff = 2 * fc->folder.x + fc->folder.width - 1;
|
|
st = f->manager.shadow_thickness;
|
|
if (!st)
|
|
return;
|
|
cd = f->folder.cornerDimension;
|
|
|
|
tCount = 0;
|
|
bCount = 0;
|
|
topSeg = (XSegment *)malloc(sizeof(XSegment) * st);
|
|
botSeg = (XSegment *)malloc(sizeof(XSegment) * st);
|
|
for (i = 0; i < st; i++)
|
|
{
|
|
/* top tab shadow */
|
|
topSeg[tCount].x1 = fc->folder.x + cd + st;
|
|
topSeg[tCount].y1 = fc->folder.y + i;
|
|
topSeg[tCount].x2 = fc->folder.x + fc->folder.width - 1;
|
|
if (w == f->folder.activeW)
|
|
topSeg[tCount].x2 += i;
|
|
topSeg[tCount].y2 = fc->folder.y + i;
|
|
if (f->folder.tabPlacement == XmFOLDER_RIGHT)
|
|
{
|
|
topSeg[tCount].x1 = rightOff - topSeg[tCount].x1;
|
|
topSeg[tCount].x2 = rightOff - topSeg[tCount].x2;
|
|
}
|
|
tCount++;
|
|
/* bottom tab shadow */
|
|
botSeg[bCount].x1 = fc->folder.x + cd + st;
|
|
botSeg[bCount].y1 = fc->folder.y + fc->folder.height - i - 1;
|
|
botSeg[bCount].x2 = fc->folder.x + fc->folder.width - 1;
|
|
if (w == f->folder.activeW)
|
|
botSeg[bCount].x2 += i;
|
|
botSeg[bCount].y2 = fc->folder.y + fc->folder.height - i - 1;
|
|
if (f->folder.tabPlacement == XmFOLDER_RIGHT)
|
|
{
|
|
botSeg[bCount].x1 = rightOff - botSeg[bCount].x1;
|
|
botSeg[bCount].x2 = rightOff - botSeg[bCount].x2;
|
|
}
|
|
bCount++;
|
|
}
|
|
if (tCount)
|
|
{
|
|
SetGC(f, GC_SHADOWTOP);
|
|
XDrawSegments(dpy, win, f->folder.gc, topSeg, tCount);
|
|
SetGC(f, GC_UNSET);
|
|
}
|
|
if (bCount)
|
|
{
|
|
SetGC(f, GC_SHADOWBOT);
|
|
XDrawSegments(dpy, win, f->folder.gc, botSeg, bCount);
|
|
SetGC(f, GC_UNSET);
|
|
}
|
|
tCount = 0;
|
|
for (i = 0; i < st; i++)
|
|
{
|
|
/* left tab shadow */
|
|
topSeg[tCount].x1 = fc->folder.x + i;
|
|
topSeg[tCount].y1 = fc->folder.y + cd + st;
|
|
topSeg[tCount].x2 = fc->folder.x + i;
|
|
topSeg[tCount].y2 = fc->folder.y + fc->folder.height - cd - st - 1;
|
|
if (f->folder.tabPlacement == XmFOLDER_RIGHT)
|
|
{
|
|
topSeg[tCount].x1 = rightOff - topSeg[tCount].x1;
|
|
topSeg[tCount].x2 = rightOff - topSeg[tCount].x2;
|
|
}
|
|
tCount++;
|
|
}
|
|
if (tCount)
|
|
{
|
|
if (f->folder.tabPlacement == XmFOLDER_LEFT)
|
|
SetGC(f, GC_SHADOWTOP);
|
|
else
|
|
SetGC(f, GC_SHADOWBOT);
|
|
XDrawSegments(dpy, win, f->folder.gc, topSeg, tCount);
|
|
SetGC(f, GC_UNSET);
|
|
}
|
|
free((char *)topSeg);
|
|
free((char *)botSeg);
|
|
|
|
/* top line */
|
|
points[0].x = fc->folder.x + cd + st - 1;
|
|
points[0].y = fc->folder.y;
|
|
points[1].x = fc->folder.x;
|
|
points[1].y = fc->folder.y + cd + st - 1;
|
|
points[2].x = fc->folder.x + cd + st - 1;
|
|
points[2].y = fc->folder.y + cd + st - 1;
|
|
if (f->folder.tabPlacement == XmFOLDER_RIGHT)
|
|
{
|
|
points[0].x = rightOff - points[0].x;
|
|
points[1].x = rightOff - points[1].x;
|
|
points[2].x = rightOff - points[2].x;
|
|
}
|
|
if (f->folder.tabPlacement == XmFOLDER_RIGHT)
|
|
x = fc->folder.x + fc->folder.width - cd - st;
|
|
else
|
|
x = fc->folder.x;
|
|
SetGC(f, GC_BLANK);
|
|
XFillRectangle(dpy, win, f->folder.gc, x, fc->folder.y, cd + st, cd + st);
|
|
SetGC(f, GC_UNSET);
|
|
SetGC(f, GC_SHADOWTOP);
|
|
XFillPolygon(dpy, win, f->folder.gc, points, 3, Nonconvex,
|
|
CoordModeOrigin);
|
|
points[3].x = points[0].x;
|
|
points[3].y = points[0].y;
|
|
XDrawLines(dpy, win, f->folder.gc, points, 4, CoordModeOrigin);
|
|
SetGC(f, GC_UNSET);
|
|
if (w == f->folder.activeW)
|
|
XSetForeground(dpy, f->folder.gc, f->core.background_pixel);
|
|
else
|
|
XSetForeground(dpy, f->folder.gc, f->folder.inactiveBg);
|
|
points[0].y += st;
|
|
points[1].x += st;
|
|
if (f->folder.tabPlacement == XmFOLDER_RIGHT)
|
|
points[1].x -= st * 2;
|
|
XFillPolygon(dpy, win, f->folder.gc, points, 3,
|
|
Nonconvex, CoordModeOrigin);
|
|
points[3].x = points[0].x;
|
|
points[3].y = points[0].y;
|
|
XDrawLines(dpy, win, f->folder.gc, points, 4, CoordModeOrigin);
|
|
|
|
/* bottom line */
|
|
points[0].x = fc->folder.x + cd + st - 1;
|
|
points[0].y = fc->folder.y + fc->folder.height - 1;
|
|
points[1].x = fc->folder.x;
|
|
points[1].y = fc->folder.y + fc->folder.height - cd - st;
|
|
points[2].x = fc->folder.x + cd + st - 1;
|
|
points[2].y = fc->folder.y + fc->folder.height - cd - st;
|
|
if (f->folder.tabPlacement == XmFOLDER_RIGHT)
|
|
{
|
|
points[0].x = rightOff - points[0].x;
|
|
points[1].x = rightOff - points[1].x;
|
|
points[2].x = rightOff - points[2].x;
|
|
}
|
|
if (f->folder.tabPlacement == XmFOLDER_RIGHT)
|
|
x = fc->folder.x + fc->folder.width - cd - st;
|
|
else
|
|
x = fc->folder.x;
|
|
SetGC(f, GC_BLANK);
|
|
XFillRectangle(dpy, win, f->folder.gc, x, fc->folder.y +
|
|
fc->folder.height - cd - st, cd + st, cd + st);
|
|
SetGC(f, GC_UNSET);
|
|
SetGC(f, GC_SHADOWBOT);
|
|
XFillPolygon(dpy, win, f->folder.gc, points, 3, Nonconvex,
|
|
CoordModeOrigin);
|
|
points[3].x = points[0].x;
|
|
points[3].y = points[0].y;
|
|
XDrawLines(dpy, win, f->folder.gc, points, 4, CoordModeOrigin);
|
|
SetGC(f, GC_UNSET);
|
|
if (w == f->folder.activeW)
|
|
XSetForeground(dpy, f->folder.gc, f->core.background_pixel);
|
|
else
|
|
XSetForeground(dpy, f->folder.gc, f->folder.inactiveBg);
|
|
points[0].y -= st;
|
|
points[1].x += st;
|
|
if (f->folder.tabPlacement == XmFOLDER_RIGHT)
|
|
points[1].x -= st * 2;
|
|
XFillPolygon(dpy, win, f->folder.gc, points, 3, Nonconvex,
|
|
CoordModeOrigin);
|
|
points[3].x = points[0].x;
|
|
points[3].y = points[0].y;
|
|
XDrawLines(dpy, win, f->folder.gc, points, 4, CoordModeOrigin);
|
|
}
|
|
|
|
static void
|
|
DrawTabShadowNoneTopBottom(XmLFolderWidget f,
|
|
Widget w)
|
|
{
|
|
XmLFolderConstraintRec *fc;
|
|
Display *dpy;
|
|
Window win;
|
|
XSegment *topSeg, *botSeg;
|
|
int i, st, botOff, tCount, bCount;
|
|
|
|
dpy = XtDisplay(f);
|
|
win = XtWindow(f);
|
|
fc = (XmLFolderConstraintRec *)(w->core.constraints);
|
|
botOff = 2 * fc->folder.y + fc->folder.height - 1;
|
|
st = f->manager.shadow_thickness;
|
|
if (!st)
|
|
return;
|
|
|
|
tCount = 0;
|
|
bCount = 0;
|
|
topSeg = (XSegment *)malloc(sizeof(XSegment) * st * 2);
|
|
botSeg = (XSegment *)malloc(sizeof(XSegment) * st * 2);
|
|
for (i = 0; i < st; i++)
|
|
{
|
|
/* left tab shadow */
|
|
topSeg[tCount].x1 = fc->folder.x + i;
|
|
topSeg[tCount].y1 = fc->folder.y + i;
|
|
topSeg[tCount].x2 = fc->folder.x + i;
|
|
topSeg[tCount].y2 = fc->folder.y + fc->folder.height - 1;
|
|
if (w == f->folder.activeW)
|
|
topSeg[tCount].y2 += i;
|
|
if (f->folder.tabPlacement == XmFOLDER_BOTTOM)
|
|
{
|
|
topSeg[tCount].y1 = botOff - topSeg[tCount].y1;
|
|
topSeg[tCount].y2 = botOff - topSeg[tCount].y2;
|
|
}
|
|
tCount++;
|
|
|
|
/* right tab shadow */
|
|
botSeg[bCount].x1 = fc->folder.x + fc->folder.width - 1 - i;
|
|
botSeg[bCount].y1 = fc->folder.y + i;
|
|
botSeg[bCount].x2 = fc->folder.x + fc->folder.width - 1 - i;
|
|
botSeg[bCount].y2 = fc->folder.y + fc->folder.height - 1;
|
|
if (w == f->folder.activeW)
|
|
botSeg[bCount].y2 += i;
|
|
if (f->folder.tabPlacement == XmFOLDER_BOTTOM)
|
|
{
|
|
botSeg[bCount].y1 = botOff - botSeg[bCount].y1;
|
|
botSeg[bCount].y2 = botOff - botSeg[bCount].y2;
|
|
}
|
|
bCount++;
|
|
}
|
|
if (tCount)
|
|
{
|
|
SetGC(f, GC_SHADOWTOP);
|
|
XDrawSegments(dpy, win, f->folder.gc, topSeg, tCount);
|
|
SetGC(f, GC_UNSET);
|
|
}
|
|
if (bCount)
|
|
{
|
|
SetGC(f, GC_SHADOWBOT);
|
|
XDrawSegments(dpy, win, f->folder.gc, botSeg, bCount);
|
|
SetGC(f, GC_UNSET);
|
|
}
|
|
|
|
tCount = 0;
|
|
for (i = 0; i < st; i++)
|
|
{
|
|
/* top tab shadow */
|
|
topSeg[tCount].x1 = fc->folder.x + i + 1;
|
|
topSeg[tCount].y1 = fc->folder.y + i;
|
|
topSeg[tCount].x2 = fc->folder.x + fc->folder.width - i - 1;
|
|
topSeg[tCount].y2 = fc->folder.y + i;
|
|
if (f->folder.tabPlacement == XmFOLDER_BOTTOM)
|
|
{
|
|
topSeg[tCount].y1 = botOff - topSeg[tCount].y1;
|
|
topSeg[tCount].y2 = botOff - topSeg[tCount].y2;
|
|
}
|
|
tCount++;
|
|
}
|
|
if (tCount)
|
|
{
|
|
if (f->folder.tabPlacement == XmFOLDER_TOP)
|
|
SetGC(f, GC_SHADOWTOP);
|
|
else
|
|
SetGC(f, GC_SHADOWBOT);
|
|
XDrawSegments(dpy, win, f->folder.gc, topSeg, tCount);
|
|
SetGC(f, GC_UNSET);
|
|
}
|
|
free((char *)topSeg);
|
|
free((char *)botSeg);
|
|
}
|
|
|
|
static void
|
|
DrawTabShadowNoneLeftRight(XmLFolderWidget f,
|
|
Widget w)
|
|
{
|
|
XmLFolderConstraintRec *fc;
|
|
Display *dpy;
|
|
Window win;
|
|
XSegment *topSeg, *botSeg;
|
|
int i, st, rightOff, tCount, bCount;
|
|
|
|
dpy = XtDisplay(f);
|
|
win = XtWindow(f);
|
|
fc = (XmLFolderConstraintRec *)(w->core.constraints);
|
|
rightOff = 2 * fc->folder.x + fc->folder.width - 1;
|
|
st = f->manager.shadow_thickness;
|
|
if (!st)
|
|
return;
|
|
|
|
tCount = 0;
|
|
bCount = 0;
|
|
topSeg = (XSegment *)malloc(sizeof(XSegment) * st * 2);
|
|
botSeg = (XSegment *)malloc(sizeof(XSegment) * st * 2);
|
|
for (i = 0; i < st; i++)
|
|
{
|
|
/* bottom tab shadow */
|
|
topSeg[tCount].x1 = fc->folder.x + i;
|
|
topSeg[tCount].y1 = fc->folder.y + i;
|
|
topSeg[tCount].x2 = fc->folder.x + fc->folder.width - 1;
|
|
if (w == f->folder.activeW)
|
|
topSeg[tCount].x2 += i;
|
|
topSeg[tCount].y2 = fc->folder.y + i;
|
|
if (f->folder.tabPlacement == XmFOLDER_RIGHT)
|
|
{
|
|
topSeg[tCount].x1 = rightOff - topSeg[tCount].x1;
|
|
topSeg[tCount].x2 = rightOff - topSeg[tCount].x2;
|
|
}
|
|
tCount++;
|
|
|
|
/* top tab shadow */
|
|
botSeg[bCount].x1 = fc->folder.x + i;
|
|
botSeg[bCount].y1 = fc->folder.y + fc->folder.height - i - 1;
|
|
botSeg[bCount].x2 = fc->folder.x + fc->folder.width - 1;
|
|
if (w == f->folder.activeW)
|
|
botSeg[bCount].x2 += i;
|
|
botSeg[bCount].y2 = fc->folder.y + fc->folder.height - i - 1;
|
|
if (f->folder.tabPlacement == XmFOLDER_RIGHT)
|
|
{
|
|
botSeg[bCount].x1 = rightOff - botSeg[bCount].x1;
|
|
botSeg[bCount].x2 = rightOff - botSeg[bCount].x2;
|
|
}
|
|
bCount++;
|
|
}
|
|
if (tCount)
|
|
{
|
|
SetGC(f, GC_SHADOWTOP);
|
|
XDrawSegments(dpy, win, f->folder.gc, topSeg, tCount);
|
|
SetGC(f, GC_UNSET);
|
|
}
|
|
if (bCount)
|
|
{
|
|
SetGC(f, GC_SHADOWBOT);
|
|
XDrawSegments(dpy, win, f->folder.gc, botSeg, bCount);
|
|
SetGC(f, GC_UNSET);
|
|
}
|
|
|
|
tCount = 0;
|
|
for (i = 0; i < st; i++)
|
|
{
|
|
/* left tab shadow */
|
|
topSeg[tCount].x1 = fc->folder.x + i;
|
|
topSeg[tCount].y1 = fc->folder.y + i + 1;
|
|
topSeg[tCount].x2 = fc->folder.x + i;
|
|
topSeg[tCount].y2 = fc->folder.y + fc->folder.height - i - 1;
|
|
if (f->folder.tabPlacement == XmFOLDER_RIGHT)
|
|
{
|
|
topSeg[tCount].x1 = rightOff - topSeg[tCount].x1;
|
|
topSeg[tCount].x2 = rightOff - topSeg[tCount].x2;
|
|
}
|
|
tCount++;
|
|
}
|
|
if (tCount)
|
|
{
|
|
if (f->folder.tabPlacement == XmFOLDER_RIGHT)
|
|
SetGC(f, GC_SHADOWBOT);
|
|
else
|
|
SetGC(f, GC_SHADOWTOP);
|
|
XDrawSegments(dpy, win, f->folder.gc, topSeg, tCount);
|
|
SetGC(f, GC_UNSET);
|
|
}
|
|
free((char *)topSeg);
|
|
free((char *)botSeg);
|
|
}
|
|
|
|
static void
|
|
SetGC(XmLFolderWidget f,
|
|
int type)
|
|
{
|
|
Display *dpy;
|
|
XGCValues values;
|
|
XtGCMask mask;
|
|
|
|
dpy = XtDisplay(f);
|
|
if (type == GC_SHADOWBOT)
|
|
{
|
|
mask = GCForeground;
|
|
values.foreground = f->manager.bottom_shadow_color;
|
|
if (f->manager.bottom_shadow_pixmap != XmUNSPECIFIED_PIXMAP)
|
|
{
|
|
mask |= GCFillStyle | GCTile;
|
|
values.fill_style = FillTiled;
|
|
values.tile = f->manager.bottom_shadow_pixmap;
|
|
}
|
|
XChangeGC(dpy, f->folder.gc, mask, &values);
|
|
}
|
|
else if (type == GC_SHADOWTOP)
|
|
{
|
|
mask = GCForeground;
|
|
values.foreground = f->manager.top_shadow_color;
|
|
if (f->manager.top_shadow_pixmap != XmUNSPECIFIED_PIXMAP)
|
|
{
|
|
mask |= GCFillStyle | GCTile;
|
|
values.fill_style = FillTiled;
|
|
values.tile = f->manager.top_shadow_pixmap;
|
|
}
|
|
XChangeGC(dpy, f->folder.gc, mask, &values);
|
|
}
|
|
else if (type == GC_BLANK)
|
|
{
|
|
mask = GCForeground;
|
|
values.foreground = f->folder.blankBg;
|
|
if (f->folder.blankPix != XmUNSPECIFIED_PIXMAP)
|
|
{
|
|
mask |= GCFillStyle | GCTile;
|
|
values.fill_style = FillTiled;
|
|
values.tile = f->folder.blankPix;
|
|
}
|
|
XChangeGC(dpy, f->folder.gc, mask, &values);
|
|
}
|
|
else
|
|
{
|
|
mask = GCFillStyle;
|
|
values.fill_style = FillSolid;
|
|
XChangeGC(dpy, f->folder.gc, mask, &values);
|
|
}
|
|
}
|
|
|
|
static void
|
|
DrawTabHighlight(XmLFolderWidget f,
|
|
Widget w)
|
|
{
|
|
XmLFolderConstraintRec *fc;
|
|
Display *dpy;
|
|
Window win;
|
|
int ht;
|
|
|
|
if (!XtIsRealized(w))
|
|
return;
|
|
if (!f->core.visible)
|
|
return;
|
|
dpy = XtDisplay(f);
|
|
win = XtWindow(f);
|
|
fc = (XmLFolderConstraintRec *)(w->core.constraints);
|
|
ht = f->folder.highlightThickness;
|
|
if (f->folder.focusW == w)
|
|
XSetForeground(dpy, f->folder.gc, f->manager.highlight_color);
|
|
else
|
|
{
|
|
if (f->folder.activeW == w)
|
|
XSetForeground(dpy, f->folder.gc, f->core.background_pixel);
|
|
else
|
|
XSetForeground(dpy, f->folder.gc, f->folder.inactiveBg);
|
|
}
|
|
XFillRectangle(dpy, win, f->folder.gc,
|
|
w->core.x - ht, w->core.y - ht,
|
|
XtWidth(w) + w->core.border_width * 2 + ht * 2,
|
|
XtHeight(w) + w->core.border_width * 2 + ht * 2);
|
|
}
|
|
|
|
static void
|
|
SetTabPlacement(XmLFolderWidget f,
|
|
Widget tab)
|
|
{
|
|
if (!XmIsDrawnButton(tab))
|
|
return;
|
|
if (f->folder.allowRotate == True &&
|
|
f->folder.tabPlacement == XmFOLDER_LEFT)
|
|
XmLDrawnButtonSetType(tab, XmDRAWNB_STRING, XmDRAWNB_UP);
|
|
else if (f->folder.allowRotate == True &&
|
|
f->folder.tabPlacement == XmFOLDER_RIGHT)
|
|
XmLDrawnButtonSetType(tab, XmDRAWNB_STRING, XmDRAWNB_DOWN);
|
|
else
|
|
XmLDrawnButtonSetType(tab, XmDRAWNB_STRING, XmDRAWNB_RIGHT);
|
|
if (XtIsRealized(tab))
|
|
XClearArea(XtDisplay(tab), XtWindow(tab), 0, 0, 0, 0, True);
|
|
}
|
|
|
|
static void
|
|
GetTabRect(XmLFolderWidget f,
|
|
Widget tab,
|
|
XRectangle *rect,
|
|
int includeShadow)
|
|
{
|
|
XmLFolderConstraintRec *fc;
|
|
int st;
|
|
|
|
st = f->manager.shadow_thickness;
|
|
fc = (XmLFolderConstraintRec *)(tab->core.constraints);
|
|
rect->x = fc->folder.x;
|
|
rect->y = fc->folder.y;
|
|
rect->width = fc->folder.width;
|
|
rect->height = fc->folder.height;
|
|
if (includeShadow)
|
|
{
|
|
if (f->folder.tabPlacement == XmFOLDER_TOP)
|
|
rect->height += st;
|
|
else if (f->folder.tabPlacement == XmFOLDER_BOTTOM)
|
|
{
|
|
rect->y -= st;
|
|
rect->height += st;
|
|
}
|
|
else if (f->folder.tabPlacement == XmFOLDER_LEFT)
|
|
rect->width += st;
|
|
else
|
|
{
|
|
rect->x -= st;
|
|
rect->width += st;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
SetActiveTab(XmLFolderWidget f,
|
|
Widget w,
|
|
XEvent *event,
|
|
Boolean notify)
|
|
{
|
|
XmLFolderCallbackStruct cbs;
|
|
XmLFolderConstraintRec *fc, *cfc;
|
|
int i, j, pos;
|
|
Display *dpy;
|
|
Window win;
|
|
Widget activeW, child, mw, managedW;
|
|
WidgetList children;
|
|
XRectangle rect;
|
|
char *name, buf[256];
|
|
|
|
win = (Window)NULL;
|
|
|
|
if (f->folder.activeW == w)
|
|
return;
|
|
dpy = 0;
|
|
if (XtIsRealized((Widget)f) && f->core.visible)
|
|
{
|
|
dpy = XtDisplay(f);
|
|
win = XtWindow(f);
|
|
}
|
|
|
|
pos = -1;
|
|
for (i = 0; i < f->folder.tabCount; i++)
|
|
if (w == f->folder.tabs[i])
|
|
pos = i;
|
|
|
|
cbs.allowActivate = 1;
|
|
cbs.layoutNeeded = 0;
|
|
if (notify == True)
|
|
{
|
|
if (f->folder.debugLevel)
|
|
fprintf(stderr, "XmLFolder: activated %d\n", pos);
|
|
cbs.reason = XmCR_ACTIVATE;
|
|
cbs.event = event;
|
|
cbs.pos = pos;
|
|
XtCallCallbackList((Widget)f, f->folder.activateCallback, &cbs);
|
|
}
|
|
if (!cbs.allowActivate)
|
|
return;
|
|
|
|
/* redraw current active tab */
|
|
activeW = f->folder.activeW;
|
|
if (activeW && dpy)
|
|
{
|
|
GetTabRect(f, activeW, &rect, 1);
|
|
XClearArea(dpy, win, rect.x, rect.y, rect.width,
|
|
rect.height, True);
|
|
}
|
|
|
|
f->folder.activeTab = pos;
|
|
f->folder.activeW = w;
|
|
if (!w)
|
|
return;
|
|
|
|
/* Not sure this needs to be in the 3.0 (Microline) stuff */
|
|
PrimFocusIn(w, NULL, NULL, NULL);
|
|
|
|
/* if we selected a tab not in active row - move row into place */
|
|
if (f->folder.tabsPerRow)
|
|
{
|
|
fc = (XmLFolderConstraintRec *)(w->core.constraints);
|
|
if (fc->folder.row != f->folder.activeRow)
|
|
Layout(f, False);
|
|
}
|
|
|
|
/* manage this tabs managed widget if it exists */
|
|
children = f->composite.children;
|
|
f->folder.allowLayout = 0;
|
|
for (i = 0; i < f->composite.num_children; i++)
|
|
{
|
|
child = children[i];
|
|
if (!XtIsSubclass(child, xmPrimitiveWidgetClass))
|
|
continue;
|
|
fc = (XmLFolderConstraintRec *)(child->core.constraints);
|
|
managedW = 0;
|
|
if (fc->folder.managedName)
|
|
{
|
|
for (j = 0; j < f->composite.num_children; j++)
|
|
{
|
|
mw = children[j];
|
|
if (XtIsSubclass(mw, xmPrimitiveWidgetClass))
|
|
continue;
|
|
name = XtName(mw);
|
|
if (name && !strcmp(name, fc->folder.managedName))
|
|
managedW = mw;
|
|
cfc = (XmLFolderConstraintRec *)(mw->core.constraints);
|
|
name = cfc->folder.managedName;
|
|
if (name && !strcmp(name, fc->folder.managedName))
|
|
managedW = mw;
|
|
}
|
|
if (!managedW)
|
|
{
|
|
sprintf(buf, "SetActiveTab() - managed widget named ");
|
|
strcat(buf, fc->folder.managedName);
|
|
strcat(buf, " not found");
|
|
XmLWarning(child, buf);
|
|
}
|
|
}
|
|
else
|
|
managedW = fc->folder.managedW;
|
|
if (managedW)
|
|
{
|
|
if (w == child && !XtIsManaged(managedW))
|
|
XtManageChild(managedW);
|
|
if (w != child && XtIsManaged(managedW))
|
|
XtUnmanageChild(managedW);
|
|
}
|
|
}
|
|
f->folder.allowLayout = 1;
|
|
|
|
/* redraw new active tab */
|
|
if (dpy)
|
|
{
|
|
GetTabRect(f, w, &rect, 1);
|
|
XClearArea(dpy, win, rect.x, rect.y, rect.width, rect.height, True);
|
|
XmProcessTraversal(w, XmTRAVERSE_CURRENT);
|
|
}
|
|
|
|
if (cbs.layoutNeeded)
|
|
Layout(f, 0);
|
|
}
|
|
|
|
/*
|
|
Utility
|
|
*/
|
|
|
|
static void
|
|
GetCoreBackground(Widget w,
|
|
int offset,
|
|
XrmValue *value)
|
|
{
|
|
value->addr = (caddr_t)&w->core.background_pixel;
|
|
}
|
|
|
|
static void
|
|
GetDefaultTabWidgetClass(Widget w,
|
|
int offset,
|
|
XrmValue *value)
|
|
{
|
|
value->addr = (caddr_t)&xmDrawnButtonWidgetClass;
|
|
}
|
|
|
|
static void
|
|
GetManagerForeground(Widget w,
|
|
int offset,
|
|
XrmValue *value)
|
|
{
|
|
XmLFolderWidget f;
|
|
|
|
f = (XmLFolderWidget)w;
|
|
value->addr = (caddr_t)&f->manager.foreground;
|
|
}
|
|
|
|
static Boolean
|
|
ServerDrawsArcsLarge(Display *dpy,
|
|
int debug)
|
|
{
|
|
Pixmap pixmap;
|
|
XImage *image;
|
|
Window root;
|
|
long pixel;
|
|
int x, y, width, height, result;
|
|
GC gc;
|
|
|
|
root = DefaultRootWindow(dpy);
|
|
width = 5;
|
|
height = 5;
|
|
pixmap = XCreatePixmap(dpy, root, width, height, 1);
|
|
gc = XCreateGC(dpy, pixmap, 0L, NULL);
|
|
XSetForeground(dpy, gc, 0L);
|
|
XFillRectangle(dpy, pixmap, gc, 0, 0, width, height);
|
|
XSetForeground(dpy, gc, 1L);
|
|
XDrawArc(dpy, pixmap, gc, 0, 0, width, height, 0, 360 * 64);
|
|
image = XGetImage(dpy, pixmap, 0, 0, width, height, AllPlanes, ZPixmap);
|
|
if (debug)
|
|
{
|
|
fprintf(stderr, "Test X server drawn arc (%d by %d):\n",
|
|
width, height);
|
|
for (y = 0; y < height; y++)
|
|
{
|
|
fprintf(stderr, " ");
|
|
for (x = 0; x < width; x++)
|
|
{
|
|
pixel = XGetPixel(image, x, y);
|
|
if (pixel == 0L)
|
|
fprintf(stderr, ".");
|
|
else
|
|
fprintf(stderr, "X");
|
|
}
|
|
fprintf(stderr, "\n");
|
|
}
|
|
}
|
|
if (XGetPixel(image, width - 1, height / 2) != 1L)
|
|
{
|
|
result = 1;
|
|
if (debug)
|
|
fprintf(stderr, "X Server Draws Arcs 1 Pixel Large\n");
|
|
}
|
|
else
|
|
{
|
|
result = 0;
|
|
if (debug)
|
|
fprintf(stderr, "X Server Draws Arcs Within Bounds\n");
|
|
}
|
|
XDestroyImage(image);
|
|
XFreeGC(dpy, gc);
|
|
XFreePixmap(dpy, pixmap);
|
|
return result;
|
|
}
|
|
|
|
/*
|
|
Getting and Setting Values
|
|
*/
|
|
|
|
static Boolean
|
|
SetValues(Widget curW,
|
|
Widget reqW,
|
|
Widget newW,
|
|
ArgList args,
|
|
Cardinal *narg)
|
|
{
|
|
XmLFolderWidget f;
|
|
XmLFolderWidget cur;
|
|
int i;
|
|
Boolean needsLayout, needsRedisplay;
|
|
|
|
f = (XmLFolderWidget)newW;
|
|
cur = (XmLFolderWidget)curW;
|
|
needsLayout = False;
|
|
needsRedisplay = False;
|
|
#define NE(value) (f->value != cur->value)
|
|
if (NE(folder.tabBarHeight))
|
|
{
|
|
XmLWarning((Widget)f, "SetValues() - can't set tabBarHeight");
|
|
f->folder.tabBarHeight = cur->folder.tabBarHeight;
|
|
}
|
|
if (NE(folder.tabCount))
|
|
{
|
|
XmLWarning((Widget)f, "SetValues() - can't set tabCount");
|
|
f->folder.tabCount = cur->folder.tabCount;
|
|
}
|
|
if (NE(folder.activeTab))
|
|
{
|
|
XmLWarning((Widget)f, "SetValues() - can't set activeTab");
|
|
f->folder.activeTab = cur->folder.activeTab;
|
|
}
|
|
if (f->folder.cornerDimension < 1)
|
|
{
|
|
XmLWarning((Widget)f, "SetValues() - cornerDimension can't be < 1");
|
|
f->folder.cornerDimension = cur->folder.cornerDimension;
|
|
}
|
|
if (NE(folder.tabPlacement) ||
|
|
NE(folder.allowRotate))
|
|
{
|
|
f->folder.allowLayout = 0;
|
|
for (i = 0; i < f->folder.tabCount; i++)
|
|
SetTabPlacement(f, f->folder.tabs[i]);
|
|
f->folder.allowLayout = 1;
|
|
needsLayout = True;
|
|
}
|
|
if (NE(folder.inactiveBg) ||
|
|
NE(folder.blankBg) ||
|
|
NE(folder.blankPix) ||
|
|
NE(folder.inactiveFg))
|
|
needsRedisplay = True;
|
|
if (NE(folder.cornerDimension) ||
|
|
NE(folder.cornerStyle) ||
|
|
NE(folder.highlightThickness) ||
|
|
NE(folder.marginHeight) ||
|
|
NE(folder.marginWidth) ||
|
|
NE(folder.pixmapMargin) ||
|
|
NE(manager.shadow_thickness) ||
|
|
NE(folder.tabsPerRow) ||
|
|
NE(folder.spacing))
|
|
needsLayout = True;
|
|
if (NE(folder.fontList))
|
|
{
|
|
XmFontListFree(cur->folder.fontList);
|
|
CopyFontList(f);
|
|
}
|
|
#undef NE
|
|
if (needsLayout == True)
|
|
Layout(f, 1);
|
|
return needsRedisplay;
|
|
}
|
|
|
|
static void
|
|
CopyFontList(XmLFolderWidget f)
|
|
{
|
|
if (!f->folder.fontList)
|
|
f->folder.fontList = XmLFontListCopyDefault((Widget)f);
|
|
else
|
|
f->folder.fontList = XmFontListCopy(f->folder.fontList);
|
|
if (!f->folder.fontList)
|
|
XmLWarning((Widget)f, "- fatal error - font list NULL");
|
|
}
|
|
|
|
static Boolean
|
|
ConstraintSetValues(Widget curW,
|
|
Widget reqW,
|
|
Widget newW,
|
|
ArgList args,
|
|
Cardinal *narg)
|
|
{
|
|
XmLFolderConstraintRec *cons, *curCons;
|
|
XmLFolderWidget f;
|
|
int i, hasLabelChange;
|
|
|
|
f = (XmLFolderWidget)XtParent(newW);
|
|
if (!XtIsRectObj(newW))
|
|
return False;
|
|
cons = (XmLFolderConstraintRec *)newW->core.constraints;
|
|
curCons = (XmLFolderConstraintRec *)curW->core.constraints;
|
|
#define NE(value) (cons->value != curCons->value)
|
|
if (NE(folder.managedName))
|
|
{
|
|
if (curCons->folder.managedName)
|
|
free((char *)curCons->folder.managedName);
|
|
if (cons->folder.managedName)
|
|
cons->folder.managedName = (char *)strdup(cons->folder.managedName);
|
|
}
|
|
#undef NE
|
|
hasLabelChange = 0;
|
|
if (XtIsSubclass(newW, xmPrimitiveWidgetClass))
|
|
{
|
|
for (i = 0; i < *narg; i++)
|
|
if (args[i].name && !strcmp(args[i].name, XmNlabelString))
|
|
hasLabelChange = 1;
|
|
if (hasLabelChange &&
|
|
(f->folder.tabPlacement == XmFOLDER_LEFT ||
|
|
f->folder.tabPlacement == XmFOLDER_RIGHT))
|
|
{
|
|
f->folder.allowLayout = 0;
|
|
for (i = 0; i < f->folder.tabCount; i++)
|
|
SetTabPlacement(f, f->folder.tabs[i]);
|
|
f->folder.allowLayout = 1;
|
|
}
|
|
}
|
|
if (hasLabelChange ||
|
|
curCons->folder.pix != cons->folder.pix ||
|
|
curCons->folder.inactPix != cons->folder.inactPix)
|
|
Layout((XmLFolderWidget)XtParent(curW), 1);
|
|
return False;
|
|
}
|
|
|
|
static Boolean
|
|
CvtStringToCornerStyle(Display *dpy,
|
|
XrmValuePtr args,
|
|
Cardinal *narg,
|
|
XrmValuePtr fromVal,
|
|
XrmValuePtr toVal,
|
|
XtPointer *data)
|
|
{
|
|
static XmLStringToUCharMap map[] =
|
|
{
|
|
{ "CORNER_NONE", XmCORNER_NONE },
|
|
{ "CORNER_LINE", XmCORNER_LINE },
|
|
{ "CORNER_ARC", XmCORNER_ARC },
|
|
{ 0, 0 },
|
|
};
|
|
|
|
return XmLCvtStringToUChar(dpy, "XmRCornerStyle", map, fromVal, toVal);
|
|
}
|
|
|
|
static Boolean
|
|
CvtStringToFolderResizePolicy(Display *dpy,
|
|
XrmValuePtr args,
|
|
Cardinal *narg,
|
|
XrmValuePtr fromVal,
|
|
XrmValuePtr toVal,
|
|
XtPointer *data)
|
|
{
|
|
static XmLStringToUCharMap map[] =
|
|
{
|
|
{ "RESIZE_NONE", XmRESIZE_NONE },
|
|
{ "RESIZE_STATIC", XmRESIZE_STATIC },
|
|
{ "RESIZE_DYNAMIC", XmRESIZE_DYNAMIC },
|
|
{ 0, 0 },
|
|
};
|
|
|
|
return XmLCvtStringToUChar(dpy, "XmRFolderResizePolicy", map,
|
|
fromVal, toVal);
|
|
}
|
|
|
|
static Boolean
|
|
CvtStringToTabPlacement(Display *dpy,
|
|
XrmValuePtr args,
|
|
Cardinal *narg,
|
|
XrmValuePtr fromVal,
|
|
XrmValuePtr toVal,
|
|
XtPointer *data)
|
|
{
|
|
static XmLStringToUCharMap map[] =
|
|
{
|
|
{ "FOLDER_TOP", XmFOLDER_TOP },
|
|
{ "FOLDER_LEFT", XmFOLDER_LEFT },
|
|
{ "FOLDER_BOTTOM", XmFOLDER_BOTTOM },
|
|
{ "FOLDER_RIGHT", XmFOLDER_RIGHT },
|
|
{ 0, 0 },
|
|
};
|
|
|
|
return XmLCvtStringToUChar(dpy, "XmRTabPlacement", map, fromVal, toVal);
|
|
}
|
|
|
|
/*
|
|
Actions, Callbacks and Handlers
|
|
*/
|
|
|
|
static void
|
|
Activate(Widget w,
|
|
XEvent *event,
|
|
String *params,
|
|
Cardinal *nparam)
|
|
{
|
|
XmLFolderWidget f;
|
|
XButtonEvent *be;
|
|
XRectangle rect;
|
|
Widget tab;
|
|
int i;
|
|
|
|
f = (XmLFolderWidget)w;
|
|
if (!event || event->type != ButtonPress)
|
|
return;
|
|
be = (XButtonEvent *)event;
|
|
if (f->folder.debugLevel)
|
|
fprintf(stderr, "XmLFolder: ButtonPress %d %d\n", be->x, be->y);
|
|
for (i = 0; i < f->folder.tabCount; i++)
|
|
{
|
|
tab = f->folder.tabs[i];
|
|
if (!XtIsManaged(tab) || !XtIsSensitive(tab))
|
|
continue;
|
|
GetTabRect(f, tab, &rect, 0);
|
|
if (be->x > rect.x && be->x < rect.x + (int)rect.width &&
|
|
be->y > rect.y && be->y < rect.y + (int)rect.height)
|
|
{
|
|
if (f->folder.debugLevel)
|
|
fprintf(stderr, "XmLFolder: Pressed tab %d\n", i);
|
|
SetActiveTab(f, tab, event, True);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
PrimActivate(Widget w,
|
|
XtPointer clientData,
|
|
XtPointer callData)
|
|
{
|
|
XmLFolderWidget f;
|
|
XmAnyCallbackStruct *cbs;
|
|
|
|
f = (XmLFolderWidget)XtParent(w);
|
|
cbs = (XmAnyCallbackStruct *)callData;
|
|
SetActiveTab(f, w, cbs->event, True);
|
|
}
|
|
|
|
static void
|
|
PrimFocusIn(Widget w,
|
|
XEvent *event,
|
|
String *params,
|
|
Cardinal *nparam)
|
|
{
|
|
XmLFolderWidget f;
|
|
Widget prevW;
|
|
|
|
f = (XmLFolderWidget)XtParent(w);
|
|
prevW = f->folder.focusW;
|
|
f->folder.focusW = w;
|
|
DrawTabHighlight(f, w);
|
|
if (prevW)
|
|
DrawTabHighlight(f, prevW);
|
|
XmProcessTraversal(w, XmTRAVERSE_CURRENT);
|
|
}
|
|
|
|
static void
|
|
PrimFocusOut(Widget w,
|
|
XEvent *event,
|
|
String *params,
|
|
Cardinal *nparam)
|
|
{
|
|
XmLFolderWidget f;
|
|
Widget prevW;
|
|
|
|
f = (XmLFolderWidget)XtParent(w);
|
|
prevW = f->folder.focusW;
|
|
f->folder.focusW = 0;
|
|
if (prevW)
|
|
DrawTabHighlight(f, prevW);
|
|
DrawTabHighlight(f, w);
|
|
}
|
|
|
|
/*
|
|
Public Functions
|
|
*/
|
|
|
|
Widget
|
|
XmLCreateFolder(Widget parent,
|
|
char *name,
|
|
ArgList arglist,
|
|
Cardinal argcount)
|
|
{
|
|
return XtCreateWidget(name, xmlFolderWidgetClass, parent,
|
|
arglist, argcount);
|
|
}
|
|
|
|
Widget
|
|
XmLFolderAddBitmapTab(Widget w,
|
|
XmString string,
|
|
char *bitmapBits,
|
|
int bitmapWidth,
|
|
int bitmapHeight)
|
|
{
|
|
XmLFolderWidget f;
|
|
Widget tab;
|
|
Pixmap pix, inactPix;
|
|
Window root;
|
|
Display *dpy;
|
|
int depth;
|
|
char name[20];
|
|
|
|
if (!XmLIsFolder(w))
|
|
{
|
|
XmLWarning(w, "AddBitmapTab() - widget not a XmLFolder");
|
|
return 0;
|
|
}
|
|
f = (XmLFolderWidget)w;
|
|
dpy = XtDisplay(w);
|
|
root = DefaultRootWindow(dpy);
|
|
depth = DefaultDepthOfScreen(XtScreen(w));
|
|
pix = XCreatePixmapFromBitmapData(dpy, root, bitmapBits,
|
|
bitmapWidth, bitmapHeight, f->manager.foreground,
|
|
f->core.background_pixel, depth);
|
|
inactPix = XCreatePixmapFromBitmapData(dpy, root, bitmapBits,
|
|
bitmapWidth, bitmapHeight, f->folder.inactiveFg,
|
|
f->folder.inactiveBg, depth);
|
|
sprintf(name, "tab%d", f->folder.tabCount);
|
|
tab = XtVaCreateManagedWidget(name,
|
|
xmDrawnButtonWidgetClass, w,
|
|
XmNfontList, f->folder.fontList,
|
|
XmNmarginWidth, 0,
|
|
XmNmarginHeight, 0,
|
|
XmNlabelString, string,
|
|
XmNtabPixmap, pix,
|
|
XmNtabInactivePixmap, inactPix,
|
|
XmNtabFreePixmaps, True,
|
|
NULL);
|
|
return tab;
|
|
}
|
|
|
|
Widget
|
|
XmLFolderAddBitmapTabForm(Widget w,
|
|
XmString string,
|
|
char *bitmapBits,
|
|
int bitmapWidth,
|
|
int bitmapHeight)
|
|
{
|
|
Widget form, tab;
|
|
XmLFolderWidget f;
|
|
char name[20];
|
|
|
|
if (!XmLIsFolder(w))
|
|
{
|
|
XmLWarning(w, "AddBitmapTabForm() - widget not a XmLFolder");
|
|
return 0;
|
|
}
|
|
f = (XmLFolderWidget)w;
|
|
tab = XmLFolderAddBitmapTab(w, string, bitmapBits,
|
|
bitmapWidth, bitmapHeight);
|
|
sprintf(name, "form%d", f->folder.tabCount);
|
|
form = XtVaCreateManagedWidget(name,
|
|
xmFormWidgetClass, w,
|
|
XmNbackground, f->core.background_pixel,
|
|
NULL);
|
|
XtVaSetValues(tab, XmNtabManagedWidget, form, NULL);
|
|
return form;
|
|
}
|
|
|
|
Widget
|
|
XmLFolderAddTab(Widget w,
|
|
XmString string)
|
|
{
|
|
Widget tab;
|
|
XmLFolderWidget f;
|
|
char name[20];
|
|
|
|
if (!XmLIsFolder(w))
|
|
{
|
|
XmLWarning(w, "AddTab() - widget not a XmLFolder");
|
|
return 0;
|
|
}
|
|
f = (XmLFolderWidget)w;
|
|
sprintf(name, "tab%d", f->folder.tabCount);
|
|
tab = XtVaCreateManagedWidget(name,
|
|
xmDrawnButtonWidgetClass, w,
|
|
XmNfontList, f->folder.fontList,
|
|
XmNmarginWidth, 0,
|
|
XmNmarginHeight, 0,
|
|
XmNlabelString, string,
|
|
NULL);
|
|
return tab;
|
|
}
|
|
|
|
Widget
|
|
XmLFolderAddTabFromClass(Widget w,
|
|
XmString string)
|
|
{
|
|
Widget tab;
|
|
XmLFolderWidget f;
|
|
char name[20];
|
|
|
|
if (!XmLIsFolder(w))
|
|
{
|
|
XmLWarning(w, "AddTab() - widget not a XmLFolder");
|
|
return 0;
|
|
}
|
|
f = (XmLFolderWidget)w;
|
|
sprintf(name, "tab%d", f->folder.tabCount);
|
|
|
|
tab = XtVaCreateManagedWidget(name,
|
|
f->folder.tabWidgetClass,
|
|
/* xmDrawnButtonWidgetClass, */
|
|
w,
|
|
XmNfontList, f->folder.fontList,
|
|
/* XmNmarginWidth, 0, */
|
|
/* XmNmarginHeight, 0, */
|
|
XmNlabelString, string,
|
|
NULL);
|
|
return tab;
|
|
}
|
|
|
|
Widget
|
|
XmLFolderAddTabForm(Widget w,
|
|
XmString string)
|
|
{
|
|
Widget form, tab;
|
|
XmLFolderWidget f;
|
|
char name[20];
|
|
|
|
if (!XmLIsFolder(w))
|
|
{
|
|
XmLWarning(w, "AddBitmapTabForm() - widget not a XmLFolder");
|
|
return 0;
|
|
}
|
|
f = (XmLFolderWidget)w;
|
|
tab = XmLFolderAddTab(w, string);
|
|
sprintf(name, "form%d", f->folder.tabCount);
|
|
form = XtVaCreateManagedWidget(name,
|
|
xmFormWidgetClass, w,
|
|
XmNbackground, f->core.background_pixel,
|
|
NULL);
|
|
XtVaSetValues(tab, XmNtabManagedWidget, form, NULL);
|
|
return form;
|
|
}
|
|
|
|
void
|
|
XmLFolderSetActiveTab(Widget w,
|
|
int position,
|
|
Boolean notify)
|
|
{
|
|
XmLFolderWidget f;
|
|
|
|
if (!XmLIsFolder(w))
|
|
{
|
|
XmLWarning(w, "SetActiveTab() - widget not a XmLFolder");
|
|
return;
|
|
}
|
|
f = (XmLFolderWidget)w;
|
|
if (position < 0 || position >= f->folder.tabCount)
|
|
{
|
|
XmLWarning(w, "SetActiveTab() - invalid position");
|
|
return;
|
|
}
|
|
SetActiveTab(f, f->folder.tabs[position], 0, notify);
|
|
}
|