mirror of
https://github.com/gryf/wmaker.git
synced 2026-02-09 10:05:49 +01:00
started Appearance update in WPrefs
added tabbed view changed some callbacks to delegate like stuff (textfield and browser)
This commit is contained in:
@@ -3,6 +3,24 @@ changes since wmaker 0.53.0:
|
||||
|
||||
- added balloon help
|
||||
- fixed a bug with setting initial path in browsers.
|
||||
- added WMSetButtonImageDimsWhenDisabled()
|
||||
- changed simple callback/notifications to delegate-like stuff. Affected
|
||||
widgets are:
|
||||
WMBrowser
|
||||
- WMSetBrowserFillProc() was replaced with WMSetBrowserDelegate
|
||||
- WMBrowserDidScrollNotification was replaced with a delegate callback
|
||||
|
||||
WMTextField (not completed yet)
|
||||
The notifications will still work, but using the delegate is preferable
|
||||
|
||||
How to convert old code to delegate callbacks:
|
||||
Create a variable (static or dynamic) of the type of the delegate for
|
||||
the widget type. Replace the notification observers with the
|
||||
equivalent delegate callbacks. Put pointers to the callbacks
|
||||
in the delegate variable.
|
||||
Take a look in wfilepanel.c to see how it is used there.
|
||||
|
||||
- added WMTabView
|
||||
|
||||
changes since wmaker 0.52.0:
|
||||
............................
|
||||
|
||||
@@ -89,6 +89,7 @@ libWINGs_a_SOURCES = \
|
||||
wscrollview.c \
|
||||
wslider.c \
|
||||
wsplitview.c \
|
||||
wtabview.c \
|
||||
wtextfield.c \
|
||||
wwindow.c \
|
||||
wview.c \
|
||||
|
||||
@@ -139,7 +139,7 @@ wmquery_LDADD = libWINGs.a $(LIBLIST)
|
||||
EXTRA_DIST = logo.xpm
|
||||
|
||||
# wbutton.c
|
||||
libWINGs_a_SOURCES = WINGs.h WINGsP.h configuration.c llist.h llist.c international.c notification.c selection.c userdefaults.c wapplication.c wballoon.c wbrowser.c wbutton.c wcolor.c wcolorpanel.c wcolorwell.c wevent.c wfilepanel.c wframe.c wfont.c wfontpanel.c widgets.c wlabel.c wlist.c wmisc.c wpanel.c wpixmap.c wpopupbutton.c wscroller.c wscrollview.c wslider.c wsplitview.c wtextfield.c wwindow.c wview.c error.c findfile.c hashtable.c memory.c usleep.c
|
||||
libWINGs_a_SOURCES = WINGs.h WINGsP.h configuration.c llist.h llist.c international.c notification.c selection.c userdefaults.c wapplication.c wballoon.c wbrowser.c wbutton.c wcolor.c wcolorpanel.c wcolorwell.c wevent.c wfilepanel.c wframe.c wfont.c wfontpanel.c widgets.c wlabel.c wlist.c wmisc.c wpanel.c wpixmap.c wpopupbutton.c wscroller.c wscrollview.c wslider.c wsplitview.c wtabview.c wtextfield.c wwindow.c wview.c error.c findfile.c hashtable.c memory.c usleep.c
|
||||
|
||||
|
||||
INCLUDES = -I$(top_srcdir)/wrlib -I$(top_srcdir)/src -DRESOURCE_PATH=\"$(datadir)/WINGs\" @HEADER_SEARCH_PATH@ -DDEBUG
|
||||
@@ -163,8 +163,8 @@ notification.o selection.o userdefaults.o wapplication.o wballoon.o \
|
||||
wbrowser.o wbutton.o wcolor.o wcolorpanel.o wcolorwell.o wevent.o \
|
||||
wfilepanel.o wframe.o wfont.o wfontpanel.o widgets.o wlabel.o wlist.o \
|
||||
wmisc.o wpanel.o wpixmap.o wpopupbutton.o wscroller.o wscrollview.o \
|
||||
wslider.o wsplitview.o wtextfield.o wwindow.o wview.o error.o \
|
||||
findfile.o hashtable.o memory.o usleep.o
|
||||
wslider.o wsplitview.o wtabview.o wtextfield.o wwindow.o wview.o \
|
||||
error.o findfile.o hashtable.o memory.o usleep.o
|
||||
AR = ar
|
||||
PROGRAMS = $(noinst_PROGRAMS)
|
||||
|
||||
|
||||
@@ -58,6 +58,7 @@ Widgets provided by WINGs:
|
||||
- scrollable view
|
||||
- color well
|
||||
- split view (only 2 subviews)
|
||||
- tabbed view
|
||||
|
||||
- input box
|
||||
- file panel
|
||||
@@ -86,7 +87,6 @@ Wish list: (I don't have the know-how or time to do them)
|
||||
- matrix (like NSMatrix)
|
||||
- splitviews with more than 2 subviews
|
||||
- font manager (like NSFontManager)
|
||||
- finish file panel, open/save
|
||||
- finish other wigets
|
||||
- optimize list scrolling (XCopyArea() the area that's already drawn)
|
||||
- InterfaceMaker?
|
||||
|
||||
112
WINGs/WINGs.h
112
WINGs/WINGs.h
@@ -160,13 +160,21 @@ typedef enum {
|
||||
|
||||
/* matrix types */
|
||||
typedef enum {
|
||||
WMMRadioMode,
|
||||
WMMHighlightMode,
|
||||
WMMListMode,
|
||||
WMMTrackMode
|
||||
WMRadioMode,
|
||||
WMHighlightMode,
|
||||
WMListMode,
|
||||
WMTrackMode
|
||||
} WMMatrixTypes;
|
||||
|
||||
|
||||
typedef enum {
|
||||
WTTopTabsBevelBorder,
|
||||
WTNoTabsBevelBorder,
|
||||
WTNoTabsLineBorder,
|
||||
WTNoTabsNoBorder
|
||||
} WMTabViewTypes;
|
||||
|
||||
|
||||
/* text movement types */
|
||||
enum {
|
||||
WMIllegalTextMovement,
|
||||
@@ -255,7 +263,8 @@ enum {
|
||||
WC_ColorWell = 10,
|
||||
WC_Slider = 11,
|
||||
WC_Matrix = 12, /* not ready */
|
||||
WC_SplitView = 13
|
||||
WC_SplitView = 13,
|
||||
WC_TabView = 14
|
||||
};
|
||||
|
||||
/* All widgets must start with the following structure
|
||||
@@ -297,8 +306,12 @@ typedef struct W_ColorWell WMColorWell;
|
||||
typedef struct W_Slider WMSlider;
|
||||
typedef struct W_Matrix WMMatrix; /* not ready */
|
||||
typedef struct W_SplitView WMSplitView;
|
||||
typedef struct W_TabView WMTabView;
|
||||
|
||||
/* not widgets */
|
||||
typedef struct W_TabViewItem WMTabViewItem;
|
||||
|
||||
|
||||
typedef struct W_FilePanel WMFilePanel;
|
||||
typedef WMFilePanel WMOpenPanel;
|
||||
typedef WMFilePanel WMSavePanel;
|
||||
@@ -392,9 +405,6 @@ typedef void WMSplitViewConstrainProc(WMSplitView *sPtr, int dividerIndex,
|
||||
typedef WMWidget *WMMatrixCreateCellProc(WMMatrix *mPtr);
|
||||
|
||||
|
||||
typedef void WMBrowserFillColumnProc(WMBrowser *bPtr, int column);
|
||||
|
||||
|
||||
typedef Bool WMConvertSelectionProc(WMWidget *w, Atom selection, Atom target,
|
||||
Atom *type, void **value, unsigned *length,
|
||||
int *format);
|
||||
@@ -403,6 +413,45 @@ typedef void WMLoseSelectionProc(WMWidget *w, Atom selection);
|
||||
|
||||
typedef void WMSelectionDoneProc(WMWidget *w, Atom selection, Atom target);
|
||||
|
||||
|
||||
|
||||
|
||||
typedef struct WMBrowserDelegate {
|
||||
void *data;
|
||||
|
||||
void (*createRowsForColumn)(struct WMBrowserDelegate *self,
|
||||
WMBrowser *sender, int column, WMList *list);
|
||||
|
||||
char* (*titleOfColumn)(struct WMBrowserDelegate *self, WMBrowser *sender,
|
||||
int column);
|
||||
|
||||
void (*didScroll)(struct WMBrowserDelegate *self, WMBrowser *sender);
|
||||
|
||||
void (*willScroll)(struct WMBrowserDelegate *self, WMBrowser *sender);
|
||||
} WMBrowserDelegate;
|
||||
|
||||
|
||||
typedef struct WMTextFieldDelegate {
|
||||
void *data;
|
||||
|
||||
void (*didBeginEditing)(struct WMTextFieldDelegate *self,
|
||||
WMNotification *notif);
|
||||
|
||||
void (*didChange)(struct WMTextFieldDelegate *self,
|
||||
WMNotification *notif);
|
||||
|
||||
void (*didEndEditing)(struct WMTextFieldDelegate *self,
|
||||
WMNotification *notif);
|
||||
|
||||
Bool (*shouldBeginEditing)(struct WMTextFieldDelegate *self,
|
||||
WMTextField *tPtr);
|
||||
|
||||
Bool (*shouldEndEditing)(struct WMTextFieldDelegate *self,
|
||||
WMTextField *tPtr);
|
||||
} WMTextFieldDelegate;
|
||||
|
||||
|
||||
|
||||
/* ....................................................................... */
|
||||
|
||||
|
||||
@@ -736,6 +785,8 @@ void WMSetButtonBordered(WMButton *bPtr, int isBordered);
|
||||
|
||||
void WMSetButtonEnabled(WMButton *bPtr, Bool flag);
|
||||
|
||||
void WMSetButtonImageDimsWhenDisabled(WMButton *bPtr, Bool flag);
|
||||
|
||||
void WMSetButtonTag(WMButton *bPtr, int tag);
|
||||
|
||||
void WMGroupButtons(WMButton *bPtr, WMButton *newMember);
|
||||
@@ -910,8 +961,6 @@ char *WMGetBrowserPath(WMBrowser *bPtr);
|
||||
/* you can free the returned string */
|
||||
char *WMGetBrowserPathToColumn(WMBrowser *bPtr, int column);
|
||||
|
||||
void WMSetBrowserFillColumnProc(WMBrowser *bPtr,WMBrowserFillColumnProc *proc);
|
||||
|
||||
void WMSetBrowserAction(WMBrowser *bPtr, WMAction *action, void *clientData);
|
||||
|
||||
void WMSetBrowserDoubleAction(WMBrowser *bPtr, WMAction *action,
|
||||
@@ -931,7 +980,7 @@ int WMGetBrowserMaxVisibleColumns(WMBrowser *bPtr);
|
||||
|
||||
WMList *WMGetBrowserListInColumn(WMBrowser *bPtr, int column);
|
||||
|
||||
extern char *WMBrowserDidScrollNotification;
|
||||
void WMSetBrowserDelegate(WMBrowser *bPtr, WMBrowserDelegate *delegate);
|
||||
|
||||
/* ....................................................................... */
|
||||
|
||||
@@ -1066,6 +1115,47 @@ void WMSetSplitViewResizeSubviewsProc(WMSplitView *sPtr,
|
||||
int WMGetSplitViewDividerThickness(WMSplitView *sPtr);
|
||||
|
||||
|
||||
/* ....................................................................... */
|
||||
|
||||
|
||||
WMTabView *WMCreateTabView(WMWidget *parent);
|
||||
|
||||
void WMAddItemInTabView(WMTabView *tPtr, WMTabViewItem *item);
|
||||
|
||||
void WMInsertItemInTabView(WMTabView *tPtr, int index, WMTabViewItem *item);
|
||||
|
||||
void WMRemoveTabViewItem(WMTabView *tPtr, WMTabViewItem *item);
|
||||
|
||||
WMTabViewItem *WMTabViewItemAtPoint(WMTabView *tPtr, int x, int y);
|
||||
|
||||
void WMSelectFirstTabViewItem(WMTabView *tPtr);
|
||||
|
||||
void WMSelectLastTabViewItem(WMTabView *tPtr);
|
||||
|
||||
void WMSelectNextTabViewItem(WMTabView *tPtr);
|
||||
|
||||
void WMSelectPreviousTabViewItem(WMTabView *tPtr);
|
||||
|
||||
WMTabViewItem *WMGetSelectedTabViewItem(WMTabView *tPtr);
|
||||
|
||||
void WMSelectTabViewItem(WMTabView *tPtr, WMTabViewItem *item);
|
||||
|
||||
void WMSelectTabViewItemAtIndex(WMTabView *tPtr, int index);
|
||||
|
||||
|
||||
|
||||
WMTabViewItem *WMCreateTabViewItemWithIdentifier(int identifier);
|
||||
|
||||
void WMSetTabViewItemLabel(WMTabViewItem *item, char *label);
|
||||
|
||||
char *WMGetTabViewItemLabel(WMTabViewItem *item);
|
||||
|
||||
void WMSetTabViewItemView(WMTabViewItem *item, WMView *view);
|
||||
|
||||
WMView *WMGetTabViewItemView(WMTabViewItem *item);
|
||||
|
||||
void WMDestroyTabViewItem(WMTabViewItem *item);
|
||||
|
||||
/* ....................................................................... */
|
||||
|
||||
int WMRunAlertPanel(WMScreen *app, WMWindow *owner, char *title, char *msg,
|
||||
|
||||
@@ -262,6 +262,9 @@ typedef struct W_View {
|
||||
XSetWindowAttributes attribs;
|
||||
|
||||
void *hangedData; /* data holder for user program */
|
||||
|
||||
WMColor *backColor;
|
||||
|
||||
#if 0
|
||||
struct W_DragSourceProcs *dragSourceProcs;
|
||||
struct W_DragDestinationProcs *dragDestinationProcs;
|
||||
|
||||
@@ -6,8 +6,6 @@
|
||||
#include <math.h> /* for : double rint (double) */
|
||||
|
||||
|
||||
char *WMBrowserDidScrollNotification = "WMBrowserDidScrollNotification";
|
||||
|
||||
|
||||
typedef struct W_Browser {
|
||||
W_Class widgetClass;
|
||||
@@ -35,7 +33,7 @@ typedef struct W_Browser {
|
||||
void *doubleClientData;
|
||||
WMAction *doubleAction;
|
||||
|
||||
WMBrowserFillColumnProc *fillColumn;
|
||||
WMBrowserDelegate *delegate;
|
||||
|
||||
WMScroller *scroller;
|
||||
|
||||
@@ -265,23 +263,6 @@ drawTitleOfColumn(WMBrowser *bPtr, int column)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
WMSetBrowserColumnTitle(WMBrowser *bPtr, int column, char *title)
|
||||
{
|
||||
assert(column >= 0);
|
||||
assert(column < bPtr->usedColumnCount);
|
||||
|
||||
if (bPtr->titles[column])
|
||||
free(bPtr->titles[column]);
|
||||
|
||||
bPtr->titles[column] = wstrdup(title);
|
||||
|
||||
if (COLUMN_IS_VISIBLE(bPtr, column) && bPtr->flags.isTitled) {
|
||||
drawTitleOfColumn(bPtr, column);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
WMList*
|
||||
WMGetBrowserListInColumn(WMBrowser *bPtr, int column)
|
||||
{
|
||||
@@ -293,9 +274,9 @@ WMGetBrowserListInColumn(WMBrowser *bPtr, int column)
|
||||
|
||||
|
||||
void
|
||||
WMSetBrowserFillColumnProc(WMBrowser *bPtr, WMBrowserFillColumnProc *proc)
|
||||
WMSetBrowserDelegate(WMBrowser *bPtr, WMBrowserDelegate *delegate)
|
||||
{
|
||||
bPtr->fillColumn = proc;
|
||||
bPtr->delegate = delegate;
|
||||
}
|
||||
|
||||
|
||||
@@ -389,6 +370,23 @@ WMGetBrowserSelectedRowInColumn(WMBrowser *bPtr, int column)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
WMSetBrowserColumnTitle(WMBrowser *bPtr, int column, char *title)
|
||||
{
|
||||
assert(column >= 0);
|
||||
assert(column < bPtr->usedColumnCount);
|
||||
|
||||
if (bPtr->titles[column])
|
||||
free(bPtr->titles[column]);
|
||||
|
||||
bPtr->titles[column] = wstrdup(title);
|
||||
|
||||
if (COLUMN_IS_VISIBLE(bPtr, column) && bPtr->flags.isTitled) {
|
||||
drawTitleOfColumn(bPtr, column);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
WMSetBrowserTitled(WMBrowser *bPtr, Bool flag)
|
||||
{
|
||||
@@ -750,6 +748,7 @@ WMGetBrowserPath(WMBrowser *bPtr)
|
||||
}
|
||||
|
||||
|
||||
|
||||
char*
|
||||
WMGetBrowserPathToColumn(WMBrowser *bPtr, int column)
|
||||
{
|
||||
@@ -792,11 +791,24 @@ WMGetBrowserPathToColumn(WMBrowser *bPtr, int column)
|
||||
static void
|
||||
loadColumn(WMBrowser *bPtr, int column)
|
||||
{
|
||||
assert(bPtr->fillColumn);
|
||||
|
||||
assert(bPtr->delegate);
|
||||
assert(bPtr->delegate->createRowsForColumn);
|
||||
|
||||
bPtr->flags.loadingColumn = 1;
|
||||
(*bPtr->fillColumn)(bPtr, column);
|
||||
(*bPtr->delegate->createRowsForColumn)(bPtr->delegate, bPtr, column,
|
||||
bPtr->columns[column]);
|
||||
bPtr->flags.loadingColumn = 0;
|
||||
|
||||
if (bPtr->delegate->titleOfColumn) {
|
||||
char *title;
|
||||
|
||||
title = (*bPtr->delegate->titleOfColumn)(bPtr->delegate, bPtr, column);
|
||||
|
||||
if (bPtr->titles[column])
|
||||
free(bPtr->titles[column]);
|
||||
|
||||
bPtr->titles[column] = title;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -850,12 +862,17 @@ scrollToColumn(WMBrowser *bPtr, int column, Bool updateScroller)
|
||||
int notify = 0;
|
||||
|
||||
|
||||
if (column != bPtr->firstVisibleColumn)
|
||||
if (column != bPtr->firstVisibleColumn) {
|
||||
notify = 1;
|
||||
}
|
||||
|
||||
if (column < 0)
|
||||
column = 0;
|
||||
|
||||
if (notify && bPtr->delegate && bPtr->delegate->willScroll) {
|
||||
(*bPtr->delegate->willScroll)(bPtr->delegate, bPtr);
|
||||
}
|
||||
|
||||
x = 0;
|
||||
bPtr->firstVisibleColumn = column;
|
||||
for (i = 0; i < bPtr->columnCount; i++) {
|
||||
@@ -888,8 +905,9 @@ scrollToColumn(WMBrowser *bPtr, int column, Bool updateScroller)
|
||||
if (bPtr->view->flags.mapped)
|
||||
paintBrowser(bPtr);
|
||||
|
||||
if (notify)
|
||||
WMPostNotificationName(WMBrowserDidScrollNotification, bPtr, NULL);
|
||||
if (notify && bPtr->delegate && bPtr->delegate->didScroll) {
|
||||
(*bPtr->delegate->didScroll)(bPtr->delegate, bPtr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1007,7 +1025,7 @@ listSelectionObserver(void *observerData, WMNotification *notification)
|
||||
int column, item = (int)WMGetNotificationClientData(notification);
|
||||
WMList *lPtr = (WMList*)WMGetNotificationObject(notification);
|
||||
|
||||
for (column=0; column<bPtr->usedColumnCount; column++)
|
||||
for (column = 0; column < bPtr->usedColumnCount; column++)
|
||||
if (bPtr->columns[column] == lPtr)
|
||||
break;
|
||||
|
||||
@@ -1095,7 +1113,7 @@ destroyBrowser(WMBrowser *bPtr)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i<bPtr->columnCount; i++) {
|
||||
for (i = 0; i < bPtr->columnCount; i++) {
|
||||
if (bPtr->titles[i])
|
||||
free(bPtr->titles[i]);
|
||||
}
|
||||
|
||||
@@ -63,7 +63,8 @@ static void listDirectoryOnColumn(WMFilePanel *panel, int column, char *path);
|
||||
static void browserClick();
|
||||
static void browserDClick();
|
||||
|
||||
static void fillColumn(WMBrowser *bPtr, int column);
|
||||
static void fillColumn(WMBrowserDelegate *self, WMBrowser *bPtr, int column,
|
||||
WMList *list);
|
||||
|
||||
static void goHome();
|
||||
|
||||
@@ -74,6 +75,16 @@ static char *getCurrentFileName(WMFilePanel *panel);
|
||||
static void handleEvents(XEvent *event, void *data);
|
||||
|
||||
|
||||
|
||||
static WMBrowserDelegate browserDelegate = {
|
||||
NULL, /* data */
|
||||
fillColumn, /* createRowsForColumn */
|
||||
NULL, /* titleOfColumn */
|
||||
NULL, /* didScroll */
|
||||
NULL /* willScroll */
|
||||
};
|
||||
|
||||
|
||||
static int
|
||||
closestListItem(WMList *list, char *text, Bool exact)
|
||||
{
|
||||
@@ -198,7 +209,7 @@ makeFilePanel(WMScreen *scrPtr, char *name, char *title)
|
||||
WMSetFrameRelief(fPtr->line, WRGroove);
|
||||
|
||||
fPtr->browser = WMCreateBrowser(fPtr->win);
|
||||
WMSetBrowserFillColumnProc(fPtr->browser, fillColumn);
|
||||
WMSetBrowserDelegate(fPtr->browser, &browserDelegate);
|
||||
WMSetBrowserAction(fPtr->browser, browserClick, fPtr);
|
||||
WMSetBrowserDoubleAction(fPtr->browser, browserDClick, fPtr);
|
||||
WMMoveWidget(fPtr->browser, 7, 72);
|
||||
@@ -531,7 +542,7 @@ listDirectoryOnColumn(WMFilePanel *panel, int column, char *path)
|
||||
|
||||
|
||||
static void
|
||||
fillColumn(WMBrowser *bPtr, int column)
|
||||
fillColumn(WMBrowserDelegate *self, WMBrowser *bPtr, int column, WMList *list)
|
||||
{
|
||||
char *path;
|
||||
WMFilePanel *panel;
|
||||
|
||||
@@ -323,6 +323,7 @@ extern W_ViewProcedureTable _ColorWellViewProcedures;
|
||||
extern W_ViewProcedureTable _ScrollViewViewProcedures;
|
||||
extern W_ViewProcedureTable _SliderViewProcedures;
|
||||
extern W_ViewProcedureTable _SplitViewViewProcedures;
|
||||
extern W_ViewProcedureTable _TabViewViewProcedures;
|
||||
|
||||
/*
|
||||
* All widget classes defined must have an entry here.
|
||||
@@ -353,6 +354,7 @@ initProcedureTable()
|
||||
procedureTables[WC_ScrollView] = &_ScrollViewViewProcedures;
|
||||
procedureTables[WC_Slider] = &_SliderViewProcedures;
|
||||
procedureTables[WC_SplitView] = &_SplitViewViewProcedures;
|
||||
procedureTables[WC_TabView] = &_TabViewViewProcedures;
|
||||
}
|
||||
|
||||
|
||||
|
||||
646
WINGs/wtabview.c
Normal file
646
WINGs/wtabview.c
Normal file
@@ -0,0 +1,646 @@
|
||||
|
||||
#include "WINGsP.h"
|
||||
|
||||
|
||||
typedef struct W_TabView {
|
||||
W_Class widgetClass;
|
||||
W_View *view;
|
||||
|
||||
struct W_TabViewItem **items;
|
||||
int itemCount;
|
||||
int maxItems; /* size of items array */
|
||||
|
||||
int selectedItem;
|
||||
|
||||
WMFont *font;
|
||||
|
||||
WMColor *lightGray;
|
||||
WMColor *tabColor;
|
||||
|
||||
short tabWidth;
|
||||
short tabHeight;
|
||||
|
||||
struct {
|
||||
WMReliefType relief:4;
|
||||
WMTitlePosition titlePosition:4;
|
||||
WMTabViewTypes type:2;
|
||||
|
||||
unsigned tabbed:1;
|
||||
unsigned allowsTruncatedLabels:1;
|
||||
} flags;
|
||||
} TabView;
|
||||
|
||||
|
||||
|
||||
struct W_ViewProcedureTable _TabViewViewProcedures = {
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
#define DEFAULT_WIDTH 40
|
||||
#define DEFAULT_HEIGHT 40
|
||||
|
||||
|
||||
static void destroyTabView(TabView *tPtr);
|
||||
static void paintTabView(TabView *tPtr);
|
||||
|
||||
|
||||
static void W_SetTabViewItemParent(WMTabViewItem *item, WMTabView *parent);
|
||||
|
||||
static void W_DrawLabel(WMTabViewItem *item, Drawable d, WMRect rect);
|
||||
|
||||
static void W_UnmapTabViewItem(WMTabViewItem *item);
|
||||
|
||||
static void W_MapTabViewItem(WMTabViewItem *item);
|
||||
|
||||
static WMView *W_TabViewItemView(WMTabViewItem *item);
|
||||
|
||||
static void recalcTabWidth(TabView *tPtr);
|
||||
|
||||
|
||||
static void
|
||||
handleEvents(XEvent *event, void *data)
|
||||
{
|
||||
TabView *tPtr = (TabView*)data;
|
||||
|
||||
CHECK_CLASS(data, WC_TabView);
|
||||
|
||||
switch (event->type) {
|
||||
case Expose:
|
||||
if (event->xexpose.count!=0)
|
||||
break;
|
||||
paintTabView(tPtr);
|
||||
break;
|
||||
|
||||
case ButtonPress:
|
||||
{
|
||||
WMTabViewItem *item = WMTabViewItemAtPoint(tPtr,
|
||||
event->xbutton.x,
|
||||
event->xbutton.y);
|
||||
if (item) {
|
||||
WMSelectTabViewItem(tPtr, item);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case DestroyNotify:
|
||||
destroyTabView(tPtr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
WMTabView*
|
||||
WMCreateTabView(WMWidget *parent)
|
||||
{
|
||||
TabView *tPtr;
|
||||
WMScreen *scr = WMWidgetScreen(parent);
|
||||
|
||||
tPtr = wmalloc(sizeof(TabView));
|
||||
memset(tPtr, 0, sizeof(TabView));
|
||||
|
||||
tPtr->widgetClass = WC_TabView;
|
||||
|
||||
tPtr->view = W_CreateView(W_VIEW(parent));
|
||||
if (!tPtr->view) {
|
||||
free(tPtr);
|
||||
return NULL;
|
||||
}
|
||||
tPtr->view->self = tPtr;
|
||||
|
||||
tPtr->lightGray = WMCreateRGBColor(scr, 0xd9d9, 0xd9d9, 0xd9d9, False);
|
||||
tPtr->tabColor = WMCreateRGBColor(scr, 0x8420, 0x8420, 0x8420, False);
|
||||
|
||||
tPtr->font = WMRetainFont(scr->normalFont);
|
||||
|
||||
WMCreateEventHandler(tPtr->view, ExposureMask|StructureNotifyMask
|
||||
|ButtonPressMask, handleEvents, tPtr);
|
||||
|
||||
WMResizeWidget(tPtr, DEFAULT_WIDTH, DEFAULT_HEIGHT);
|
||||
|
||||
tPtr->tabHeight = WMFontHeight(tPtr->font) + 3;
|
||||
|
||||
return tPtr;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
WMAddItemInTabView(WMTabView *tPtr, WMTabViewItem *item)
|
||||
{
|
||||
WMInsertItemInTabView(tPtr, tPtr->itemCount, item);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
WMInsertItemInTabView(WMTabView *tPtr, int index, WMTabViewItem *item)
|
||||
{
|
||||
wassertr(W_TabViewItemView(item) != NULL);
|
||||
|
||||
if (tPtr->maxItems == tPtr->itemCount) {
|
||||
WMTabViewItem **items;
|
||||
|
||||
items = wrealloc(tPtr->items, tPtr->maxItems + 10);
|
||||
if (!items) {
|
||||
wwarning("out of memory allocating memory for tabview");
|
||||
return;
|
||||
}
|
||||
tPtr->items = items;
|
||||
tPtr->maxItems += 10;
|
||||
}
|
||||
|
||||
if (index > tPtr->itemCount)
|
||||
index = tPtr->itemCount;
|
||||
|
||||
if (index == 0) {
|
||||
W_UnmapTabViewItem(tPtr->items[0]);
|
||||
}
|
||||
|
||||
if (index < tPtr->itemCount) {
|
||||
memmove(&tPtr->items[index + 1], &tPtr->items[index],
|
||||
tPtr->itemCount - index);
|
||||
}
|
||||
|
||||
tPtr->items[index] = item;
|
||||
|
||||
tPtr->itemCount++;
|
||||
|
||||
recalcTabWidth(tPtr);
|
||||
|
||||
W_SetTabViewItemParent(item, tPtr);
|
||||
|
||||
W_UnmapTabViewItem(item);
|
||||
|
||||
W_ReparentView(W_TabViewItemView(item), tPtr->view, 1,
|
||||
tPtr->tabHeight + 1);
|
||||
|
||||
W_ResizeView(W_TabViewItemView(item), tPtr->view->size.width - 3,
|
||||
tPtr->view->size.height - tPtr->tabHeight - 3);
|
||||
|
||||
if (index == 0) {
|
||||
W_MapTabViewItem(item);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
WMRemoveTabViewItem(WMTabView *tPtr, WMTabViewItem *item)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < tPtr->itemCount; i++) {
|
||||
if (tPtr->items[i] == item) {
|
||||
if (i < tPtr->itemCount - 1)
|
||||
memmove(&tPtr->items[i], &tPtr->items[i + 1],
|
||||
tPtr->itemCount - i - 1);
|
||||
else
|
||||
tPtr->items[i] = NULL;
|
||||
|
||||
W_SetTabViewItemParent(item, NULL);
|
||||
|
||||
tPtr->itemCount--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static Bool
|
||||
isInside(int x, int y, int width, int height, int px, int py)
|
||||
{
|
||||
if (py >= y + height - 3 && py <= y + height
|
||||
&& px >= x + py - (y + height - 3)
|
||||
&& px <= x + width - (py - (y + height - 3))) {
|
||||
|
||||
return True;
|
||||
}
|
||||
if (py >= y + 3 && py < y + height - 3
|
||||
&& px >= x + 3 + ((y + 3) - py)*3/7
|
||||
&& px <= x + width - 3 - ((y + 3) - py)*3/7) {
|
||||
|
||||
return True;
|
||||
}
|
||||
if (py >= y && py < y + 3
|
||||
&& px >= x + 7 + py - y
|
||||
&& px <= x + width - 7 - (py - y)) {
|
||||
|
||||
return True;
|
||||
}
|
||||
return False;
|
||||
}
|
||||
|
||||
|
||||
WMTabViewItem*
|
||||
WMTabViewItemAtPoint(WMTabView *tPtr, int x, int y)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = tPtr->selectedItem;
|
||||
if (isInside(8 + (tPtr->tabWidth-10)*i, 0, tPtr->tabWidth,
|
||||
tPtr->tabHeight, x, y)) {
|
||||
return tPtr->items[i];
|
||||
}
|
||||
|
||||
for (i = 0; i < tPtr->itemCount; i++) {
|
||||
if (isInside(8 + (tPtr->tabWidth-10)*i, 0, tPtr->tabWidth,
|
||||
tPtr->tabHeight, x, y)) {
|
||||
return tPtr->items[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
WMSelectFirstTabViewItem(WMTabView *tPtr)
|
||||
{
|
||||
WMSelectTabViewItemAtIndex(tPtr, 0);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
WMSelectLastTabViewItem(WMTabView *tPtr)
|
||||
{
|
||||
WMSelectTabViewItemAtIndex(tPtr, tPtr->itemCount);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
WMSelectNextTabViewItem(WMTabView *tPtr)
|
||||
{
|
||||
WMSelectTabViewItemAtIndex(tPtr, tPtr->selectedItem + 1);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
WMSelectPreviousTabViewItem(WMTabView *tPtr)
|
||||
{
|
||||
WMSelectTabViewItemAtIndex(tPtr, tPtr->selectedItem - 1);
|
||||
}
|
||||
|
||||
|
||||
WMTabViewItem*
|
||||
WMGetSelectedTabViewItem(WMTabView *tPtr)
|
||||
{
|
||||
return tPtr->items[tPtr->selectedItem];
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
WMSelectTabViewItem(WMTabView *tPtr, WMTabViewItem *item)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < tPtr->itemCount; i++) {
|
||||
if (tPtr->items[i] == item) {
|
||||
WMSelectTabViewItemAtIndex(tPtr, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
WMSelectTabViewItemAtIndex(WMTabView *tPtr, int index)
|
||||
{
|
||||
WMTabViewItem *item;
|
||||
|
||||
if (index == tPtr->selectedItem)
|
||||
return;
|
||||
|
||||
if (index < 0)
|
||||
index = 0;
|
||||
else if (index >= tPtr->itemCount)
|
||||
index = tPtr->itemCount - 1;
|
||||
|
||||
|
||||
item = tPtr->items[tPtr->selectedItem];
|
||||
|
||||
W_UnmapTabViewItem(item);
|
||||
|
||||
|
||||
item = tPtr->items[index];
|
||||
|
||||
W_MapTabViewItem(item);
|
||||
|
||||
tPtr->selectedItem = index;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
recalcTabWidth(TabView *tPtr)
|
||||
{
|
||||
int i;
|
||||
int twidth = W_VIEW(tPtr)->size.width;
|
||||
int width;
|
||||
|
||||
tPtr->tabWidth = 0;
|
||||
for (i = 0; i < tPtr->itemCount; i++) {
|
||||
char *str = WMGetTabViewItemLabel(tPtr->items[i]);
|
||||
|
||||
if (str) {
|
||||
width = WMWidthOfString(tPtr->font, str, strlen(str));
|
||||
if (width > tPtr->tabWidth)
|
||||
tPtr->tabWidth = width;
|
||||
}
|
||||
}
|
||||
tPtr->tabWidth += 30;
|
||||
if (tPtr->tabWidth > twidth - 10 * tPtr->itemCount
|
||||
&& tPtr->tabWidth < twidth - 16)
|
||||
tPtr->tabWidth = (twidth - 16) / tPtr->itemCount;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
drawRelief(W_Screen *scr, Drawable d, int x, int y, unsigned int width,
|
||||
unsigned int height)
|
||||
{
|
||||
Display *dpy = scr->display;
|
||||
GC bgc = WMColorGC(scr->black);
|
||||
GC wgc = WMColorGC(scr->white);
|
||||
GC dgc = WMColorGC(scr->darkGray);
|
||||
|
||||
XDrawLine(dpy, d, wgc, x, y, x, y+height-1);
|
||||
|
||||
XDrawLine(dpy, d, bgc, x, y+height-1, x+width-1, y+height-1);
|
||||
XDrawLine(dpy, d, dgc, x+1, y+height-2, x+width-2, y+height-2);
|
||||
|
||||
XDrawLine(dpy, d, bgc, x+width-1, y, x+width-1, y+height-1);
|
||||
XDrawLine(dpy, d, dgc, x+width-2, y+1, x+width-2, y+height-2);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
drawTab(TabView *tPtr, Drawable d, int x, int y,
|
||||
unsigned width, unsigned height, Bool selected)
|
||||
{
|
||||
WMScreen *scr = W_VIEW(tPtr)->screen;
|
||||
Display *dpy = scr->display;
|
||||
GC white = WMColorGC(selected ? scr->white : tPtr->lightGray);
|
||||
GC black = WMColorGC(scr->black);
|
||||
GC dark = WMColorGC(scr->darkGray);
|
||||
GC light = WMColorGC(scr->gray);
|
||||
XPoint trap[8];
|
||||
|
||||
trap[0].x = x + (selected ? 0 : 1);
|
||||
trap[0].y = y + height - (selected ? 0 : 1);
|
||||
|
||||
trap[1].x = x + 3;
|
||||
trap[1].y = y + height - 3;
|
||||
|
||||
trap[2].x = x + 10 - 3;
|
||||
trap[2].y = y + 3;
|
||||
|
||||
trap[3].x = x + 10;
|
||||
trap[3].y = y;
|
||||
|
||||
trap[4].x = x + width - 10;
|
||||
trap[4].y = y;
|
||||
|
||||
trap[5].x = x + width - 10 + 3;
|
||||
trap[5].y = y + 3;
|
||||
|
||||
trap[6].x = x + width - 3;
|
||||
trap[6].y = y + height - 3;
|
||||
|
||||
trap[7].x = x + width - (selected ? 0 : 1);
|
||||
trap[7].y = y + height - (selected ? 0 : 1);
|
||||
|
||||
XFillPolygon(dpy, d, selected ? light : WMColorGC(tPtr->tabColor), trap, 8,
|
||||
Convex, CoordModeOrigin);
|
||||
|
||||
XDrawLine(dpy, d, white, trap[0].x, trap[0].y, trap[1].x, trap[1].y);
|
||||
XDrawLine(dpy, d, white, trap[1].x, trap[1].y, trap[2].x, trap[2].y);
|
||||
XDrawLine(dpy, d, white, trap[2].x, trap[2].y, trap[3].x, trap[3].y);
|
||||
XDrawLine(dpy, d, white, trap[3].x, trap[3].y, trap[4].x, trap[4].y);
|
||||
XDrawLine(dpy, d, dark, trap[4].x, trap[4].y, trap[5].x, trap[5].y);
|
||||
XDrawLine(dpy, d, black, trap[5].x, trap[5].y, trap[6].x, trap[6].y);
|
||||
XDrawLine(dpy, d, black, trap[6].x, trap[6].y, trap[7].x, trap[7].y);
|
||||
|
||||
XDrawLine(dpy, d, selected ? light : WMColorGC(scr->white),
|
||||
trap[0].x, trap[0].y, trap[7].x, trap[7].y);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
paintTabView(TabView *tPtr)
|
||||
{
|
||||
Pixmap buffer;
|
||||
WMScreen *scr = W_VIEW(tPtr)->screen;
|
||||
Display *dpy = scr->display;
|
||||
GC white = WMColorGC(scr->white);
|
||||
int i;
|
||||
WMRect rect;
|
||||
|
||||
switch (tPtr->flags.type) {
|
||||
case WTTopTabsBevelBorder:
|
||||
drawRelief(scr, W_VIEW(tPtr)->window, 0, tPtr->tabHeight - 1,
|
||||
W_VIEW(tPtr)->size.width,
|
||||
W_VIEW(tPtr)->size.height - tPtr->tabHeight + 1);
|
||||
break;
|
||||
|
||||
case WTNoTabsBevelBorder:
|
||||
W_DrawRelief(scr, W_VIEW(tPtr)->window, 0, 0, W_VIEW(tPtr)->size.width,
|
||||
W_VIEW(tPtr)->size.height, WRRaised);
|
||||
break;
|
||||
|
||||
case WTNoTabsLineBorder:
|
||||
W_DrawRelief(scr, W_VIEW(tPtr)->window, 0, 0, W_VIEW(tPtr)->size.width,
|
||||
W_VIEW(tPtr)->size.height, WRSimple);
|
||||
break;
|
||||
|
||||
case WTNoTabsNoBorder:
|
||||
break;
|
||||
}
|
||||
|
||||
if (tPtr->flags.type == WTTopTabsBevelBorder) {
|
||||
buffer = XCreatePixmap(dpy, W_VIEW(tPtr)->window,
|
||||
W_VIEW(tPtr)->size.width, tPtr->tabHeight,
|
||||
W_VIEW(tPtr)->screen->depth);
|
||||
|
||||
XFillRectangle(dpy, buffer, WMColorGC(W_VIEW(tPtr)->backColor),
|
||||
0, 0, W_VIEW(tPtr)->size.width, tPtr->tabHeight);
|
||||
|
||||
rect.pos.x = 8 + 15;
|
||||
rect.pos.y = 2;
|
||||
rect.size.width = tPtr->tabWidth;
|
||||
rect.size.height = tPtr->tabHeight;
|
||||
|
||||
for (i = tPtr->itemCount - 1; i >= 0; i--) {
|
||||
if (i != tPtr->selectedItem) {
|
||||
drawTab(tPtr, buffer, 8 + (rect.size.width-10)*i, 0,
|
||||
rect.size.width, rect.size.height, False);
|
||||
}
|
||||
}
|
||||
drawTab(tPtr, buffer, 8 + (rect.size.width-10) * tPtr->selectedItem,
|
||||
0, rect.size.width, rect.size.height, True);
|
||||
|
||||
XDrawLine(dpy, buffer, white, 0, tPtr->tabHeight - 1,
|
||||
8, tPtr->tabHeight - 1);
|
||||
|
||||
XDrawLine(dpy, buffer, white,
|
||||
8 + 10 + (rect.size.width-10) * tPtr->itemCount,
|
||||
tPtr->tabHeight - 1, W_VIEW(tPtr)->size.width,
|
||||
tPtr->tabHeight - 1);
|
||||
|
||||
|
||||
for (i = 0; i < tPtr->itemCount; i++) {
|
||||
W_DrawLabel(tPtr->items[i], buffer, rect);
|
||||
|
||||
rect.pos.x += rect.size.width - 10;
|
||||
}
|
||||
|
||||
XCopyArea(dpy, buffer, W_VIEW(tPtr)->window, scr->copyGC, 0, 0,
|
||||
W_VIEW(tPtr)->size.width, tPtr->tabHeight, 0, 0);
|
||||
|
||||
XFreePixmap(dpy, buffer);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
destroyTabView(TabView *tPtr)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < tPtr->itemCount; i++) {
|
||||
WMDestroyTabViewItem(tPtr->items[i]);
|
||||
}
|
||||
free(tPtr->items);
|
||||
|
||||
WMReleaseColor(tPtr->lightGray);
|
||||
WMReleaseColor(tPtr->tabColor);
|
||||
WMReleaseFont(tPtr->font);
|
||||
|
||||
free(tPtr);
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
|
||||
|
||||
typedef struct W_TabViewItem {
|
||||
WMTabView *tabView;
|
||||
|
||||
W_View *view;
|
||||
|
||||
char *label;
|
||||
|
||||
int identifier;
|
||||
|
||||
struct {
|
||||
unsigned visible:1;
|
||||
} flags;
|
||||
} TabViewItem;
|
||||
|
||||
|
||||
static void
|
||||
W_SetTabViewItemParent(WMTabViewItem *item, WMTabView *parent)
|
||||
{
|
||||
item->tabView = parent;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
W_DrawLabel(WMTabViewItem *item, Drawable d, WMRect rect)
|
||||
{
|
||||
WMScreen *scr = W_VIEW(item->tabView)->screen;
|
||||
|
||||
if (!item->label)
|
||||
return;
|
||||
|
||||
WMDrawString(scr, d, WMColorGC(scr->black), item->tabView->font,
|
||||
rect.pos.x, rect.pos.y, item->label, strlen(item->label));
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
W_UnmapTabViewItem(WMTabViewItem *item)
|
||||
{
|
||||
wassertr(item->view);
|
||||
|
||||
W_UnmapView(item->view);
|
||||
|
||||
item->flags.visible = 0;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
W_MapTabViewItem(WMTabViewItem *item)
|
||||
{
|
||||
wassertr(item->view);
|
||||
|
||||
W_MapView(item->view);
|
||||
|
||||
item->flags.visible = 1;
|
||||
}
|
||||
|
||||
|
||||
static WMView*
|
||||
W_TabViewItemView(WMTabViewItem *item)
|
||||
{
|
||||
return item->view;
|
||||
}
|
||||
|
||||
|
||||
WMTabViewItem*
|
||||
WMCreateTabViewItemWithIdentifier(int identifier)
|
||||
{
|
||||
WMTabViewItem *item;
|
||||
|
||||
item = wmalloc(sizeof(WMTabViewItem));
|
||||
memset(item, 0, sizeof(WMTabViewItem));
|
||||
|
||||
item->identifier = identifier;
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
WMSetTabViewItemLabel(WMTabViewItem *item, char *label)
|
||||
{
|
||||
if (item->label)
|
||||
free(item->label);
|
||||
|
||||
item->label = wstrdup(label);
|
||||
|
||||
if (item->tabView)
|
||||
recalcTabWidth(item->tabView);
|
||||
}
|
||||
|
||||
|
||||
char*
|
||||
WMGetTabViewItemLabel(WMTabViewItem *item)
|
||||
{
|
||||
return item->label;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
WMSetTabViewItemView(WMTabViewItem *item, WMView *view)
|
||||
{
|
||||
item->view = view;
|
||||
}
|
||||
|
||||
|
||||
WMView*
|
||||
WMGetTabViewItemView(WMTabViewItem *item)
|
||||
{
|
||||
return item->view;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
WMDestroyTabViewItem(WMTabViewItem *item)
|
||||
{
|
||||
if (item->label)
|
||||
free(item->label);
|
||||
|
||||
if (item->view)
|
||||
W_DestroyView(item->view);
|
||||
|
||||
free(item);
|
||||
}
|
||||
@@ -300,6 +300,7 @@ testSlider(WMScreen *scr)
|
||||
WMMapWidget(win);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
testTextField(WMScreen *scr)
|
||||
{
|
||||
@@ -369,13 +370,67 @@ testPullDown(WMScreen *scr)
|
||||
|
||||
|
||||
|
||||
void
|
||||
testTabView(WMScreen *scr)
|
||||
{
|
||||
WMWindow *win;
|
||||
WMTabView *tabv;
|
||||
WMTabViewItem *tab;
|
||||
WMFrame *frame;
|
||||
WMLabel *label;
|
||||
|
||||
windowCount++;
|
||||
|
||||
win = WMCreateWindow(scr, "testTabs");
|
||||
WMResizeWidget(win, 400, 300);
|
||||
|
||||
WMSetWindowCloseAction(win, closeAction, NULL);
|
||||
|
||||
tabv = WMCreateTabView(win);
|
||||
WMMoveWidget(tabv, 50, 50);
|
||||
WMResizeWidget(tabv, 300, 200);
|
||||
|
||||
frame = WMCreateFrame(win);
|
||||
WMSetFrameRelief(frame, WRFlat);
|
||||
label = WMCreateLabel(frame);
|
||||
WMResizeWidget(label, 100, 100);
|
||||
WMSetLabelText(label, "Label 1");
|
||||
WMMapWidget(label);
|
||||
|
||||
|
||||
tab = WMCreateTabViewItemWithIdentifier(0);
|
||||
WMSetTabViewItemView(tab, WMWidgetView(frame));
|
||||
WMAddItemInTabView(tabv, tab);
|
||||
WMSetTabViewItemLabel(tab, "Instances");
|
||||
|
||||
|
||||
frame = WMCreateFrame(win);
|
||||
WMSetFrameRelief(frame, WRFlat);
|
||||
label = WMCreateLabel(frame);
|
||||
WMResizeWidget(label, 100, 100);
|
||||
WMMoveWidget(label, 40, 40);
|
||||
WMSetLabelText(label, "Label 2");
|
||||
WMMapWidget(label);
|
||||
|
||||
tab = WMCreateTabViewItemWithIdentifier(0);
|
||||
WMSetTabViewItemView(tab, WMWidgetView(frame));
|
||||
WMAddItemInTabView(tabv, tab);
|
||||
WMSetTabViewItemLabel(tab, "Classes");
|
||||
|
||||
WMRealizeWidget(win);
|
||||
WMMapSubwidgets(win);
|
||||
WMMapWidget(win);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#include "WUtil.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
WMScreen *scr;
|
||||
WMPixmap *pixmap;
|
||||
|
||||
WMPixmap *pixmap;
|
||||
|
||||
/* Initialize the application */
|
||||
WMInitializeApplication("Test", &argc, argv);
|
||||
|
||||
@@ -416,10 +471,14 @@ int main(int argc, char **argv)
|
||||
*
|
||||
* Put the testSomething() function you want to test here.
|
||||
*/
|
||||
testGradientButtons(scr);
|
||||
|
||||
testTextField(scr);
|
||||
|
||||
testTabView(scr);
|
||||
|
||||
#if 0
|
||||
testGradientButtons(scr);
|
||||
|
||||
testOpenFilePanel(scr);
|
||||
testFontPanel(scr);
|
||||
testList(scr);
|
||||
|
||||
@@ -13,6 +13,27 @@
|
||||
#define CURSOR_BLINK_OFF_DELAY 300
|
||||
|
||||
|
||||
typedef struct WMTextFieldDelegate {
|
||||
void *data;
|
||||
|
||||
void (*didBeginEditing)(struct WMTextFieldDelegate *self,
|
||||
WMNotification *notif);
|
||||
|
||||
void (*didChange)(struct WMTextFieldDelegate *self,
|
||||
WMNotification *notif);
|
||||
|
||||
void (*didEndEditing)(struct WMTextFieldDelegate *self,
|
||||
WMNotification *notif);
|
||||
|
||||
Bool (*shouldBeginEditing)(struct WMTextFieldDelegate *self,
|
||||
WMTextField *tPtr);
|
||||
|
||||
Bool (*shouldEndEditing)(struct WMTextFieldDelegate *self,
|
||||
WMTextField *tPtr);
|
||||
} WMTextFieldDelegate;
|
||||
|
||||
|
||||
|
||||
char *WMTextDidChangeNotification = "WMTextDidChangeNotification";
|
||||
char *WMTextDidBeginEditingNotification = "WMTextDidBeginEditingNotification";
|
||||
char *WMTextDidEndEditingNotification = "WMTextDidEndEditingNotification";
|
||||
@@ -43,6 +64,8 @@ typedef struct W_TextField {
|
||||
|
||||
WMFont *font;
|
||||
|
||||
WMTextFieldDelegate *delegate;
|
||||
|
||||
#if 0
|
||||
WMHandlerID timerID; /* for cursor blinking */
|
||||
#endif
|
||||
@@ -69,6 +92,13 @@ typedef struct W_TextField {
|
||||
} TextField;
|
||||
|
||||
|
||||
#define NOTIFY(T,C,N,A) { WMNotification *notif = WMCreateNotification(N,T,A);\
|
||||
if ((T)->delegate && (T)->delegate->C)\
|
||||
(*(T)->delegate->C)((T)->delegate,notif);\
|
||||
WMPostNotification(notif);\
|
||||
WMReleaseNotification(notif);}
|
||||
|
||||
|
||||
#define MIN_TEXT_BUFFER 2
|
||||
#define TEXT_BUFFER_INCR 8
|
||||
|
||||
@@ -218,6 +248,13 @@ WMCreateTextField(WMWidget *parent)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
WMSetTextFieldDelegate(WMTextField *tPtr, WMTextFieldDelegate *delegate)
|
||||
{
|
||||
tPtr->delegate = delegate;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
WMInsertTextFieldText(WMTextField *tPtr, char *text, int position)
|
||||
{
|
||||
@@ -248,9 +285,9 @@ WMInsertTextFieldText(WMTextField *tPtr, char *text, int position)
|
||||
/* insert text at position */
|
||||
memmv(&(tPtr->text[position+len]), &(tPtr->text[position]),
|
||||
tPtr->textLen-position+1);
|
||||
|
||||
|
||||
memcpy(&(tPtr->text[position]), text, len);
|
||||
|
||||
|
||||
tPtr->textLen += len;
|
||||
if (position >= tPtr->cursorPosition) {
|
||||
tPtr->cursorPosition += len;
|
||||
@@ -259,11 +296,11 @@ WMInsertTextFieldText(WMTextField *tPtr, char *text, int position)
|
||||
incrToFit(tPtr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
paintTextField(tPtr);
|
||||
|
||||
WMPostNotificationName(WMTextDidChangeNotification, tPtr,
|
||||
(void*)WMInsertTextEvent);
|
||||
NOTIFY(tPtr, didChange, WMTextDidChangeNotification,
|
||||
(void*)WMInsertTextEvent);
|
||||
}
|
||||
|
||||
|
||||
@@ -304,8 +341,8 @@ void
|
||||
WMDeleteTextFieldRange(WMTextField *tPtr, WMRange range)
|
||||
{
|
||||
deleteTextFieldRange(tPtr, range);
|
||||
WMPostNotificationName(WMTextDidChangeNotification, tPtr,
|
||||
(void*)WMDeleteTextEvent);
|
||||
NOTIFY(tPtr, didChange, WMTextDidChangeNotification,
|
||||
(void*)WMDeleteTextEvent);
|
||||
}
|
||||
|
||||
|
||||
@@ -349,8 +386,8 @@ WMSetTextFieldText(WMTextField *tPtr, char *text)
|
||||
if (tPtr->view->flags.realized)
|
||||
paintTextField(tPtr);
|
||||
|
||||
WMPostNotificationName(WMTextDidChangeNotification, tPtr,
|
||||
(void*)WMSetTextEvent);
|
||||
NOTIFY(tPtr, didChange, WMTextDidChangeNotification,
|
||||
(void*)WMSetTextEvent);
|
||||
}
|
||||
|
||||
|
||||
@@ -362,6 +399,7 @@ WMSetTextFieldFont(WMTextField *tPtr, WMFont *font)
|
||||
tPtr->font = WMRetainFont(font);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
WMSetTextFieldAlignment(WMTextField *tPtr, WMAlignment alignment)
|
||||
{
|
||||
@@ -679,12 +717,12 @@ paintTextField(TextField *tPtr)
|
||||
|
||||
ty = tPtr->offsetWidth;
|
||||
switch (tPtr->flags.alignment) {
|
||||
case WALeft:
|
||||
case WALeft:
|
||||
tx = tPtr->offsetWidth + 1;
|
||||
if (tw < tPtr->usableWidth)
|
||||
XFillRectangle(screen->display, drawbuffer,
|
||||
WMColorGC(screen->white),
|
||||
bd+tw,bd, totalWidth-tw,view->size.height-2*bd);
|
||||
XFillRectangle(screen->display, drawbuffer,
|
||||
WMColorGC(screen->white),
|
||||
bd+tw,bd, totalWidth-tw,view->size.height-2*bd);
|
||||
break;
|
||||
|
||||
case WACenter:
|
||||
@@ -742,8 +780,8 @@ paintTextField(TextField *tPtr)
|
||||
WMSetColorInGC(screen->black, screen->textFieldGC);
|
||||
} else {
|
||||
XFillRectangle(screen->display, drawbuffer,
|
||||
WMColorGC(screen->white),
|
||||
bd,bd, totalWidth,view->size.height-2*bd);
|
||||
WMColorGC(screen->white),
|
||||
bd,bd, totalWidth,view->size.height-2*bd);
|
||||
}
|
||||
|
||||
/* draw relief */
|
||||
@@ -754,8 +792,8 @@ paintTextField(TextField *tPtr)
|
||||
if (tPtr->flags.secure)
|
||||
free(text);
|
||||
XCopyArea(screen->display, drawbuffer, view->window,
|
||||
screen->copyGC, 0,0, view->size.width,
|
||||
view->size.height,0,0);
|
||||
screen->copyGC, 0,0, view->size.width,
|
||||
view->size.height,0,0);
|
||||
XFreePixmap(screen->display, drawbuffer);
|
||||
|
||||
/* draw cursor */
|
||||
@@ -805,11 +843,11 @@ handleEvents(XEvent *event, void *data)
|
||||
#endif
|
||||
paintTextField(tPtr);
|
||||
|
||||
WMPostNotificationName(WMTextDidBeginEditingNotification, tPtr, NULL);
|
||||
NOTIFY(tPtr, didBeginEditing, WMTextDidBeginEditingNotification, NULL);
|
||||
|
||||
tPtr->flags.notIllegalMovement = 0;
|
||||
break;
|
||||
|
||||
|
||||
case FocusOut:
|
||||
tPtr->flags.focused = 0;
|
||||
#if 0
|
||||
@@ -820,8 +858,8 @@ handleEvents(XEvent *event, void *data)
|
||||
|
||||
paintTextField(tPtr);
|
||||
if (!tPtr->flags.notIllegalMovement) {
|
||||
WMPostNotificationName(WMTextDidEndEditingNotification, tPtr,
|
||||
(void*)WMIllegalTextMovement);
|
||||
NOTIFY(tPtr, didEndEditing, WMTextDidEndEditingNotification,
|
||||
(void*)WMIllegalTextMovement);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -878,22 +916,22 @@ handleTextFieldKeyPress(TextField *tPtr, XEvent *event)
|
||||
tPtr->view->prevFocusChain);
|
||||
tPtr->flags.notIllegalMovement = 1;
|
||||
}
|
||||
WMPostNotificationName(WMTextDidEndEditingNotification, tPtr,
|
||||
(void*)WMBacktabTextMovement);
|
||||
NOTIFY(tPtr, didEndEditing, WMTextDidEndEditingNotification,
|
||||
(void*)WMBacktabTextMovement);
|
||||
} else {
|
||||
if (tPtr->view->nextFocusChain) {
|
||||
W_SetFocusOfTopLevel(W_TopLevelOfView(tPtr->view),
|
||||
tPtr->view->nextFocusChain);
|
||||
tPtr->view->nextFocusChain);
|
||||
tPtr->flags.notIllegalMovement = 1;
|
||||
}
|
||||
WMPostNotificationName(WMTextDidEndEditingNotification,
|
||||
tPtr, (void*)WMTabTextMovement);
|
||||
NOTIFY(tPtr, didEndEditing, WMTextDidEndEditingNotification,
|
||||
(void*)WMTabTextMovement);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case XK_Return:
|
||||
WMPostNotificationName(WMTextDidEndEditingNotification, tPtr,
|
||||
(void*)WMReturnTextMovement);
|
||||
NOTIFY(tPtr, didEndEditing, WMTextDidEndEditingNotification,
|
||||
(void*)WMReturnTextMovement);
|
||||
break;
|
||||
|
||||
case WM_EMACSKEY_LEFT:
|
||||
@@ -1196,7 +1234,7 @@ handleTextFieldActionEvents(XEvent *event, void *data)
|
||||
}
|
||||
if(textWidth < tPtr->usableWidth){
|
||||
tPtr->cursorPosition = pointToCursorPosition(tPtr,
|
||||
event->xbutton.x - tPtr->usableWidth
|
||||
event->xbutton.x - tPtr->usableWidth
|
||||
+ textWidth);
|
||||
}
|
||||
else tPtr->cursorPosition = pointToCursorPosition(tPtr,
|
||||
@@ -1231,12 +1269,13 @@ handleTextFieldActionEvents(XEvent *event, void *data)
|
||||
text = W_GetTextSelection(tPtr->view->screen,
|
||||
tPtr->view->screen->clipboardAtom);
|
||||
if (!text) {
|
||||
text = W_GetTextSelection(tPtr->view->screen, XA_CUT_BUFFER0);
|
||||
text = W_GetTextSelection(tPtr->view->screen,
|
||||
XA_CUT_BUFFER0);
|
||||
}
|
||||
if (text) {
|
||||
WMInsertTextFieldText(tPtr, text, tPtr->cursorPosition);
|
||||
XFree(text);
|
||||
WMPostNotificationName(WMTextDidChangeNotification, tPtr, NULL);
|
||||
WMInsertTextFieldText(tPtr, text, tPtr->cursorPosition);
|
||||
XFree(text);
|
||||
NOTIFY(tPtr, didChange, WMTextDidChangeNotification, NULL);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -127,6 +127,8 @@ createView(W_Screen *screen, W_View *parent)
|
||||
view->attribs.border_pixel = W_PIXEL(screen->black);
|
||||
view->attribs.colormap = screen->colormap;
|
||||
|
||||
view->backColor = WMRetainColor(screen->gray);
|
||||
|
||||
adoptChildView(parent, view);
|
||||
}
|
||||
|
||||
@@ -492,6 +494,10 @@ W_RedisplayView(W_View *view)
|
||||
void
|
||||
W_SetViewBackgroundColor(W_View *view, WMColor *color)
|
||||
{
|
||||
if (view->backColor)
|
||||
WMReleaseColor(view->backColor);
|
||||
view->backColor = WMRetainColor(color);
|
||||
|
||||
view->attribFlags |= CWBackPixel;
|
||||
view->attribs.background_pixel = color->color.pixel;
|
||||
if (view->flags.realized) {
|
||||
|
||||
Reference in New Issue
Block a user