1
0
mirror of https://github.com/gryf/wmaker.git synced 2026-02-08 17:35:55 +01:00

0.51.1 pre snapshot. Be careful, it may be buggy. It fixes some bugs though.

This commit is contained in:
dan
1999-02-17 11:06:40 +00:00
parent 931a37b124
commit e7495baff7
189 changed files with 16952 additions and 9682 deletions

View File

@@ -1,3 +1,18 @@
changes since wmaker 0.51.0:
............................
- applied c++ compat header patch from Martynas Kunigelis <mkunigelis@alna.lt>
- added WMSetTextFieldBeveled()
changes since wmaker 0.50.1:
............................
- fixed various bugs
- added patch from Franck Wolff <frawolff@club-internet.fr>, with
many fixes and enhancements
- added notification queues, asynchronous notifications etc.
- added WMSetBrowserDoubleAction()
- fixed list double click action
changes since wmaker 0.50.2:
............................

View File

@@ -6,7 +6,7 @@ SUBDIRS = Resources
LIBLIST= $(top_builddir)/wrlib/libwraster.la\
@GFXLFLAGS@ @XLFLAGS@ @GFXLIBS@ @XLIBS@ \
@LIBRARY_SEARCH_PATH@ @GFXLIBS@ @XLIBS@ \
-lm @LIBPL@
@@ -18,7 +18,8 @@ lib_LIBRARIES = libWINGs.a
include_HEADERS = WINGs.h WUtil.h WINGsP.h
noinst_PROGRAMS = wtest wmquery wmfile fontl testmywidget testcolorpanel
noinst_PROGRAMS = wtest wmquery wmfile fontl testmywidget testcolorpanel \
testnot
testmywidget_SOURCES = testmywidget.c mywidget.c mywidget.h
@@ -42,6 +43,10 @@ testcolorpanel_SOURCES = testcolorpanel.c
testcolorpanel_LDADD = libWINGs.a $(LIBLIST)
testnot_SOURCES = testnot.c
testnot_LDADD = libWINGs.a $(LIBLIST)
wmquery_SOURCES = wmquery.c
@@ -55,6 +60,8 @@ libWINGs_a_SOURCES = \
WINGs.h \
WINGsP.h \
configuration.c \
llist.h \
llist.c \
international.c \
notification.c \
selection.c \
@@ -90,11 +97,7 @@ libWINGs_a_SOURCES = \
memory.c \
usleep.c
##
## Find a better way than $(GFXFLAGS) to inform widgets.c wich of
## tiff or xpm images should be used
INCLUDES = -I$(top_srcdir)/wrlib -I$(top_srcdir)/src \
-DRESOURCE_PATH=\"$(datadir)/WINGs\" $(GFXFLAGS) -DDEBUG \
@XCFLAGS@
-DRESOURCE_PATH=\"$(datadir)/WINGs\" @HEADER_SEARCH_PATH@ -DDEBUG

View File

@@ -62,13 +62,13 @@ host_triplet = @host@
CC = @CC@
CPP_PATH = @CPP_PATH@
DFLAGS = @DFLAGS@
GFXFLAGS = @GFXFLAGS@
GFXLFLAGS = @GFXLFLAGS@
GFXLIBS = @GFXLIBS@
HEADER_SEARCH_PATH = @HEADER_SEARCH_PATH@
ICONEXT = @ICONEXT@
INTLIBS = @INTLIBS@
LD = @LD@
LIBPL = @LIBPL@
LIBRARY_SEARCH_PATH = @LIBRARY_SEARCH_PATH@
LIBTOOL = @LIBTOOL@
LITE = @LITE@
LN_S = @LN_S@
@@ -91,7 +91,7 @@ AUTOMAKE_OPTIONS = no-dependencies
SUBDIRS = Resources
LIBLIST = $(top_builddir)/wrlib/libwraster.la @GFXLFLAGS@ @XLFLAGS@ @GFXLIBS@ @XLIBS@ -lm @LIBPL@
LIBLIST = $(top_builddir)/wrlib/libwraster.la @LIBRARY_SEARCH_PATH@ @GFXLIBS@ @XLIBS@ -lm @LIBPL@
#lib_LTLIBRARIES = libWINGs.la
@@ -102,7 +102,8 @@ lib_LIBRARIES = libWINGs.a
include_HEADERS = WINGs.h WUtil.h WINGsP.h
noinst_PROGRAMS = wtest wmquery wmfile fontl testmywidget testcolorpanel
noinst_PROGRAMS = wtest wmquery wmfile fontl testmywidget testcolorpanel testnot
testmywidget_SOURCES = testmywidget.c mywidget.c mywidget.h
@@ -126,6 +127,10 @@ testcolorpanel_SOURCES = testcolorpanel.c
testcolorpanel_LDADD = libWINGs.a $(LIBLIST)
testnot_SOURCES = testnot.c
testnot_LDADD = libWINGs.a $(LIBLIST)
wmquery_SOURCES = wmquery.c
wmquery_LDADD = libWINGs.a $(LIBLIST)
@@ -133,10 +138,10 @@ wmquery_LDADD = libWINGs.a $(LIBLIST)
EXTRA_DIST = logo.xpm
# wbutton.c
libWINGs_a_SOURCES = WINGs.h WINGsP.h configuration.c international.c notification.c selection.c userdefaults.c wapplication.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 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
INCLUDES = -I$(top_srcdir)/wrlib -I$(top_srcdir)/src -DRESOURCE_PATH=\"$(datadir)/WINGs\" $(GFXFLAGS) -DDEBUG @XCFLAGS@
INCLUDES = -I$(top_srcdir)/wrlib -I$(top_srcdir)/src -DRESOURCE_PATH=\"$(datadir)/WINGs\" @HEADER_SEARCH_PATH@ -DDEBUG
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = ../src/config.h
@@ -152,13 +157,13 @@ X_CFLAGS = @X_CFLAGS@
X_LIBS = @X_LIBS@
X_PRE_LIBS = @X_PRE_LIBS@
libWINGs_a_LIBADD =
libWINGs_a_OBJECTS = configuration.o international.o notification.o \
selection.o userdefaults.o wapplication.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
libWINGs_a_OBJECTS = configuration.o llist.o international.o \
notification.o selection.o userdefaults.o wapplication.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
AR = ar
PROGRAMS = $(noinst_PROGRAMS)
@@ -181,6 +186,9 @@ testcolorpanel_OBJECTS = testcolorpanel.o
testcolorpanel_DEPENDENCIES = libWINGs.a \
$(top_builddir)/wrlib/libwraster.la
testcolorpanel_LDFLAGS =
testnot_OBJECTS = testnot.o
testnot_DEPENDENCIES = libWINGs.a $(top_builddir)/wrlib/libwraster.la
testnot_LDFLAGS =
CFLAGS = @CFLAGS@
COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
@@ -195,8 +203,8 @@ DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
TAR = tar
GZIP_ENV = --best
SOURCES = $(libWINGs_a_SOURCES) $(wtest_SOURCES) $(wmquery_SOURCES) $(wmfile_SOURCES) $(fontl_SOURCES) $(testmywidget_SOURCES) $(testcolorpanel_SOURCES)
OBJECTS = $(libWINGs_a_OBJECTS) $(wtest_OBJECTS) $(wmquery_OBJECTS) $(wmfile_OBJECTS) $(fontl_OBJECTS) $(testmywidget_OBJECTS) $(testcolorpanel_OBJECTS)
SOURCES = $(libWINGs_a_SOURCES) $(wtest_SOURCES) $(wmquery_SOURCES) $(wmfile_SOURCES) $(fontl_SOURCES) $(testmywidget_SOURCES) $(testcolorpanel_SOURCES) $(testnot_SOURCES)
OBJECTS = $(libWINGs_a_OBJECTS) $(wtest_OBJECTS) $(wmquery_OBJECTS) $(wmfile_OBJECTS) $(fontl_OBJECTS) $(testmywidget_OBJECTS) $(testcolorpanel_OBJECTS) $(testnot_OBJECTS)
all: all-redirect
.SUFFIXES:
@@ -317,6 +325,10 @@ testcolorpanel: $(testcolorpanel_OBJECTS) $(testcolorpanel_DEPENDENCIES)
@rm -f testcolorpanel
$(LINK) $(testcolorpanel_LDFLAGS) $(testcolorpanel_OBJECTS) $(testcolorpanel_LDADD) $(LIBS)
testnot: $(testnot_OBJECTS) $(testnot_DEPENDENCIES)
@rm -f testnot
$(LINK) $(testnot_LDFLAGS) $(testnot_OBJECTS) $(testnot_LDADD) $(LIBS)
install-includeHEADERS: $(include_HEADERS)
@$(NORMAL_INSTALL)
$(mkinstalldirs) $(DESTDIR)$(includedir)

View File

@@ -62,13 +62,13 @@ host_triplet = @host@
CC = @CC@
CPP_PATH = @CPP_PATH@
DFLAGS = @DFLAGS@
GFXFLAGS = @GFXFLAGS@
GFXLFLAGS = @GFXLFLAGS@
GFXLIBS = @GFXLIBS@
HEADER_SEARCH_PATH = @HEADER_SEARCH_PATH@
ICONEXT = @ICONEXT@
INTLIBS = @INTLIBS@
LD = @LD@
LIBPL = @LIBPL@
LIBRARY_SEARCH_PATH = @LIBRARY_SEARCH_PATH@
LIBTOOL = @LIBTOOL@
LITE = @LITE@
LN_S = @LN_S@

View File

