guisize.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 700 行 · 第 1/2 页

C
700
字号
/****************************************************************************
*
*                            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 "guiwhole.h"
#include "guiscale.h"
#include "guicontr.h"
#include "guixutil.h"
#include "guisysme.h"
#include "guisize.h"
#include "guigadgt.h"
#include "guistat.h"
#include "guixdlg.h"
#include <stdio.h>
#include <string.h>

static void UnMinimize( gui_window *wnd )
{
    gui_window  *child;

    uivsetactive( &wnd->screen );
    if( wnd->flags & NEEDS_RESIZE_REDRAW ) {
        GUIWndDirty( wnd );
    }
    for( child = wnd->child; child != NULL; child = child->sibling ) {
        uivshow( &child->screen );
        child->screen.open = TRUE;
        uivsetactive( &child->screen );
    }
}

static void RedrawResize( gui_window *wnd, SAREA *old )
{
    if( ( ( wnd->use.width > old->width )  &&
          ( wnd->use.height > old->height ) ) || GUI_WND_MINIMIZED( wnd ) ) {
        GUIWholeWndDirty( wnd );
    } else {
        if( wnd->flags & NEEDS_RESIZE_REDRAW ) {
            if( wnd->use.width > old->width ) {
                COPYAREA( wnd->use, wnd->dirty );
                wnd->dirty.col += old->width;
                wnd->dirty.width = wnd->use.width - old->width;
            }
            if( wnd->use.height > old->height ) {
                COPYAREA( wnd->use, wnd->dirty );
                wnd->dirty.row += old->height;
                wnd->dirty.height = wnd->use.height - old->height;
            }
        }
        if( !EMPTY_AREA( wnd->dirty ) ) {
            wnd->flags |= CONTENTS_INVALID;
        }
        GUIWndUpdate( wnd );
    }
}

static void CheckChildResize( SAREA *child, SAREA *area, resize_dir dir )
{
    int diff;

    if( dir & RESIZE_RIGHT ) {
        if( ( area->col + area->width ) < ( child->col + child->width ) ) {
            area->width = child->col - area->col + child->width;
        }
    } else {
        if( dir & RESIZE_LEFT ) {
            diff = 0;
            if( area->col > child->col ) {
                diff = area->col - child->col;
            }
            area->width += diff;
            area->col -= diff;
        }
    }
    if( dir & RESIZE_DOWN ) {
        if( ( area->row + area->height ) < ( child->row + child->height ) ) {
            area->height = child->row - area->row + child->height;
        }
    } else {
        if( dir & RESIZE_UP ) {
            diff = 0;
            if( area->row > child->row ) {
                diff = area->row - child->row;
            }
            area->height += diff;
            area->row -= diff;
        }
    }
}

void GUISetCheckResizeAreaForChildren( gui_window *wnd, bool check )
{
    if( wnd ) {
        if( check ) {
            wnd->flags |= CHECK_CHILDREN_ON_RESIZE;
        } else {
            wnd->flags &= ~CHECK_CHILDREN_ON_RESIZE;
        }
    }
}

void GUICheckResizeAreaForChildren( gui_window *wnd, SAREA *area,
                                    resize_dir dir )
{
    gui_window  *child_wnd;
    SAREA       *child;
    SAREA       use;
    SAREA       old_use;

    if( ( wnd->flags & CHECK_CHILDREN_ON_RESIZE ) == 0 ) {
        return;
    }

    GUISetUseArea( wnd, area, &use );
    use.row += wnd->screen.area.row;
    use.col += wnd->screen.area.col;
    COPYAREA( use, old_use );
    for( child_wnd = wnd->child; child_wnd != NULL; child_wnd = child_wnd->sibling ) {
        child = &child_wnd->screen.area;
        CheckChildResize( child, &use, dir );
    }
    if( use.row != old_use.row ) {
        area->row += ( use.row - old_use.row );
    }
    if( use.col != old_use.col ) {
        area->col += ( use.col - old_use.col );
    }
    if( use.width != old_use.width ) {
        area->width += ( use.width - old_use.width );
    }
    if( use.height != old_use.height ) {
        area->height += ( use.height - old_use.height );
    }
}

void GUICheckResizeAreaForParent( gui_window *wnd, SAREA *area,
                                  resize_dir dir )
{
    SAREA       parent;
    int         diff;

    if( wnd->parent != NULL ) {
        COPYAREA( wnd->parent->use, parent );
        parent.row += wnd->parent->screen.area.row;
        parent.col += wnd->parent->screen.area.col;
        if( dir & RESIZE_RIGHT ) {
            if( ( area->col + area->width ) > ( parent.col + parent.width ) ) {
                area->width = parent.col + parent.width - area->col;
            }
        } else {
            if( dir & RESIZE_LEFT ) {
                diff = 0;
                if( area->col < parent.col ) {
                    diff = parent.col - area->col;
                }
                area->col += diff;
                area->width -= diff;
            }
        }
        if( dir & RESIZE_DOWN ) {
            if( ( area->row + area->height ) > ( parent.row + parent.height ) ) {
                area->height = parent.row + parent.height - area->row;
            }
        } else {
            if( dir & RESIZE_UP ) {
                diff = 0;
                if( area->row < parent.row ) {
                    diff = parent.row - area->row;
                }
                area->row += diff;
                area->height -= diff;
            }
        }
    }
}

static void ResizeGadget( p_gadget gadget, ORD length, ORD anchor,
                          bool set_range )
{
    GUIInitGadget( gadget, gadget->start, length, anchor );
    if( !set_range ) {
        gadget->total_size = length - 1 + gadget->pos;
    }
    GUISetShowGadget( gadget, TRUE, TRUE, gadget->pos );
}

/*
 * SizeWnd -- resize the windows to the new width and height if it's vaild
 *            to do so
 */

