1
0
mirror of https://github.com/gryf/wmaker.git synced 2025-12-24 07:02:30 +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
- removed WMArrayBag and reorganized WMTreeBag to be WMBag.
- 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:

View File

@@ -1059,6 +1059,10 @@ void WMSetScrollerArrowsPosition(WMScroller *sPtr,
WMList *WMCreateList(WMWidget *parent);
void WMSetListAllowMultipleSelection(WMList *lPtr, Bool flag);
void WMSetListAllowEmptySelection(WMList *lPtr, Bool flag);
#define WMAddListItem(lPtr, text) WMInsertListItem((lPtr), -1, (text))
WMListItem *WMInsertListItem(WMList *lPtr, int row, char *text);
@@ -1073,8 +1077,7 @@ WMListItem *WMGetListItem(WMList *lPtr, int row);
WMArray *WMGetListItems(WMList *lPtr);
void WMRemoveListItem(WMList *lPtr, int row);
int WMRemoveListItem(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);
/* 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);
@@ -1103,6 +1115,11 @@ void WMSetListBottomPosition(WMList *lPtr, int row);
int WMGetListPosition(WMList *lPtr);
Bool WMListAllowsMultipleSelection(WMList *lPtr);
Bool WMListAllowsEmptySelection(WMList *lPtr);
extern char *WMListDidScrollNotification;
extern char *WMListSelectionDidChangeNotification;

View File

@@ -112,8 +112,9 @@ typedef enum {
enum {
WBNotFound = INT_MIN, /* element was not found in bag */
WANotFound = -1 /* element was not found in array */
WBNotFound = INT_MIN, /* element was not found in WMBag */
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
WMInsertInArray(WMArray *array, int index, void *item)
{
wassertrv(index <= array->itemCount, 0);
wassertrv(index >= 0 && index <= array->itemCount, 0);
if (array->itemCount >= array->allocSize) {
array->allocSize += RESIZE_INCREMENT;
@@ -145,7 +145,7 @@ WMReplaceInArray(WMArray *array, int index, void *item)
{
void *old;
wassertrv(index > array->itemCount, 0);
wassertrv(index >= 0 && index <= array->itemCount, NULL);
if (index == array->itemCount) {
WMAddToArray(array, item);
@@ -162,8 +162,7 @@ WMReplaceInArray(WMArray *array, int index, void *item)
int
WMDeleteFromArray(WMArray *array, int index)
{
if (index >= array->itemCount)
return 0;
wassertrv(index >= 0 && index < array->itemCount, 0);
if (array->destructor) {
array->destructor(array->items[index]);
@@ -198,7 +197,7 @@ WMRemoveFromArray(WMArray *array, void *item)
void*
WMGetFromArray(WMArray *array, int index)
{
if (index >= array->itemCount)
if (index < 0 || index >= array->itemCount)
return NULL;
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 char*
createTruncatedString(WMFont *font, char *text, int *textLen, int width);
static char* createTruncatedString(WMFont *font, char *text, int *textLen,
int width);
static void willResizeBrowser(W_ViewDelegate*, WMView*,
unsigned int*, unsigned int*);
@@ -1030,7 +1030,7 @@ static void
listSelectionObserver(void *observerData, WMNotification *notification)
{
WMBrowser *bPtr = (WMBrowser*)observerData;
int column, item = (int)WMGetNotificationClientData(notification);
int column;
WMList *lPtr = (WMList*)WMGetNotificationObject(notification);
for (column = 0; column < bPtr->usedColumnCount; column++)
@@ -1043,7 +1043,7 @@ listSelectionObserver(void *observerData, WMNotification *notification)
return;
}
if (item < 0)
if (WMGetArrayItemCount(WMGetListSelectedItems(lPtr)) == 0)
column--;
bPtr->selectedColumn = column;

View File

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