Flu_DND.cpp
上传用户:yhdzpy8989
上传日期:2007-06-13
资源大小:13604k
文件大小:7k
- /*
- * ===========================================================================
- * PRODUCTION $Log: Flu_DND.cpp,v $
- * PRODUCTION Revision 1000.1 2004/06/01 21:05:44 gouriano
- * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.2
- * PRODUCTION
- * ===========================================================================
- */
- /*
- * These files were imported into NCBI's CVS directly from FLU version 2.9.1.
- * Modifications to the source are listed below.
- *
- * ==========================================================================
- * $Log: Flu_DND.cpp,v $
- * Revision 1000.1 2004/06/01 21:05:44 gouriano
- * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.2
- *
- * Revision 1.2 2004/05/21 22:27:51 gorelenk
- * Added PCH ncbi_pch.hpp
- *
- * Revision 1.1 2004/03/11 13:51:39 dicuccio
- * Imported FLU version 2.9.1. Altered export specifiers to match NCBI layout.
- * Altered include paths to match NCBI toolkit layout.
- *
- * ==========================================================================
- */
- // $Id: Flu_DND.cpp,v 1000.1 2004/06/01 21:05:44 gouriano Exp $
- /***************************************************************
- * FLU - FLTK Utility Widgets
- * Copyright (C) 2002 Ohio Supercomputer Center, Ohio State University
- *
- * This file and its content is protected by a software license.
- * You should have received a copy of this license with this file.
- * If not, please contact the Ohio Supercomputer Center immediately:
- * Attn: Jason Bryan Re: FLU 1224 Kinnear Rd, Columbus, Ohio 43212
- *
- ***************************************************************/
- #include <ncbi_pch.hpp>
- #include <stdio.h>
- #include <gui/widgets/FLU/Flu_DND.h>
- Flu_DND_Event :: Flu_DND_Event()
- {
- _text = _dataType = 0;
- clear();
- }
- Flu_DND_Event :: ~Flu_DND_Event()
- {
- clear();
- }
- void Flu_DND_Event :: clear()
- {
- // reset everything
- objUnderMouse = false;
- dragging = false;
- exit = false;
- if(_text) free(_text); _text = 0;
- if(_dataType) free(_dataType); _dataType = 0;
- _data = 0;
- _grab_x = _grab_y = _drop_x = _drop_y = 0;
- }
- Flu_DND_Event Flu_DND::dndEvent;
- Flu_DND :: Flu_DND( const char *thisType )
- {
- // initialize everything
- nTypes = 0;
- _thisType = strdup( thisType );
- dnd_allow_text( false );
- dnd_callback( 0 );
- allowDragging = allowDropping = true;
- }
- Flu_DND :: ~Flu_DND()
- {
- // free all the stored types
- if( _thisType )
- free( _thisType );
- for( int i = 0; i < nTypes; i++ )
- free( allowedTypes[i] );
- }
- void Flu_DND :: dnd_allow_type( const char *t )
- {
- if( nTypes >= FLU_DND_MAX_TYPES )
- return;
- allowedTypes[nTypes++] = strdup( t );
- }
- bool Flu_DND :: dnd_type_allowed( const char *t ) const
- {
- for( int i = 0; i < nTypes; i++ )
- if( strcmp( allowedTypes[i], t ) == 0 )
- return true;
- return false;
- }
- void Flu_DND :: dnd_grab( void *data, const char *type )
- {
- dndEvent.clear();
- if( !allowDragging || !data )
- return;
- // remember the event
- //printf( "dnd_grab %s %Xn", _thisType, this );
- dndEvent.dragging = true;
- dndEvent.exit = false;
- dndEvent.objUnderMouse = this;
- dndEvent._data = data;
- dndEvent._dataType = strdup( type );
- dndEvent._grab_x = Fl::event_x();
- dndEvent._grab_y = Fl::event_y();
- // start the fltk system-wide DND
- Fl::copy( " ", 1, 0 );
- Fl::dnd();
- }
- void Flu_DND :: on_dnd_enter()
- {
- }
- void Flu_DND :: on_dnd_leave()
- {
- }
- void Flu_DND :: on_dnd_drop( const Flu_DND_Event *e )
- {
- }
- void Flu_DND :: on_dnd_release()
- {
- }
- bool Flu_DND :: on_dnd_drag( int X, int Y )
- {
- return true;
- }
- int Flu_DND :: dnd_handle( int event )
- {
- // if dnd is on, then only DND events are generated
- // but, there appears to be a bug in fltk where an FL_NO_EVENT is generated if the mouse
- // is released when outside of any fltk widget. so, if we detect the NO_EVENT, and we are still
- // dragging, then we need to process it as a release
- if( dndEvent.dragging && event == FL_NO_EVENT )
- {
- if( dndEvent.exit ) // not in any widget
- {
- // trash the event and return
- //printf( "exit %s %Xn", _thisType, this );
- dndEvent.clear();
- return 1;
- }
- // otherwise the NO_EVENT is inside a widget. i don't know why a NO_EVENT is generated
- // since the event is inside a widget. but, whatever. at any rate, this object should process
- // it as a paste, only if it is the object the mouse is over (as tracked by dndEvent.objUnderMouse)
- if( dndEvent.objUnderMouse == this )
- {
- //printf( "FL_NO_EVENT %s %Xn", _thisType, this );
- event = FL_PASTE;
- }
- }
- //printf( "event %d %s %Xn", event, _thisType, this );
- switch( event )
- {
- case FL_DND_DRAG:
- {
- //printf( "FL_DND_DRAG %s %Xn", _thisType, this );
- // if we receive a drag event and we are not holding data, then it must be
- // from an fltk text widget
- // remember where the dragging occurs and check if it's ok for us
- // to drop the item here
- dndEvent.dragging = true;
- dndEvent.objUnderMouse = this;
- dndEvent._drop_x = Fl::event_x();
- dndEvent._drop_y = Fl::event_y();
- return ok2drop();
- }
- case FL_DND_RELEASE:
- //printf( "FL_DND_RELEASE %s %Xn", _thisType, this );
- on_dnd_release();
- return ok2drop();
- case FL_UNFOCUS:
- //printf( "FL_UNFOCUS %s %Xn", _thisType, this );
- return 1;
- case FL_FOCUS:
- //printf( "FL_FOCUS %s %Xn", _thisType, this );
- return 1;
- case FL_DND_ENTER:
- //printf( "FL_DND_ENTER %s %Xn", _thisType, this );
- dndEvent.exit = false;
- dndEvent.objUnderMouse = this;
- dndEvent._drop_x = Fl::event_x();
- dndEvent._drop_y = Fl::event_y();
- if( ok2drop() ) // if it's ok to drop, then it's ok to enter
- {
- on_dnd_enter();
- return 1;
- }
- else
- return 0;
- case FL_DND_LEAVE:
- //printf( "FL_DND_LEAVE %s %Xn", _thisType, this );
- dndEvent.exit = true;
- dndEvent.objUnderMouse = NULL;
- on_dnd_leave();
- return 1;
- case FL_PASTE:
- //printf( "FL_PASTE %s %Xn", _thisType, this );
- on_dnd_release();
- // if the mouse is not inside a DND widget, then there's nothing to do
- if( dndEvent.exit )
- {
- dndEvent.clear();
- return 0;
- }
- //if( dndEvent.objUnderMouse != this )
- //return 0;
- // if there's no data, then this paste is generated from an FLTK text DND event
- if( !dndEvent.data() )
- {
- dndEvent.clear();
- dndEvent._text = strdup( Fl::event_text() );
- }
- dndEvent._drop_x = Fl::event_x();
- dndEvent._drop_y = Fl::event_y();
- // if it's ok to drop, then call the drop processing members
- if( true )
- {
- if( dndCallback )
- dndCallback( &dndEvent, dndCallbackData );
- on_dnd_drop(&dndEvent);
- dndEvent.clear();
- return 1;
- }
- else
- {
- dndEvent.clear();
- return 0;
- }
- default:
- // just in case
- //printf( "event: %dn", event );
- if( dndEvent.exit )
- {
- on_dnd_release();
- dndEvent.clear();
- }
- break;
- }
- return 0;
- }
- bool Flu_DND :: ok2drop()
- {
- if( !allowDropping )
- return false;
- if( dndEvent.data() ) // see if the dnd event is valid
- {
- // check if the source type is allowed by this class
- if( !dnd_type_allowed( dndEvent.data_type() ) )
- return false;
- }
- else if( !allowTextEvents ) // event is a normal FLTK text dnd event
- return false;
- return on_dnd_drag( Fl::event_x(), Fl::event_y() );
- }