static bool SizeWnd( gui_window *wnd, SAREA *area, gui_flags flag,
                     resize_dir dir )
{
    SAREA       new;
    gui_coord   newsize;
    SAREA       save;
    gui_window  *child;
    bool        was_minimized;
    int         row_diff;
    int         col_diff;

    COPYAREA( *area, new )
    COPYAREA( wnd->use, save );
    if( flag != MINIMIZED ) {
        GUICheckResizeAreaForChildren( wnd, &new, dir );
    }
    GUICheckResizeAreaForParent( wnd, &new, dir );
    row_diff = new.row - wnd->screen.area.row;
    col_diff = new.col - wnd->screen.area.col;
    if( uivresize( &wnd->screen, new ) == NULL ) {
        return( FALSE );
    }
    GUISetUseWnd( wnd );
    GUIResizeControls( wnd, row_diff, col_diff );
    if( GUIHasStatus( wnd ) ) {
        GUIResizeStatus( wnd );
    }
    if( wnd->hgadget != NULL ) {
        ResizeGadget( wnd->hgadget, wnd->use.width, wnd->use.height,
                      GUI_HRANGE_SET( wnd ) );
    }
    if( wnd->vgadget != NULL ) {
        ResizeGadget( wnd->vgadget, wnd->use.height, wnd->use.width,
                      GUI_VRANGE_SET( wnd ) );
    }
    if( GUI_WND_MAXIMIZED( wnd ) ) {
        wnd->flags &= ~MAXIMIZED;
    }
    was_minimized = GUI_WND_MINIMIZED( wnd );
    if( was_minimized ) {
        wnd->flags &= ~MINIMIZED;
    }
    wnd->flags |= flag;
    wnd->flags |= DONT_SEND_PAINT+NEEDS_RESIZE_REDRAW;
    if( was_minimized ) {
        uivsetactive( &wnd->screen );
        GUIWholeWndDirty( wnd );
    } else {
        wnd->flags |= NON_CLIENT_INVALID;
        RedrawResize( wnd, &save );
    }
    wnd->flags |= NEEDS_RESIZE_REDRAW;
    wnd->flags &= ~DONT_SEND_PAINT;
    if( flag != MINIMIZED ) {
        newsize.x = wnd->use.width;
        newsize.y = wnd->use.height;
        GUIScreenToScaleR( &newsize );
        GUIEVENTWND( wnd, GUI_RESIZE, &newsize );
    }
    if( was_minimized ) {
        UnMinimize( wnd );
    } else {
        if( flag == MINIMIZED ) {
            for( child = wnd->child; child != NULL; child = child->sibling ) {
                uivhide( &child->screen );
                child->screen.open = FALSE;
            }
        }
        RedrawResize( wnd, &save );
    }
    wnd->flags &= ~NEEDS_RESIZE_REDRAW;
    GUISetCursor( wnd );
    GUIDrawStatus( wnd );
    return( TRUE );
}

void GUICheckMove( gui_window *wnd, int *row_diff, int *col_diff )
{
    SAREA       parent;

    if( wnd->parent != NULL ) {
        COPYAREA( wnd->parent->use, parent );
        parent.row += wnd->parent->screen.area.row;
        parent.col += wnd->parent->screen.area.col;
        if( ( wnd->screen.area.row + *row_diff + wnd->screen.area.height ) >
            ( parent.row + parent.height ) ) {
            *row_diff = parent.row + parent.height -
                       wnd->screen.area.row - wnd->screen.area.height;
        }
        if( ( wnd->screen.area.col + *col_diff + wnd->screen.area.width ) >
            ( parent.col + parent.width ) ) {
            *col_diff = parent.col + parent.width -
                       wnd->screen.area.col - wnd->screen.area.width;
        }
        if( ( wnd->screen.area.row + *row_diff ) < parent.row ) {
            *row_diff = parent.row - wnd->screen.area.row;
        }
        if( ( wnd->screen.area.col + *col_diff ) < parent.col ) {
            *col_diff = parent.col - wnd->screen.area.col;
        }
    }
}

static void MoveWnd( gui_window *wnd, int row_diff, int col_diff )
{
    gui_window  *curr;

    GUICheckMove( wnd, &row_diff, &col_diff );
    uivmove( &wnd->screen, (ORD)( row_diff + (int)wnd->screen.area.row),
             (ORD)(col_diff + (int)wnd->screen.area.col ) );
    GUISetUseWnd( wnd );
    GUIEVENTWND( wnd, GUI_MOVE, NULL );
    if( !GUI_WND_MINIMIZED( wnd ) ) {
        /* don't move children if parent is minimized */
        for( curr = wnd->child; curr != NULL; curr = curr->sibling ) {
            MoveWnd( curr, row_diff, col_diff );
        }
        GUIResizeControls( wnd, row_diff, col_diff );
    }
}

void GUICheckArea( SAREA *area, resize_dir dir )
{
    SAREA       screen;
    int         diff;

    GUIGetScreenArea( &screen );

    if( area->row < screen.row ) {
        diff = screen.row - area->row;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?