1
0
mirror of https://github.com/gryf/wmaker.git synced 2026-02-13 12:25:53 +01:00

- the list multiple selection code is working now. it still needs some

minor work and cleanup.
- made some bag and array functions to return void instead of int.
- a few new array functions.
- better handling of mouse wheel.

!!! make clean after this update before you rebuild. some enums changed.
This commit is contained in:
dan
2000-10-01 23:26:03 +00:00
parent 6de1c41865
commit b2478b634f
13 changed files with 467 additions and 157 deletions

View File

@@ -201,7 +201,7 @@ WMInsertListItem(WMList *lPtr, int row, char *text)
}
int
void
WMRemoveListItem(WMList *lPtr, int row)
{
WMListItem *item;
@@ -210,13 +210,13 @@ WMRemoveListItem(WMList *lPtr, int row)
CHECK_CLASS(lPtr, WC_List);
if (row < 0 || row >= WMGetArrayItemCount(lPtr->items))
return 0;
/*wassertr(row>=0 && row<WMGetArrayItemCount(lPtr->items));*/
if (row<0 || row>=WMGetArrayItemCount(lPtr->items))
return;
item = WMGetFromArray(lPtr->items, row);
if (item->selected) {
WMRemoveFromArray(lPtr->selectedItems, item);
//WMUnselectListItem(lPtr, row);
selNotify = 1;
}
@@ -236,8 +236,6 @@ WMRemoveListItem(WMList *lPtr, int row)
if (selNotify) {
WMPostNotificationName(WMListSelectionDidChangeNotification, lPtr, NULL);
}
return 1;
}
@@ -446,6 +444,14 @@ vScrollCallBack(WMWidget *scroller, void *self)
scrollByAmount(lPtr, lPtr->fullFitLines-(1-lPtr->flags.dontFitAll)-1);
break;
case WSDecrementWheel:
scrollByAmount(lPtr, -lPtr->fullFitLines / 3);
break;
case WSIncrementWheel:
scrollByAmount(lPtr, lPtr->fullFitLines / 3);
break;
case WSKnob:
lPtr->topItem = WMGetScrollerValue(lPtr->vScroller) *
(float)(itemCount - lPtr->fullFitLines);
@@ -513,6 +519,13 @@ paintItem(List *lPtr, int index)
WALeft, WMColorGC(scr->black), False,
itemPtr->text, strlen(itemPtr->text));
}
if ((index-lPtr->topItem+lPtr->fullFitLines)*lPtr->itemHeight >
lPtr->view->size.height-2) {
W_DrawRelief(lPtr->view->screen, lPtr->view->window, 0, 0,
lPtr->view->size.width, lPtr->view->size.height,
WRSunken);
}
}
@@ -620,62 +633,40 @@ WMFindRowOfListItemWithTitle(WMList *lPtr, char *title)
void
WMSelectListItem(WMList *lPtr, int row)
{
WMListItem *item, *oldSelected;
WMListItem *item;
if (row >= WMGetArrayItemCount(lPtr->items))
return;
if (row < 0) {
/* Should row = -1 deselect all or just do nothing ?. Check it. -Dan */
if (!lPtr->flags.allowMultipleSelection) {
WMUnselectAllListItems(lPtr);
}
/* row = -1 will deselects all for backward compatibility.
* will be removed later. -Dan */
WMUnselectAllListItems(lPtr);
return;
}
item = WMGetFromArray(lPtr->items, row);
if (item->selected)
return; /* Return if already selected */
return; /* Return if already selected */
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);
}
if (!lPtr->flags.allowMultipleSelection) {
/* unselect previous selected items */
WMUnselectAllListItems(lPtr);
}
/* select item */
item->selected = 1;
WMAddToArray(lPtr->selectedItems, item);
if (lPtr->view->flags.mapped) {
if (lPtr->view->flags.mapped && row>=lPtr->topItem
&& row<=lPtr->topItem+lPtr->fullFitLines) {
paintItem(lPtr, row);
if ((row-lPtr->topItem+lPtr->fullFitLines)*lPtr->itemHeight
> lPtr->view->size.height-2)
W_DrawRelief(lPtr->view->screen, lPtr->view->window, 0, 0,
lPtr->view->size.width, lPtr->view->size.height,
WRSunken);
}
WMPostNotificationName(WMListSelectionDidChangeNotification, lPtr, NULL);
}
// make them return an int
void
WMUnselectListItem(WMList *lPtr, int row)
{
@@ -684,7 +675,10 @@ WMUnselectListItem(WMList *lPtr, int row)
if (!item || !item->selected)
return;
// also add check for allowEmptySelection
if (!lPtr->flags.allowEmptySelection &&
WMGetArrayItemCount(lPtr->selectedItems) <= 1) {
return;
}
item->selected = 0;
WMRemoveFromArray(lPtr->selectedItems, item);
@@ -693,6 +687,120 @@ WMUnselectListItem(WMList *lPtr, int row)
&& row<=lPtr->topItem+lPtr->fullFitLines) {
paintItem(lPtr, row);
}
WMPostNotificationName(WMListSelectionDidChangeNotification, lPtr, NULL);
}
void
WMSelectListItemsInRange(WMList *lPtr, WMRange range)
{
WMListItem *item;
int position = range.position, k = 1, notify = 0;
int total = WMGetArrayItemCount(lPtr->items);
if (!lPtr->flags.allowMultipleSelection)
return;
if (range.count==0)
return; /* Nothing to select */
if (range.count < 0) {
range.count = -range.count;
k = -1;
}
for (; range.count>0 && position>=0 && position<total; range.count--) {
item = WMGetFromArray(lPtr->items, position);
if (!item->selected) {
item->selected = 1;
WMAddToArray(lPtr->selectedItems, item);
if (lPtr->view->flags.mapped && position>=lPtr->topItem
&& position<=lPtr->topItem+lPtr->fullFitLines) {
paintItem(lPtr, position);
}
notify = 1;
}
position += k;
}
if (notify) {
WMPostNotificationName(WMListSelectionDidChangeNotification, lPtr, NULL);
}
}
void
WMSetListSelectionToRange(WMList *lPtr, WMRange range)
{
WMListItem *item;
int mark1, mark2, i, k;
int position = range.position, notify = 0;
int total = WMGetArrayItemCount(lPtr->items);
if (!lPtr->flags.allowMultipleSelection)
return;
if (range.count==0) {
WMUnselectAllListItems(lPtr);
return;
}
if (range.count < 0) {
mark1 = range.position + range.count + 1;
mark2 = range.position + 1;
range.count = -range.count;
k = -1;
} else {
mark1 = range.position;
mark2 = range.position + range.count;
k = 1;
}
if (mark1 > total)
mark1 = total;
if (mark2 < 0)
mark2 = 0;
WMEmptyArray(lPtr->selectedItems);
for (i=0; i<mark1; i++) {
item = WMGetFromArray(lPtr->items, i);
if (item->selected) {
item->selected = 0;
if (lPtr->view->flags.mapped && i>=lPtr->topItem
&& i<=lPtr->topItem+lPtr->fullFitLines) {
paintItem(lPtr, i);
}
notify = 1;
}
}
for (; range.count>0 && position>=0 && position<total; range.count--) {
item = WMGetFromArray(lPtr->items, position);
if (!item->selected) {
item->selected = 1;
if (lPtr->view->flags.mapped && position>=lPtr->topItem
&& position<=lPtr->topItem+lPtr->fullFitLines) {
paintItem(lPtr, position);
}
notify = 1;
}
WMAddToArray(lPtr->selectedItems, item);
position += k;
}
for (i=mark2; i<total; i++) {
item = WMGetFromArray(lPtr->items, i);
if (item->selected) {
item->selected = 0;
if (lPtr->view->flags.mapped && i>=lPtr->topItem
&& i<=lPtr->topItem+lPtr->fullFitLines) {
paintItem(lPtr, i);
}
notify = 1;
}
}
if (notify) {
WMPostNotificationName(WMListSelectionDidChangeNotification, lPtr, NULL);
}
}
@@ -705,28 +813,43 @@ WMSelectAllListItems(WMList *lPtr)
if (!lPtr->flags.allowMultipleSelection)
return;
// implement some WMDuplicateArray() ?
if (WMGetArrayItemCount(lPtr->items) ==
WMGetArrayItemCount(lPtr->selectedItems)) {
return; /* All items are selected already */
}
WMFreeArray(lPtr->selectedItems);
lPtr->selectedItems = WMCreateArrayWithArray(lPtr->items);
for (i=0; i<WMGetArrayItemCount(lPtr->items); i++) {
item = WMGetFromArray(lPtr->items, i);
if (!item->selected) {
item->selected = 1;
WMAddToArray(lPtr->selectedItems, item);
if (lPtr->view->flags.mapped && i>=lPtr->topItem
&& i<=lPtr->topItem+lPtr->fullFitLines) {
paintItem(lPtr, i);
}
}
}
WMPostNotificationName(WMListSelectionDidChangeNotification, lPtr, NULL);
}
void
WMUnselectAllListItems(WMList *lPtr)
{
int i;
WMListItem *item;
int i;//, keep;
WMListItem *item;//, *keepItem;
// check for allowEmptySelection
// FIXME: check for allowEmptySelection
//keep = lPtr->flags.allowEmptySelection ? 0 : 1;
//if (WMGetArrayItemCount(lPtr->selectedItems) == keep)
// return 1; /* Nothing selected so return */
//keepItem = (keep==1 ? WMGetFromArray(lPtr->selectedItems, 0) : NULL);
for (i=0; i<WMGetArrayItemCount(lPtr->items); i++) {
item = WMGetFromArray(lPtr->items, i);
@@ -740,6 +863,7 @@ WMUnselectAllListItems(WMList *lPtr)
}
WMEmptyArray(lPtr->selectedItems);
WMPostNotificationName(WMListSelectionDidChangeNotification, lPtr, NULL);
}
@@ -763,30 +887,29 @@ handleActionEvents(XEvent *event, void *data)
List *lPtr = (List*)data;
int tmp;
int topItem = lPtr->topItem;
static int oldClicked = -1;
static int lastClicked = -1, prevItem = -1;
CHECK_CLASS(data, WC_List);
switch (event->type) {
case ButtonRelease:
#define CHECK_WHEEL_PATCH
#ifdef CHECK_WHEEL_PATCH
/* Ignore mouse wheel events, they're not "real" button events */
if (event->xbutton.button == WINGsConfiguration.mouseWheelUp ||
event->xbutton.button == WINGsConfiguration.mouseWheelDown) {
break;
}
#endif
lPtr->flags.buttonPressed = 0;
tmp = getItemIndexAt(lPtr, event->xbutton.y);
if (/*tmp == lPtr->selectedItem && */tmp >= 0) {
if (tmp >= 0) {
if (lPtr->action)
(*lPtr->action)(lPtr, lPtr->clientData);
}
oldClicked = tmp;
if (!(event->xbutton.state & ShiftMask))
lastClicked = prevItem = tmp;
break;
case EnterNotify:
@@ -800,52 +923,96 @@ handleActionEvents(XEvent *event, void *data)
break;
case ButtonPress:
if (event->xbutton.x > WMWidgetWidth(lPtr->vScroller)) {
#ifdef CHECK_WHEEL_PATCH
if (event->xbutton.button == WINGsConfiguration.mouseWheelDown ||
event->xbutton.button == WINGsConfiguration.mouseWheelUp) {
int amount = 0;
if (event->xbutton.x <= WMWidgetWidth(lPtr->vScroller))
break;
if (event->xbutton.button == WINGsConfiguration.mouseWheelDown ||
event->xbutton.button == WINGsConfiguration.mouseWheelUp) {
int amount = 0;
if (event->xbutton.state & ShiftMask) {
amount = lPtr->fullFitLines-(1-lPtr->flags.dontFitAll)-1;
} else if (event->xbutton.state & ControlMask) {
amount = 1;
} else {
amount = lPtr->fullFitLines / 3;
if (amount == 0)
amount++;
}
if (event->xbutton.button == WINGsConfiguration.mouseWheelUp)
amount = -amount;
scrollByAmount(lPtr, amount);
break;
if (event->xbutton.state & ControlMask) {
amount = lPtr->fullFitLines-(1-lPtr->flags.dontFitAll)-1;
} else if (event->xbutton.state & ShiftMask) {
amount = 1;
} else {
amount = lPtr->fullFitLines / 3;
if (amount == 0)
amount++;
}
#endif
if (event->xbutton.button == WINGsConfiguration.mouseWheelUp)
amount = -amount;
tmp = getItemIndexAt(lPtr, event->xbutton.y);
lPtr->flags.buttonPressed = 1;
if (tmp >= 0) {
if (tmp == oldClicked && WMIsDoubleClick(event)) {
WMSelectListItem(lPtr, tmp);
if (lPtr->doubleAction)
(*lPtr->doubleAction)(lPtr, lPtr->doubleClientData);
} else {
WMSelectListItem(lPtr, tmp);
}
}
oldClicked = tmp;
scrollByAmount(lPtr, amount);
break;
}
tmp = getItemIndexAt(lPtr, event->xbutton.y);
lPtr->flags.buttonPressed = 1;
if (tmp >= 0) {
if (tmp == lastClicked && WMIsDoubleClick(event)) {
WMSelectListItem(lPtr, tmp);
if (lPtr->doubleAction)
(*lPtr->doubleAction)(lPtr, lPtr->doubleClientData);
} else {
if (!lPtr->flags.allowMultipleSelection) {
WMSelectListItem(lPtr, tmp);
} else {
WMRange range;
WMListItem *item, *lastSel;
if (event->xbutton.state & ControlMask) {
item = WMGetFromArray(lPtr->items, tmp);
if (item && item->selected) {
WMUnselectListItem(lPtr, tmp);
} else {
WMSelectListItem(lPtr, tmp);
}
} else if (event->xbutton.state & ShiftMask) {
if (WMGetArrayItemCount(lPtr->selectedItems) == 0) {
WMSelectListItem(lPtr, tmp);
} else {
lastSel = WMGetFromArray(lPtr->items, lastClicked);
range.position = WMGetFirstInArray(lPtr->items,
lastSel);
if (tmp >= range.position)
range.count = tmp - range.position + 1;
else
range.count = tmp - range.position - 1;
WMSetListSelectionToRange(lPtr, range);
}
} else {
range.position = tmp;
range.count = 1;
WMSetListSelectionToRange(lPtr, range);
}
}
}
}
if (!(event->xbutton.state & ShiftMask))
lastClicked = prevItem = tmp;
break;
case MotionNotify:
if (lPtr->flags.buttonPressed) {
tmp = getItemIndexAt(lPtr, event->xmotion.y);
if (tmp>=0 /*&& tmp != lPtr->selectedItem*/) {
WMSelectListItem(lPtr, tmp);
if (tmp>=0 && tmp!=prevItem) {
if (lPtr->flags.allowMultipleSelection) {
WMRange range;
range.position = lastClicked;
if (tmp >= lastClicked)
range.count = tmp - lastClicked + 1;
else
range.count = tmp - lastClicked - 1;
WMSetListSelectionToRange(lPtr, range);
} else {
WMSelectListItem(lPtr, tmp);
}
}
prevItem = tmp;
}
break;
}