1
0
mirror of https://github.com/gryf/wmaker.git synced 2025-12-28 09:22:27 +01:00

Remake of the WMList code to allow multiple selection. Not complete yet.

It will not even compile. I Will finish it later today.
This commit is contained in:
dan
2000-09-28 03:09:57 +00:00
parent df357ae1de
commit 6973f07f30
6 changed files with 149 additions and 87 deletions

View File

@@ -17,7 +17,13 @@ changes since wmaker 0.62.1:
subdirectories subdirectories
- removed WMArrayBag and reorganized WMTreeBag to be WMBag. - removed WMArrayBag and reorganized WMTreeBag to be WMBag.
- added WMArray class. - added WMArray class.
- added WMSetWindowUserPosition() - added WMSetWindowUserPosition().
- added WMGetListSelectedItems()
- added WMSetListAllowMultipleSelection(), WMListAllowsMultipleSelection().
- added WMSetListAllowEmptySelection(), WMListAllowsEmptySelection().
- WMListSelectionDidChangeNotification passes NULL as the notification
client data (previously passed the selected item row).
- WMRemoveListItem() returns an int : 1 success, 0 fail (previously was void).
changes since wmaker 0.62.0: changes since wmaker 0.62.0:

View File

@@ -1059,6 +1059,10 @@ void WMSetScrollerArrowsPosition(WMScroller *sPtr,
WMList *WMCreateList(WMWidget *parent); WMList *WMCreateList(WMWidget *parent);
void WMSetListAllowMultipleSelection(WMList *lPtr, Bool flag);
void WMSetListAllowEmptySelection(WMList *lPtr, Bool flag);
#define WMAddListItem(lPtr, text) WMInsertListItem((lPtr), -1, (text)) #define WMAddListItem(lPtr, text) WMInsertListItem((lPtr), -1, (text))
WMListItem *WMInsertListItem(WMList *lPtr, int row, char *text); WMListItem *WMInsertListItem(WMList *lPtr, int row, char *text);
@@ -1073,8 +1077,7 @@ WMListItem *WMGetListItem(WMList *lPtr, int row);
WMArray *WMGetListItems(WMList *lPtr); WMArray *WMGetListItems(WMList *lPtr);
int WMRemoveListItem(WMList *lPtr, int row);
void WMRemoveListItem(WMList *lPtr, int row);
void WMSelectListItem(WMList *lPtr, int row); void WMSelectListItem(WMList *lPtr, int row);
@@ -1085,7 +1088,16 @@ void WMSetListUserDrawItemHeight(WMList *lPtr, unsigned short height);
int WMGetListItemHeight(WMList *lPtr); int WMGetListItemHeight(WMList *lPtr);
/* don't free the returned data */ /* don't free the returned data */
WMListItem *WMGetListSelectedItem(WMList *lPtr); WMArray* WMGetListSelectedItems(WMList *lPtr);
/*
* For the following 2 functions, in case WMList allows multiple selection,
* the first item in the list of selected items, respective its row number,
* will be returned.
*/
/* don't free the returned data */
WMListItem* WMGetListSelectedItem(WMList *lPtr);
int WMGetListSelectedItemRow(WMList *lPtr); int WMGetListSelectedItemRow(WMList *lPtr);
@@ -1103,6 +1115,11 @@ void WMSetListBottomPosition(WMList *lPtr, int row);
int WMGetListPosition(WMList *lPtr); int WMGetListPosition(WMList *lPtr);
Bool WMListAllowsMultipleSelection(WMList *lPtr);
Bool WMListAllowsEmptySelection(WMList *lPtr);
extern char *WMListDidScrollNotification; extern char *WMListDidScrollNotification;
extern char *WMListSelectionDidChangeNotification; extern char *WMListSelectionDidChangeNotification;

View File

@@ -112,8 +112,9 @@ typedef enum {
enum { enum {
WBNotFound = INT_MIN, /* element was not found in bag */ WBNotFound = INT_MIN, /* element was not found in WMBag */
WANotFound = -1 /* element was not found in array */ WANotFound = -1, /* element was not found in WMArray */
WLNotFound = -1 /* element was not found in WMList */
}; };

View File

@@ -122,7 +122,7 @@ WMAddToArray(WMArray *array, void *item)
int int
WMInsertInArray(WMArray *array, int index, void *item) WMInsertInArray(WMArray *array, int index, void *item)
{ {
wassertrv(index <= array->itemCount, 0); wassertrv(index >= 0 && index <= array->itemCount, 0);
if (array->itemCount >= array->allocSize) { if (array->itemCount >= array->allocSize) {
array->allocSize += RESIZE_INCREMENT; array->allocSize += RESIZE_INCREMENT;
@@ -145,7 +145,7 @@ WMReplaceInArray(WMArray *array, int index, void *item)
{ {
void *old; void *old;
wassertrv(index > array->itemCount, 0); wassertrv(index >= 0 && index <= array->itemCount, NULL);
if (index == array->itemCount) { if (index == array->itemCount) {
WMAddToArray(array, item); WMAddToArray(array, item);
@@ -162,8 +162,7 @@ WMReplaceInArray(WMArray *array, int index, void *item)
int int
WMDeleteFromArray(WMArray *array, int index) WMDeleteFromArray(WMArray *array, int index)
{ {
if (index >= array->itemCount) wassertrv(index >= 0 && index < array->itemCount, 0);
return 0;
if (array->destructor) { if (array->destructor) {
array->destructor(array->items[index]); array->destructor(array->items[index]);
@@ -198,7 +197,7 @@ WMRemoveFromArray(WMArray *array, void *item)
void* void*
WMGetFromArray(WMArray *array, int index) WMGetFromArray(WMArray *array, int index)
{ {
if (index >= array->itemCount) if (index < 0 || index >= array->itemCount)
return NULL; return NULL;
return array->items[index]; return array->items[index];

View File

@@ -84,8 +84,8 @@ static void loadColumn(WMBrowser *bPtr, int column);
static void removeColumn(WMBrowser *bPtr, int column); static void removeColumn(WMBrowser *bPtr, int column);
static char* static char* createTruncatedString(WMFont *font, char *text, int *textLen,
createTruncatedString(WMFont *font, char *text, int *textLen, int width); int width);
static void willResizeBrowser(W_ViewDelegate*, WMView*, static void willResizeBrowser(W_ViewDelegate*, WMView*,
unsigned int*, unsigned int*); unsigned int*, unsigned int*);
@@ -1030,7 +1030,7 @@ static void
listSelectionObserver(void *observerData, WMNotification *notification) listSelectionObserver(void *observerData, WMNotification *notification)
{ {
WMBrowser *bPtr = (WMBrowser*)observerData; WMBrowser *bPtr = (WMBrowser*)observerData;
int column, item = (int)WMGetNotificationClientData(notification); int column;
WMList *lPtr = (WMList*)WMGetNotificationObject(notification); WMList *lPtr = (WMList*)WMGetNotificationObject(notification);
for (column = 0; column < bPtr->usedColumnCount; column++) for (column = 0; column < bPtr->usedColumnCount; column++)
@@ -1043,7 +1043,7 @@ listSelectionObserver(void *observerData, WMNotification *notification)
return; return;
} }
if (item < 0) if (WMGetArrayItemCount(WMGetListSelectedItems(lPtr)) == 0)
column--; column--;
bPtr->selectedColumn = column; bPtr->selectedColumn = column;

View File

@@ -14,7 +14,7 @@ typedef struct W_List {
WMArray *items; /* list of WMListItem */ WMArray *items; /* list of WMListItem */
WMArray *selectedItems; /* list of selected WMListItems */ WMArray *selectedItems; /* list of selected WMListItems */
short selectedItem; //short selectedItem;
short itemHeight; short itemHeight;
@@ -115,6 +115,7 @@ WMCreateList(WMWidget *parent)
lPtr->itemHeight = WMFontHeight(scrPtr->normalFont) + 1; lPtr->itemHeight = WMFontHeight(scrPtr->normalFont) + 1;
lPtr->items = WMCreateArrayWithDestructor(4, releaseItem); lPtr->items = WMCreateArrayWithDestructor(4, releaseItem);
lPtr->selectedItems = WMCreateArray(4);
/* create the vertical scroller */ /* create the vertical scroller */
lPtr->vScroller = WMCreateScroller(lPtr); lPtr->vScroller = WMCreateScroller(lPtr);
@@ -128,12 +129,27 @@ WMCreateList(WMWidget *parent)
W_ResizeView(lPtr->view, DEFAULT_WIDTH, DEFAULT_HEIGHT); W_ResizeView(lPtr->view, DEFAULT_WIDTH, DEFAULT_HEIGHT);
lPtr->selectedItem = -1; //lPtr->selectedItem = -1;
return lPtr; return lPtr;
} }
void
WMSetListAllowMultipleSelection(WMList *lPtr, Bool flag)
{
lPtr->flags.allowMultipleSelection = flag ? 1 : 0;
}
void
WMSetListAllowEmptySelection(WMList *lPtr, Bool flag)
{
lPtr->flags.allowEmptySelection = flag ? 1 : 0;
}
static int static int
comparator(const void *a, const void *b) comparator(const void *a, const void *b)
{ {
@@ -173,9 +189,9 @@ WMInsertListItem(WMList *lPtr, int row, char *text)
item->text = wstrdup(text); item->text = wstrdup(text);
if (lPtr->selectedItem >= row && lPtr->selectedItem >= 0 //if (lPtr->selectedItem >= row && lPtr->selectedItem >= 0
&& row >= 0) // && row >= 0)
lPtr->selectedItem++; // lPtr->selectedItem++;
row = WMIN(row, WMGetArrayItemCount(lPtr->items)); row = WMIN(row, WMGetArrayItemCount(lPtr->items));
@@ -194,24 +210,32 @@ WMInsertListItem(WMList *lPtr, int row, char *text)
} }
void int
WMRemoveListItem(WMList *lPtr, int row) WMRemoveListItem(WMList *lPtr, int row)
{ {
WMLIstItem *item;
int topItem = lPtr->topItem; int topItem = lPtr->topItem;
int selNotify = 0; int selNotify = 0;
CHECK_CLASS(lPtr, WC_List); CHECK_CLASS(lPtr, WC_List);
if (row < 0 || row >= WMGetArrayItemCount(lPtr->items)) if (row < 0 || row >= WMGetArrayItemCount(lPtr->items))
return; return 0;
if (lPtr->selectedItem == row) { item = WMGetFromArray(lPtr->items, row);
lPtr->selectedItem = -1; if (item->flags.selected) {
WMRemoveFromArray(lPtr->selectedItems, item);
//WMUnselectListItem(lPtr, row);
selNotify = 1; selNotify = 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) if (row <= lPtr->topItem+lPtr->fullFitLines+lPtr->flags.dontFitAll)
lPtr->topItem--; lPtr->topItem--;
if (lPtr->topItem < 0) if (lPtr->topItem < 0)
@@ -222,13 +246,15 @@ WMRemoveListItem(WMList *lPtr, int row)
if (!lPtr->idleID) { if (!lPtr->idleID) {
lPtr->idleID = WMAddIdleHandler((WMCallback*)updateScroller, lPtr); lPtr->idleID = WMAddIdleHandler((WMCallback*)updateScroller, lPtr);
} }
if (lPtr->topItem != topItem) if (lPtr->topItem != topItem) {
WMPostNotificationName(WMListDidScrollNotification, lPtr, NULL); WMPostNotificationName(WMListDidScrollNotification, lPtr, NULL);
if (selNotify) }
WMPostNotificationName(WMListSelectionDidChangeNotification, lPtr, if (selNotify) {
(void*)((int)lPtr->selectedItem)); WMPostNotificationName(WMListSelectionDidChangeNotification, lPtr, NULL);
} }
return 1;
}
WMListItem* WMListItem*
@@ -245,7 +271,6 @@ WMGetListItems(WMList *lPtr)
} }
void void
WMSetListUserDrawProc(WMList *lPtr, WMListDrawProc *proc) WMSetListUserDrawProc(WMList *lPtr, WMListDrawProc *proc)
{ {
@@ -269,12 +294,13 @@ WMSetListUserDrawItemHeight(WMList *lPtr, unsigned short height)
void void
WMClearList(WMList *lPtr) WMClearList(WMList *lPtr)
{ {
int oldSelected = lPtr->selectedItem; int selNo = WMGetArrayItemCount(lPtr->selectedItems);
WMEmptyArray(lPtr->selectedItems);
WMEmptyArray(lPtr->items); WMEmptyArray(lPtr->items);
lPtr->topItem = 0; lPtr->topItem = 0;
lPtr->selectedItem = -1; //lPtr->selectedItem = -1;
if (!lPtr->idleID) { if (!lPtr->idleID) {
WMDeleteIdleHandler(lPtr->idleID); WMDeleteIdleHandler(lPtr->idleID);
@@ -283,9 +309,9 @@ WMClearList(WMList *lPtr)
if (lPtr->view->flags.realized) { if (lPtr->view->flags.realized) {
updateScroller(lPtr); updateScroller(lPtr);
} }
if (oldSelected != -1) if (selNo > 0) {
WMPostNotificationName(WMListSelectionDidChangeNotification, lPtr, WMPostNotificationName(WMListSelectionDidChangeNotification, lPtr, NULL);
(void*)-1); }
} }
@@ -305,20 +331,26 @@ WMSetListDoubleAction(WMList *lPtr, WMAction *action, void *clientData)
} }
WMArray*
WMGetListSelectedItems(WMList *lPtr)
{
return lPtr->selectedItems;
}
WMListItem* WMListItem*
WMGetListSelectedItem(WMList *lPtr) WMGetListSelectedItem(WMList *lPtr)
{ {
if (lPtr->selectedItem < 0) return WMGetFromArray(lPtr->selectedItems, 0);
return NULL;
return WMGetFromArray(lPtr->items, lPtr->selectedItem);
} }
int int
WMGetListSelectedItemRow(WMList *lPtr) WMGetListSelectedItemRow(WMList *lPtr)
{ {
return lPtr->selectedItem; WMListItem *item = WMGetFromArray(lPtr->selectedItems, 0);
return (item!=NULL ? WMGetFirstInArray(lPtr->items, item) : WLNotFound);
} }
@@ -363,6 +395,7 @@ WMGetListNumberOfRows(WMList *lPtr)
return WMGetArrayItemCount(lPtr->items); return WMGetArrayItemCount(lPtr->items);
} }
int int
WMGetListPosition(WMList *lPtr) WMGetListPosition(WMList *lPtr)
{ {
@@ -370,6 +403,20 @@ WMGetListPosition(WMList *lPtr)
} }
Bool
WMListAllowsMultipleSelection(WMList *lPtr)
{
return lPtr->flags.allowMultipleSelection;
}
Bool
WMListAllowsEmptySelection(WMList *lPtr)
{
return lPtr->flags.allowEmptySelection;
}
static void static void
vScrollCallBack(WMWidget *scroller, void *self) vScrollCallBack(WMWidget *scroller, void *self)
{ {
@@ -479,11 +526,12 @@ paintItem(List *lPtr, int index)
(*lPtr->draw)(lPtr, index, view->window, itemPtr->text, flags, (*lPtr->draw)(lPtr, index, view->window, itemPtr->text, flags,
&rect); &rect);
} else { } else {
if (itemPtr->selected) if (itemPtr->selected) {
XFillRectangle(scr->display, view->window, WMColorGC(scr->white), XFillRectangle(scr->display, view->window, WMColorGC(scr->white),
x, y, width, height); x, y, width, height);
else } else {
XClearArea(scr->display, view->window, x, y, width, height, False); XClearArea(scr->display, view->window, x, y, width, height, False);
}
W_PaintText(view, view->window, scr->normalFont, x+4, y, width, W_PaintText(view, view->window, scr->normalFont, x+4, y, width,
WALeft, WMColorGC(scr->black), False, WALeft, WMColorGC(scr->black), False,
@@ -596,55 +644,45 @@ WMFindRowOfListItemWithTitle(WMList *lPtr, char *title)
void void
WMSelectListItem(WMList *lPtr, int row) WMSelectListItem(WMList *lPtr, int row)
{ {
WMListItem *itemPtr; WMListItem *item, *oldSelected;
int notify = 0;
if (row >= WMGetArrayItemCount(lPtr->items)) if (row >= WMGetArrayItemCount(lPtr->items))
return; 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;
assert(lPtr->selectedItem < WMGetArrayItemCount(lPtr->items));
if (!lPtr->flags.allowMultipleSelection) {
/* unselect previous selected item */
if (lPtr->selectedItem >= 0) {
itemPtr = WMGetFromArray(lPtr->items, lPtr->selectedItem);
if (itemPtr->selected) {
itemPtr->selected = 0;
if (lPtr->view->flags.mapped
&& lPtr->selectedItem>=lPtr->topItem
&& lPtr->selectedItem<=lPtr->topItem+lPtr->fullFitLines) {
paintItem(lPtr, lPtr->selectedItem);
}
}
}
}
if (row < 0) { if (row < 0) {
/* Should row = -1 deselect all or just do nothing ?. Check it. -Dan */
if (!lPtr->flags.allowMultipleSelection) { if (!lPtr->flags.allowMultipleSelection) {
lPtr->selectedItem = -1; WMUnselectAllListItems(lPtr);
if (notify)
WMPostNotificationName(WMListSelectionDidChangeNotification,
lPtr, (void*)((int)lPtr->selectedItem));
} }
return; return;
} }
/* select item */ item = WMGetFromArray(lPtr->items, row);
itemPtr = WMGetFromArray(lPtr->items, row); if (item->selected)
return; /* Return if already selected */
if (lPtr->flags.allowMultipleSelection) oldSelected = WMGetFromArray(lPtr->selectedItems, 0);
itemPtr->selected = !itemPtr->selected;
else /* unselect previous selected item if case */
itemPtr->selected = 1; if (!lPtr->flags.allowMultipleSelection && oldSelected) {
int oldSelectedRow = WMGetListSelectedItemRow(lPtr);
// better call WMUnselectAllListItems() here? -Dan
oldSelected->selected = 0;
WMDeleteFromArray(lPtr->selectedItems, 0);
// This is faster and have the same effect in the single selected case
// but may leave xxx->selected flags set after a multi->single selected
// switch
//WMEmptyArray(lPtr->selectedItems);
if (lPtr->view->flags.mapped && oldSelectedRow>=lPtr->topItem
&& oldSelectedRow<=lPtr->topItem+lPtr->fullFitLines) {
paintItem(lPtr, oldSelectedRow);
}
}
/* select item */
item->selected = 1;
WMAddToArray(lPtr->selectedItems, item);
if (lPtr->view->flags.mapped) { if (lPtr->view->flags.mapped) {
paintItem(lPtr, row); paintItem(lPtr, row);
@@ -655,10 +693,9 @@ WMSelectListItem(WMList *lPtr, int row)
lPtr->view->size.width, lPtr->view->size.height, lPtr->view->size.width, lPtr->view->size.height,
WRSunken); WRSunken);
} }
lPtr->selectedItem = row; //lPtr->selectedItem = row;
if (notify)
WMPostNotificationName(WMListSelectionDidChangeNotification, lPtr, WMPostNotificationName(WMListSelectionDidChangeNotification, lPtr, NULL);
(void*)((int)lPtr->selectedItem));
} }
@@ -826,3 +863,5 @@ destroyList(List *lPtr)
wfree(lPtr); wfree(lPtr);
} }