[comp.windows.interviews] "odd" Button state

juando@cnm.us.es (05/14/91)

	Playing with alert, I found that if you press and hold any mouse button
outside the screen button and then move the pointer inside it and release, the
button enters an "odd" state: Although no mouse button is pressed, it is
highlighted whenever the pointer enters it. Looking at the code that implements
Button class you can see that it is "swallowing" mouse events. I could fix
that with the patch that follows, but I'm not sure if that is the desired
behavior for Button. Can you tell me if this is right?

Juan.

Apply with patch -p -N at the top level source directory

*** iv/src/lib/IV-look/button.c.orig	Thu Jan 24 21:59:00 1991
--- iv/src/lib/IV-look/button.c	Mon May 13 21:53:54 1991
***************
*** 60,74 ****
  }
  
  void Button::event(Event& e) {
      listener_->sensor()->motion(true);
      do {
!         if (listener_->picks(e.pointer_x(), e.pointer_y())) {
              if (telltale_ != nil) {
-                 telltale_->highlight(true);
-             }
-         } else {
-             if (telltale_ != nil) {
                  telltale_->highlight(false);
              }
          }
  	e.world()->read(e);
--- 60,78 ----
  }
  
  void Button::event(Event& e) {
+     if (e.type() != Event::down) {
+ 	return;
+     }
+     if (telltale_ != nil) {
+ 	telltale_->highlight(true);
+     }
      listener_->sensor()->motion(true);
      do {
!         if (!listener_->picks(e.pointer_x(), e.pointer_y())) {
              if (telltale_ != nil) {
                  telltale_->highlight(false);
+ 		listener_->sensor()->motion(false);
+ 		return;
              }
          }
  	e.world()->read(e);

linton@marktwain.rad.sgi.com (Mark Linton) (05/15/91)

In article <"<9105132259.AA23725@cnmus.cnm.us.es>, juando@cnm.us.es writes:
|> 
|> 	Playing with alert, I found that if you press and hold any mouse button
|> outside the screen button and then move the pointer inside it and release, the
|> button enters an "odd" state: Although no mouse button is pressed, it is
|> highlighted whenever the pointer enters it. Looking at the code that implements
|> Button class you can see that it is "swallowing" mouse events. I could fix
|> that with the patch that follows, but I'm not sure if that is the desired
|> behavior for Button. Can you tell me if this is right?

Your changes looked ok, but Button really should use grab by deriving from
PointerHandler instead of having its own read loop.  Below are new versions
of button.h and button.c that seem to work.

/*
 * Copyright (c) 1987, 1988, 1989, 1990, 1991 Stanford University
 * Copyright (c) 1991 Silicon Graphics, Inc.
 *
 * Permission to use, copy, modify, distribute, and sell this software and 
 * its documentation for any purpose is hereby granted without fee, provided
 * that (i) the above copyright notices and this permission notice appear in
 * all copies of the software and related documentation, and (ii) the names of
 * Stanford and Silicon Graphics may not be used in any advertising or
 * publicity relating to the software without the specific, prior written
 * permission of Stanford and Silicon Graphics.
 * 
 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
 *
 * IN NO EVENT SHALL STANFORD OR SILICON GRAPHICS BE LIABLE FOR
 * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
 * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
 * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
 * OF THIS SOFTWARE.
 */

/*
 * Button - clickable Action
 */

#ifndef ivlook_button_h
#define ivlook_button_h

#include <InterViews/ptrhandler.h>
#include <InterViews/monoglyph.h>

class Action;
class Listener;
class Telltale;

class Button : public MonoGlyph, public PointerHandler {
public:
    Button(Action*, Telltale*);

    virtual void drag(Event&);
    virtual void release(Event&);
    virtual void commit(Event&);
protected:
    virtual ~Button();
private:
    Action* action_;
    Listener* listener_;
    Telltale* telltale_;
};

#endif
/*
 * Copyright (c) 1987, 1988, 1989, 1990, 1991 Stanford University
 * Copyright (c) 1991 Silicon Graphics, Inc.
 *
 * Permission to use, copy, modify, distribute, and sell this software and 
 * its documentation for any purpose is hereby granted without fee, provided
 * that (i) the above copyright notices and this permission notice appear in
 * all copies of the software and related documentation, and (ii) the names of
 * Stanford and Silicon Graphics may not be used in any advertising or
 * publicity relating to the software without the specific, prior written
 * permission of Stanford and Silicon Graphics.
 * 
 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
 *
 * IN NO EVENT SHALL STANFORD OR SILICON GRAPHICS BE LIABLE FOR
 * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
 * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
 * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
 * OF THIS SOFTWARE.
 */

/*
 * Button - clickable Action
 */

#include <IV-look/button.h>
#include <IV-look/telltale.h>
#include <InterViews/action.h>
#include <InterViews/event.h>
#include <InterViews/listener.h>
#include <InterViews/sensor.h>
#include <InterViews/world.h>

Button::Button(Action* a, Telltale* t) : MonoGlyph(nil), PointerHandler() {
    action_ = a;
    Resource::ref(action_);
    telltale_ = t;
    Resource::ref(telltale_);
    listener_ = new Listener(telltale_, this);
    listener_->sensor()->button(true, Event::any);
    listener_->sensor()->motion(true);
    body(listener_);
}

Button::~Button() {
    Resource::unref(action_);
    action_ = nil;
    Resource::unref(telltale_);
    telltale_ = nil;
}

void Button::drag(Event& e) {
    if (telltale_ != nil) {
	telltale_->highlight(listener_->picks(e.pointer_x(), e.pointer_y()));
    }
}

void Button::release(Event& e) {
    if (telltale_ != nil) {
	telltale_->highlight(false);
    }
    PointerHandler::release(e);
}

void Button::commit(Event& e) {
    if (action_ != nil && listener_->picks(e.pointer_x(), e.pointer_y())) {
	action_->execute();
    }
}