mouse.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,373 行 · 第 1/3 页
C
1,373 行
} /* CompareRect */
static OBJPTR FindBSelectRoot( LPRECT rect )
/******************************************/
{
RECT obj_loc;
OBJPTR root;
OBJPTR obj;
LIST * list; // children of root
SUBOBJ_REQUEST req;
compare_rect_rc rc;
BOOL done;
root = GetMainObject();
req.a.ty = ALL;
done = FALSE;
while( !done ) {
list = NULL;
FindObjList( root, &req, &list );
for( ; list != NULL; list = ListConsume( list ) ) {
/* check each child for containment */
obj = ListElement( list );
Location( obj, &obj_loc );
rc = CompareRect( rect, &obj_loc );
if( rc == RECT_A_IN_B || rc == RECT_EQUAL ) {
/* we have containment in one of the children so set the */
/* root to that child and start over */
root = obj;
/**/ break;
}
}
if( list == NULL ) {
/* we made it down the list without finding further containment */
done = TRUE;
} else {
ListFree( list );
}
}
return( root );
} /* FindBSelectRoot */
static void FindBSelectChildren( OBJPTR root, LIST ** child, LIST ** gchild )
/***************************************************************************/
/* find the children and grand children of root */
{
SUBOBJ_REQUEST req;
LIST * curr;
LIST * new_gchild;
req.a.ty = ALL;
*child = NULL;
*gchild = NULL;
FindObjList( root, &req, child );
for( curr = *child; curr != NULL; curr = ListNext( curr ) ) {
new_gchild = NULL;
FindObjList( ListElement( curr ), &req, &new_gchild );
ListMerge( gchild, new_gchild );
}
} /* FindBSelectChildren */
static BOOL BuildBSelectList( LPRECT rect, LIST * child, LIST ** sel )
/********************************************************************/
/* returns TRUE if at least one of the objects in sel was contained */
{
BOOL contained;
RECT obj_loc;
LIST * curr;
OBJPTR currobj;
*sel = NULL;
contained = FALSE;
for( curr = child; curr != NULL; curr = ListNext( curr ) ) {
currobj = ListElement( curr );
Location( currobj, &obj_loc );
switch( CompareRect( rect, &obj_loc ) ) {
case RECT_EQUAL:
case RECT_B_IN_A:
contained = TRUE;
/* fall through */
case RECT_A_IN_B:
case RECT_INTERSECT:
ListAddElt( sel, currobj );
break;
}
}
return( contained );
} /* BuildBSelectList */
static void BandedSelect( LPRECT rect )
/*************************************/
/* Banded selection is done by finding the lowest level object that fully */
/* contains the selection rect and calling that the root. The objects that */
/* may be select are either children of the root or grandchildren of the root */
/* which intersect with the rect. Preference is given to which ever of the two*/
/* sets contains an object which is fully contained in rect with ties going */
/* to the child set. */
{
OBJPTR root;
LIST * child; // children of root
LIST * gchild; // grandchildren of root
LIST * child_sel;
LIST * gchild_sel;
LIST * sel_list;
BOOL child_cont; // some children were fully contained in rect
BOOL gchild_cont; // some gchildren were fully contained in rect
OBJPTR currobj;
CURROBJPTR currptr;
root = FindBSelectRoot( rect );
FindBSelectChildren( root, &child, &gchild );
/* if the root has no children try one level up so that, if possible, */
/* something will be select on a banded select */
if( ListCount( child ) == 0 ) {
GetObjectParent( root, &root );
if( root == NULL ) {
/* this can happen if root was the main object */
return;
}
FindBSelectChildren( root, &child, &gchild );
}
child_cont = BuildBSelectList( rect, child, &child_sel );
gchild_cont = BuildBSelectList( rect, gchild, &gchild_sel );
/* use the intersecting children if either any of them were fully */
/* contained in rect or if no grandchildren were fully contained */
if( child_cont || !gchild_cont ) {
sel_list = child_sel;
} else {
sel_list = gchild_sel;
}
/* select the objects if there are any */
if( sel_list != NULL ) {
if( !GetShift() ) {
ResetCurrObject( FALSE );
}
StartCurrObjMod();
for( ; sel_list != NULL; sel_list = ListNext( sel_list ) ) {
currobj = ListElement( sel_list );
currptr = GetCurrObjptr( currobj );
if( currptr == NULL ) {
AddCurrObject( currobj );
} else {
/* Object already in list, just make it primary */
SetPrimaryObject( currptr );
}
}
EndCurrObjMod();
}
if( child != NULL ) ListFree( child );
if( gchild != NULL ) ListFree( gchild );
if( child_sel != NULL ) ListFree( child_sel );
if( gchild_sel != NULL ) ListFree( gchild_sel );
} /* BandedSelect */
static void FinishSelect( POINT fin_pt )
/**************************************/
/* Finish the select operation */
{
OBJPTR eatom;
RECT rect;
POINT pt;
fin_pt = fin_pt;
eatom = GetSelectEatom();
if( eatom != NULL ) {
GetAnchor( eatom, &pt );
Location( eatom, &rect );
Destroy( eatom, FALSE );
SetSelectEatom( NULL );
if( IsRectEmpty( &rect ) ) {
PointSelect( pt );
} else {
BandedSelect( &rect );
}
}
SetDefState();
}
static void FinishMovePending( POINT pt )
/***************************************/
/* Leave the MovePending state because mouse up happened before a move */
{
OBJPTR obj;
SetDefState();
if( GetControl() ) {
obj = FindOneObjPt( pt );
DeleteCurrObjptr( obj );
}
MarkCurrObject();
}
extern void FinishMoveOperation( BOOL change_state )
/**************************************************/
/* Finish the move operation */
{
CURROBJPTR currobj;
LIST * mycurrobjlist;
LIST * clist;
DLIST * movedlist;
BOOL success;
OBJPTR eatom;
OBJPTR obj;
OBJPTR primary;
DLIST * dlist;
DLIST_ELT elt;
DLIST * newmovedlist;
RECT rect;
if( change_state ) SetState( MOVING );
primary = GetObjptr( GetCurrObject() );
mycurrobjlist = GetCurrObjectList();
for( clist = mycurrobjlist; clist != NULL; clist = ListNext( clist ) ) {
RemoveFromParent( ListElement( clist ) );
}
SetShowError( FALSE ); /* Don't want error message in the middle of
multiple moves - paint won't work properly */
success = TRUE; /* Flag to indicate whether or not any move failed */
movedlist = NULL; /* List of objects that have been moved */
dlist = OrderList( mycurrobjlist );
/* Move all objects until done or a move fails. Move in correct order */
while( dlist != NULL ) {
elt = GetNextElement( dlist );
success = Register( elt.original );
if( success ) {
DListRemoveElt( &dlist, elt );
DListAddElt( &movedlist, elt );
} else {
break;
}
}
/* If a move failed, first remove all objects from their parents and
* then undo all moves that already happened, including the
* one that failed. Use the correct order.
*/
if( !success ) {
newmovedlist = DListCopy( movedlist );
while( newmovedlist != NULL ) {
elt = GetNextElement( newmovedlist );
RemoveFromParent( elt.original );
DListRemoveElt( &newmovedlist, elt );
}
while( movedlist != NULL ) {
elt = GetNextElement( movedlist );
UndoMove( elt.original );
DListRemoveElt( &movedlist, elt );
}
}
/* Notify all objects that the move operation is done */
obj = GetECurrObject();
while( obj != NULL ) {
Notify( obj, MOVE_END, NULL );
obj = GetNextECurrObject( obj );
}
/* Register all of the objects that got removed from the parent but
* never got moved or moved back. Use correct order.
*/
ResetCurrObject( FALSE );
while( dlist != NULL ) {
elt = DListElement( dlist );
eatom = elt.original;
obj = GetObjptr( eatom );
Location( eatom, &rect );
MarkInvalid( &rect );
Register( obj );
DListRemoveElt( &dlist, elt );
}
StartCurrObjMod();
for( clist = mycurrobjlist; clist != NULL; clist = ListConsume( clist ) ) {
obj = ListElement( clist );
AddCurrObject( GetObjptr( obj ) );
Destroy( obj, FALSE );
}
DListFree( movedlist );
DListFree( dlist );
/* Set correct object to be primary */
if( primary != NULL ) {
currobj = GetCurrObjptr( primary );
if( currobj != NULL ) {
SetPrimaryObject( currobj );
}
}
EndCurrObjMod();
SetShowError( TRUE ); /* Set flag saying it's okay to show errors now */
if( change_state ) SetDefState();
/* Any error shown will cause repainting, so be sure */
/* that we repaint the current object markers */
UpdateWindow( GetAppWnd() );
ReportPending(); /* Report any pending errors */
}
static DLIST * OrderList( LIST * list )
/*************************************/
/* Return a DLIST that has an element for each element in list (in original)
* and that object's priority in copy.
*/
{
DLIST * dlist;
DLIST_ELT elt;
CURROBJPTR currobj;
int priority;
OBJPTR obj;
LIST * mylist;
mylist = list;
dlist = NULL;
while( mylist != NULL ) {
currobj = ListElement( mylist );
elt.original = currobj;
mylist = ListNext( mylist );
elt.copy = 0;
obj = GetObjptr( currobj );
GetPriority( obj, &priority );
elt.copy = ( OBJPTR ) priority;
DListAddElt( &dlist, elt );
}
return( dlist );
}
static DLIST_ELT GetNextElement( DLIST * dlist )
/***********************************************/
/* Return the lowest priority element in the list */
{
DLIST_ELT elt;
DLIST_ELT curr;
DLIST * mydlist;
elt.original = NULL;
elt.copy = NULL;
mydlist = dlist;
if( mydlist == NULL ) {
return( elt );
} else {
curr = DListElement( mydlist );
mydlist = DListNext( mydlist );
}
while( mydlist != NULL ) {
elt = DListElement( mydlist );
if( elt.copy < curr.copy ) {
curr.copy = elt.copy;
curr.original = elt.original;
}
mydlist = DListNext( mydlist );
}
return( curr );
}
extern void BeginMoveOperation( LIST * mycurrobjlist )
/****************************************************/
/* Prepare for the move operation */
{
POINT init;
OBJPTR eatom;
OBJPTR currobj;
RECT rect;
OBJPTR primary;
/* Remember the primary object so that it's eatom can be set to primary */
primary = GetCurrObject();
ResetCurrObject( FALSE );
currobj = ListElement( mycurrobjlist );
StartCurrObjMod();
while( currobj != NULL ) {
Location( currobj, &rect );
eatom = Create( O_EATOM, currobj, &rect, NULL );
AddCurrObject( eatom );
/* Remember eatom if this is the eatom for the primary object */
if( currobj == primary ) {
primary = GetPrimaryObject();
}
init.x = rect.left;
init.y = rect.top;
SnapPointToGrid( &init );
init.x -= rect.left;
init.y -= rect.top;
if( (init.x != 0) || (init.y != 0) ) {
Move( eatom, &init, TRUE );
}
mycurrobjlist = ListNext( mycurrobjlist );
if( mycurrobjlist != NULL ) {
currobj = ListElement( mycurrobjlist );
} else {
currobj = NULL;
}
}
/* Set correct eatom to be primary */
if( primary != NULL ) {
SetPrimaryObject( primary );
}
EndCurrObjMod();
/* notify the objects of the move start */
currobj = GetECurrObject();
while( currobj != NULL ) {
Notify( currobj, MOVE_START, NULL );
currobj = GetNextECurrObject( currobj );
}
} /* BeginMoveOperation */
extern void AbortMoveOperation( void )
/************************************/
{
LIST * objlist;
OBJPTR obj;
OBJPTR eatom;
OBJPTR currobj;
OBJPTR primary;
objlist = GetCurrObjectList();
primary = GetObjptr( GetCurrObject() );
/* Notify all objects that the move operation is done */
obj = GetECurrObject();
while( obj != NULL ) {
Notify( obj, MOVE_END, NULL );
obj = GetNextECurrObject( obj );
}
ResetCurrObject( FALSE );
StartCurrObjMod();
for( ; objlist != NULL; objlist = ListConsume( objlist ) ) {
eatom = ListElement( objlist );
currobj = GetObjptr( eatom );
AddCurrObject( currobj );
Destroy( eatom, FALSE );
}
/* Set correct object to be primary */
if( primary != NULL ) {
currobj = GetCurrObjptr( primary );
if( currobj != NULL ) {
SetPrimaryObject( currobj );
}
}
EndCurrObjMod();
} /* AbortMoveOperation */
static void FinishActionAborted( POINT pt )
/***************************************/
{
pt = pt;
SetState( DORMANT );
} /* FinishActionAborted */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?