mouse.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,373 行 · 第 1/3 页
C
1,373 行
/****************************************************************************
*
* Open Watcom Project
*
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
* ========================================================================
*
* This file contains Original Code and/or Modifications of Original
* Code as defined in and that are subject to the Sybase Open Watcom
* Public License version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
* provided with the Original Code and Modifications, and is also
* available at www.sybase.com/developer/opensource.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
* NON-INFRINGEMENT. Please see the License for the specific language
* governing rights and limitations under the License.
*
* ========================================================================
*
* Description: Routines to handle the mouse interactions.
*
****************************************************************************/
#include "limits.h"
#include "windows.h"
#include "fmedit.def"
#include "object.def"
#include "state.def"
#include "currobj.def"
#include "grid.def"
#include "list.def"
#include "align.def"
#include "dlist.def"
#include "clip.def"
#include "mouse.def"
/* forward references */
// mouse press actions
static void ActionBegin( POINT, WORD, OBJPTR );
static void ResizeBegin( POINT, WORD, OBJPTR );
static void BeginPaste( POINT, WORD, OBJPTR );
static void ResetEdit( POINT, WORD, OBJPTR );
static void IgnoreMousePress( POINT, WORD, OBJPTR );
static void UnexpectedPressStateRecover( POINT, WORD, OBJPTR );
// mouse move and release actions
static void CheckMousePosn( POINT );
static void DoObjectMove( POINT );
static void DoObjectResize( POINT );
static void DoObjectRecreate( POINT );
static void UnexpectedStateRecover( POINT );
static void BeginMove( POINT );
static void MovePendingBegin( BOOL, OBJPTR );
static void DoPasteMove( POINT );
static void DoSelectRecreate( POINT );
static void IgnoreMouse( POINT );
static void FinishMove( POINT );
static void FinishResize( POINT );
static void FinishCreate( POINT );
static void FinishPaste( POINT );
static void FinishSelect( POINT );
static void FinishMovePending( POINT );
static void FinishActionAborted( POINT pt );
static DLIST * OrderList( LIST * );
static DLIST_ELT GetNextElement( DLIST * );
static void (*MousePressActions[])( POINT, WORD, OBJPTR ) = {
ActionBegin /* DORMANT */
, ResizeBegin /* OVERBOX */
, UnexpectedPressStateRecover /* MOVING */
, ResetEdit /* EDITING */
, UnexpectedPressStateRecover /* SIZING */
, UnexpectedPressStateRecover /* CREATING */
, UnexpectedPressStateRecover /* ALIGNING */
, BeginPaste /* PASTE_PENDING */
, UnexpectedPressStateRecover /* PASTEING */
, UnexpectedPressStateRecover /* SELECTING */
, UnexpectedPressStateRecover /* MOVE_PENDING */
, UnexpectedPressStateRecover /* ACTION_ABORTED */
, IgnoreMousePress /* KBD_MOVING */
};
static void (*MouseMoveActions[])( POINT ) = {
CheckMousePosn /* DORMANT */
, CheckMousePosn /* OVERBOX */
, DoObjectMove /* MOVING */
, CheckMousePosn /* EDITING */
, DoObjectResize /* SIZING */
, DoObjectRecreate /* CREATING */
, UnexpectedStateRecover /* ALIGNING */
, UnexpectedStateRecover /* PASTE_PENDING */
, DoPasteMove /* PASTEING */
, DoSelectRecreate /* SELECTING */
, BeginMove /* MOVE_PENDING */
, IgnoreMouse /* ACTION_ABORTED */
, IgnoreMouse /* KBD_MOVING */
};
static void (*MouseReleaseActions[])( POINT ) = {
UnexpectedStateRecover /* DORMANT */
, UnexpectedStateRecover /* OVERBOX */
, FinishMove /* MOVING */
, IgnoreMouse /* EDITING */
, FinishResize /* SIZING */
, FinishCreate /* CREATING */
, UnexpectedStateRecover /* ALIGNING */
, UnexpectedStateRecover /* PASTE_PENDING */
, FinishPaste /* PASTEING */
, FinishSelect /* SELECTING */
, FinishMovePending /* MOVE_PENDING */
, FinishActionAborted /* ACTION_ABORTED */
, IgnoreMouse /* KBD_MOVING */
};
extern void ProcessDBLCLK( POINT point )
/**************************************/
/* Process a double click on the current object. This implies a request
* to define/redefine the characteristics of the object.
*/
{
POINT pt;
OBJPTR currobj;
pt = point;
currobj = GetPrimaryObject();
if( currobj != NULL ) {
Define( currobj, &pt, NULL );
}
}
static void ResizeBegin( POINT pt, WORD ks, OBJPTR d )
/****************************************************/
/* Begin a resizing operation */
{
OBJPTR object;
RECT rect;
RECT offrect;
NOTE_ID noteid;
POINT rgrid;
pt = pt; /* ref'd to avoid warning */
ks = ks; /* ref'd to avoid warning */
d = d;
SetDefState();
object = GetPrimaryObject();
if( object != NULL ) {
if( GetState() == EDITING ) {
noteid = TERMINATE_EDIT;
Notify( object, noteid, NULL );
}
SetDefState();
if( !ValidateAction( object, RESIZE, NULL ) ) {
return;
}
SetState( SIZING );
Location( object, &rect );
rgrid.x = GetHorizontalInc();
rgrid.y = GetVerticalInc();
ResizeIncrements( object, &rgrid );
SetResizeGrid( rgrid.x, rgrid.y );
SaveObject();
object = GetObjptr( object );
ResetCurrObject( FALSE );
object = Create( O_EATOM, object, &rect, NULL );
SetCurrObject( object );
offrect = rect;
if( SnapRectToGrid( &offrect ) ) {
offrect.top -= rect.top;
offrect.left -= rect.left;
offrect.right -= rect.right;
offrect.bottom -= rect.bottom;
Resize( object, &offrect, TRUE );
}
}
}
static void ResetEdit( POINT pt, WORD keystate, OBJPTR d )
/********************************************************/
/* Reset the previous editing operation and proceed with the default
* action for a mouse press.
*/
{
NOTE_ID noteid;
OBJPTR currobj;
d = d;
noteid = TERMINATE_EDIT;
currobj = GetECurrObject();
if( currobj != NULL ) {
Notify( currobj, noteid, NULL );
}
SetBaseState( DORMANT );
SetDefState();
MousePressActions[GetState()]( pt, keystate, NULL );
}
static void UnexpectedStateRecover( POINT pt )
/********************************************/
/* A mouse press was received in a state where it should be impossible to
* get a mouse press. Ignore it.
*/
{
pt = pt; /* ref'd to avoid warning */
#ifdef DEBUG_ON
MessageBox( GFileIO.hWnd, ( LPSTR ) "State Error",
NULL, MB_OK | MB_ICONSTOP );
#endif
}
static void UnexpectedPressStateRecover( POINT pt, WORD ks, OBJPTR d )
/********************************************************************/
/* A mouse press was received in a state where it should be impossible to
* get a mouse press. Ignore it.
*/
{
pt = pt; /* ref'd to avoid warning */
ks = ks; /* ref'd to avoid warning */
d = d; /* ref'd to avoid warning */
#ifdef DEBUG_ON
MessageBox( GFileIO.hWnd, ( LPSTR ) "State Error",
NULL, MB_OK | MB_ICONSTOP );
#endif
}
static void CreateBegin( POINT pt, OBJPTR parent )
/*********************************************/
/* begin the creation of a new object */
{
RECT origin;
SetState( CREATING );
SnapPointToGrid( &pt );
origin.top = pt.y;
origin.bottom = pt.y;
origin.left = pt.x;
origin.right = pt.x;
SaveObject();
ResetCurrObject( FALSE );
SetCurrObject( Create( O_EATOM, parent, &origin, NULL ) );
}
static void MovePendingBegin( BOOL keystate, OBJPTR object )
/**********************************************************/
/* begin a move operation */
{
/* If the object the mouse press was on is not in the current object list
* then, if mulitple select, add it to the list, otherwise, make it the
* current object */
if( GetCurrObjptr( object ) == NULL ) {
if( !(keystate & MK_SHIFT) && !(keystate & MK_CONTROL) ) {
ResetCurrObject( FALSE );
}
AddCurrObject( object );
/* Remove the Control flag so that the added selection isn't removed
* on the Mouse UP of thhe state stays the same as MOVE_PENDING
*/
keystate &= ~MK_CONTROL;
} else {
SetPrimaryObject( GetCurrObjptr( object ) );
}
SetKeyState( keystate);
SetState( MOVE_PENDING );
}
extern BOOL CheckMoveOperation( LIST ** objlist )
/***********************************************/
{
LIST * clist;
OBJPTR obj;
RECT rect;
POINT pt;
*objlist = GetCurrObjectList();
for( clist = *objlist; clist != NULL; clist = ListNext( clist ) ) {
obj = ListElement( clist );
Location( obj, &rect );
pt.x = rect.left;
pt.y = rect.top;
if( !ValidateAction( obj, MOVE, &pt ) ) {
SetPrimaryObject( GetCurrObjptr( obj ) );
MessageBox( GetAppWnd(), "The current selected object cannot be moved.",
NULL, MB_ICONEXCLAMATION | MB_OK );
ListFree( *objlist );
*objlist = NULL;
return( FALSE );
}
}
return( TRUE );
}
static void BeginMove( POINT p )
/******************************/
/* Begin the movement operation */
{
LIST * movelist;
if( CheckMoveOperation( &movelist ) ) {
SetState( MOVING );
BeginMoveOperation( movelist );
ListFree( movelist );
} else {
SetState( DORMANT );
}
SetPrevMouse( p );
}
static void SelectBegin( POINT pt, WORD keystate )
/************************************************/
{
RECT origin;
origin.top = pt.y;
origin.bottom = pt.y;
origin.left = pt.x;
origin.right = pt.x;
SaveObject();
SetKeyState( keystate );
SetState( SELECTING );
SetSelectEatom( Create( O_EATOM, NULL, &origin, NULL ) );
}
static BOOL InVicinity( OBJPTR * obj, short y, short x )
/******************************************************/
/* See if we're in the vicinity of an object that can be moved */
{
POINT pt;
OBJPTR closeobj;
pt.x = x;
pt.y = y;
closeobj = FindOneObjPt( pt );
if( (closeobj == *obj) || !ValidateAction( closeobj, MOVE, &pt ) ) {
return( FALSE );
} else {
*obj = closeobj;
}
return( TRUE );
}
static BOOL IsMoveOperation( OBJPTR obj, POINT point, WORD keystate )
/*******************************************************************/
{
BOOL ret;
ret = FALSE;
if( ValidateAction( obj, MOVE, &point ) ||
InVicinity( &obj, point.y - OBJ_VICINITY, point.x ) ||
InVicinity( &obj, point.y + OBJ_VICINITY, point.x ) ||
InVicinity( &obj, point.y, point.x - OBJ_VICINITY ) ||
InVicinity( &obj, point.y, point.x + OBJ_VICINITY ) )
{
MovePendingBegin( keystate, obj );
ret = TRUE;
}
return( ret );
}
static void ActionBegin( POINT point, WORD keystate, OBJPTR obj )
/***************************************************************/
/* begin a create or move action depending on the button pressed */
{
if( obj == NULL ) {
obj = FindOneObjPt( point );
}
if( GetBaseObjType() != O_NONE ) {
CreateBegin( point, obj );
} else if( !IsMoveOperation( obj, point, keystate ) ) {
SelectBegin( point, keystate );
}
}
extern void ProcessButtonDown( POINT point, WORD keystate, OBJPTR obj )
/**********************************************************************/
/* responds to a button down message from the mouse */
{
STATE_ID st;
st = GetState();
if( st != PASTE_PENDING ) {
SetCapture( GetAppWnd() );
}
MousePressActions[st]( point, keystate, obj );
SetPrevMouse( point );
}
static void FinishMove( POINT pt )
/********************************/
/* Finish the movement operation */
{
pt = pt;
FinishMoveOperation( TRUE );
}
static void IgnoreMouse( POINT pt )
/*********************************/
/* Ignore a mouse action */
{
pt = pt; /* ref'd to avoid warning */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?