guixloop.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 772 行 · 第 1/2 页
C
772 行
/****************************************************************************
*
* 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: WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
* DESCRIBE IT HERE!
*
****************************************************************************/
#include "guiwind.h"
#include "guixutil.h"
#include "uimouse.h"
#include "guiscrol.h"
#include "guixloop.h"
#include "guiwhole.h"
#include "guicontr.h"
#include "guiscale.h"
#include "guifloat.h"
#include "guixkey.h"
#include "guisysme.h"
#include "guixwind.h"
#include "guisize.h"
#include "guismove.h"
#include "guimapky.h"
#include "guixhook.h"
#include "guigadgt.h"
#include "guixinit.h"
#include <stdlib.h>
#include <stdio.h>
/* includes from guixmain.c */
extern gui_window *GUICurrWnd;
/* statics */
static ORD OldCol = -1; /* old column of mouse */
static ORD OldRow = -1; /* old row of mouse */
static gui_window *GUIMouseWnd = NULL;
static enum {
MOUSE_FREE, /* mouse moving not in press-drag sequence */
MOUSE_CLIENT, /* mouse press in client area, no release */
MOUSE_MOVE, /* window being moved by mouse */
MOUSE_SIZE, /* window being resized by mouse */
MOUSE_MAX_START, /* mouse press to start maximize */
MOUSE_MIN_START, /* mouse press to start minimize */
MOUSE_RESTORE_START /* mouse press to start restore */
} MouseState;
EVENT GUIUserEvents[] = {
GUI_FIRST_USER_EVENT, LAST_EVENT,
EV_NO_EVENT,
EV_NO_EVENT
};
static EVENT GUIInternalEvents[] = {
GUI_FIRST_SYS_MENU, GUI_LAST_SYS_MENU,
EV_NO_EVENT,
EV_NO_EVENT
};
static EVENT PrevMouseEvent = EV_NO_EVENT;
static bool MinimizedMoved = FALSE;
static gui_window *ButtonDownSent = NULL;
/*
* SendPointEvent -- send mouse event to use with the point it occured at
*/
static void SendPointEvent( gui_window *wnd, gui_event gui_ev,
gui_coord *point )
{
gui_point pt;
bool down_sent;
down_sent = ButtonDownSent == wnd;
switch( gui_ev ) {
case GUI_LBUTTONDOWN :
case GUI_RBUTTONDOWN :
ButtonDownSent = wnd;
break;
case GUI_LBUTTONUP :
case GUI_RBUTTONUP :
ButtonDownSent = NULL;
break;
default :
break;
}
/* if the mouse event is not on the border, or if it is a mouse up on
* the border
*/
if( down_sent || ( MouseState == MOUSE_CLIENT ) ) {
if( ( wnd->hgadget != NULL ) && !GUI_HSCROLL_EVENTS_SET( wnd ) ) {
point->x += wnd->hgadget->pos;
}
if( ( wnd->vgadget != NULL ) && !GUI_VSCROLL_EVENTS_SET( wnd ) ) {
point->y += wnd->vgadget->pos;
}
GUIMakeRelative( wnd, point, &pt );
GUIEVENTWND( wnd, gui_ev, &pt );
}
}
static bool ValidMaxRestore( gui_window *wnd, ORD wnd_row, ORD wnd_col )
{
return( ( wnd->style & GUI_MAXIMIZE ) &&
GUI_RESIZE_GADGETS_USEABLE( wnd ) &&
( wnd_col >= wnd->screen.area.width-MAXOFFSET-1 ) &&
( wnd_col <= wnd->screen.area.width-MAXOFFSET+1 ) &&
( wnd_row == ( wnd->use.row - 1 ) ) );
}
static bool ValidMin( gui_window *wnd, ORD wnd_row, ORD wnd_col )
{
return( ( wnd->style & GUI_MINIMIZE ) &&
GUI_RESIZE_GADGETS_USEABLE( wnd ) &&
( wnd_col >= wnd->screen.area.width-MINOFFSET-1 ) &&
( wnd_col <= wnd->screen.area.width-MINOFFSET+1 ) &&
( wnd_row == ( wnd->use.row - 1 ) ) );
}
/*
* ProcessMouseReleaseDrag -- take action because mouse was released.
* Also use in the case of drag.
*/
static void ProcessMouseReleaseDrag( EVENT ev, gui_event gui_ev, ORD row,
ORD col )
{
gui_coord point;
ORD wnd_row;
ORD wnd_col;
OldCol = col;
OldRow = row;
if( GUIMouseWnd == NULL ) {
return;
}
wnd_row = row - GUIMouseWnd->screen.area.row;
wnd_col = col - GUIMouseWnd->screen.area.col;
switch( MouseState ) {
case MOUSE_RESTORE_START :
if( ValidMaxRestore( GUIMouseWnd, wnd_row, wnd_col ) &&
( gui_ev == GUI_LBUTTONUP ) ) {
GUIZoomWnd( GUIMouseWnd, GUI_NONE );
}
break;
case MOUSE_MAX_START :
if( ValidMaxRestore( GUIMouseWnd, wnd_row, wnd_col ) &&
( gui_ev == GUI_LBUTTONUP ) ) {
GUIZoomWnd( GUIMouseWnd, GUI_MAXIMIZE );
}
break;
case MOUSE_MIN_START :
if( ValidMin( GUIMouseWnd, wnd_row, wnd_col ) &&
( gui_ev == GUI_LBUTTONUP ) ) {
GUIZoomWnd( GUIMouseWnd, GUI_MINIMIZE );
}
break;
case MOUSE_SIZE:
if( !( GUIMouseWnd->style & GUI_RESIZEABLE ) ) {
return;
}
/* fall through */
case MOUSE_MOVE:
if( ev == EV_MOUSE_RELEASE_R ) {
return;
}
GUIDoMoveResize( GUIMouseWnd, row, col, ev, NULL );
break;
default :
if( GUIMouseWnd != NULL ) {
point.x = (gui_ord)col;
point.y = (gui_ord)row;
SendPointEvent( GUIMouseWnd, gui_ev, &point );
}
}
if( ev == EV_MOUSE_RELEASE || ev == EV_MOUSE_RELEASE_R ) {
MouseState = MOUSE_FREE;
}
}
/*
* ProcessMousePos - if the mouse has move, send the new position and the
* indicated event to the window containing the mouse
*/
static bool ProcessMousePos( gui_event gui_ev, ORD row, ORD col, gui_window * wnd )
{
gui_coord point;
OldCol = col;
OldRow = row;
if( wnd == NULL ) {
return( FALSE );
}
point.x = (gui_ord)col;
point.y = (gui_ord)row;
SendPointEvent( wnd, gui_ev, &point );
return( TRUE );
}
EVENT GUICreatePopup( gui_window *wnd, gui_coord *point )
{
EVENT ev;
point->x -= wnd->screen.area.col;
point->y -= (wnd->screen.area.row - 1);
uipushlist( NULL );
uipushlist( GUIInternalEvents );
uipushlist( GUIUserEvents );
ev = GUICreateMenuPopup( wnd, point, wnd->menu, GUI_TRACK_LEFT, NULL );
uipoplist( /* GUIUserEvents */ );
uipoplist( /* GUIInternalEvents */ );
uipoplist( /* NULL */ );
return( ev );
}
static void ProcessMinimizedMouseEvent( EVENT ev, ORD row, ORD col )
{
gui_coord point;
switch( ev ) {
case EV_MOUSE_PRESS :
if( GUIStartMoveResize( GUIMouseWnd, row, col, RESIZE_NONE ) ) {
MouseState = MOUSE_MOVE;
}
MinimizedMoved = FALSE;
break;
case EV_MOUSE_DRAG :
MinimizedMoved = TRUE;
GUIDoMoveResize( GUIMouseWnd, row, col, ev, NULL );
break;
case EV_MOUSE_RELEASE :
if( MouseState == MOUSE_MOVE ) {
GUIDoMoveResize( GUIMouseWnd, row, col, ev, NULL );
MouseState = MOUSE_FREE;
}
if( !MinimizedMoved ) {
point.x = (gui_ord)col;
point.y = (gui_ord)row;
if( GUICreatePopup( GUICurrWnd, &point ) == EV_MOUSE_DCLICK ) {
GUIZoomWnd( GUICurrWnd, GUI_NONE );
}
}
break;
case EV_MOUSE_DCLICK :
GUIZoomWnd( GUICurrWnd, GUI_NONE );
break;
}
}
/*
* ProcessMousePress -- respond to the press of the mouse
*/
static void ProcessMousePress( EVENT ev, gui_event gui_ev, ORD row, ORD col,
bool new_curr_wnd )
{
gui_coord point;
ORD wnd_row;
ORD wnd_col;
resize_dir dir;
bool use_gadgets;
point.x = (gui_ord)col;
point.y = (gui_ord)row;
OldCol = col;
OldRow = row;
if( GUICurrWnd == NULL ) {
return;
}
dir = RESIZE_NONE;
if( MouseState == MOUSE_SIZE || MouseState == MOUSE_MOVE ) {
return;
}
MouseState = MOUSE_FREE; /* default */
if( !( GUICurrWnd->style & GUI_VISIBLE ) ) {
return;
}
wnd_row = row - GUICurrWnd->screen.area.row;
wnd_col = col - GUICurrWnd->screen.area.col;
if( wnd_row < GUICurrWnd->use.row ) {
use_gadgets = !new_curr_wnd || ( GUIGetWindowStyles() &
( GUI_INACT_GADGETS | GUI_INACT_SAME ) );
if( use_gadgets && GUI_HAS_CLOSER( GUICurrWnd ) &&
( wnd_col >= CLOSER_COL -1 ) && ( wnd_col <= CLOSER_COL+1 ) ) {
if( ( GUICurrWnd->menu != NULL ) && ( ev == EV_MOUSE_PRESS ) ) {
point.x = GUICurrWnd->screen.area.col;
ev = GUICreatePopup( GUICurrWnd, &point );
}
if( (GUICurrWnd->style & GUI_CLOSEABLE) && (ev == EV_MOUSE_DCLICK) ) {
if( GUICloseWnd( GUICurrWnd ) ) {
MouseState = MOUSE_FREE;
}
}
} else if( use_gadgets && ValidMaxRestore( GUICurrWnd, wnd_row, wnd_col ) ) {
if( GUI_WND_MAXIMIZED( GUICurrWnd ) ) {
MouseState = MOUSE_RESTORE_START;
} else {
MouseState = MOUSE_MAX_START;
}
} else if( use_gadgets && ValidMin( GUICurrWnd, wnd_row, wnd_col ) &&
( ev == EV_MOUSE_PRESS ) ) {
MouseState = MOUSE_MIN_START;
} else if( (GUICurrWnd->style & GUI_RESIZEABLE) && (ev == EV_MOUSE_PRESS) &&
( ( wnd_col == 0) || (wnd_col == GUICurrWnd->screen.area.width-1) ) ) {
dir = RESIZE_UP;
} else if( ( ev == EV_MOUSE_DCLICK ) || ( ev == EV_MOUSE_PRESS ) ) {
if( GUIStartMoveResize( GUICurrWnd, row, col, RESIZE_NONE ) ) {
MouseState = MOUSE_MOVE;
}
}
} else if( GUIPtInRect( &GUICurrWnd->use, wnd_row, wnd_col ) ) {
MouseState = MOUSE_CLIENT;
SendPointEvent( GUICurrWnd, gui_ev, &point );
} else if( ( GUICurrWnd->style & GUI_RESIZEABLE ) && ( ev == EV_MOUSE_PRESS ) &&
( wnd_row == GUICurrWnd->screen.area.height-1 ) &&
( ( wnd_col == 0 ) || ( wnd_col == GUICurrWnd->screen.area.width-1 ) ) ) {
dir = RESIZE_DOWN;
}
if( dir != RESIZE_NONE ) {
if( wnd_col == 0 ) {
dir |= RESIZE_LEFT;
} else {
dir |= RESIZE_RIGHT;
}
if( GUIStartMoveResize( GUICurrWnd, row, col, dir ) ) {
MouseState = MOUSE_SIZE;
}
}
GUIMouseWnd = GUICurrWnd;
}
static void ProcessInitPopupEvent( void )
{
MENUITEM menu;
unsigned id;
if( uigetcurrentmenu ( &menu ) ) {
id = (unsigned) menu.event - GUI_FIRST_USER_EVENT;
if ( id ) {
GUIEVENTWND( GUICurrWnd, GUI_INITMENUPOPUP, &id );
}
}
}
static void ProcessScrollEvent( EVENT ev )
{
gui_event gui_ev;
p_gadget gadget;
int diff;
bool events;
gui_event notify;
switch( ev ) {
case EV_SCROLL_UP :
events = GUICurrWnd->style & GUI_VSCROLL_EVENTS;
gui_ev = GUI_SCROLL_UP;
diff = -1;
gadget = GUICurrWnd->vgadget;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?