summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorjoye <joye>2014-06-02 20:57:47 (GMT)
committerjoye <joye>2014-06-02 20:57:47 (GMT)
commitcdddc8a605504152b60bd34781d9018e2d752650 (patch)
tree53ed622355f6bfe119514b3c06cc9ba2e2c69021 /src
parent03cb7456569ba0fdaeab16446eeb62f4d124b042 (diff)
downloadblt-cdddc8a605504152b60bd34781d9018e2d752650.zip
blt-cdddc8a605504152b60bd34781d9018e2d752650.tar.gz
blt-cdddc8a605504152b60bd34781d9018e2d752650.tar.bz2
*** empty log message ***
Diffstat (limited to 'src')
-rw-r--r--src/bltGrBind.C158
1 files changed, 12 insertions, 146 deletions
diff --git a/src/bltGrBind.C b/src/bltGrBind.C
index 5476870..a649667 100644
--- a/src/bltGrBind.C
+++ b/src/bltGrBind.C
@@ -44,7 +44,7 @@ BindTable::BindTable(Graph* graphPtr, Pick* pickPtr)
{
graphPtr_ = graphPtr;
pickPtr_ = pickPtr;
- flags_ =0;
+ grab_ =0;
table_ = Tk_CreateBindingTable(graphPtr->interp_);
currentItem_ =NULL;
currentContext_ =CID_NONE;
@@ -164,66 +164,15 @@ void BindTable::doEvent(XEvent* eventPtr)
delete [] tagArray;
}
-#define REPICK_IN_PROGRESS (1<<0)
-#define LEFT_GRABBED_ITEM (1<<1)
-
void BindTable::pickItem(XEvent* eventPtr)
{
- // This code comes from tkCanvas.c
-
- // Check whether or not a button is down. If so, we'll log entry and exit
- // into and out of the current item, but not entry into any other item.
- // This implements a form of grabbing equivalent to what the X server does
- // for windows.
-
int buttonDown = state_
& (Button1Mask|Button2Mask|Button3Mask|Button4Mask|Button5Mask);
- // Save information about this event in the widget. The event in the
- // widget is used for two purposes:
- // 1. Event bindings: if the current item changes, fake events are
- // generated to allow item-enter and item-leave bindings to trigger.
- // 2. Reselection: if the current item gets deleted, can use the
- // saved event to find a new current item.
- // Translate MotionNotify events into EnterNotify events, since that's
- // what gets reported to item handlers.
-
- if (eventPtr != &pickEvent_) {
- if ((eventPtr->type == MotionNotify) || (eventPtr->type == ButtonRelease)) {
- pickEvent_.xcrossing.type = EnterNotify;
- pickEvent_.xcrossing.serial = eventPtr->xmotion.serial;
- pickEvent_.xcrossing.send_event = eventPtr->xmotion.send_event;
- pickEvent_.xcrossing.display = eventPtr->xmotion.display;
- pickEvent_.xcrossing.window = eventPtr->xmotion.window;
- pickEvent_.xcrossing.root = eventPtr->xmotion.root;
- pickEvent_.xcrossing.subwindow = None;
- pickEvent_.xcrossing.time = eventPtr->xmotion.time;
- pickEvent_.xcrossing.x = eventPtr->xmotion.x;
- pickEvent_.xcrossing.y = eventPtr->xmotion.y;
- pickEvent_.xcrossing.x_root = eventPtr->xmotion.x_root;
- pickEvent_.xcrossing.y_root = eventPtr->xmotion.y_root;
- pickEvent_.xcrossing.mode = NotifyNormal;
- pickEvent_.xcrossing.detail = NotifyNonlinear;
- pickEvent_.xcrossing.same_screen = eventPtr->xmotion.same_screen;
- pickEvent_.xcrossing.focus = False;
- pickEvent_.xcrossing.state = eventPtr->xmotion.state;
- }
- else
- pickEvent_ = *eventPtr;
- }
-
- // If this is a recursive call (there's already a partially completed call
- // pending on the stack; it's in the middle of processing a Leave event
- // handler for the old current item) then just return; the pending call
- // will do everything that's needed.
- if (flags_ & REPICK_IN_PROGRESS)
- return;
-
// A LeaveNotify event automatically means that there's no current item,
- // so the check for closest item can be skipped.
- if (pickEvent_.type != LeaveNotify) {
- int x = pickEvent_.xcrossing.x;
- int y = pickEvent_.xcrossing.y;
+ if (eventPtr->type != LeaveNotify) {
+ int x = eventPtr->xcrossing.x;
+ int y = eventPtr->xcrossing.y;
newItem_ = pickPtr_->pickEntry(x, y, &newContext_);
}
else {
@@ -232,123 +181,40 @@ void BindTable::pickItem(XEvent* eventPtr)
}
// Nothing to do: the current item hasn't changed.
- if ((newItem_ == currentItem_) && !(flags_ & LEFT_GRABBED_ITEM))
+ if ((newItem_ == currentItem_) && !grab_)
return;
if (!buttonDown)
- flags_ &= ~LEFT_GRABBED_ITEM;
+ grab_ =0;
if ((newItem_ != currentItem_) && buttonDown) {
- flags_ |= LEFT_GRABBED_ITEM;
+ grab_ =1;
return;
}
- // Simulate a LeaveNotify event on the previous current item and an
- // EnterNotify event on the new current item. Remove the "current" tag
- // from the previous current item and place it on the new current item.
- if (currentItem_ && (newItem_ != currentItem_) && !(flags_ & LEFT_GRABBED_ITEM)) {
- XEvent event = pickEvent_;
- event.type = LeaveNotify;
-
- // If the event's detail happens to be NotifyInferior the binding
- // mechanism will discard the event. To be consistent, always use
- // NotifyAncestor.
- event.xcrossing.detail = NotifyAncestor;
- flags_ |= REPICK_IN_PROGRESS;
- doEvent(&event);
- flags_ &= ~REPICK_IN_PROGRESS;
-
- // Note: during DoEvent above, it's possible that newItem got
- // reset to NULL because the item was deleted.
- if ((newItem_ != currentItem_) && buttonDown) {
- flags_ |= LEFT_GRABBED_ITEM;
- return;
- }
- }
-
- // Special note:
- // it's possible that newItem_ == currentItem_
- // here. This can happen, for example, if LEFT_GRABBED_ITEM was set.
- flags_ &= ~LEFT_GRABBED_ITEM;
+ grab_ =0;
currentItem_ = newItem_;
currentContext_ = newContext_;
- if (currentItem_ != NULL) {
- XEvent event = pickEvent_;
- event.type = EnterNotify;
- event.xcrossing.detail = NotifyAncestor;
- doEvent(&event);
- }
}
static void BindProc(ClientData clientData, XEvent* eventPtr)
{
- // This code comes from tkCanvas.c
-
- // This code below keeps track of the current modifier state in
- // bindPtr->state. This information is used to defer repicks of the
- // current item while buttons are down.
-
BindTable* bindPtr = (BindTable*)clientData;
-
Tcl_Preserve(bindPtr->graphPtr_);
switch (eventPtr->type) {
case ButtonPress:
case ButtonRelease:
- {
- int mask = 0;
- switch (eventPtr->xbutton.button) {
- case Button1:
- mask = Button1Mask;
- break;
- case Button2:
- mask = Button2Mask;
- break;
- case Button3:
- mask = Button3Mask;
- break;
- case Button4:
- mask = Button4Mask;
- break;
- case Button5:
- mask = Button5Mask;
- break;
- default:
- break;
- }
-
- // For button press events, repick the current item using the button
- // state before the event, then process the event. For button release
- // events, first process the event, then repick the current item using
- // the button state *after* the event (the button has logically gone
- // up before we change the current item).
-
- if (eventPtr->type == ButtonPress) {
- // On a button press, first repick the current item using the
- // button state before the event, the process the event.
- bindPtr->state_ = eventPtr->xbutton.state;
- bindPtr->pickItem(eventPtr);
- bindPtr->state_ ^= mask;
- bindPtr->doEvent(eventPtr);
- }
- else {
- // Button release: first process the event, with the button still
- // considered to be down. Then repick the current item under the
- // assumption that the button is no longer down.
- bindPtr->state_ = eventPtr->xbutton.state;
- bindPtr->doEvent(eventPtr);
- eventPtr->xbutton.state ^= mask;
- bindPtr->state_ = eventPtr->xbutton.state;
- bindPtr->pickItem(eventPtr);
- eventPtr->xbutton.state ^= mask;
- }
- }
+ bindPtr->state_ = eventPtr->xbutton.state;
+ bindPtr->pickItem(eventPtr);
+ bindPtr->doEvent(eventPtr);
break;
case EnterNotify:
case LeaveNotify:
bindPtr->state_ = eventPtr->xcrossing.state;
bindPtr->pickItem(eventPtr);
+ bindPtr->doEvent(eventPtr);
break;
case MotionNotify: