guixdlg.c

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

C
951
字号
/****************************************************************************
*
*                            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:  Dialog box low level routines.
*
****************************************************************************/


#include "guiwind.h"
#include "guicontr.h"
#include "guixmain.h"
#include "guixwind.h"
#include "guilistb.h"
#include "guixdlg.h"
#include "guicolor.h"
#include "guihotsp.h"
#include "guixedit.h"
#include "guiutil.h"
#include "guixutil.h"
#include "guistr.h"
#include "guikey.h"
#include <stdio.h>
#include <string.h>

#define GETID( ev ) ( ev - GUI_FIRST_USER_EVENT )

extern EVENT GUIUserEvents[];

static a_radio_group * RadioGroup = NULL;
static bool Group = FALSE;

static EVENT DlgEvents[] = {
    EV_NO_EVENT,
    EV_ESCAPE,
    EV_NO_EVENT,
};

static EVENT ControlEvents[] = {
    EV_NO_EVENT,
    EV_LIST_BOX_CHANGED,
    EV_LIST_BOX_DCLICK,
    EV_LIST_BOX_CLOSED,
    EV_CHECK_BOX_CLICK,
    EV_CURSOR_UP,
    EV_CURSOR_DOWN,
    EV_NO_EVENT
};

static a_field_type ui_types[GUI_NUM_CONTROL_CLASSES] = {
    FLD_HOT,      /* GUI_PUSH_BUTTON    */
    FLD_HOT,      /* GUI_DEFPUSH_BUTTON */
    FLD_RADIO,    /* GUI_RADIO_BUTTON   */
    FLD_CHECK,    /* GUI_CHECK_BOX      */
    FLD_PULLDOWN, /* GUI_COMBOBOX       */
    FLD_EDIT,     /* GUI_EDIT           */
    FLD_LISTBOX,  /* GUI_LISTBOX        */
    FLD_VOID,     /* GUI_SCROLLBAR      */
    FLD_TEXT,     /* GUI_STATIC         */
    FLD_FRAME,    /* GUI_GROUPBOX       */
    FLD_COMBOBOX, /* GUI_EDIT_COMBOBOX  */
    FLD_EDIT_MLE  /* GUI_EDIT_MLE       */
};

/* functions to find dialog boxes */

static  dialog_node     *MyDialog       = NULL;

void GUISetJapanese( void )
{
}

static bool InsertDialog( gui_window *wnd, a_dialog *dialog, int num_controls,
                          char *name, bool colours_set )
{
    dialog_node *curr;

    curr = (dialog_node *) GUIMemAlloc( sizeof( dialog_node ) );
    if( curr == NULL ) {
        return( FALSE );
    }
    curr->wnd = wnd;
    curr->dialog = dialog;
    curr->next = MyDialog;
    curr->num_controls = num_controls;
    curr->name = name;
    curr->colours_set = colours_set;
    MyDialog = curr;
    return( TRUE );
}

void GUIDeleteDialog( a_dialog *dialog )
{
    dialog_node *curr;
    dialog_node *prev;

    prev = NULL;
    for( curr = MyDialog; curr != NULL; curr = curr->next ) {
        if( curr->dialog == dialog ) {
            if( prev != NULL ) {
                prev->next = curr->next;
            } else {
                MyDialog = curr->next;
            }
            GUIMemFree( curr );
            break;
        } else {
            prev = curr;
        }
    }
}

dialog_node *GUIGetDlgByWnd( gui_window *wnd )
{
    dialog_node *curr;

    for( curr = MyDialog; curr != NULL; curr = curr->next ) {
        if( curr->wnd == wnd ) {
            return( curr );
        }
    }
    return( NULL );
}

static dialog_node *GetDialog( a_dialog *dialog )
{
    dialog_node *curr;

    for( curr = MyDialog; curr != NULL; curr = curr->next ) {
        if( curr->dialog == dialog ) {
            return( curr );
        }
    }
    return( NULL );
}

static bool GetIndexOfField( a_dialog *dialog, VFIELD *field, int num_controls,
                             int *index )
{
    int i;

    for( i = 0; i < num_controls; i++ ) {
        if( &dialog->fields[i] == field ) {
            *index = i;
            return( TRUE );
        }
    }
    return( FALSE );
}