@@ -9,8 +9,12 @@
#define WINGS_H_VERSION 981220
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#if 0
}
#endif
typedef unsigned long WMPixel;
@@ -768,6 +772,10 @@ void WMSetTextFieldAlignment(WMTextField *tPtr, WMAlignment alignment);
void WMSetTextFieldBordered(WMTextField *tPtr, Bool bordered);
void WMSetTextFieldBeveled(WMTextField *tPtr, Bool flag);
Bool WMGetTextFieldEnabled(WMTextField *tPtr);
void WMSetTextFieldEnabled(WMTextField *tPtr, Bool flag);
void WMSetTextFieldSecure(WMTextField *tPtr, Bool flag);
@@ -776,8 +784,11 @@ void WMSelectTextFieldRange(WMTextField *tPtr, WMRange range);
void WMSetTextFieldCursorPosition(WMTextField *tPtr, unsigned int position);
void WMSetTextFieldNextTextField(WMTextField *tPtr, WMTextField *next);
void WMSetTextFieldPrevTextField(WMTextField *tPtr, WMTextField *prev);
extern char *WMListDidScrollNotification;
extern char *WMTextDidChangeNotification;
extern char *WMTextDidBeginEditingNotification;
extern char *WMTextDidEndEditingNotification;
@@ -844,6 +855,7 @@ void WMSetListBottomPosition(WMList *lPtr, int row);
int WMGetListPosition(WMList *lPtr);
extern char *WMListDidScrollNotification;
extern char *WMListSelectionDidChangeNotification;
/* ....................................................................... */
@@ -867,7 +879,8 @@ WMListItem *WMAddSortedBrowserItem(WMBrowser *bPtr, int column, char *text, Bool
WMListItem *WMInsertBrowserItem(WMBrowser *bPtr, int column, int row, char *text, Bool isBranch);
Bool WMSetBrowserPath(WMBrowser *bPtr, char *path);
/* Don't free the returned string. */
char* WMSetBrowserPath(WMBrowser *bPtr, char *path);
/* you can free the returned string */
char *WMGetBrowserPath(WMBrowser *bPtr);
@@ -878,6 +891,9 @@ void WMSetBrowserFillColumnProc(WMBrowser *bPtr,WMBrowserFillColumnProc *proc);
void WMSetBrowserAction(WMBrowser *bPtr, WMAction *action, void *clientData);
void WMSetBrowserDoubleAction(WMBrowser *bPtr, WMAction *action,
void *clientData);
WMListItem *WMGetBrowserSelectedItemInColumn(WMBrowser *bPtr, int column);
int WMGetBrowserFirstVisibleColumn(WMBrowser *bPtr);
@@ -1057,11 +1073,8 @@ char *WMGetFilePanelFileName(WMFilePanel *panel);
void WMFreeFilePanel(WMFilePanel *panel);
int WMRunModalOpenPanelForDirectory(WMFilePanel *panel, WMWindow *owner,
char *path, char *name, char **fileTypes);
int WMRunModalSavePanelForDirectory(WMFilePanel *panel, WMWindow *owner,
char *path, char *name);
int WMRunModalFilePanelForDirectory(WMFilePanel *panel, WMWindow *owner,
char *path, char *name, char **fileTypes);
void WMSetFilePanelAccessoryView(WMFilePanel *panel, WMView *view);
@@ -1084,5 +1097,9 @@ char *WMGetFontPanelFontName(WMFontPanel *panel);
WMFont *WMGetFontPanelFont(WMFontPanel *panel);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif

View File

@@ -1,3 +1,6 @@
#ifndef _WINGSP_H_
#define _WINGSP_H_
#include <X11/Xlib.h>
#include <X11/Xutil.h>
@@ -16,6 +19,10 @@
#include <string.h>
#include <stdio.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#define DOUBLE_BUFFER
@@ -177,25 +184,17 @@ typedef struct W_Screen {
struct W_Pixmap *checkMark;
struct W_Pixmap *homeIcon;
struct W_Pixmap *homeAltIcon;
struct W_Pixmap *altHomeIcon;
struct W_Pixmap *magnifyIcon;
struct W_Pixmap *wheelIcon;
struct W_Pixmap *grayIcon;
struct W_Pixmap *rgbIcon;
struct W_Pixmap *cmykIcon;
struct W_Pixmap *hsbIcon;
struct W_Pixmap *customPaletteIcon;
struct W_Pixmap *colorListIcon;
struct W_Pixmap *magnifyAltIcon;
struct W_Pixmap *wheelAltIcon;
struct W_Pixmap *grayAltIcon;
struct W_Pixmap *rgbAltIcon;
struct W_Pixmap *cmykAltIcon;
struct W_Pixmap *hsbAltIcon;
struct W_Pixmap *customPaletteAltIcon;
struct W_Pixmap *colorListAltIcon;
struct W_Pixmap *magnifyIcon;
struct W_Pixmap *altMagnifyIcon;
struct W_Pixmap *wheelIcon;
struct W_Pixmap *grayIcon;
struct W_Pixmap *rgbIcon;
struct W_Pixmap *cmykIcon;
struct W_Pixmap *hsbIcon;
struct W_Pixmap *customPaletteIcon;
struct W_Pixmap *colorListIcon;
struct W_Pixmap *defaultObjectIcon;
@@ -346,7 +345,7 @@ void W_DestroyView(W_View *view);
void W_RealizeView(W_View *view);
void W_ReparentView(W_View *view, W_View *newParent);
void W_ReparentView(W_View *view, W_View *newParent, int x, int y);
void W_MapView(W_View *view);
@@ -416,3 +415,14 @@ Bool W_ApplicationInitialized(void);
char *W_GetTextSelection(WMScreen *scr, Atom selection);
void W_HandleSelectionEvent(XEvent *event);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* _WINGSP_H_ */
void W_FlushASAPNotificationQueue();
void W_FlushIdleNotificationQueue();

View File

@@ -61,6 +61,10 @@
#endif /* !NDEBUG */
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
typedef enum {
WMPostWhenIdle = 1,
@@ -227,9 +231,12 @@ WMNotificationQueue *WMGetDefaultNotificationQueue(void);
WMNotificationQueue *WMCreateNotificationQueue(void);
void WMDequeueNotificationMatching(WMNotificationQueue *queue, unsigned mask);
void WMDequeueNotificationMatching(WMNotificationQueue *queue,
WMNotification *notification,
unsigned mask);
void WMEnqueueNotification(WMNotificationQueue *queue, WMNotification *notification,
void WMEnqueueNotification(WMNotificationQueue *queue,
WMNotification *notification,
WMPostingStyle postingStyle);
void WMEnqueueCoalesceNotification(WMNotificationQueue *queue,
@@ -254,7 +261,7 @@ char *WMGetUDStringForKey(WMUserDefaults *database, char *defaultName);
int WMGetUDIntegerForKey(WMUserDefaults *database, char *defaultName);
int WMGetUDFloatForKey(WMUserDefaults *database, char *defaultName);
float WMGetUDFloatForKey(WMUserDefaults *database, char *defaultName);
Bool WMGetUDBoolForKey(WMUserDefaults *database, char *defaultName);
@@ -274,6 +281,9 @@ proplist_t WMGetUDSearchList(WMUserDefaults *database);
void WMSetUDSearchList(WMUserDefaults *database, proplist_t list);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif

126
WINGs/llist.c Normal file
View File

@@ -0,0 +1,126 @@
#include "WUtil.h"
#include <stdlib.h>
#include "llist.h"
WINLINE void*
lhead(list_t *list)
{
if (!list)
return NULL;
return list->head;
}
WINLINE list_t*
ltail(list_t *list)
{
if (!list)
return NULL;
return list->tail;
}
WINLINE list_t*
lcons(void *newHead, list_t *list)
{
list_t *newNode;
newNode = wmalloc(sizeof(list_t));
newNode->head = newHead;
newNode->tail = list;
return newNode;
}
WINLINE list_t*
lappend(list_t *list, list_t *tail)
{
list_t *ptr;
if (!list)
return tail;
for (ptr = list; ptr->tail == NULL; ptr = ptr->tail);
ptr->tail = tail;
return ptr;
}
WINLINE void
lfree(list_t *list)
{
if (list) {
lfree(list->tail);
free(list);
}
}
WINLINE void*
lfind(void *objeto, list_t *list, int (*compare)(void*, void*))
{
while (list) {
if ((*compare)(list->head, objeto)==0) {
return list->head;
}
list = list->tail;
}
return NULL;
}
WINLINE int
llength(list_t *list)
{
int i = 0;
while (list) {
list = list->tail;
i++;
}
return i;
}
WINLINE list_t*
lremove(list_t *list, void *object)
{
if (!list)
return NULL;
if (list->head == object) {
list_t *tmp = list->tail;
free(list);
return tmp;
}
list->tail = lremove(list->tail, object);
return list;
}
WINLINE list_t*
lremovehead(list_t *list)
{
list_t *tmp = NULL;
if (list) {
tmp = list->tail;
free(list);
}
return tmp;
}

40
WINGs/llist.h Normal file
View File

@@ -0,0 +1,40 @@
#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
# define WINLINE inline
#else
# define WINLINE
#endif
typedef struct list_t {
void *head;
struct list_t *tail;
} list_t;
WINLINE void *lhead(list_t *list);
WINLINE list_t *ltail(list_t *list);
WINLINE list_t *lcons(void *newHead, list_t *list);
WINLINE list_t *lappend(list_t *list, list_t *tail);
WINLINE void lfree(list_t *list);
WINLINE void *lfind(void *object, list_t *list, int (*compare)(void*, void*));
WINLINE int llength(list_t *list);
WINLINE list_t *lremove(list_t *list, void *object);
WINLINE list_t *lremovehead(list_t *list);

View File

@@ -6,6 +6,7 @@
#include "WUtil.h"
#include "llist.h"
typedef struct W_Notification {
char *name;
@@ -15,6 +16,8 @@ typedef struct W_Notification {
} Notification;
extern void W_FlushASAPNotificationQueue();
char*
WMGetNotificationName(WMNotification *notification)
@@ -214,17 +217,16 @@ WMPostNotification(WMNotification *notification)
}
WMReleaseNotification(notification);
W_FlushASAPNotificationQueue();
}
void
WMRemoveNotificationObserver(void *observer)
{
NotificationObserver *orec, *tmp, *rec;
/* get the list of actions the observer is doing */
orec = WMHashGet(notificationCenter->observerTable, observer);
@@ -285,10 +287,15 @@ void
WMRemoveNotificationObserverWithName(void *observer, char *name, void *object)
{
NotificationObserver *orec, *tmp, *rec;
NotificationObserver *newList = NULL;
/* get the list of actions the observer is doing */
orec = WMHashGet(notificationCenter->observerTable, observer);
WMHashRemove(notificationCenter->observerTable, observer);
/* rebuild the list of actions for the observer */
while (orec) {
tmp = orec->nextAction;
if (orec->name == name && orec->object == object) {
@@ -301,8 +308,8 @@ WMRemoveNotificationObserverWithName(void *observer, char *name, void *object)
assert(rec->prev==NULL);
/* replace table entry */
if (orec->next) {
WMHashInsert(notificationCenter->objectTable, orec->object,
orec->next);
WMHashInsert(notificationCenter->objectTable,
orec->object, orec->next);
} else {
WMHashRemove(notificationCenter->objectTable,
orec->object);
@@ -314,34 +321,42 @@ WMRemoveNotificationObserverWithName(void *observer, char *name, void *object)
assert(rec->prev==NULL);
/* replace table entry */
if (orec->next) {
WMHashInsert(notificationCenter->nameTable, orec->name,
orec->next);
WMHashInsert(notificationCenter->nameTable,
orec->name, orec->next);
} else {
WMHashRemove(notificationCenter->nameTable, orec->name);
WMHashRemove(notificationCenter->nameTable,
orec->name);
}
}
}
/* update the action list for the observer */
rec = WMHashGet(notificationCenter->observerTable, observer);
if (rec == orec) {
if (orec->nextAction) {
WMHashInsert(notificationCenter->nameTable, observer,
orec->nextAction);
} else {
WMHashRemove(notificationCenter->nameTable, observer);
}
}
if (orec->prev)
orec->prev->next = orec->next;
if (orec->next)
orec->next->prev = orec->prev;
free(orec);
} else {
/* append this action in the new action list */
orec->nextAction = NULL;
if (!newList) {
newList = orec;
} else {
NotificationObserver *p;
p = newList;
while (p->nextAction) {
p = p->nextAction;
}
p->nextAction = orec;
}
}
orec = tmp;
}
/* reinsert the list to the table */
if (newList) {
WMHashInsert(notificationCenter->observerTable, observer, newList);
}
}
@@ -363,18 +378,25 @@ WMPostNotificationName(char *name, void *object, void *clientData)
typedef struct W_NotificationQueue {
NotificationCenter *center;
void *asapQueue;
void *idleQueue;
list_t *asapQueue;
list_t *idleQueue;
struct W_NotificationQueue *next;
} NotificationQueue;
static WMNotificationQueue *notificationQueueList = NULL;
/* default queue */
static WMNotificationQueue *notificationQueue = NULL;
WMNotificationQueue*
WMGetDefaultNotificationQueue(void)
{
if (!notificationQueue)
notificationQueue = WMCreateNotificationQueue();
return notificationQueue;
}
@@ -382,20 +404,76 @@ WMGetDefaultNotificationQueue(void)
WMNotificationQueue*
WMCreateNotificationQueue(void)
{
return NULL;
NotificationQueue *queue;
queue = wmalloc(sizeof(NotificationQueue));
queue->asapQueue = NULL;
queue->idleQueue = NULL;
queue->next = notificationQueueList;
notificationQueueList = queue;
return queue;
}
void
WMDequeueNotificationMatching(WMNotificationQueue *queue, unsigned mask)
{
}
void
WMEnqueueNotification(WMNotificationQueue *queue, WMNotification *notification,
WMPostingStyle postingStyle)
{
WMEnqueueCoalesceNotification(queue, notification, postingStyle,
WNCOnName|WNCOnSender);
}
static int
matchName(void *a, void *b)
{
WMNotification *n1 = (WMNotification*)a;
WMNotification *n2 = (WMNotification*)b;
return strcmp(n1->name, n2->name);
}
static int
matchSender(void *a, void *b)
{
WMNotification *n1 = (WMNotification*)a;
WMNotification *n2 = (WMNotification*)b;
return (n1->object == n2->object);
}
void
WMDequeueNotificationMatching(WMNotificationQueue *queue,
WMNotification *notification, unsigned mask)
{
void *n;
if (mask & WNCOnName) {
while ((n = lfind(notification->name, queue->asapQueue, matchName))) {
queue->asapQueue = lremove(queue->asapQueue, n);
WMReleaseNotification((WMNotification*)n);
}
while ((n = lfind(notification->name, queue->idleQueue, matchName))) {
queue->idleQueue = lremove(queue->idleQueue, n);
WMReleaseNotification((WMNotification*)n);
}
}
if (mask & WNCOnSender) {
while ((n = lfind(notification->name, queue->asapQueue, matchSender))) {
queue->asapQueue = lremove(queue->asapQueue, n);
WMReleaseNotification((WMNotification*)n);
}
while ((n = lfind(notification->name, queue->idleQueue, matchSender))) {
queue->idleQueue = lremove(queue->idleQueue, n);
WMReleaseNotification((WMNotification*)n);
}
}
}
@@ -405,10 +483,51 @@ WMEnqueueCoalesceNotification(WMNotificationQueue *queue,
WMPostingStyle postingStyle,
unsigned coalesceMask)
{
if (coalesceMask != WNCNone)
WMDequeueNotificationMatching(queue, notification, coalesceMask);
switch (postingStyle) {
case WMPostNow:
WMPostNotification(notification);
break;
case WMPostASAP:
queue->asapQueue = lappend(queue->asapQueue,
lcons(notification, NULL));
break;
case WMPostWhenIdle:
queue->idleQueue = lappend(queue->idleQueue,
lcons(notification, NULL));
break;
}
}
void
W_FlushASAPNotificationQueue()
{
WMNotificationQueue *queue = notificationQueueList;
while (queue) {
while (queue->asapQueue) {
WMPostNotification((WMNotification*)lhead(queue->asapQueue));
queue->asapQueue = lremovehead(queue->asapQueue);
}
}
}
void
W_FlushIdleNotificationQueue()
{
WMNotificationQueue *queue = notificationQueueList;
while (queue) {
while (queue->idleQueue) {
WMPostNotification((WMNotification*)lhead(queue->idleQueue));
queue->idleQueue = lremovehead(queue->idleQueue);
}
}
}

91
WINGs/testnot.c Normal file
View File

@@ -0,0 +1,91 @@
/*
* test notifications
*/
#include "WUtil.h"
#include <stdio.h>
#include <stdlib.h>
char *notificationA = "notificationA";
char *notificationB = "notificationB";
char *notificationC = "notificationC";
void
observer1(void *data, WMNotification *notification)
{
printf("ObserverAction 1 got %s with object=%s, clientdata=%s\n",
WMGetNotificationName(notification),
(char*)WMGetNotificationObject(notification),
(char*)WMGetNotificationClientData(notification));
}
void
observer3(void *data, WMNotification *notification)
{
printf("ObserverAction 3 got %s with object=%s, clientdata=%s\n",
WMGetNotificationName(notification),
(char*)WMGetNotificationObject(notification),
(char*)WMGetNotificationClientData(notification));
}
void
observer2(void *data, WMNotification *notification)
{
printf("ObserverAction 2 got %s with object=%s, clientdata=%s\n",
WMGetNotificationName(notification),
(char*)WMGetNotificationObject(notification),
(char*)WMGetNotificationClientData(notification));
}
main(int argc, char **argv)
{
int i;
char *obser1 = "obser1";
char *obser2 = "obser2";
char *obser3 = "obser3";
char *obj1 = "obj1";
char *obj2 = "obj2";
char *obj3 = "obj3";
char *cdata1 = "client data1";
char *cdata2 = "client data2";
char *cdata3 = "client data3";
WMInitializeApplication("test", &argc, argv);
WMAddNotificationObserver(observer1, obser1, notificationA, obj1);
WMAddNotificationObserver(observer1, obser1, notificationA, obj2);
WMAddNotificationObserver(observer1, obser1, notificationA, obj3);
puts("post1");
WMPostNotificationName(notificationA, obj3, cdata1);
puts("post2");
WMPostNotificationName(notificationA, obj2, cdata2);
puts("post3");
WMPostNotificationName(notificationA, obj1, cdata3);
puts("REMOVE1");
WMRemoveNotificationObserverWithName(obser1, notificationA, obj2);
puts("REMOVE2");
WMRemoveNotificationObserverWithName(obser1, notificationA, obj2);
puts("post1");
WMPostNotificationName(notificationA, obj3, cdata1);
puts("post2");
WMPostNotificationName(notificationA, obj2, cdata2);
puts("post3");
WMPostNotificationName(notificationA, obj1, cdata3);
return 0;
}

View File

@@ -279,7 +279,7 @@ WMGetUDIntegerForKey(WMUserDefaults *database, char *defaultName)
int
float
WMGetUDFloatForKey(WMUserDefaults *database, char *defaultName)
{
proplist_t val;
@@ -288,16 +288,12 @@ WMGetUDFloatForKey(WMUserDefaults *database, char *defaultName)
val = WMGetUDObjectForKey(database, defaultName);
if (!val)
if (!val || !PLIsString(val))
return 0.0;
if (!PLIsString(val))
if (!(str = PLGetString(val)))
return 0.0;
str = PLGetString(val);
if (!str)
return 0.0;
if (sscanf(str, "%f", &value)!=1)
return 0.0;

View File

@@ -3,6 +3,7 @@
#include "WINGsP.h"
#include <math.h> /* for : double rint (double) */
char *WMBrowserDidScrollNotification = "WMBrowserDidScrollNotification";
@@ -55,11 +56,17 @@ typedef struct W_Browser {
#define COLUMN_SPACING 4
#define TITLE_SPACING 2
#define DEFAULT_WIDTH 305
#define DEFAULT_HEIGHT 200
#define DEFAULT_HAS_SCROLLER True
#define DEFAULT_WIDTH 305
#define DEFAULT_HEIGHT 200
#define DEFAULT_HAS_SCROLLER True
#define DEFAULT_TITLE_HEIGHT 20
#define DEFAULT_IS_TITLED True
#define DEFAULT_MAX_VISIBLE_COLUMNS 2
#define DEFAULT_SEPARATOR "/"
#define MIN_VISIBLE_COLUMNS 1
#define MAX_VISIBLE_COLUMNS 32
#define DEFAULT_SEPARATOR "/"
#define COLUMN_IS_VISIBLE(b, c) ((c) >= (b)->firstVisibleColumn \
&& (c) < (b)->firstVisibleColumn + (b)->maxVisibleColumns)
@@ -70,13 +77,17 @@ static void destroyBrowser(WMBrowser *bPtr);
static void setupScroller(WMBrowser *bPtr);
static void scrollToColumn(WMBrowser *bPtr, int column);
static void scrollToColumn(WMBrowser *bPtr, int column, Bool updateScroller);
static void paintItem(WMList *lPtr, int index, Drawable d, char *text,
int state, WMRect *rect);
static void loadColumn(WMBrowser *bPtr, int column);
static void removeColumn(WMBrowser *bPtr, int column);
static char*
createTruncatedString(WMFont *font, char *text, int *textLen, int width);
static void resizeBrowser(WMWidget*, unsigned int, unsigned int);
@@ -94,6 +105,8 @@ WMCreateBrowser(WMWidget *parent)
WMBrowser *bPtr;
int i;
wassertrv(parent, NULL);
bPtr = wmalloc(sizeof(WMBrowser));
memset(bPtr, 0, sizeof(WMBrowser));
@@ -112,9 +125,9 @@ WMCreateBrowser(WMWidget *parent)
/* default configuration */
bPtr->flags.hasScroller = DEFAULT_HAS_SCROLLER;
bPtr->titleHeight = 20;
bPtr->flags.isTitled = 1;
bPtr->maxVisibleColumns = 2;
bPtr->titleHeight = DEFAULT_TITLE_HEIGHT;
bPtr->flags.isTitled = DEFAULT_IS_TITLED;
bPtr->maxVisibleColumns = DEFAULT_MAX_VISIBLE_COLUMNS;
resizeBrowser(bPtr, DEFAULT_WIDTH, DEFAULT_HEIGHT);
@@ -137,24 +150,58 @@ WMCreateBrowser(WMWidget *parent)
void
WMSetBrowserMaxVisibleColumns(WMBrowser *bPtr, int columns)
{
if (columns > bPtr->maxVisibleColumns) {
int curMaxVisibleColumns;
int newFirstVisibleColumn = 0;
assert ((int) bPtr);
columns = (columns < MIN_VISIBLE_COLUMNS) ? MIN_VISIBLE_COLUMNS : columns;
columns = (columns > MAX_VISIBLE_COLUMNS) ? MAX_VISIBLE_COLUMNS : columns;
if (columns == bPtr->maxVisibleColumns) {
return;
}
curMaxVisibleColumns = bPtr->maxVisibleColumns;
bPtr->maxVisibleColumns = columns;
/* browser not loaded */
if (!bPtr->flags.loaded) {
if ((columns > curMaxVisibleColumns) && (columns > bPtr->columnCount)) {
int i = columns - bPtr->columnCount;
bPtr->usedColumnCount = bPtr->columnCount;
while (i--) {
WMAddBrowserColumn(bPtr);
}
bPtr->usedColumnCount = 0;
}
/* browser loaded and columns > curMaxVisibleColumns */
} else if (columns > curMaxVisibleColumns) {
if (bPtr->usedColumnCount > columns) {
newFirstVisibleColumn = bPtr->usedColumnCount - columns;
}
if (newFirstVisibleColumn > bPtr->firstVisibleColumn) {
newFirstVisibleColumn = bPtr->firstVisibleColumn;
}
if (columns > bPtr->columnCount) {
int i = columns - bPtr->columnCount;
int curUsedColumnCount = bPtr->usedColumnCount;
bPtr->usedColumnCount = bPtr->columnCount;
while (i--) {
WMAddBrowserColumn(bPtr);
}
bPtr->usedColumnCount = curUsedColumnCount;
}
/* browser loaded and columns < curMaxVisibleColumns */
} else {
newFirstVisibleColumn = bPtr->firstVisibleColumn;
if (newFirstVisibleColumn + columns >= bPtr->usedColumnCount) {
removeColumn(bPtr, newFirstVisibleColumn + columns);
}
resizeBrowser(bPtr, bPtr->view->size.width, bPtr->view->size.height);
} else if (columns < bPtr->maxVisibleColumns) {
resizeBrowser(bPtr, bPtr->view->size.width, bPtr->view->size.height);
}
bPtr->maxVisibleColumns = columns;
resizeBrowser(bPtr, bPtr->view->size.width, bPtr->view->size.height);
if (bPtr->flags.loaded) {
XClearArea(bPtr->view->screen->display, bPtr->view->window, 0, 0,
bPtr->view->size.width, bPtr->titleHeight, False);
scrollToColumn (bPtr, newFirstVisibleColumn, True);
}
}
@@ -187,11 +234,27 @@ drawTitleOfColumn(WMBrowser *bPtr, int column)
W_DrawRelief(scr, bPtr->view->window, x, 0,
bPtr->columnSize.width, bPtr->titleHeight, WRSunken);
if (column < bPtr->usedColumnCount && bPtr->titles[column])
W_PaintText(bPtr->view, bPtr->view->window, scr->boldFont, x,
(bPtr->titleHeight-WMFontHeight(scr->boldFont))/2,
bPtr->columnSize.width, WACenter, W_GC(scr->white),
False, bPtr->titles[column], strlen(bPtr->titles[column]));
if (column < bPtr->usedColumnCount && bPtr->titles[column]) {
int titleLen = strlen(bPtr->titles[column]);
int widthC = bPtr->columnSize.width-8;
if (WMWidthOfString(scr->boldFont, bPtr->titles[column], titleLen)
> widthC) {
char *titleBuf = createTruncatedString(scr->boldFont,
bPtr->titles[column],
&titleLen, widthC);
W_PaintText(bPtr->view, bPtr->view->window, scr->boldFont, x,
(bPtr->titleHeight-WMFontHeight(scr->boldFont))/2,
bPtr->columnSize.width, WACenter, W_GC(scr->white),
False, titleBuf, titleLen);
free (titleBuf);
} else {
W_PaintText(bPtr->view, bPtr->view->window, scr->boldFont, x,
(bPtr->titleHeight-WMFontHeight(scr->boldFont))/2,
bPtr->columnSize.width, WACenter, W_GC(scr->white),
False, bPtr->titles[column], titleLen);
}
}
}
@@ -239,70 +302,50 @@ WMGetBrowserFirstVisibleColumn(WMBrowser *bPtr)
static void
removeColumn(WMBrowser *bPtr, int column)
{
int i;
int i, clearEnd, destroyEnd;
WMList **clist;
char **tlist;
if (column >= bPtr->usedColumnCount)
assert ((int) bPtr);
column = (column < 0) ? 0 : column;
if (column >= bPtr->columnCount) {
return;
if (column < bPtr->maxVisibleColumns) {
int tmp;
#if 0
/* this code causes bugs */
int limit;
if(bPtr->usedColumnCount < bPtr->maxVisibleColumns)
limit = bPtr->usedColumnCount;
else
limit = bPtr->maxVisibleColumns;
for (i=column; i < limit; i++) {
if (bPtr->titles[i])
free(bPtr->titles[i]);
bPtr->titles[i] = NULL;
WMClearList(bPtr->columns[i]);
bPtr->usedColumnCount--;
}
#else
for (i=column; i < bPtr->maxVisibleColumns; i++) {
if (bPtr->titles[i])
free(bPtr->titles[i]);
bPtr->titles[i] = NULL;
WMClearList(bPtr->columns[i]);
bPtr->usedColumnCount--;
}
tmp = bPtr->columnCount;
for (i=bPtr->maxVisibleColumns; i < tmp; i++) {
if (bPtr->titles[i])
free(bPtr->titles[i]);
bPtr->titles[i] = NULL;
WMDestroyWidget(bPtr->columns[i]);
bPtr->columns[i] = NULL;
bPtr->columnCount--;
bPtr->usedColumnCount--;
}
#endif
} else {
int tmp = bPtr->columnCount;
for (i=column; i < tmp; i++) {
if (bPtr->titles[i])
free(bPtr->titles[i]);
bPtr->titles[i] = NULL;
WMDestroyWidget(bPtr->columns[i]);
bPtr->columns[i] = NULL;
bPtr->columnCount--;
bPtr->usedColumnCount--;
}
}
clist = wmalloc(sizeof(WMList*)*bPtr->columnCount);
tlist = wmalloc(sizeof(char*)*bPtr->columnCount);
memcpy(clist, bPtr->columns, sizeof(WMList*)*bPtr->columnCount);
memcpy(tlist, bPtr->titles, sizeof(char*)*bPtr->columnCount);
if (column < bPtr->maxVisibleColumns) {
clearEnd = bPtr->maxVisibleColumns;
destroyEnd = bPtr->columnCount;
bPtr->columnCount = bPtr->maxVisibleColumns;
} else {
clearEnd = column;
destroyEnd = bPtr->columnCount;
bPtr->columnCount = column;
}
if (column < bPtr->usedColumnCount) {
bPtr->usedColumnCount = column;
}
for (i=column; i < clearEnd; i++) {
if (bPtr->titles[i]) {
free(bPtr->titles[i]);
bPtr->titles[i] = NULL;
}
WMClearList(bPtr->columns[i]);
}
for (;i < destroyEnd; i++) {
if (bPtr->titles[i]) {
free(bPtr->titles[i]);
bPtr->titles[i] = NULL;
}
WMRemoveNotificationObserverWithName(bPtr,
WMListSelectionDidChangeNotification,
bPtr->columns[i]);
WMDestroyWidget(bPtr->columns[i]);
bPtr->columns[i] = NULL;
}
clist = wmalloc(sizeof(WMList*) * (bPtr->columnCount));
tlist = wmalloc(sizeof(char*) * (bPtr->columnCount));
memcpy(clist, bPtr->columns, sizeof(WMList*) * (bPtr->columnCount));
memcpy(tlist, bPtr->titles, sizeof(char*) * (bPtr->columnCount));
free(bPtr->titles);
free(bPtr->columns);
bPtr->titles = tlist;
@@ -310,11 +353,10 @@ removeColumn(WMBrowser *bPtr, int column)
}
WMListItem*
WMGetBrowserSelectedItemInColumn(WMBrowser *bPtr, int column)
{
if ((column < 0) || (column > bPtr->columnCount))
if ((column < 0) || (column >= bPtr->usedColumnCount))
return NULL;
return WMGetListSelectedItem(bPtr->columns[column]);
@@ -430,8 +472,8 @@ resizeBrowser(WMWidget *w, unsigned int width, unsigned int height)
bPtr->columnSize.height = height;
if (bPtr->flags.isTitled) {
bPtr->columnSize.height -= TITLE_SPACING + bPtr->titleHeight;
colY = TITLE_SPACING + bPtr->titleHeight;
bPtr->columnSize.height -= colY;
} else {
colY = 0;
}
@@ -481,8 +523,19 @@ paintItem(WMList *lPtr, int index, Drawable d, char *text, int state,
XClearArea(scr->display, d, x, y, width, height, False);
if (text) {
W_PaintText(view, d, scr->normalFont, x+4, y, width,
WALeft, W_GC(scr->black), False, text, strlen(text));
/* Avoid overlaping... */
int textLen = strlen(text);
int widthC = (state & WLDSIsBranch) ? width-20 : width-8;
if (WMWidthOfString(scr->normalFont, text, textLen) > widthC) {
char *textBuf = createTruncatedString(scr->normalFont,
text, &textLen, widthC);
W_PaintText(view, d, scr->normalFont, x+4, y, widthC,
WALeft, W_GC(scr->black), False, textBuf, textLen);
free(textBuf);
} else {
W_PaintText(view, d, scr->normalFont, x+4, y, widthC,
WALeft, W_GC(scr->black), False, text, textLen);
}
}
if (state & WLDSIsBranch) {
@@ -511,7 +564,7 @@ scrollCallback(WMWidget *scroller, void *self)
switch (WMGetScrollerHitPart(sPtr)) {
case WSDecrementLine:
if (bPtr->firstVisibleColumn > 0) {
scrollToColumn(bPtr, bPtr->firstVisibleColumn-1);
scrollToColumn(bPtr, bPtr->firstVisibleColumn-1, True);
}
break;
@@ -519,44 +572,45 @@ scrollCallback(WMWidget *scroller, void *self)
if (bPtr->firstVisibleColumn > 0) {
newFirst = bPtr->firstVisibleColumn - bPtr->maxVisibleColumns;
scrollToColumn(bPtr, newFirst);
scrollToColumn(bPtr, newFirst, True);
}
break;
case WSIncrementLine:
if (LAST_VISIBLE_COLUMN < bPtr->columnCount) {
scrollToColumn(bPtr, bPtr->firstVisibleColumn+1);
if (LAST_VISIBLE_COLUMN < bPtr->usedColumnCount) {
scrollToColumn(bPtr, bPtr->firstVisibleColumn+1, True);
}
break;
case WSIncrementPage:
if (LAST_VISIBLE_COLUMN < bPtr->columnCount) {
if (LAST_VISIBLE_COLUMN < bPtr->usedColumnCount) {
newFirst = bPtr->firstVisibleColumn + bPtr->maxVisibleColumns;
if (newFirst+bPtr->maxVisibleColumns >= bPtr->columnCount)
newFirst = bPtr->columnCount - bPtr->maxVisibleColumns;
scrollToColumn(bPtr, newFirst);
scrollToColumn(bPtr, newFirst, True);
}
break;
case WSKnob:
{
float floatValue;
float value = bPtr->columnCount - bPtr->maxVisibleColumns;
double floatValue;
double value = bPtr->columnCount - bPtr->maxVisibleColumns;
floatValue = WMGetScrollerValue(bPtr->scroller);
floatValue = (floatValue*value)/value;
newFirst = floatValue*(float)(bPtr->columnCount - bPtr->maxVisibleColumns);
newFirst = rint(floatValue*(float)(bPtr->columnCount - bPtr->maxVisibleColumns));
if (bPtr->firstVisibleColumn != newFirst)
scrollToColumn(bPtr, newFirst);
else
scrollToColumn(bPtr, newFirst, False);
/* else
WMSetScrollerParameters(bPtr->scroller, floatValue,
bPtr->maxVisibleColumns/(float)bPtr->columnCount);
*/
}
break;
@@ -597,6 +651,14 @@ WMSetBrowserAction(WMBrowser *bPtr, WMAction *action, void *clientData)
}
void
WMSetBrowserDoubleAction(WMBrowser *bPtr, WMAction *action, void *clientData)
{
bPtr->doubleAction = action;
bPtr->doubleClientData = clientData;
}
void
WMSetBrowserHasScroller(WMBrowser *bPtr, int hasScroller)
{
@@ -605,30 +667,34 @@ WMSetBrowserHasScroller(WMBrowser *bPtr, int hasScroller)
Bool
char*
WMSetBrowserPath(WMBrowser *bPtr, char *path)
{
int i;
char *str = wstrdup(path);
char *tmp;
char *tmp, *retPtr = NULL;
int item;
Bool ok = True;
WMListItem *listItem;
/* WMLoadBrowserColumnZero must be call first */
if (!bPtr->flags.loaded) {
return False;
}
removeColumn(bPtr, 1);
i = 0;
tmp = strtok(str, bPtr->pathSeparator);
while (tmp) {
/* select it in the column */
item = WMFindRowOfListItemWithTitle(bPtr->columns[i], tmp);
item = WMFindRowOfListItemWithTitle(bPtr->columns[i], tmp);
if (item<0) {
ok = False;
retPtr = &path[(int)(tmp - str)];
break;
}
WMSelectListItem(bPtr->columns[i], item);
WMSetListPosition(bPtr->columns[i], item);
listItem = WMGetListItem(bPtr->columns[i], item);
if (!listItem || !listItem->isBranch) {
break;
@@ -645,11 +711,25 @@ WMSetBrowserPath(WMBrowser *bPtr, char *path)
}
free(str);
bPtr->selectedColumn = bPtr->usedColumnCount - 1;
for (i = bPtr->usedColumnCount - 1;
(i > -1) && !WMGetListSelectedItem(bPtr->columns[i]);
i--);
scrollToColumn(bPtr, bPtr->columnCount-bPtr->maxVisibleColumns);
bPtr->selectedColumn = i;
if (bPtr->columnCount < bPtr->maxVisibleColumns) {
int i = bPtr->maxVisibleColumns - bPtr->columnCount;
int curUsedColumnCount = bPtr->usedColumnCount;
bPtr->usedColumnCount = bPtr->columnCount;
while (i--) {
WMAddBrowserColumn(bPtr);
}
bPtr->usedColumnCount = curUsedColumnCount;
}
return ok;
scrollToColumn(bPtr, bPtr->columnCount - bPtr->maxVisibleColumns, True);
return retPtr;
}
@@ -669,7 +749,11 @@ WMGetBrowserPathToColumn(WMBrowser *bPtr, int column)
if (column >= bPtr->usedColumnCount)
column = bPtr->usedColumnCount-1;
if (column < 0) {
return wstrdup(bPtr->pathSeparator);
}
/* calculate size of buffer */
size = 0;
for (i = 0; i <= column; i++) {
@@ -749,7 +833,7 @@ handleEvents(XEvent *event, void *data)
static void
scrollToColumn(WMBrowser *bPtr, int column)
scrollToColumn(WMBrowser *bPtr, int column, Bool updateScroller)
{
int i;
int x;
@@ -764,7 +848,7 @@ scrollToColumn(WMBrowser *bPtr, int column)
x = 0;
bPtr->firstVisibleColumn = column;
for (i = 0; i < bPtr->usedColumnCount; i++) {
for (i = 0; i < bPtr->columnCount; i++) {
if (COLUMN_IS_VISIBLE(bPtr, i)) {
WMMoveWidget(bPtr->columns[i], x,
WMWidgetView(bPtr->columns[i])->pos.y);
@@ -778,15 +862,17 @@ scrollToColumn(WMBrowser *bPtr, int column)
}
/* update the scroller */
if (bPtr->columnCount > bPtr->maxVisibleColumns) {
float value, proportion;
if (updateScroller) {
if (bPtr->columnCount > bPtr->maxVisibleColumns) {
float value, proportion;
value = bPtr->firstVisibleColumn
/(float)(bPtr->columnCount-bPtr->maxVisibleColumns);
proportion = bPtr->maxVisibleColumns/(float)bPtr->columnCount;
WMSetScrollerParameters(bPtr->scroller, value, proportion);
} else {
WMSetScrollerParameters(bPtr->scroller, 0, 1);
value = bPtr->firstVisibleColumn
/(float)(bPtr->columnCount-bPtr->maxVisibleColumns);
proportion = bPtr->maxVisibleColumns/(float)bPtr->columnCount;
WMSetScrollerParameters(bPtr->scroller, value, proportion);
} else {
WMSetScrollerParameters(bPtr->scroller, 0, 1);
}
}
if (bPtr->view->flags.mapped)
@@ -803,10 +889,11 @@ listCallback(void *self, void *clientData)
WMBrowser *bPtr = (WMBrowser*)clientData;
WMList *lPtr = (WMList*)self;
WMListItem *item;
static WMListItem *oldItem = NULL;
int i;
item = WMGetListSelectedItem(lPtr);
if (!item)
if (!item || oldItem == item)
return;
for (i=0; i<bPtr->columnCount; i++) {
@@ -815,8 +902,6 @@ listCallback(void *self, void *clientData)
}
assert(i<bPtr->columnCount);
bPtr->selectedColumn = i;
/* columns at right must be cleared */
removeColumn(bPtr, i+1);
/* open directory */
@@ -828,11 +913,30 @@ listCallback(void *self, void *clientData)
i = 0;
else
i = bPtr->usedColumnCount-bPtr->maxVisibleColumns;
scrollToColumn(bPtr, i);
scrollToColumn(bPtr, i, True);
/* call callback for click */
if (bPtr->action)
(*bPtr->action)(bPtr, bPtr->clientData);
oldItem = item;
}
static void
listDoubleCallback(void *self, void *clientData)
{
WMBrowser *bPtr = (WMBrowser*)clientData;
WMList *lPtr = (WMList*)self;
WMListItem *item;
item = WMGetListSelectedItem(lPtr);
if (!item)
return;
/* call callback for double click */
if (bPtr->doubleAction)
(*bPtr->doubleAction)(bPtr, bPtr->doubleClientData);
}
@@ -846,7 +950,7 @@ WMLoadBrowserColumnZero(WMBrowser *bPtr)
loadColumn(bPtr, 0);
/* make column 0 visible */
scrollToColumn(bPtr, 0);
scrollToColumn(bPtr, 0, True);
bPtr->flags.loaded = 1;
}
@@ -857,25 +961,50 @@ void
WMRemoveBrowserItem(WMBrowser *bPtr, int column, int row)
{
WMList *list;
if (column < 0 || column >= bPtr->usedColumnCount)
return;
list = WMGetBrowserListInColumn(bPtr, column);
if (row < 0 || row >= WMGetListNumberOfRows(list))
return;
removeColumn(bPtr, column+1);
if (bPtr->usedColumnCount < bPtr->maxVisibleColumns)
scrollToColumn(bPtr, 0);
scrollToColumn(bPtr, 0, True);
else
scrollToColumn(bPtr, bPtr->usedColumnCount-bPtr->maxVisibleColumns);
scrollToColumn(bPtr, bPtr->usedColumnCount-bPtr->maxVisibleColumns,
True);
WMRemoveListItem(list, row);
}
static void
listSelectionObserver(void *observerData, WMNotification *notification)
{
WMBrowser *bPtr = (WMBrowser*)observerData;
int column, item = (int)WMGetNotificationClientData(notification);
WMList *lPtr = (WMList*)WMGetNotificationObject(notification);
for (column=0; column<bPtr->usedColumnCount; column++)
if (bPtr->columns[column] == lPtr)
break;
/* this can happen when a list is being cleared with WMClearList
* after the column was removed */
if (column >= bPtr->usedColumnCount) {
return;
}
if (item < 0)
column--;
bPtr->selectedColumn = column;
}
int
WMAddBrowserColumn(WMBrowser *bPtr)
{
@@ -915,7 +1044,11 @@ WMAddBrowserColumn(WMBrowser *bPtr)
list = WMCreateList(bPtr);
WMSetListAction(list, listCallback, bPtr);
WMSetListDoubleAction(list, listDoubleCallback, bPtr);
WMSetListUserDrawProc(list, paintItem);
WMAddNotificationObserver(listSelectionObserver, bPtr,
WMListSelectionDidChangeNotification, list);
bPtr->columns[index] = list;
WMResizeWidget(list, bPtr->columnSize.width, bPtr->columnSize.height);
@@ -951,7 +1084,37 @@ destroyBrowser(WMBrowser *bPtr)
free(bPtr->pathSeparator);
WMRemoveNotificationObserver(bPtr);
free(bPtr);
}
static char*
createTruncatedString(WMFont *font, char *text, int *textLen, int width)
{
int dLen = WMWidthOfString(font, ".", 1);
char *textBuf = (char*)wmalloc((*textLen)+4);
if (width >= 3*dLen) {
int dddLen = 3*dLen;
int tmpTextLen = *textLen;
strcpy(textBuf, text);
while (tmpTextLen
&& (WMWidthOfString(font, textBuf, tmpTextLen)+dddLen > width))
tmpTextLen--;
strcpy(textBuf+tmpTextLen, "...");
*textLen = tmpTextLen+3;
} else if (width >= 2*dLen) {
strcpy(textBuf, "..");
*textLen = 2;
} else if (width >= dLen) {
strcpy(textBuf, ".");
*textLen = 1;
} else {
*textBuf = '\0';
*textLen = 0;
}
return textBuf;
}

File diff suppressed because it is too large Load Diff

View File

@@ -328,8 +328,10 @@ checkIdleHandlers()
{
IdleHandler *handler, *tmp;
if (!idleHandler)
return;
if (!idleHandler) {
W_FlushIdleNotificationQueue();
return;
}
handler = idleHandler;
@@ -344,6 +346,7 @@ checkIdleHandlers()
handler = tmp;
}
W_FlushIdleNotificationQueue();
}
@@ -353,7 +356,7 @@ checkTimerHandlers()
{
TimerHandler *handler;
struct timeval now;
rightNow(&now);
while (timerHandler && IS_AFTER(now, timerHandler->when)) {
@@ -363,6 +366,8 @@ checkTimerHandlers()
(*handler->callback)(handler->clientData);
free(handler);
}
W_FlushASAPNotificationQueue();
}
@@ -797,7 +802,9 @@ W_WaitForEvent(Display *dpy, unsigned long xeventmask)
retval = fds[0].revents & (POLLIN|POLLRDNORM|POLLRDBAND|POLLPRI);
free(fds);
W_FlushASAPNotificationQueue();
return retval;
#else /* not HAVE_POLL */
#ifdef HAVE_SELECT
@@ -882,7 +889,9 @@ W_WaitForEvent(Display *dpy, unsigned long xeventmask)
handler = handler->next;
}
}
W_FlushASAPNotificationQueue();
return FD_ISSET(ConnectionNumber(dpy), &rset);
#else /* not HAVE_SELECT, not HAVE_POLL */
Neither select nor poll. You lose.
@@ -890,6 +899,7 @@ Neither select nor poll. You lose.
#endif /* HAVE_POLL */
}
void
WMNextEvent(Display *dpy, XEvent *event)
{

View File

@@ -1,7 +1,4 @@
#include "WINGsP.h"
#include <sys/types.h>
@@ -47,15 +44,24 @@ typedef struct W_FilePanel {
unsigned int showAllFiles:1;
unsigned int canFreeFileTypes:1;
unsigned int fileMustExist:1;
unsigned int panelType:1;
/**/
unsigned int ignoreTextChangeNotification:1;
} flags;
} W_FilePanel;
/* Type of panel */
#define WP_OPEN 0
#define WP_SAVE 1
#define PWIDTH 320
#define PHEIGHT 360
static void listDirectoryOnColumn(WMFilePanel *panel, int column, char *path);
static void browserClick();
static void browserDClick();
static void fillColumn(WMBrowser *bPtr, int column);
@@ -65,6 +71,7 @@ static void buttonClick();
static char *getCurrentFileName(WMFilePanel *panel);
static void handleEvents(XEvent *event, void *data);
static int
@@ -94,14 +101,24 @@ static void
textChangedObserver(void *observerData, WMNotification *notification)
{
W_FilePanel *panel = (W_FilePanel*)observerData;
char *text, *text1;
char *text;
WMList *list;
int col = WMGetBrowserNumberOfColumns(panel->browser) - 1;
int i, j, textEvent = (int)WMGetNotificationClientData(notification);
static int running = 0;
if (running)
return;
running = 1;
if (panel->flags.ignoreTextChangeNotification)
return;
list = WMGetBrowserListInColumn(panel->browser, col);
if (!list)
return;
text = WMGetTextFieldText(panel->fileField);
if (panel->flags.autoCompletion && textEvent!=WMDeleteTextEvent)
@@ -110,45 +127,28 @@ textChangedObserver(void *observerData, WMNotification *notification)
i = closestListItem(list, text, True);
WMSelectListItem(list, i);
if (i>=0) {
if (i>=0 && panel->flags.autoCompletion) {
WMListItem *item = WMGetListItem(list, i);
int textLen = strlen(text), itemTextLen = strlen(item->text);
WMSetListPosition(list, i);
if (panel->flags.autoCompletion) {
/* Be careful with the '<' condition below. Changing it can drop
* you into an endless loop. We call here, inside a function
* called from a notification observer, to a function that
* generates notification events. So make sure we do not call it
* recursively for ever.
* '<' means we only update text field if it is really not yet
* complete. -Dan
*/
if (textLen < itemTextLen && textEvent!=WMDeleteTextEvent) {
WMRange range;
WMInsertTextFieldText(panel->fileField, &item->text[textLen],
textLen);
WMSetTextFieldCursorPosition(panel->fileField, itemTextLen);
range.position = textLen;
range.count = itemTextLen - textLen;
WMSelectTextFieldRange(panel->fileField, range);
}
text1 = WMGetTextFieldText(panel->fileField);
j = closestListItem(list, text1, True);
if (i != j) {
WMSelectListItem(list, j);
if (j>=0) {
WMSetListPosition(list, j);
}
}
free(text1);
}
int visibleItems = WMWidgetHeight(list)/WMGetListItemHeight(list);
if (textEvent!=WMSetTextEvent || textLen<itemTextLen)
WMSetListPosition(list, i - visibleItems/2);
if (textEvent!=WMDeleteTextEvent && textLen<itemTextLen) {
WMRange range;
WMInsertTextFieldText(panel->fileField, &item->text[textLen],
textLen);
WMSetTextFieldCursorPosition(panel->fileField, itemTextLen);
range.position = textLen;
range.count = itemTextLen - textLen;
WMSelectTextFieldRange(panel->fileField, range);
}
}
free(text);
running = 0;
}
@@ -178,6 +178,11 @@ makeFilePanel(WMScreen *scrPtr, char *name, char *title)
WMResizeWidget(fPtr->win, PWIDTH, PHEIGHT);
WMSetWindowTitle(fPtr->win, "");
WMCreateEventHandler(WMWidgetView(fPtr->win), StructureNotifyMask,
handleEvents, fPtr);
WMSetWindowMinSize(fPtr->win, PWIDTH, PHEIGHT);
fPtr->iconLabel = WMCreateLabel(fPtr->win);
WMResizeWidget(fPtr->iconLabel, 64, 64);
WMMoveWidget(fPtr->iconLabel, 0, 0);
@@ -200,6 +205,7 @@ makeFilePanel(WMScreen *scrPtr, char *name, char *title)
fPtr->browser = WMCreateBrowser(fPtr->win);
WMSetBrowserFillColumnProc(fPtr->browser, fillColumn);
WMSetBrowserAction(fPtr->browser, browserClick, fPtr);
WMSetBrowserDoubleAction(fPtr->browser, browserDClick, fPtr);
WMMoveWidget(fPtr->browser, 7, 72);
WMHangData(fPtr->browser, fPtr);
@@ -238,12 +244,15 @@ makeFilePanel(WMScreen *scrPtr, char *name, char *title)
WMResizeWidget(fPtr->homeButton, 28, 28);
WMSetButtonImagePosition(fPtr->homeButton, WIPImageOnly);
WMSetButtonImage(fPtr->homeButton, scrPtr->homeIcon);
WMSetButtonAltImage(fPtr->homeButton, scrPtr->homeAltIcon);
WMSetButtonAltImage(fPtr->homeButton, scrPtr->altHomeIcon);
WMSetButtonAction(fPtr->homeButton, goHome, fPtr);
WMRealizeWidget(fPtr->win);
WMMapSubwidgets(fPtr->win);
WMSetFocusToWidget(fPtr->fileField);
WMSetTextFieldCursorPosition(fPtr->fileField, 0);
WMLoadBrowserColumnZero(fPtr->browser);
fPtr->flags.canChooseFiles = 1;
@@ -264,6 +273,7 @@ WMGetOpenPanel(WMScreen *scrPtr)
panel = makeFilePanel(scrPtr, "openFilePanel", "Open");
panel->flags.fileMustExist = 1;
panel->flags.panelType = WP_OPEN;
scrPtr->sharedOpenPanel = panel;
@@ -281,6 +291,7 @@ WMGetSavePanel(WMScreen *scrPtr)
panel = makeFilePanel(scrPtr, "saveFilePanel", "Save");
panel->flags.fileMustExist = 0;
panel->flags.panelType = WP_SAVE;
scrPtr->sharedSavePanel = panel;
@@ -305,20 +316,40 @@ WMFreeFilePanel(WMFilePanel *panel)
int
WMRunModalSavePanelForDirectory(WMFilePanel *panel, WMWindow *owner,
char *path, char *name)
WMRunModalFilePanelForDirectory(WMFilePanel *panel, WMWindow *owner,
char *path, char *name, char **fileTypes)
{
WMScreen *scr = WMWidgetScreen(panel->win);
XEvent event;
WMChangePanelOwner(panel->win, owner);
if (name && !owner) {
WMSetWindowTitle(panel->win, name);
}
WMSetFilePanelDirectory(panel, path);
panel->flags.done = 0;
panel->fileTypes = NULL;
switch(panel->flags.panelType) {
case WP_OPEN:
if (fileTypes)
panel->flags.filtered = 1;
panel->fileTypes = fileTypes;
if (name == NULL)
name = "Open";
break;
case WP_SAVE:
panel->fileTypes = NULL;
panel->flags.filtered = 0;
if (name == NULL)
name = "Save";
break;
default:
break;
}
panel->flags.filtered = 0;
WMSetLabelText(panel->titleLabel, name);
WMMapWidget(panel->win);
@@ -337,35 +368,6 @@ WMRunModalSavePanelForDirectory(WMFilePanel *panel, WMWindow *owner,
int
WMRunModalOpenPanelForDirectory(WMFilePanel *panel, WMWindow *owner,
char *path, char *name, char **fileTypes)
{
WMScreen *scr = WMWidgetScreen(panel->win);
XEvent event;
WMChangePanelOwner(panel->win, owner);
WMSetFilePanelDirectory(panel, path);
panel->flags.done = 0;
if (fileTypes)
panel->flags.filtered = 1;
panel->fileTypes = fileTypes;
WMMapWidget(panel->win);
while (!panel->flags.done) {
WMNextEvent(scr->display, &event);
WMHandleEvent(&event);
}
WMCloseWindow(panel->win);
return (panel->flags.canceled ? False : True);
}
void
WMSetFilePanelDirectory(WMFilePanel *panel, char *path)
@@ -373,18 +375,22 @@ WMSetFilePanelDirectory(WMFilePanel *panel, char *path)
WMList *list;
WMListItem *item;
int col;
WMSetBrowserPath(panel->browser, path);
col = WMGetBrowserNumberOfColumns(panel->browser) - 1;
char *rest;
rest = WMSetBrowserPath(panel->browser, path);
if (strcmp(path, "/")==0)
rest = NULL;
col = WMGetBrowserSelectedColumn(panel->browser);
list = WMGetBrowserListInColumn(panel->browser, col);
if (list && (item = WMGetListSelectedItem(list))) {
if (item->isBranch) {
WMSetTextFieldText(panel->fileField, NULL);
} else {
WMSetTextFieldText(panel->fileField, item->text);
}
if (item->isBranch) {
WMSetTextFieldText(panel->fileField, rest);
} else {
WMSetTextFieldText(panel->fileField, item->text);
}
} else {
WMSetTextFieldText(panel->fileField, path);
WMSetTextFieldText(panel->fileField, rest);
}
}
@@ -425,7 +431,7 @@ WMSetFilePanelAccessoryView(WMFilePanel *panel, WMView *view)
v = WMWidgetView(panel->win);
W_ReparentView(view, v);
W_ReparentView(view, v, 0, 0);
W_MoveView(view, (v->size.width - v->size.width)/2, 300);
}
@@ -541,18 +547,27 @@ fillColumn(WMBrowser *bPtr, int column)
}
static void
browserDClick(WMBrowser *bPtr, WMFilePanel *panel)
{
WMPerformButtonClick(panel->okButton);
}
static void
browserClick(WMBrowser *bPtr, WMFilePanel *panel)
{
int col = WMGetBrowserSelectedColumn(bPtr);
WMListItem *item = WMGetBrowserSelectedItemInColumn(bPtr, col);
panel->flags.ignoreTextChangeNotification = 1;
if (!item || item->isBranch)
WMSetTextFieldText(panel->fileField, NULL);
else {
WMSetTextFieldText(panel->fileField, item->text);
}
panel->flags.ignoreTextChangeNotification = 0;
}
@@ -570,6 +585,39 @@ goHome(WMButton *bPtr, WMFilePanel *panel)
}
static void
handleEvents(XEvent *event, void *data)
{
W_FilePanel *pPtr = (W_FilePanel*)data;
W_View *view = WMWidgetView(pPtr->win);
if (event->type == ConfigureNotify) {
if (event->xconfigure.width != view->size.width
|| event->xconfigure.height != view->size.height) {
unsigned int newWidth = event->xconfigure.width;
unsigned int newHeight = event->xconfigure.height;
int newColumnCount;
W_ResizeView(view, newWidth, newHeight);
WMResizeWidget(pPtr->line, newWidth, 2);
WMResizeWidget(pPtr->browser, newWidth-14,
newHeight-(PHEIGHT-200));
WMResizeWidget(pPtr->fileField, newWidth-60-10, 24);
WMMoveWidget(pPtr->nameLabel, 7, newHeight-(PHEIGHT-282));
WMMoveWidget(pPtr->fileField, 60, newHeight-(PHEIGHT-278));
WMMoveWidget(pPtr->okButton, newWidth-(PWIDTH-230),
newHeight-(PHEIGHT-325));
WMMoveWidget(pPtr->cancelButton, newWidth-(PWIDTH-140),
newHeight-(PHEIGHT-325));
WMMoveWidget(pPtr->homeButton, 55, newHeight-(PHEIGHT-325));
newColumnCount = (newWidth - 14) / 140;
WMSetBrowserMaxVisibleColumns(pPtr->browser, newColumnCount);
}
}
}
static char*
getCurrentFileName(WMFilePanel *panel)
{
@@ -604,23 +652,30 @@ static Bool
validOpenFile(WMFilePanel *panel)
{
WMListItem *item;
int col;
int col, haveFile = 0;
char *file = WMGetTextFieldText(panel->fileField);
/*col = WMGetBrowserSelectedColumn(panel->browser);*/
col = WMGetBrowserNumberOfColumns(panel->browser) - 1;
if (file[0] != '\0')
haveFile = 1;
free(file);
col = WMGetBrowserSelectedColumn(panel->browser);
item = WMGetBrowserSelectedItemInColumn(panel->browser, col);
if (item) {
if (item->isBranch && !panel->flags.canChooseDirectories)
if (item->isBranch && !panel->flags.canChooseDirectories && !haveFile)
return False;
else if (!item->isBranch && !panel->flags.canChooseFiles)
return False;
else
return True;
} else {
/* we compute for / here */
if (!panel->flags.canChooseDirectories && !haveFile)
return False;
else
return True;
}
if (!panel->flags.canChooseDirectories)
return False;
else
return True;
return True;
}
@@ -628,11 +683,13 @@ validOpenFile(WMFilePanel *panel)
static void
buttonClick(WMButton *bPtr, WMFilePanel *panel)
{
WMRange range;
if (bPtr == panel->okButton) {
if (!validOpenFile(panel))
return;
if (panel->flags.fileMustExist) {
char *file;
if (!validOpenFile(panel))
return;
file = getCurrentFileName(panel);
if (access(file, F_OK)!=0) {
@@ -648,6 +705,8 @@ buttonClick(WMButton *bPtr, WMFilePanel *panel)
} else
panel->flags.canceled = 1;
range.count = range.position = 0;
WMSelectTextFieldRange(panel->fileField, range);
panel->flags.done = 1;
}

View File

@@ -140,6 +140,9 @@ WMSystemFontOfSize(WMScreen *scrPtr, int size)
if (!font) {
wwarning("could not load font set %s. Trying fixed.", fontSpec);
font = WMCreateFont(scrPtr, "fixed");
if (!font) {
font = WMCreateFont(scrPtr, "-*-fixed-medium-r-normal-*-14-*-*-*-*-*-*-*");
}
if (!font) {
wwarning("could not load fixed font!");
free(fontSpec);
@@ -165,6 +168,9 @@ WMBoldSystemFontOfSize(WMScreen *scrPtr, int size)
if (!font) {
wwarning("could not load font set %s. Trying fixed.", fontSpec);
font = WMCreateFont(scrPtr, "fixed");
if (!font) {
font = WMCreateFont(scrPtr, "-*-fixed-medium-r-normal-*-14-*-*-*-*-*-*-*");
}
if (!font) {
wwarning("could not load fixed font!");
free(fontSpec);

View File

@@ -421,196 +421,96 @@ makePixmap(W_Screen *sPtr, char **data, int width, int height, int masked)
sPtr->depth);
}
#ifdef USE_TIFF
#define WINGS_IMAGES_FILE RESOURCE_PATH"/Images.tiff"
#define DEFAULT_OBJECT_ICON_FILE RESOURCE_PATH"/defaultIcon.tiff"
#else
#define WINGS_IMAGES_FILE RESOURCE_PATH"/Images.xpm"
#define DEFAULT_OBJECT_ICON_FILE RESOURCE_PATH"/defaultIcon.xpm"
#endif
#define T_WINGS_IMAGES_FILE RESOURCE_PATH"/Images.tiff"
#define T_DEFAULT_OBJECT_ICON_FILE RESOURCE_PATH"/defaultIcon.tiff"
#define X_WINGS_IMAGES_FILE RESOURCE_PATH"/Images.xpm"
#define X_DEFAULT_OBJECT_ICON_FILE RESOURCE_PATH"/defaultIcon.xpm"
static Bool
loadPixmaps(WMScreen *scr)
{
RImage *image, *tmp;
Pixmap pixmap;
RColor gray;
image = RLoadImage(scr->rcontext, WINGS_IMAGES_FILE, 0);
if (!image) {
wwarning("WINGs: could not load widget images file: %s",
RMessageForError(RErrorCode));
return False;
}
/* make it have a gray background */
RColor white;
gray.red = 0xae;
gray.green = 0xaa;
gray.blue = 0xae;
RCombineImageWithColor(image, &gray);
tmp = RGetSubImage(image, 0, 0, 24, 24);
if (!RConvertImage(scr->rcontext, tmp, &pixmap)) {
scr->homeIcon = NULL;
} else {
scr->homeIcon = WMCreatePixmapFromXPixmaps(scr, pixmap, None, 24, 24,
scr->depth);
}
RDestroyImage(tmp);
/* Magnifying Glass Icon for ColorPanel */
tmp = RGetSubImage(image, 24, 0, 40, 32);
if (!RConvertImage(scr->rcontext, tmp, &pixmap)) {
scr->magnifyIcon = NULL;
} else {
scr->magnifyIcon = WMCreatePixmapFromXPixmaps(scr, pixmap, None, 40, 32, scr->depth);
}
RDestroyImage(tmp);
/* ColorWheel Icon for ColorPanel */
tmp = RGetSubImage(image, 0, 25, 24, 24);
if (!RConvertImage(scr->rcontext, tmp, &pixmap)) {
scr->wheelIcon = NULL;
} else {
scr->wheelIcon = WMCreatePixmapFromXPixmaps(scr, pixmap, None, 24, 24, scr->depth);
}
RDestroyImage(tmp);
/* GrayScale Icon for ColorPanel */
tmp = RGetSubImage(image, 65, 0, 40, 24);
if (!RConvertImage(scr->rcontext, tmp, &pixmap)) {
scr->grayIcon = NULL;
} else {
scr->grayIcon = WMCreatePixmapFromXPixmaps(scr, pixmap, None, 40, 24, scr->depth);
}
RDestroyImage(tmp);
/* RGB Icon for ColorPanel */
tmp = RGetSubImage(image, 25, 33, 40, 24);
if (!RConvertImage(scr->rcontext, tmp, &pixmap)) {
scr->rgbIcon = NULL;
} else {
scr->rgbIcon = WMCreatePixmapFromXPixmaps(scr, pixmap, None, 40, 24, scr->depth);
}
RDestroyImage(tmp);
/* CMYK Icon for ColorPanel */
tmp = RGetSubImage(image, 65, 25, 40, 24);
if (!RConvertImage(scr->rcontext, tmp, &pixmap)) {
scr->cmykIcon = NULL;
} else {
scr->cmykIcon = WMCreatePixmapFromXPixmaps(scr, pixmap, None, 40, 24, scr->depth);
}
RDestroyImage(tmp);
/* HSB Icon for ColorPanel */
tmp = RGetSubImage(image, 0, 57, 40, 24);
if (!RConvertImage(scr->rcontext, tmp, &pixmap)) {
scr->hsbIcon = NULL;
} else {
scr->hsbIcon = WMCreatePixmapFromXPixmaps(scr, pixmap, None, 40, 24, scr->depth);
}
RDestroyImage(tmp);
/* CustomColorPalette Icon for ColorPanel */
tmp = RGetSubImage(image, 81, 57, 40, 24);
if (!RConvertImage(scr->rcontext, tmp, &pixmap)) {
scr->customPaletteIcon = NULL;
} else {
scr->customPaletteIcon = WMCreatePixmapFromXPixmaps(scr, pixmap, None, 40, 24, scr->depth);
}
RDestroyImage(tmp);
/* ColorList Icon for ColorPanel */
tmp = RGetSubImage(image, 41, 57, 40, 24);
if (!RConvertImage(scr->rcontext, tmp, &pixmap)) {
scr->colorListIcon = NULL;
} else {
scr->colorListIcon = WMCreatePixmapFromXPixmaps(scr, pixmap, None, 40, 24, scr->depth);
}
RDestroyImage(tmp);
RDestroyImage(image);
white.red = 0xff;
white.green = 0xff;
white.blue = 0xff;
image = RLoadImage(scr->rcontext, WINGS_IMAGES_FILE, 0);
image = RLoadImage(scr->rcontext, T_WINGS_IMAGES_FILE, 0);
if (!image)
image = RLoadImage(scr->rcontext, X_WINGS_IMAGES_FILE, 0);
if (!image) {
wwarning("WINGs: could not load widget images file: %s",
RMessageForError(RErrorCode));
return False;
}
/* make it have a white background */
gray.red = 0xff;
gray.green = 0xff;
gray.blue = 0xff;
RCombineImageWithColor(image, &gray);
/* home icon */
/* make it have a gray background */
tmp = RGetSubImage(image, 0, 0, 24, 24);
if (!RConvertImage(scr->rcontext, tmp, &pixmap)) {
scr->homeAltIcon = NULL;
} else {
scr->homeAltIcon = WMCreatePixmapFromXPixmaps(scr, pixmap, None, 24, 24,
scr->depth);
}
RCombineImageWithColor(tmp, &gray);
scr->homeIcon = WMCreatePixmapFromRImage(scr, tmp, 128);
RDestroyImage(tmp);
/* make it have a white background */
tmp = RGetSubImage(image, 0, 0, 24, 24);
RCombineImageWithColor(tmp, &white);
scr->altHomeIcon = WMCreatePixmapFromRImage(scr, tmp, 128);
RDestroyImage(tmp);
/* Magnifying Glass Icon for ColorPanel */
tmp = RGetSubImage(image, 25, 0, 40, 32);
if (!RConvertImage(scr->rcontext, tmp, &pixmap)) {
scr->magnifyAltIcon = NULL;
} else {
scr->magnifyAltIcon = WMCreatePixmapFromXPixmaps(scr, pixmap, None, 40, 32, scr->depth);
}
RDestroyImage(tmp);
/* ColorWheel Icon for ColorPanel */
tmp = RGetSubImage(image, 0, 25, 24, 24);
if (!RConvertImage(scr->rcontext, tmp, &pixmap)) {
scr->wheelAltIcon = NULL;
} else {
scr->wheelAltIcon = WMCreatePixmapFromXPixmaps(scr, pixmap, None, 24, 24, scr->depth);
}
RDestroyImage(tmp);
/* GrayScale Icon for ColorPanel */
tmp = RGetSubImage(image, 65, 0, 40, 24);
if (!RConvertImage(scr->rcontext, tmp, &pixmap)) {
scr->grayAltIcon = NULL;
} else {
scr->grayAltIcon = WMCreatePixmapFromXPixmaps(scr, pixmap, None, 40, 24, scr->depth);
}
RDestroyImage(tmp);
/* RGB Icon for ColorPanel */
tmp = RGetSubImage(image, 25, 33, 40, 24);
if (!RConvertImage(scr->rcontext, tmp, &pixmap)) {
scr->rgbAltIcon = NULL;
} else {
scr->rgbAltIcon = WMCreatePixmapFromXPixmaps(scr, pixmap, None, 40, 24, scr->depth);
}
RDestroyImage(tmp);
/* CMYK Icon for ColorPanel */
tmp = RGetSubImage(image, 65, 25, 40, 24);
if (!RConvertImage(scr->rcontext, tmp, &pixmap)) {
scr->cmykAltIcon = NULL;
} else {
scr->cmykAltIcon = WMCreatePixmapFromXPixmaps(scr, pixmap, None, 40, 24, scr->depth);
}
RDestroyImage(tmp);
/* HSB Icon for ColorPanel */
tmp = RGetSubImage(image, 0, 57, 40, 24);
if (!RConvertImage(scr->rcontext, tmp, &pixmap)) {
scr->hsbAltIcon = NULL;
} else {
scr->hsbAltIcon = WMCreatePixmapFromXPixmaps(scr, pixmap, None, 40, 24, scr->depth);
}
RDestroyImage(tmp);
/* CustomColorPalette Icon for ColorPanel */
tmp = RGetSubImage(image, 81, 57, 40, 24);
if (!RConvertImage(scr->rcontext, tmp, &pixmap)) {
scr->customPaletteAltIcon = NULL;
} else {
scr->customPaletteAltIcon = WMCreatePixmapFromXPixmaps(scr, pixmap, None, 40, 24, scr->depth);
}
RDestroyImage(tmp);
/* ColorList Icon for ColorPanel */
tmp = RGetSubImage(image, 41, 57, 40, 24);
if (!RConvertImage(scr->rcontext, tmp, &pixmap)) {
scr->colorListAltIcon = NULL;
} else {
scr->colorListAltIcon = WMCreatePixmapFromXPixmaps(scr, pixmap, None, 40, 24, scr->depth);
}
RDestroyImage(tmp);
RDestroyImage(image);
/* Magnifying Glass Icon for ColorPanel */
tmp = RGetSubImage(image, 24, 0, 40, 32);
RCombineImageWithColor(tmp, &gray);
scr->magnifyIcon = WMCreatePixmapFromRImage(scr, tmp, 128);
RDestroyImage(tmp);
tmp = RGetSubImage(image, 24, 0, 40, 32);
RCombineImageWithColor(tmp, &white);
scr->altMagnifyIcon = WMCreatePixmapFromRImage(scr, tmp, 128);
RDestroyImage(tmp);
/* ColorWheel Icon for ColorPanel */
tmp = RGetSubImage(image, 0, 25, 24, 24);
scr->wheelIcon = WMCreatePixmapFromRImage(scr, tmp, 128);
RDestroyImage(tmp);
/* GrayScale Icon for ColorPanel */
tmp = RGetSubImage(image, 65, 0, 40, 24);
scr->grayIcon = WMCreatePixmapFromRImage(scr, tmp, 128);
RDestroyImage(tmp);
/* RGB Icon for ColorPanel */
tmp = RGetSubImage(image, 25, 33, 40, 24);
scr->rgbIcon = WMCreatePixmapFromRImage(scr, tmp, 128);
RDestroyImage(tmp);
/* CMYK Icon for ColorPanel */
tmp = RGetSubImage(image, 65, 25, 40, 24);
scr->cmykIcon = WMCreatePixmapFromRImage(scr, tmp, 128);
RDestroyImage(tmp);
/* HSB Icon for ColorPanel */
tmp = RGetSubImage(image, 0, 57, 40, 24);
scr->hsbIcon = WMCreatePixmapFromRImage(scr, tmp, 128);
RDestroyImage(tmp);
/* CustomColorPalette Icon for ColorPanel */
tmp = RGetSubImage(image, 81, 57, 40, 24);
scr->customPaletteIcon = WMCreatePixmapFromRImage(scr, tmp, 128);
RDestroyImage(tmp);
/* ColorList Icon for ColorPanel */
tmp = RGetSubImage(image, 41, 57, 40, 24);
scr->colorListIcon = WMCreatePixmapFromRImage(scr, tmp, 128);
RDestroyImage(tmp);
RDestroyImage(image);
#if 0
scr->defaultObjectIcon =
WMCreatePixmapFromFile(scr, DEFAULT_OBJECT_ICON_FILE);
WMCreatePixmapFromFile(scr, T_DEFAULT_OBJECT_ICON_FILE);
if (!scr->defaultObjectIcon) {
scr->defaultObjectIcon =
WMCreatePixmapFromFile(scr, X_DEFAULT_OBJECT_ICON_FILE);
}
if (!scr->defaultObjectIcon) {
wwarning("WINGs: could not load default icon file");
return False;

View File

@@ -5,7 +5,7 @@
#include "WINGsP.h"
char *WMListDidScrollNotification = "WMListDidScrollNotification";
char *WMListSelectionDidChangeNotification = "WMListSelectionDidChangeNotification";
typedef struct W_List {
W_Class widgetClass;
@@ -227,16 +227,19 @@ WMRemoveListItem(WMList *lPtr, int row)
WMListItem *llist;
WMListItem *tmp;
int topItem = lPtr->topItem;
int selNotify = 0;
CHECK_CLASS(lPtr, WC_List);
if (row < 0 || row >= lPtr->itemCount)
return;
if (lPtr->selectedItem == row)
lPtr->selectedItem = -1;
else if (lPtr->selectedItem > row)
lPtr->selectedItem--;
if (lPtr->selectedItem == row) {
lPtr->selectedItem = -1;
selNotify = 1;
} else if (lPtr->selectedItem > row) {
lPtr->selectedItem--;
}
if (row <= lPtr->topItem+lPtr->fullFitLines+lPtr->flags.dontFitAll)
lPtr->topItem--;
@@ -271,6 +274,9 @@ WMRemoveListItem(WMList *lPtr, int row)
}
if (lPtr->topItem != topItem)
WMPostNotificationName(WMListDidScrollNotification, lPtr, NULL);
if (selNotify)
WMPostNotificationName(WMListSelectionDidChangeNotification, lPtr,
(void*)((int)lPtr->selectedItem));
}
@@ -312,7 +318,8 @@ void
WMClearList(WMList *lPtr)
{
WMListItem *item, *tmp;
int oldSelected = lPtr->selectedItem;
item = lPtr->items;
while (item) {
free(item->text);
@@ -332,6 +339,9 @@ WMClearList(WMList *lPtr)
if (lPtr->view->flags.realized) {
updateScroller(lPtr);
}
if (oldSelected != -1)
WMPostNotificationName(WMListSelectionDidChangeNotification, lPtr,
(void*)-1);
}
@@ -654,11 +664,19 @@ void
WMSelectListItem(WMList *lPtr, int row)
{
WMListItem *itemPtr;
int i;
int i, notify = 0;
if (row >= lPtr->itemCount)
return;
/* the check below must be changed when the multiple selection is
* implemented. -Dan
*/
if (!lPtr->flags.allowMultipleSelection && row == lPtr->selectedItem)
notify = 0;
else
notify = 1;
if (!lPtr->flags.allowMultipleSelection) {
/* unselect previous selected item */
if (lPtr->selectedItem >= 0) {
@@ -676,8 +694,12 @@ WMSelectListItem(WMList *lPtr, int row)
}
if (row < 0) {
if (!lPtr->flags.allowMultipleSelection)
if (!lPtr->flags.allowMultipleSelection) {
lPtr->selectedItem = -1;
if (notify)
WMPostNotificationName(WMListSelectionDidChangeNotification,
lPtr, (void*)((int)lPtr->selectedItem));
}
return;
}
@@ -700,6 +722,9 @@ WMSelectListItem(WMList *lPtr, int row)
WRSunken);
}
lPtr->selectedItem = row;
if (notify)
WMPostNotificationName(WMListSelectionDidChangeNotification, lPtr,
(void*)((int)lPtr->selectedItem));
}
@@ -732,7 +757,6 @@ handleActionEvents(XEvent *event, void *data)
tmp = getItemIndexAt(lPtr, event->xbutton.y);
if (tmp == lPtr->selectedItem && tmp >= 0) {
if (lPtr->action)
(*lPtr->action)(lPtr, lPtr->clientData);
}
@@ -751,16 +775,16 @@ handleActionEvents(XEvent *event, void *data)
case ButtonPress:
if (event->xbutton.x > WMWidgetWidth(lPtr->vScroller)) {
tmp = getItemIndexAt(lPtr, event->xbutton.y);
lPtr->flags.buttonPressed = 1;
if (tmp >= 0) {
WMSelectListItem(lPtr, tmp);
if (tmp == lPtr->selectedItem && WMIsDoubleClick(event)) {
WMSelectListItem(lPtr, tmp);
if (lPtr->doubleAction)
(*lPtr->doubleAction)(lPtr, lPtr->doubleClientData);
} else {
WMSelectListItem(lPtr, tmp);
}
lPtr->selectedItem = tmp;
}
}
break;
@@ -770,7 +794,6 @@ handleActionEvents(XEvent *event, void *data)
tmp = getItemIndexAt(lPtr, event->xmotion.y);
if (tmp>=0 && tmp != lPtr->selectedItem) {
WMSelectListItem(lPtr, tmp);
lPtr->selectedItem = tmp;
}
}
break;

View File

@@ -1,7 +1,16 @@
/*
* Author: Len Trigg <trigg@cs.waikato.ac.nz>
*/
/*
Update: Franck Wolff <frawolff@club-internet.fr>
-----------------------------------------------------------------------
List of updated functions :
- main :
add -s option for a save panel...
-----------------------------------------------------------------------
*/
#include "WINGs.h"
@@ -29,6 +38,7 @@ void usage(void)
"\t%s [-options]\n"
"\n"
"options:\n"
" -s\t\tSave panel (default open panel)\n"
" -i <str>\tInitial directory (default /)\n"
" -t <str>\tQuery window title (default none)\n"
"\n"
@@ -42,16 +52,21 @@ void usage(void)
exit(0);
}
#define OPEN_PANEL_TYPE 0
#define SAVE_PANEL_TYPE 1
int main(int argc, char **argv)
{
Display *dpy = XOpenDisplay("");
WMScreen *scr;
WMPixmap *pixmap;
WMOpenPanel *panel;
WMOpenPanel *oPanel;
WMSavePanel *sPanel;
/* RImage *image;*/
char *title = NULL;
char *initial = "/";
int ch;
int panelType = OPEN_PANEL_TYPE;
extern char *optarg;
extern int optind;
@@ -63,9 +78,12 @@ int main(int argc, char **argv)
puts("could not open display");
exit(1);
}
while((ch = getopt(argc, argv, "i:ht:")) != -1)
while((ch = getopt(argc, argv, "si:ht:")) != -1)
switch(ch)
{
case 's':
panelType = SAVE_PANEL_TYPE;
break;
case 'i':
initial = optarg;
break;
@@ -76,24 +94,30 @@ int main(int argc, char **argv)
usage();
}
for(; optind <argc; optind++)
usage();
for(; optind <argc; optind++)
usage();
scr = WMCreateSimpleApplicationScreen(dpy);
scr = WMCreateSimpleApplicationScreen(dpy);
pixmap = WMCreatePixmapFromXPMData(scr, GNUSTEP_XPM);
WMSetApplicationIconImage(scr, pixmap); WMReleasePixmap(pixmap);
panel = WMGetOpenPanel(scr);
/*WMSetFilePanelAutoCompletion(panel, False);*/
/* The 3rd argument for this function is the initial name of the file,
* not the name of the window, although it's not implemented yet */
if (WMRunModalOpenPanelForDirectory(panel, NULL, initial, /*title*/ NULL, NULL) == True)
printf("%s\n", WMGetFilePanelFileName(panel));
else
printf("\n");
return 0;
pixmap = WMCreatePixmapFromXPMData(scr, GNUSTEP_XPM);
WMSetApplicationIconImage(scr, pixmap);
WMReleasePixmap(pixmap);
if (panelType == SAVE_PANEL_TYPE) {
sPanel = WMGetSavePanel(scr);
if (WMRunModalFilePanelForDirectory(sPanel, NULL, initial,
/*title*/ NULL, NULL) == True)
printf("%s\n", WMGetFilePanelFileName(sPanel));
else
printf("\n");
} else {
oPanel = WMGetOpenPanel(scr);
if (WMRunModalFilePanelForDirectory(oPanel, NULL, initial,
/*title*/ NULL, NULL) == True)
printf("%s\n", WMGetFilePanelFileName(oPanel));
else
printf("\n");
}
return 0;
}

View File

@@ -338,11 +338,19 @@ WMSetPopUpButtonPullsDown(WMPopUpButton *bPtr, Bool flag)
{
bPtr->flags.pullsDown = flag;
if (!flag) {
bPtr->selectedItem = bPtr->items;
/* This code causes bugs. It should not select any item,
* since it was not asked to. -Dan
bPtr->selectedItem = bPtr->items;
if (bPtr->selectedItem)
bPtr->selectedItemIndex = 0;
else
bPtr->selectedItemIndex = -1;
bPtr->selectedItemIndex = -1;
*/
bPtr->selectedItem = NULL;
/* the drawing routine, still draws things wrong if we put
* the index to -1 (i.e. not selected).
* Find out why. -Dan */
bPtr->selectedItemIndex = 0;
} else
bPtr->selectedItemIndex = -1;

View File

@@ -398,7 +398,7 @@ WMSetScrollViewContentView(WMScrollView *sPtr, WMView *view)
sPtr->contentView = view;
W_ReparentView(sPtr->contentView, sPtr->viewport);
W_ReparentView(sPtr->contentView, sPtr->viewport, 0, 0);
if (sPtr->flags.hasHScroller) {
float prop;

View File

@@ -533,6 +533,8 @@ destroySlider(Slider *sPtr)
if (sPtr->backPixmap)
WMReleasePixmap(sPtr->backPixmap);
WMRemoveNotificationObserver(sPtr);
free(sPtr);
}

View File

@@ -144,7 +144,7 @@ WMAddSplitViewSubview(WMSplitView *sPtr, WMView *subview)
W_UnmapView(subview);
}
W_ReparentView(subview, sPtr->view);
W_ReparentView(subview, sPtr->view, 0, 0);
#if 0
if (sPtr->resizeSubviewsProc && subviewCount(sPtr)>1) {

View File

@@ -46,10 +46,10 @@ testOpenFilePanel(WMScreen *scr)
/* get the shared Open File panel */
panel = WMGetOpenPanel(scr);
WMRunModalOpenPanelForDirectory(panel, NULL, "/usr/local", NULL, NULL);
WMRunModalFilePanelForDirectory(panel, NULL, "/usr/local", NULL, NULL);
/* free the panel to save some memory. Not needed otherwise. */
WMFreeFilePanel(panel);
WMFreeFilePanel(WMGetOpenPanel(scr));
}

View File

@@ -22,8 +22,10 @@ typedef struct W_TextField {
W_Class widgetClass;
W_View *view;
#if 0
struct W_TextField *nextField; /* next textfield in the chain */
struct W_TextField *prevField;
#endif
char *text;
int textLen; /* size of text */
@@ -39,6 +41,8 @@ typedef struct W_TextField {
WMRange selection;
WMRange prevselection;
WMFont *font;
#if 0
WMHandlerID timerID; /* for cursor blinking */
#endif
@@ -46,13 +50,15 @@ typedef struct W_TextField {
WMAlignment alignment:2;
unsigned int bordered:1;
unsigned int beveled:1;
unsigned int enabled:1;
unsigned int focused:1;
unsigned int cursorOn:1;
unsigned int secure:1; /* password entry style */
/**/
@@ -97,11 +103,11 @@ struct W_ViewProcedureTable _TextFieldViewProcedures = {
};
#define TEXT_WIDTH(tPtr, start) (WMWidthOfString((tPtr)->view->screen->normalFont, \
&((tPtr)->text[(start)]), (tPtr)->textLen - (start) + 1))
#define TEXT_WIDTH(tPtr, start) (WMWidthOfString((tPtr)->font, \
&((tPtr)->text[(start)]), (tPtr)->textLen - (start) + 1))
#define TEXT_WIDTH2(tPtr, start, end) (WMWidthOfString((tPtr)->view->screen->normalFont, \
&((tPtr)->text[(start)]), (end) - (start) + 1))
#define TEXT_WIDTH2(tPtr, start, end) (WMWidthOfString((tPtr)->font, \
&((tPtr)->text[(start)]), (end) - (start) + 1))
static void
@@ -163,7 +169,6 @@ WMCreateTextField(WMWidget *parent)
{
TextField *tPtr;
tPtr = wmalloc(sizeof(TextField));
memset(tPtr, 0, sizeof(TextField));
@@ -185,24 +190,28 @@ WMCreateTextField(WMWidget *parent)
tPtr->text[0] = 0;
tPtr->textLen = 0;
tPtr->bufferSize = MIN_TEXT_BUFFER;
tPtr->flags.enabled = 1;
WMCreateEventHandler(tPtr->view, ExposureMask|StructureNotifyMask
|FocusChangeMask, handleEvents, tPtr);
W_ResizeView(tPtr->view, DEFAULT_WIDTH, DEFAULT_HEIGHT);
WMSetTextFieldBordered(tPtr, DEFAULT_BORDERED);
tPtr->font = WMRetainFont(tPtr->view->screen->normalFont);
tPtr->flags.bordered = DEFAULT_BORDERED;
tPtr->flags.beveled = True;
tPtr->flags.alignment = DEFAULT_ALIGNMENT;
tPtr->offsetWidth = (tPtr->view->size.height
- WMFontHeight(tPtr->view->screen->normalFont))/2;
tPtr->offsetWidth =
WMAX((tPtr->view->size.height - WMFontHeight(tPtr->font))/2, 1);
WMCreateEventHandler(tPtr->view, EnterWindowMask|LeaveWindowMask
|ButtonPressMask|KeyPressMask|Button1MotionMask,
handleTextFieldActionEvents, tPtr);
tPtr->flags.cursorOn = 1;
return tPtr;
}
@@ -311,10 +320,6 @@ WMGetTextFieldText(WMTextField *tPtr)
void
WMSetTextFieldText(WMTextField *tPtr, char *text)
{
/* We do not set text if it's the same. This will also help
* to avoid some infinite loops if this function is called from
* a function called by a notification observer. -Dan
*/
if ((text && strcmp(tPtr->text, text) == 0) ||
(!text && tPtr->textLen == 0))
return;
@@ -347,6 +352,14 @@ WMSetTextFieldText(WMTextField *tPtr, char *text)
}
void
WMSetTextFieldFont(WMTextField *tPtr, WMFont *font)
{
/* TODO: update font change after field is mapped */
WMReleaseFont(tPtr->font);
tPtr->font = WMRetainFont(font);
}
void
WMSetTextFieldAlignment(WMTextField *tPtr, WMAlignment alignment)
{
@@ -373,6 +386,17 @@ WMSetTextFieldBordered(WMTextField *tPtr, Bool bordered)
}
void
WMSetTextFieldBeveled(WMTextField *tPtr, Bool flag)
{
tPtr->flags.beveled = flag;
if (tPtr->view->flags.realized) {
paintTextField(tPtr);
}
}
void
WMSetTextFieldSecure(WMTextField *tPtr, Bool flag)
@@ -385,6 +409,13 @@ WMSetTextFieldSecure(WMTextField *tPtr, Bool flag)
}
Bool
WMGetTextFieldEnabled(WMTextField *tPtr)
{
return tPtr->flags.enabled;
}
void
WMSetTextFieldEnabled(WMTextField *tPtr, Bool flag)
{
@@ -438,15 +469,61 @@ WMSetTextFieldCursorPosition(WMTextField *tPtr, unsigned int position)
}
void
WMSetTextFieldNextTextField(WMTextField *tPtr, WMTextField *next)
{
CHECK_CLASS(tPtr, WC_TextField);
if (next == NULL) {
if (tPtr->view->nextFocusChain)
tPtr->view->nextFocusChain->prevFocusChain = NULL;
tPtr->view->nextFocusChain = NULL;
return;
}
CHECK_CLASS(next, WC_TextField);
if (tPtr->view->nextFocusChain)
tPtr->view->nextFocusChain->prevFocusChain = NULL;
if (next->view->prevFocusChain)
next->view->prevFocusChain->nextFocusChain = NULL;
tPtr->view->nextFocusChain = next->view;
next->view->prevFocusChain = tPtr->view;
}
void
WMSetTextFieldPrevTextField(WMTextField *tPtr, WMTextField *prev)
{
CHECK_CLASS(tPtr, WC_TextField);
if (prev == NULL) {
if (tPtr->view->prevFocusChain)
tPtr->view->prevFocusChain->nextFocusChain = NULL;
tPtr->view->prevFocusChain = NULL;
return;
}
CHECK_CLASS(prev, WC_TextField);
if (tPtr->view->prevFocusChain)
tPtr->view->prevFocusChain->nextFocusChain = NULL;
if (prev->view->nextFocusChain)
prev->view->nextFocusChain->prevFocusChain = NULL;
tPtr->view->prevFocusChain = prev->view;
prev->view->nextFocusChain = tPtr->view;
}
static void
resizeTextField(WMTextField *tPtr, unsigned int width, unsigned int height)
{
W_ResizeView(tPtr->view, width, height);
tPtr->offsetWidth = (tPtr->view->size.height
- WMFontHeight(tPtr->view->screen->normalFont))/2;
tPtr->usableWidth = tPtr->view->size.width - 2*tPtr->offsetWidth;
tPtr->offsetWidth =
WMAX((tPtr->view->size.height - WMFontHeight(tPtr->font))/2, 1);
tPtr->usableWidth = tPtr->view->size.width - 2*tPtr->offsetWidth + 2;
}
@@ -457,27 +534,24 @@ paintCursor(TextField *tPtr)
WMScreen *screen = tPtr->view->screen;
int textWidth;
cx = WMWidthOfString(screen->normalFont,
&(tPtr->text[tPtr->viewPosition]),
cx = WMWidthOfString(tPtr->font, &(tPtr->text[tPtr->viewPosition]),
tPtr->cursorPosition-tPtr->viewPosition);
switch (tPtr->flags.alignment) {
case WARight:
textWidth = WMWidthOfString(screen->normalFont, tPtr->text,
tPtr->textLen);
textWidth = WMWidthOfString(tPtr->font, tPtr->text, tPtr->textLen);
if (textWidth < tPtr->usableWidth)
cx += tPtr->offsetWidth + tPtr->usableWidth - textWidth;
cx += tPtr->offsetWidth + tPtr->usableWidth - textWidth + 1;
else
cx += tPtr->offsetWidth;
cx += tPtr->offsetWidth + 1;
break;
case WALeft:
cx += tPtr->offsetWidth;
cx += tPtr->offsetWidth + 1;
break;
case WAJustified:
/* not supported */
case WACenter:
textWidth = WMWidthOfString(screen->normalFont, tPtr->text,
tPtr->textLen);
textWidth = WMWidthOfString(tPtr->font, tPtr->text, tPtr->textLen);
if (textWidth < tPtr->usableWidth)
cx += tPtr->offsetWidth + (tPtr->usableWidth-textWidth)/2;
else
@@ -497,7 +571,7 @@ paintCursor(TextField *tPtr)
static void
drawRelief(WMView *view)
drawRelief(WMView *view, Bool beveled)
{
WMScreen *scr = view->screen;
Display *dpy = scr->display;
@@ -507,8 +581,14 @@ drawRelief(WMView *view)
int width = view->size.width;
int height = view->size.height;
wgc = W_GC(scr->white);
dgc = W_GC(scr->darkGray);
if (!beveled) {
XDrawRectangle(dpy, view->window, dgc, 0, 0, width-1, height-1);
return;
}
wgc = W_GC(scr->white);
lgc = W_GC(scr->gray);
/* top left */
@@ -550,16 +630,15 @@ paintTextField(TextField *tPtr)
totalWidth = tPtr->view->size.width - 2*bd;
if (tPtr->textLen > 0) {
tw = WMWidthOfString(screen->normalFont,
&(tPtr->text[tPtr->viewPosition]),
tw = WMWidthOfString(tPtr->font, &(tPtr->text[tPtr->viewPosition]),
tPtr->textLen - tPtr->viewPosition);
th = WMFontHeight(screen->normalFont);
th = WMFontHeight(tPtr->font);
ty = tPtr->offsetWidth;
switch (tPtr->flags.alignment) {
case WALeft:
tx = tPtr->offsetWidth;
tx = tPtr->offsetWidth + 1;
if (tw < tPtr->usableWidth)
XClearArea(screen->display, view->window, bd+tw, bd,
totalWidth-tw, view->size.height-2*bd,
@@ -575,7 +654,7 @@ paintTextField(TextField *tPtr)
default:
case WARight:
tx = tPtr->offsetWidth + tPtr->usableWidth - tw;
tx = tPtr->offsetWidth + tPtr->usableWidth - tw - 1;
if (tw < tPtr->usableWidth)
XClearArea(screen->display, view->window, bd, bd,
totalWidth-tw, view->size.height-2*bd, False);
@@ -587,7 +666,7 @@ paintTextField(TextField *tPtr)
WMSetColorInGC(screen->darkGray, screen->textFieldGC);
WMDrawImageString(screen, view->window, screen->textFieldGC,
screen->normalFont, tx, ty,
tPtr->font, tx, ty,
&(tPtr->text[tPtr->viewPosition]),
tPtr->textLen - tPtr->viewPosition);
@@ -598,7 +677,7 @@ paintTextField(TextField *tPtr)
? tPtr->selection.position + tPtr->selection.count
: tPtr->selection.position;
rx = tx + WMWidthOfString(screen->normalFont,
rx = tx + WMWidthOfString(tPtr->font,
&(tPtr->text[tPtr->viewPosition]),
count);
@@ -606,8 +685,7 @@ paintTextField(TextField *tPtr)
screen->gray->color.pixel);
WMDrawImageString(screen, view->window, screen->textFieldGC,
screen->normalFont, rx, ty,
&(tPtr->text[count]),
tPtr->font, rx, ty, &(tPtr->text[count]),
abs(tPtr->selection.count));
XSetBackground(screen->display, screen->textFieldGC,
@@ -630,7 +708,7 @@ paintTextField(TextField *tPtr)
/* draw relief */
if (tPtr->flags.bordered) {
drawRelief(view);
drawRelief(view, tPtr->flags.beveled);
}
}
@@ -715,7 +793,6 @@ handleTextFieldKeyPress(TextField *tPtr, XEvent *event)
KeySym ksym;
int count, refresh = 0;
int control_pressed = 0;
WMScreen *scr = tPtr->view->screen;
if (((XKeyEvent *) event)->state & WM_EMACSKEYMASK) {
control_pressed = 1;
@@ -733,9 +810,9 @@ handleTextFieldKeyPress(TextField *tPtr, XEvent *event)
}
/* Be careful in any case in this switch statement, never to call
* to more than 2 functions at the same time, that can generate text
* change notifications. Only one text change notification should be sent
* in any case. Else hazardous things can happen.
* to more than a function that can generate text change notifications.
* Only one text change notification should be sent in any case.
* Else hazardous things can happen.
* Maybe we need a better solution than the function wrapper to inform
* functions that change text in text fields, if they need to send a
* change notification or not. -Dan
@@ -811,7 +888,7 @@ handleTextFieldKeyPress(TextField *tPtr, XEvent *event)
} else {
tPtr->cursorPosition++;
}
while (WMWidthOfString(scr->normalFont,
while (WMWidthOfString(tPtr->font,
&(tPtr->text[tPtr->viewPosition]),
tPtr->cursorPosition-tPtr->viewPosition)
> tPtr->usableWidth) {
@@ -851,7 +928,7 @@ handleTextFieldKeyPress(TextField *tPtr, XEvent *event)
paintCursor(tPtr);
tPtr->cursorPosition = tPtr->textLen;
tPtr->viewPosition = 0;
while (WMWidthOfString(scr->normalFont,
while (WMWidthOfString(tPtr->font,
&(tPtr->text[tPtr->viewPosition]),
tPtr->textLen-tPtr->viewPosition)
> tPtr->usableWidth) {
@@ -870,6 +947,7 @@ handleTextFieldKeyPress(TextField *tPtr, XEvent *event)
case XK_BackSpace:
if (tPtr->cursorPosition > 0) {
WMRange range;
if (tPtr->prevselection.count) {
range.position = tPtr->prevselection.count < 0
? tPtr->prevselection.position + tPtr->prevselection.count
@@ -892,6 +970,7 @@ handleTextFieldKeyPress(TextField *tPtr, XEvent *event)
case XK_Delete:
if (tPtr->cursorPosition < tPtr->textLen || tPtr->prevselection.count) {
WMRange range;
if (tPtr->prevselection.count) {
range.position = tPtr->prevselection.count < 0
? tPtr->prevselection.position + tPtr->prevselection.count
@@ -910,6 +989,7 @@ handleTextFieldKeyPress(TextField *tPtr, XEvent *event)
default:
if (count > 0 && !iscntrl(buffer[0])) {
WMRange range;
if (tPtr->prevselection.count) {
range.position = tPtr->prevselection.count < 0
? tPtr->prevselection.position + tPtr->prevselection.count
@@ -944,7 +1024,6 @@ handleTextFieldKeyPress(TextField *tPtr, XEvent *event)
static int
pointToCursorPosition(TextField *tPtr, int x)
{
WMFont *font = tPtr->view->screen->normalFont;
int a, b, mid;
int tw;
@@ -953,13 +1032,13 @@ pointToCursorPosition(TextField *tPtr, int x)
a = tPtr->viewPosition;
b = tPtr->viewPosition + tPtr->textLen;
if (WMWidthOfString(font, &(tPtr->text[tPtr->viewPosition]),
if (WMWidthOfString(tPtr->font, &(tPtr->text[tPtr->viewPosition]),
tPtr->textLen-tPtr->viewPosition) < x)
return tPtr->textLen;
while (a < b && b-a>1) {
mid = (a+b)/2;
tw = WMWidthOfString(font, &(tPtr->text[tPtr->viewPosition]),
tw = WMWidthOfString(tPtr->font, &(tPtr->text[tPtr->viewPosition]),
mid - tPtr->viewPosition);
if (tw > x)
b = mid;
@@ -981,7 +1060,7 @@ handleTextFieldActionEvents(XEvent *event, void *data)
switch (event->type) {
case KeyPress:
if (tPtr->flags.enabled)
if (tPtr->flags.enabled && tPtr->flags.focused)
handleTextFieldKeyPress(tPtr, event);
break;
@@ -1045,7 +1124,9 @@ destroyTextField(TextField *tPtr)
if (tPtr->timerID)
WMDeleteTimerHandler(tPtr->timerID);
#endif
WMReleaseFont(tPtr->font);
if (tPtr->text)
free(tPtr->text);

View File

@@ -102,6 +102,32 @@ adoptChildView(W_View *view, W_View *child)
}
static void
getPosition(Display *dpy, Window win, int *x_ret, int *y_ret)
{
unsigned foo;
Window bar;
Window parent;
Window *childs;
int x, y;
XGetGeometry(dpy, win, &bar, &x, &y, &foo, &foo, &foo, &foo);
if (XQueryTree(dpy, win, &bar, &parent, &childs, &foo)) {
int px, py;
XFree(childs);
if (parent != bar) {
getPosition(dpy, parent, &px, &py);
x += px;
y += py;
}
}
*x_ret = x;
*y_ret = y;
}
static void
handleEvents(XEvent *event, void *data)
@@ -109,17 +135,29 @@ handleEvents(XEvent *event, void *data)
W_View *view = (W_View*)data;
if (event->type == ConfigureNotify) {
if (event->xconfigure.width != view->size.width
|| event->xconfigure.height != view->size.height) {
view->size.width = event->xconfigure.width;
view->size.height = event->xconfigure.height;
if (view->flags.notifySizeChanged) {
view->size.width = event->xconfigure.width;
view->size.height = event->xconfigure.height;
WMPostNotificationName(WMViewSizeDidChangeNotification,
view, NULL);
}
}
if (event->xconfigure.x != view->pos.x
|| event->xconfigure.y != view->pos.y) {
if (event->xconfigure.send_event) {
view->pos.x = event->xconfigure.x;
view->pos.y = event->xconfigure.y;
} else {
getPosition(view->screen->display, view->window,
&view->pos.x, &view->pos.y);
}
}
}
}
@@ -265,34 +303,26 @@ W_CheckInternalMessage(W_Screen *scr, XClientMessageEvent *cev, int event)
void
W_ReparentView(W_View *view, W_View *newParent)
W_ReparentView(W_View *view, W_View *newParent, int x, int y)
{
int wasMapped;
Display *dpy = view->screen->display;
assert(!view->flags.topLevel);
wasMapped = view->flags.mapped;
if (wasMapped)
W_UnmapView(view);
unparentView(view);
adoptChildView(newParent, view);
if (view->flags.realized) {
if (newParent->flags.realized) {
XReparentWindow(dpy, view->window, newParent->window, 0, 0);
XReparentWindow(dpy, view->window, newParent->window, x, y);
} else {
wwarning("trying to reparent realized view to unrealized parent");
return;
}
}
view->pos.x = 0;
view->pos.y = 0;
if (wasMapped)
W_MapView(view);
view->pos.x = x;
view->pos.y = y;
}
@@ -382,6 +412,11 @@ destroyView(W_View *view)
return;
view->flags.alreadyDead = 1;
if (view->nextFocusChain)
view->nextFocusChain->prevFocusChain = view->prevFocusChain;
if (view->prevFocusChain)
view->prevFocusChain->nextFocusChain = view->nextFocusChain;
/* Do not leave focus in a inexisting control */
if (W_FocusedViewOfToplevel(W_TopLevelOfView(view))==view)
W_SetFocusOfTopLevel(W_TopLevelOfView(view), NULL);