WWindow *WDialog::switchChild( WWindow *win, bool forward ) { /***********************************************************/ unsigned control; if( GUIGetFocus( handle(), &control ) ) { // control has the focus WWindow* child = getControl( control ); return( WWindow::switchChild( child, forward ) ); } else if( this == win->parent() ) { // window inside a dialog has the focus // GUI won't generate a "losing focus" message so WCLASS // has to simulate one win->losingFocus( NULL ); return( WWindow::switchChild( win, forward ) ); } return( NULL ); }
static void UpdateControlVisibility( gui_window *gui, a_dialog_header *curr_dialog, bool init ) /*********************************************************************************************/ // Hide controls which have the optional visibility condition evaluate to false, and show // the ones that have it evaluate to true. (Controls with no vis. condition are always shown.) // When a control is hidden, the controls BELOW it move up by the hidden control's height. // A currently hidden controls that needs to be made visible causes all controls BELOW it // to move down by the "appearing" control's height so that it can be shown again. // The dialog window height also gets affected, while the top edge remains fixed on the screen. // // NOTE: be careful with RADIO_BUTTONS... making radio buttons appear and disappear because of // other radio buttons in the same dialog being checked may not work (nor does it make sense anyways) { gui_ord last_height; gui_rect rect; gui_rect control_rect; gui_rect parent_rect; gui_window *parent; int i, j, sign; unsigned id_i; unsigned id_j; unsigned checked_radio_id = 0; unsigned new_check_candidate; unsigned focus; unsigned new_focus; bool enabled; bool control_on_new_line[MAX_VARS]; bool visible_checked_radiobutton; vhandle var_handle; // vhandle *pVariable; if( gui == NULL ) return; if( init ) { // How much the height of the dialog has changed from its original value curr_dialog->height_change = 0; // The GUIGetRect below gets the dialog's position so that when it is resized, // it can be put back in its original position // NOTE that GUIGetRect does not want to give the EXACT location of the dialog, // so if you set the position to the coordinates that you got with GUIGetRect, // the dialog will MOVE slightly (not pleasing to the eye). // The current hack is to get the original coordinates, and go back to them every time // the dialog is resized with GUIResizeWindow. // This way, the dialog will be off by the same amount from the original // every time, and not appear to move. GUIGetRect( gui, &curr_dialog->original_rect ); // Make child windows appear in the correct place, since GUIGetRect() gives back // a rect that is tranlsated off by the parent's x and y. parent = GUIGetParentWindow( gui ); if( parent != MainWnd && parent != NULL ) { GUIGetRect( parent, &parent_rect ); curr_dialog->original_rect.x -= parent_rect.x; curr_dialog->original_rect.y -= parent_rect.y; } // Return if there are radio buttons // because UpdateControlVisibility is going to be called again anyways after init. // Without returning, the visibility conditions having to do with radio buttons // would not work sometimes. // We do not want to return if there are no radio buttons // because UpdateControlVisibility will not be called before showing // the dialog in that case. for( i = 0; i < curr_dialog->num_controls; i++ ) { if( curr_dialog->controls[i].control_class == GUI_RADIO_BUTTON ) { return; } } } memcpy( &rect, &curr_dialog->original_rect, sizeof( gui_rect ) ); last_height = rect.height + curr_dialog->height_change; control_on_new_line[0] = TRUE; GUIGetFocus( gui, &focus ); // Figure out which controls are on a separate line from the last control for( i = 1; i < curr_dialog->num_controls; i++ ) { if( curr_dialog->controls[i].rect.y > curr_dialog->controls[i - 1].rect.y ) { control_on_new_line[i] = TRUE; } else { control_on_new_line[i] = FALSE; } } // Initialize Variables corresponding to radio buttons and check boxes // This needs to be done for the part further below that checks to see if any // buttons are checked to work. // Also, figure out which radio button is currently checked. for( i = 0; i < curr_dialog->num_controls; i++ ) { if( curr_dialog->controls[i].control_class == GUI_RADIO_BUTTON || curr_dialog->controls[i].control_class == GUI_CHECK_BOX ) { // pVariable = curr_dialog->pVariables; var_handle = curr_dialog->controls[i].id; if( curr_dialog->controls[i].control_class == GUI_RADIO_BUTTON && GUIIsChecked( gui, VarGetId( var_handle ) ) ) { checked_radio_id = var_handle; } for( j = 0; curr_dialog->pVariables[j] != NO_VAR; j++ ) { if( curr_dialog->pVariables[j] == var_handle && GUIIsChecked( gui, VarGetId( var_handle ) ) ) { SetVariableByHandle( var_handle, "1" ); } } } } // Allow EvalCondition to evaluate conditions with no 'shortcuts' // (See GetOptionVarValue() in setupinf.c) // Kind of like an on and off (below) switch // for special behaviour of GetOptionVarValue() // SetVariableByName( "_Visibility_Condition_", "1" ); VisibilityCondition = 1; for( i = 0; i < curr_dialog->num_controls; i++ ) { // Figure out which controls to hide and which to show. // Move all the controls below any control in transition // either up or down. if( curr_dialog->pVisibilityConds[i] != NULL ) { id_i = curr_dialog->controls[i].id; enabled = GUIIsControlEnabled( gui, id_i ); if( EvalCondition( curr_dialog->pVisibilityConds[i] ) ) { if( !enabled ) { GUIEnableControl( gui, id_i, TRUE ); sign = 1; } else { continue; } } else if( enabled ) { GUIEnableControl( gui, id_i, FALSE ); GUIHideControl( gui, curr_dialog->controls[i].id ); sign = -1; } else { continue; } if( control_on_new_line[i] ) { for( j = i + 1; j < curr_dialog->num_controls && !control_on_new_line[j]; j++ ); for( ; j < curr_dialog->num_controls; j++ ) { id_j = curr_dialog->controls[j].id; enabled = GUIIsControlEnabled( gui, id_j ); GUIGetControlRect( gui, curr_dialog->controls[j].id, &control_rect ); control_rect.y += curr_dialog->controls[i].rect.height * sign; if( enabled ) { GUIHideControl( gui, id_j ); // control will be made visible again below // after being moved. } GUIResizeControl( gui, id_j, &control_rect ); } curr_dialog->height_change += curr_dialog->controls[i].rect.height * sign; } } } // SetVariableByName( "_Visibility_Condition_", "0" ); VisibilityCondition = 0; visible_checked_radiobutton = FALSE; new_check_candidate = 0; for( i = 0; i < curr_dialog->num_controls; i++ ) { id_i = curr_dialog->controls[i].id; // figure out if there are no enabled radio buttons that are checked // use this info further down... if( curr_dialog->controls[i].control_class == GUI_RADIO_BUTTON && !visible_checked_radiobutton && GUIIsControlEnabled( gui, id_i ) ) { if( GUIIsChecked( gui, id_i ) == GUI_CHECKED ) { visible_checked_radiobutton = TRUE; } else if( new_check_candidate == 0 ) { new_check_candidate = id_i; } } // show enabled controls that were hidden for moving only if( GUIIsControlEnabled( gui, id_i ) && !GUIIsControlVisible( gui, id_i ) ) { GUIShowControl( gui, id_i ); } } // Keep the original focus in case it has changed. GUIGetFocus( gui, &new_focus ); if( new_focus != focus && GUIIsControlEnabled( gui, focus ) ) { GUISetFocus( gui, focus ); } if( GUIIsControlEnabled( gui, checked_radio_id ) ) { GUISetChecked( gui, checked_radio_id, 1 ); } else if( !visible_checked_radiobutton && new_check_candidate != 0 ) { // 'Check' a visible radio button if the currently checked button // is invisible. GUISetChecked( gui, new_check_candidate, 1 ); } rect.height += curr_dialog->height_change; if( rect.height != last_height ) { GUIResizeWindow( gui, &rect ); } }
/* * ProcessOKorDClick -- user clicked OK or double clicked on a file */ void ProcessOKorDClick( gui_window *gui, unsigned id ) { process_rc prc; int sel; int realsel; char path[_MAX_PATH]; char *optr; char *ptr; int i; unsigned focusid; dlg_info *dlg = GUIGetExtra( gui ); if( id == CTL_OK ) { /* hit enter or clicked ok */ GUIGetFocus( gui, &focusid ); switch( focusid ) { case CTL_DIR_LIST : id = focusid; break; case CTL_FILE_LIST : ptr = GUIGetText( gui, CTL_FILE_LIST ); GUISetText( gui, CTL_EDIT, ptr ); GUIMemFree( ptr ); break; } } switch( id ) { case CTL_FILE_LIST : case CTL_OK : prc = processFileName( gui ); if( prc == PROCESS_TRUE ) { dlg->dialogRC = OFN_RC_FILE_SELECTED; GUICloseDialog( gui ); } else if( prc == PROCESS_FAIL ) { dlg->dialogRC = OFN_RC_RUNTIME_ERROR; GUICloseDialog( gui ); } break; case CTL_DIR_LIST : sel = GUIGetCurrSelect( gui, id ); #if defined( __UNIX__ ) || defined( __NETWARE__ ) path[0] = FILE_SEP_CHAR; path[1] = 0; #else path[0] = 0; #endif realsel = 0; for( i=0;i<sel;i++ ) { ptr = GUIGetListItem( gui, id, i ); if( ptr == NULL ) { return; } optr = ptr; while( *ptr == INDENT_CHAR ) { ptr++; } if( *ptr == '-' ) { strcat( path, ptr+1 ); realsel++; if( i > 0 ) { strcat( path, FILE_SEP ); } } else { GUIMemFree( optr ); break; } GUIMemFree( optr ); } ptr = GUIGetListItem( gui, id, sel ); if( ptr == NULL ) { return; } optr = ptr; while( *ptr == INDENT_CHAR ) { ptr++; } strcat( path, ptr+1 ); GUIMemFree( optr ); goToDir( gui, path ); if( !initDialog( gui, NULL, NULL ) ) { dlg->dialogRC = OFN_RC_RUNTIME_ERROR; GUICloseDialog( gui ); } else { GUISetCurrSelect( gui, id, realsel ); } break; } } /* ProcessOKorDClick */
static bool StatusEventProc( gui_window *gui, gui_event gui_ev, void *parm ) /**************************************************************************/ { static bool button_pressed = false; gui_ctl_id id; gui_key key; gui_keystate state; const char *msg; parm = parm; if( gui == NULL ) return( false ); switch( gui_ev ) { case GUI_INIT_WINDOW: return( true ); case GUI_PAINT: { if( StatusBarLen == 0 ) { break; } msg = GetVariableStrVal( Messages[MsgLine0] ); GUIDrawTextExtent( gui, msg, strlen( msg ), LINE0_ROW, LINE0_COL * CharSize.x, WND_STATUS_TEXT, GUI_NO_COLUMN ); GUIDrawTextExtent( gui, StatusLine1, strlen( StatusLine1 ), LINE1_ROW, LINE1_COL * CharSize.x, WND_STATUS_TEXT, GUI_NO_COLUMN ); #ifdef _UI { int len1, len2; char num[20]; memset( StatusBarBuf, ' ', StatusBarLen ); StatusBarBuf[StatusBarLen] = '\0'; itoa( Percent, num, 10 ); strcat( num, "%" ); memcpy( StatusBarBuf + StatusBarLen / 2 - 1, num, strlen( num ) ); // draw bar in two parts len1 = (StatusBarLen * (long)Percent) / 100; if( len1 < 0 ) { len1 = 0; } else if( len1 > StatusBarLen ) { len1 = StatusBarLen; } len2 = StatusBarLen - len1; if( len1 > 0 ) { GUIDrawText( gui, StatusBarBuf, len1, STATUS_ROW, StatusBarRect.x, WND_STATUS_BAR ); } if( len2 > 0 ) { GUIDrawText( gui, StatusBarBuf + len1, len2, STATUS_ROW, StatusBarRect.x + len1 * CharSize.x, WND_STATUS_TEXT ); } memset( StatusBarBuf, UiGChar[UI_SBOX_TOP_LINE], StatusBarLen ); GUIDrawText( gui, StatusBarBuf, StatusBarLen, STATUS_ROW - 1, StatusBarRect.x, WND_STATUS_TEXT ); GUIDrawText( gui, StatusBarBuf, StatusBarLen, STATUS_ROW + 1, StatusBarRect.x, WND_STATUS_TEXT ); } #else { gui_coord coord; int str_len, width, height; int bar_width, len1, len2, divider; gui_point start, end; gui_rect rStatusBar; // sprintf( StatusBarBuf, "%d%%", Percent ); // clear whole bar GUIFillRect( gui, &StatusBarRect, WND_STATUS_BAR ); // calculate where divider splits rectangle bar_width = StatusBarRect.width; divider = (bar_width * (long)Percent) / 100; if( divider < 0 ) { divider = 0; } else if( divider > bar_width ) { divider = bar_width; } rStatusBar = StatusBarRect; rStatusBar.width = divider; // calculate position for text (centre it) str_len = strlen( StatusBarBuf ); width = GUIGetExtentX( gui, StatusBarBuf, str_len ); height = GUIGetExtentY( gui, StatusBarBuf ); coord.y = StatusBarRect.y + (StatusBarRect.height - height) / 2; coord.x = StatusBarRect.x + (StatusBarRect.width - width) / 2; divider += StatusBarRect.x; if( coord.x > divider ) { // text is completely to right of divider GUIFillRect( gui, &rStatusBar, WND_STATUS_TEXT ); GUIDrawTextPos( gui, StatusBarBuf, str_len, &coord, WND_STATUS_TEXT ); } else if( coord.x + width < divider ) { // text is completely to left of divider GUIFillRect( gui, &rStatusBar, WND_STATUS_TEXT ); GUIDrawTextPos( gui, StatusBarBuf, str_len, &coord, WND_STATUS_BAR ); } else { // need to split text len1 = ((long)(divider - coord.x) * str_len) / width; if( len1 < 0 ) { len1 = 0; } else if( len1 > str_len ) { len1 = str_len; } len2 = str_len - len1; // recalc divider, so it falls on a character boundary divider = coord.x + GUIGetExtentX( gui, StatusBarBuf, len1 ); rStatusBar.width = divider - StatusBarRect.x; GUIFillRect( gui, &rStatusBar, WND_STATUS_TEXT ); if( len1 > 0 ) { GUIDrawTextPos( gui, StatusBarBuf, len1, &coord, WND_STATUS_BAR ); } if( len2 > 0 ) { coord.x = divider; GUIDrawTextPos( gui, StatusBarBuf + len1, len2, &coord, WND_STATUS_TEXT ); } } // draw frame start.x = StatusBarRect.x; start.y = StatusBarRect.y; end.x = StatusBarRect.width + StatusBarRect.x; end.y = start.y; // top line GUIDrawLine( gui, &start, &end, GUI_PEN_SOLID, 1, WND_STATUS_FRAME ); start.y = StatusBarRect.y + StatusBarRect.height; // bottom line end.y = start.y; GUIDrawLine( gui, &start, &end, GUI_PEN_SOLID, 1, WND_STATUS_FRAME ); end.y = StatusBarRect.y; start.x = StatusBarRect.x; end.x = start.x; // left side GUIDrawLine( gui, &start, &end, GUI_PEN_SOLID, 1, WND_STATUS_FRAME ); start.x = StatusBarRect.x + StatusBarRect.width; end.x = start.x; // right side GUIDrawLine( gui, &start, &end, GUI_PEN_SOLID, 1, WND_STATUS_FRAME ); } #endif return( false ); } case GUI_DESTROY: StatusWnd = NULL; return( false ); case GUI_CONTROL_CLICKED: GUIGetFocus( gui, &id ); GUI_GETID( parm, id ); switch( id ) { case CTL_CANCEL: if( !button_pressed ) { button_pressed = true; if( MsgBox( gui, "IDS_QUERYABORT", GUI_YES_NO ) == GUI_RET_YES ) { CancelSetup = true; } button_pressed = false; break; } case CTL_DONE: if( !button_pressed ) { CancelSetup = true; break; } } return( true ); case GUI_KEYDOWN: GUI_GET_KEY_STATE( parm, key, state ); state = state; switch( key ) { case GUI_KEY_ESCAPE: if( !button_pressed ) { button_pressed = true; if( MsgBox( gui, "IDS_QUERYABORT", GUI_YES_NO ) == GUI_RET_YES ) { CancelSetup = true; } button_pressed = false; break; } default: break; } return( true ); default: break; } return( false ); }