unsigned GUIGetControlId( gui_window *wnd, VFIELD *field )
{
    gui_control *control;
    int         index;
    dialog_node *node;

    node = GUIGetDlgByWnd( wnd );
    if( node == NULL ) {
        return( 0 );
    }
    if( !GetIndexOfField( node->dialog, field, node->num_controls, &index ) ) {
        return( 0 );
    }
    for( control = wnd->controls; control != NULL; control = control->sibling ) {
        if( control->index == index ) {
            return( control->id );
        }
    }
    return( 0 );
}

a_dialog *GUIGetDialog( gui_window *wnd )
{
    dialog_node *node;

    node = GUIGetDlgByWnd( wnd );
    if( node != NULL ) {
        return( node->dialog );
    } else {
        return( NULL );
    }
}

VFIELD *GUIGetField( gui_window *wnd, unsigned id )
{
    a_dialog    *ui_dialog;
    dialog_node *node;
    gui_control *control;

    node = GUIGetDlgByWnd( wnd );
    if( node != NULL ) {
        ui_dialog = node->dialog;
        control = GUIGetControl( wnd, id );
        if( control != NULL && ( control->index < node->num_controls ) ) {
            return( &ui_dialog->fields[control->index] );
        }
    }
    return( NULL );
}

/************************** end of dialog box functions *********************/

void GUIPushControlEvents( void )
{
    uipushlist( ControlEvents );
}

void GUIPopControlEvents( void )
{
    uipoplist( /* ControlEvents */ );
}

static bool ResetFieldSize( dialog_node *dialog, int new_num )
{
    VFIELD      *fields;

    fields = (VFIELD *)GUIMemRealloc( dialog->dialog->fields,
                                   ( new_num + 1 ) * sizeof( VFIELD ) );
    if( fields != NULL ) {
        dialog->dialog->fields = fields;
        memset( &fields[new_num], 0, sizeof( VFIELD ) );
        return( TRUE );
    }
    return( FALSE );
}

bool GUIInsertDialog( gui_window *wnd )
{
    a_dialog    *dialog;
    dialog_node *node;

    if( GUIGetDlgByWnd( wnd ) != NULL ) {
        return( TRUE );
    } else {
        dialog = (a_dialog *)GUIMemAlloc( sizeof( a_dialog ) );
        if( dialog == NULL ) {
            return( FALSE );
        }
        memset( dialog, 0, sizeof( a_dialog ) );
        dialog->vs = &wnd->screen;
        if( InsertDialog( wnd, dialog, 0, NULL, FALSE ) ) {
            node = GUIGetDlgByWnd( wnd );
            if( node != NULL ) {
                if( ResetFieldSize( node, 0 ) ) {
                    uireinitdialog( dialog, dialog->fields );
                    return( TRUE );
                }
            }
        }
        return( FALSE );
    }
}

void GUIRefreshControl( gui_window *wnd, unsigned id )
{
    a_dialog    *dialog;
    bool        colours_set;
    VFIELD      *field;

    field = GUIGetField( wnd, id );
    if( field != NULL ) {
        dialog = GUIGetDialog( wnd );
        if( dialog != NULL ) {
            colours_set = GUISetDialColours();
            uiprintfield( dialog, field );
            if( colours_set ) {
                GUIResetDialColours();
            }
        }
    }
}

/*
 * GUIGetList -- return the list in the given field
 */

a_list *GUIGetList( VFIELD *field )
{
    a_list      *list;
    a_combo_box *combo_box;

    list = NULL;
    switch( field->typ ) {
    case FLD_PULLDOWN :
    case FLD_LISTBOX :
    case FLD_EDIT_MLE:
        list = (a_list *)field->ptr;
        break;
    case FLD_COMBOBOX :
        combo_box = (a_combo_box *)field->ptr;
        list = &combo_box->list;
        break;
    }
    return( list );
}

static void FreeEdit( an_edit_control *edit_control, bool free_edit, bool is_GUI_data )
{
    void        uifree( void * );  // Function in ui project

    if( is_GUI_data )
        GUIMemFree( edit_control->buffer );
    else
        uifree( edit_control->buffer );
    if( free_edit ) {
        GUIMemFree( edit_control );
    }
}

