1
0
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:
kojima
1999-05-15 17:38:05 +00:00
parent 70a363de7b
commit dd2d71fc9b
43 changed files with 1831 additions and 500 deletions

View File

@@ -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:
............................

View File

@@ -89,6 +89,7 @@ libWINGs_a_SOURCES = \
wscrollview.c \
wslider.c \
wsplitview.c \
wtabview.c \
wtextfield.c \
wwindow.c \
wview.c \

View File

@@ -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)

View File

@@ -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?

View File

@@ -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,

View File

@@ -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;

View File

@@ -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]);
}

View File

@@ -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;

View File

@@ -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
View 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);
}

View File

@@ -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);

View File

@@ -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;

View File

@@ -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) {