root/src/apps/cortex/support/MouseTrackingHelpers.cpp
/*
 * Copyright (c) 1999-2000, Eric Moon.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions, and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions, and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * 3. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */


// MouseTrackingHelpers.cpp
// e.moon 8mar99

#include "MouseTrackingHelpers.h"

__USE_CORTEX_NAMESPACE


MouseTrackingSourceView::MouseTrackingSourceView(BRect frame, const char* name,
                uint32 resizeMode, uint32 flags, uint32 trackingFlags)
        : BView(frame, name, resizeMode, flags),
        m_pDest(0),
        m_trackingFlags(trackingFlags),
        m_bTracking(false)
{
        //FrameResized(frame.Width(), frame.Height());
}


MouseTrackingSourceView::~MouseTrackingSourceView()
{
}


// get mouse-down point in screen coordinates; returns
// B_OK on success, or B_ERROR if no longer tracking
// the mouse.
status_t MouseTrackingSourceView::getTrackingOrigin(
        BPoint* poPoint) const {
        if(!m_bTracking)
                return B_ERROR;
        *poPoint = m_initPoint;
        return B_OK;
}

// fetch/set the destination handler

status_t MouseTrackingSourceView::setTrackingDestination(
        IMouseTrackingDestination* pDest) {
        if(m_bTracking)
                return B_ERROR;

        m_pDest = pDest;
        return B_OK;
}

// ---------------------------------------------------------------- //
// BView impl.
// ---------------------------------------------------------------- //

// handle mouse events
void MouseTrackingSourceView::MouseDown(BPoint point) {
        if(!m_trackingFlags)
                return;

        // get mouse state & initial point
        uint32 buttons;
        GetMouse(&point, &buttons);
        m_prevPoint = ConvertToScreen(point);
        m_initPoint = m_prevPoint;

        // start tracking the mouse
        SetMouseEventMask(B_POINTER_EVENTS,
                B_LOCK_WINDOW_FOCUS|B_NO_POINTER_HISTORY);
        m_bTracking = true;

        // notify destination
        if(m_pDest)
                m_pDest->mouseTrackingBegin(this, buttons, point);
}

void MouseTrackingSourceView::MouseMoved(BPoint point, uint32 transit,
        const BMessage* pMsg) {

        if(m_bTracking) {

                // mouse-tracking update: figure number of pixels moved
                // (along the axes I care about)
                uint32 buttons;
                GetMouse(&point, &buttons, false);
                ConvertToScreen(&point);

                if(point == m_prevPoint) // no motion?
                        return;

                float xDelta = m_trackingFlags & TRACK_HORIZONTAL ?
                        point.x - m_prevPoint.x : 0.0;
                float yDelta = m_trackingFlags & TRACK_VERTICAL ?
                        point.y - m_prevPoint.y : 0.0;

                // pass info to destination view
                if(m_pDest)
                        m_pDest->mouseTrackingUpdate(buttons, xDelta, yDelta, point);

                // store point for future delta calculations
                m_prevPoint = point;
        }
}

void MouseTrackingSourceView::MouseUp(BPoint point) {
        if(m_bTracking) {
//              PRINT(( "MouseTrackingSourceView::MouseUp()\n"));

                // +++++ handle final update

                // clean up
                m_bTracking = false;
                if(m_pDest)
                        m_pDest->mouseTrackingEnd();
        }
}

// look for a default destination
void MouseTrackingSourceView::AttachedToWindow() {
        if(m_pDest) // already have a destination
                return;

        for(BView* pParent = Parent(); pParent; pParent = pParent->Parent()) {
                IMouseTrackingDestination* pFound =
                        dynamic_cast<IMouseTrackingDestination*>(pParent);
                if(pFound) // found a valid destination
                        m_pDest = pFound;
        }
}

/*
// track current frame rectangle
void MouseTrackingSourceView::FrameResized(float width, float height) {
        _inherited::FrameResized(width, height);
        m_prevFrame = Frame();

        // +++++ adjust if currently tracking?
}
*/

// END -- MouseTrackingHelpers.cpp --