bool GUIGetFocus( gui_window *wnd, unsigned *id )
{
    dialog_node *node;

    if( id == NULL ) {
        return( FALSE );
    }
    node = GUIGetDlgByWnd( wnd );
    if( node != NULL ) {
        if( node->dialog->curr != NULL ) {
            *id = GUIGetControlId( wnd, node->dialog->curr );
            return( *id != (unsigned)NULL );
        }
    }
    return( FALSE );
}

static void FreeRadioGroup( a_radio_group * group )
{
    GUIMemFree( group->caption );
    GUIMemFree( group );
}

static void GUIFreeRadio( a_radio * radio )
{
    GUIMemFree( radio->str );
    GUIMemFree( radio );
}

static void GUIFreeCheck( a_check * check )
{
    GUIMemFree( check->str );
    GUIMemFree( check );
}

/*
 * GUIDoFreeField -- free memory allocation during GUIDoAddControl
 */

void GUIDoFreeField( VFIELD *field, a_radio_group **group )
{
    a_radio     *radio;
    a_combo_box *combo_box;

    switch( field->typ ) {
    case FLD_HOT :
        GUIFreeHotSpot( (a_hot_spot *)field->ptr );
        break;
    case FLD_RADIO :
        radio = (a_radio *)field->ptr;
        if( ( group != NULL ) && ( *group != radio->group ) ) {
            FreeRadioGroup( radio->group );
            *group = radio->group;
        }
        GUIFreeRadio( radio );
        break;
    case FLD_CHECK :
        GUIFreeCheck( (a_check *)field->ptr );
        break;
    case FLD_COMBOBOX :
        combo_box = (a_combo_box *)field->ptr;
        GUIFreeList( &combo_box->list, FALSE );
        FreeEdit( &combo_box->edit, FALSE, TRUE );
        GUIMemFree( combo_box );
        break;
    case FLD_EDIT :
        FreeEdit( field->ptr, TRUE, FALSE );
        break;
    case FLD_INVISIBLE_EDIT :
        FreeEdit( field->ptr, TRUE, TRUE );
        break;
    case FLD_EDIT_MLE:
    case FLD_LISTBOX :
    case FLD_PULLDOWN :
        GUIFreeList( (a_list *)field->ptr, TRUE );
        break;
    case FLD_FRAME :
    case FLD_TEXT :
        if( field->ptr != NULL ) {
            GUIMemFree( (char *)field->ptr );
        }
        break;
    }
}

static void FreeFields( VFIELD *fields )
{
    int                 i;
    a_radio_group       *group;

    if( fields == NULL ) {
        return;
    }
    group = NULL;
    for( i = 0; fields[i].typ != FLD_VOID; i++ ) {
        if( fields[i].ptr != NULL ) {
            GUIDoFreeField( &fields[i], &group );
        }
    }
    GUIMemFree( fields );
}

static void CleanUpRadioGroups( void )
{
    if( RadioGroup != NULL ) {
        FreeRadioGroup( RadioGroup );
    }
}

bool GUIDoAddControl( gui_control_info *info, gui_window *wnd, VFIELD *field )
{
    a_radio             *radio;
    a_check             *check;
    a_combo_box         *combo_box;
    an_edit_control     *edit_control;
    bool                group_allocated;
    SAREA               area;

    group_allocated = FALSE;
    if( (info->style & GUI_GROUP) &&
        (info->control_class == GUI_RADIO_BUTTON) ) {
        if( !Group ) {
            RadioGroup = (a_radio_group * )GUIMemAlloc( sizeof( a_radio_group ) );
            if( RadioGroup == NULL ) {
                return( FALSE );
            }
            RadioGroup->value = -1;
            if( !GUIStrDup( info->text, &RadioGroup->caption ) ) {
                CleanUpRadioGroups();
                return( FALSE );
            }
            Group = TRUE;
            group_allocated = TRUE;
        }
    }

    GUIGetSAREA( wnd, &area );
    if( !GUISetDialogArea( wnd, &field->area, &info->rect, &area ) ) {
        return( FALSE );
    }

    field->typ = ui_types[info->control_class];
    if( field->typ == FLD_EDIT && ( info->style & GUI_EDIT_INVISIBLE ) ) {
        field->typ = FLD_INVISIBLE_EDIT;
    }

⌨️ 快捷键说明

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