00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00015 #define WIN32_LEAN_AND_MEAN
00016 #pragma warning ( disable : 4201 4214 )
00017 #include <windows.h>
00018 #pragma warning ( default : 4201 4214 )
00019 #include <string.h>
00020 #include <assert.h>
00021 #include "Genesis.h"
00022 #include "Ram.h"
00023 #include "Text.h"
00024 #include "MenuItem.h"
00025
00026
00027 #define MENU_ITEMCHECKED_ACTIVE_STRING ("x ")
00028 #define MENU_SELECTED_BORDER (24) // selected menu item will stay in a box that the menu height, trimmed
00029
00031
00033
00034
00035 typedef struct tag_MenuItem_T
00036 {
00037
00038
00039 struct tag_MenuItem_T *Next;
00040 struct tag_MenuItem_T *Prev;
00041
00042
00043 int32 Identifier;
00044 Menu_ItemType ItemType;
00045 int32 MaxWidth;
00046 int32 MaxHeight;
00047 void *Data;
00048
00049 } MenuItem_T;
00050
00051
00052 typedef struct
00053 {
00054 geEngine *Engine;
00055 int32 Width;
00056 int32 Top,Bottom;
00057 int32 ItemWidth, ItemHeight;
00058 int32 x, y;
00059 int32 ItemCount;
00060 int32 Identifier;
00061 MenuItem_T *Head;
00062 MenuItem_T *Current;
00063 int32 MinimumSelectedY;
00064 int32 MaximumSelectedY;
00065 } Menu_T;
00066
00067
00068
00070
00071
00072
00073
00074
00076 geBoolean Menu_ToggleItem(
00077 Menu_T *Menu,
00078 int32 Identifier )
00079 {
00080
00081
00082 MenuItem_T *CurItem;
00083
00084
00085 if ( Menu == NULL )
00086 {
00087 assert( 0 );
00088 return GE_FALSE;
00089 }
00090
00091
00092 CurItem = Menu->Head;
00093 while ( CurItem != NULL )
00094 {
00095
00096
00097 if ( CurItem->Identifier == Identifier )
00098 {
00099
00100
00101 MenuItemToggle_T *Data;
00102
00103
00104 assert( CurItem->ItemType == Menu_ItemToggle );
00105 Data = (MenuItemToggle_T *)CurItem->Data;
00106 assert( Data != NULL );
00107
00108
00109 Data->ActiveItem = !Data->ActiveItem;
00110
00111
00112 return GE_TRUE;
00113 }
00114
00115
00116 CurItem = CurItem->Next;
00117 }
00118
00119
00120 return GE_FALSE;
00121
00122 }
00123
00124
00125
00127
00128
00129
00130
00131
00133 geBoolean Menu_FlagString(
00134 Menu_T *Menu,
00135 int32 Identifier,
00136 geBoolean Flag )
00137 {
00138
00139
00140 MenuItem_T *CurItem;
00141
00142
00143 if ( Menu == NULL )
00144 {
00145 assert( 0 );
00146 return GE_FALSE;
00147 }
00148
00149
00150 CurItem = Menu->Head;
00151 while ( CurItem != NULL )
00152 {
00153
00154
00155 if ( CurItem->Identifier == Identifier )
00156 {
00157
00158
00159 MenuItemString_T *Data;
00160 int32 Size;
00161
00162
00163 assert( CurItem->ItemType == Menu_ItemString );
00164 Data = (MenuItemString_T *)CurItem->Data;
00165 assert( Data != NULL );
00166
00167
00168 Data->AwaitingInput = Flag;
00169
00170 Size = strlen(Data->StringData);
00171
00172 if (Flag)
00173 {
00174 if (Size + 2 < MENU_MAXSTRINGSIZE)
00175 {
00176 Data->StringData[Size] = 0x40;
00177 Data->StringData[Size+1] = 0;
00178 }
00179 }
00180
00181 return GE_TRUE;
00182 }
00183
00184
00185 CurItem = CurItem->Next;
00186 }
00187
00188
00189 return GE_FALSE;
00190
00191 }
00192
00193
00194
00196
00197
00198
00199
00200
00202 geBoolean Menu_FlagField(
00203 Menu_T *Menu,
00204 int32 Identifier,
00205 geBoolean Flag )
00206 {
00207
00208
00209 MenuItem_T *CurItem;
00210
00211
00212 if ( Menu == NULL )
00213 {
00214 assert( 0 );
00215 return GE_FALSE;
00216 }
00217
00218
00219 CurItem = Menu->Head;
00220 while ( CurItem != NULL )
00221 {
00222
00223
00224 if ( CurItem->Identifier == Identifier )
00225 {
00226
00227
00228 MenuItemField_T *Data;
00229
00230
00231 assert( CurItem->ItemType == Menu_ItemField );
00232 Data = (MenuItemField_T *)CurItem->Data;
00233 assert( Data != NULL );
00234
00235
00236 Data->AwaitingChange = Flag;
00237
00238
00239 return GE_TRUE;
00240 }
00241
00242
00243 CurItem = CurItem->Next;
00244 }
00245
00246
00247 return GE_FALSE;
00248
00249 }
00250
00251
00252
00254
00255
00256
00257
00258
00260 geBoolean Menu_SetFieldText(
00261 Menu_T *Menu,
00262 int32 Identifier,
00263 char *NewText )
00264 {
00265
00266
00267 MenuItem_T *CurItem;
00268
00269
00270 if ( ( Menu == NULL ) || ( NewText == NULL ) )
00271 {
00272 assert( 0 );
00273 return GE_FALSE;
00274 }
00275
00276
00277 CurItem = Menu->Head;
00278 while ( CurItem != NULL )
00279 {
00280
00281
00282 if ( CurItem->Identifier == Identifier )
00283 {
00284
00285
00286 MenuItemField_T *Data;
00287
00288
00289 assert( CurItem->ItemType == Menu_ItemField );
00290 Data = (MenuItemField_T *)CurItem->Data;
00291 assert( Data != NULL );
00292
00293
00294 strcpy( Data->FieldTextData, NewText );
00295 Data->FieldTextDataLength = strlen( Data->FieldTextData );
00296
00297
00298 return GE_TRUE;
00299 }
00300
00301
00302 CurItem = CurItem->Next;
00303 }
00304
00305
00306 return GE_FALSE;
00307
00308 }
00309
00310
00311
00313
00314
00315
00316
00317
00319 geBoolean Menu_SetStringText(
00320 Menu_T *Menu,
00321 int32 Identifier,
00322 char *NewText )
00323 {
00324
00325
00326 MenuItem_T *CurItem;
00327
00328
00329 if ( ( Menu == NULL ) || ( NewText == NULL ) )
00330 {
00331 assert( 0 );
00332 return GE_FALSE;
00333 }
00334
00335
00336 CurItem = Menu->Head;
00337 while ( CurItem != NULL )
00338 {
00339
00340
00341 if ( CurItem->Identifier == Identifier )
00342 {
00343
00344
00345 MenuItemString_T *Data;
00346
00347
00348 assert( CurItem->ItemType == Menu_ItemString );
00349 Data = (MenuItemString_T *)CurItem->Data;
00350 assert( Data != NULL );
00351
00352
00353 strcpy( Data->StringData, NewText );
00354 Data->StringDataLength = strlen( Data->StringData );
00355
00356
00357 return GE_TRUE;
00358 }
00359
00360
00361 CurItem = CurItem->Next;
00362 }
00363
00364
00365 return GE_FALSE;
00366
00367 }
00368
00369
00371
00372
00373
00374
00375
00377 geBoolean Menu_GetStringText(
00378 Menu_T *Menu,
00379 int32 Identifier,
00380 char *NewText )
00381 {
00382
00383
00384 MenuItem_T *CurItem;
00385
00386
00387 if ( ( Menu == NULL ) || ( NewText == NULL ) )
00388 {
00389 assert( 0 );
00390 return GE_FALSE;
00391 }
00392
00393
00394 CurItem = Menu->Head;
00395 while ( CurItem != NULL )
00396 {
00397
00398
00399 if ( CurItem->Identifier == Identifier )
00400 {
00401
00402
00403 MenuItemString_T *Data;
00404
00405
00406 assert( CurItem->ItemType == Menu_ItemString );
00407 Data = (MenuItemString_T *)CurItem->Data;
00408 assert( Data != NULL );
00409
00410
00411 strcpy(NewText, Data->StringData);
00412 Data->StringDataLength = strlen( Data->StringData );
00413
00414
00415 return GE_TRUE;
00416 }
00417
00418
00419 CurItem = CurItem->Next;
00420 }
00421
00422
00423 return GE_FALSE;
00424
00425 }
00426
00427
00429
00430
00431
00432
00433
00435 int32 Menu_GetIdentifier(
00436 Menu_T *Menu )
00437 {
00438
00439
00440 if ( Menu == NULL )
00441 {
00442 assert( 0 );
00443 return -1;
00444 }
00445
00446
00447 return Menu->Identifier;
00448
00449 }
00450
00451
00452
00454
00455
00456
00457
00458
00460 float Menu_GetSliderPercent(
00461 Menu_T *Menu,
00462 int32 Identifier )
00463 {
00464
00465
00466 MenuItem_T *CurItem;
00467
00468
00469 if ( Menu == NULL )
00470 {
00471 assert( 0 );
00472 return -1.0f;
00473 }
00474
00475
00476 CurItem = Menu->Head;
00477 while ( CurItem != NULL )
00478 {
00479
00480
00481 if ( CurItem->Identifier == Identifier )
00482 {
00483
00484
00485 MenuItemSlider_T *Data;
00486
00487
00488 assert( CurItem->ItemType == Menu_ItemSlider );
00489 Data = (MenuItemSlider_T *)CurItem->Data;
00490 assert( Data != NULL );
00491
00492
00493 return Data->Percent;
00494 }
00495
00496
00497 CurItem = CurItem->Next;
00498 }
00499
00500
00501 return -1.0f;
00502
00503 }
00504
00505
00507
00508
00509
00511 void Menu_SetSliderText(
00512 Menu_T *Menu,
00513 int32 Identifier,
00514 char * NewText)
00515 {
00516
00517
00518 MenuItem_T *CurItem;
00519
00520
00521 if ( Menu == NULL )
00522 {
00523 assert( 0 );
00524 return;
00525 }
00526
00527
00528 CurItem = Menu->Head;
00529 while ( CurItem != NULL )
00530 {
00531
00532
00533 if ( CurItem->Identifier == Identifier )
00534 {
00535
00536 MenuItemSlider_T *Data;
00537
00538
00539 assert( CurItem->ItemType == Menu_ItemSlider );
00540 Data = (MenuItemSlider_T *)CurItem->Data;
00541 assert( Data != NULL );
00542
00543 strcpy(Data->Text, NewText);
00544 Data->TextLength = strlen(NewText);
00545
00546 return;
00547 }
00548
00549
00550 CurItem = CurItem->Next;
00551 }
00552
00553
00554 return;
00555
00556 }
00557
00558
00560
00561
00562
00563
00564
00566 void Menu_SetSliderPercent(
00567 Menu_T *Menu,
00568 int32 Identifier,
00569 float Percent)
00570 {
00571
00572
00573 MenuItem_T *CurItem;
00574
00575
00576 if ( Menu == NULL )
00577 {
00578 assert( 0 );
00579 return;
00580 }
00581
00582
00583 CurItem = Menu->Head;
00584 while ( CurItem != NULL )
00585 {
00586
00587
00588 if ( CurItem->Identifier == Identifier )
00589 {
00590
00591 MenuItemSlider_T *Data;
00592
00593
00594 assert( CurItem->ItemType == Menu_ItemSlider );
00595 Data = (MenuItemSlider_T *)CurItem->Data;
00596 assert( Data != NULL );
00597
00598 Data->Percent = Percent;
00599
00600 return;
00601 }
00602
00603
00604 CurItem = CurItem->Next;
00605 }
00606
00607
00608 return;
00609
00610 }
00611
00612
00614
00615
00616
00617
00618
00620 static int32 Menu_GetItemSize(
00621 Menu_ItemType ItemType )
00622 {
00623
00624
00625 switch ( ItemType )
00626 {
00627 case Menu_ItemText:
00628 {
00629 return sizeof( MenuItemText_T );
00630 }
00631
00632 case Menu_ItemSlider:
00633 {
00634 return sizeof( MenuItemSlider_T );
00635 }
00636
00637 case Menu_ItemField:
00638 {
00639 return sizeof( MenuItemField_T );
00640 }
00641
00642 case Menu_ItemString:
00643 {
00644 return sizeof( MenuItemString_T );
00645 }
00646
00647 case Menu_ItemGraphic:
00648 {
00649 return sizeof( MenuItemGraphic_T );
00650 }
00651
00652 case Menu_ItemToggle:
00653 {
00654 return sizeof( MenuItemToggle_T );
00655 }
00656
00657 case Menu_ItemChecked:
00658 {
00659 return sizeof( MenuItemChecked_T );
00660 }
00661 }
00662
00663
00664 assert( 0 );
00665 return 0;
00666
00667 }
00668
00669
00671
00672
00673
00674
00675
00677 geBoolean Menu_GetCheckedData(
00678 Menu_T *Menu,
00679 int32 Identifier,
00680 int32 *UserData )
00681 {
00682
00683
00684 MenuItem_T *CurItem;
00685
00686
00687 if ( Menu == NULL || UserData == NULL )
00688 {
00689 assert( 0 );
00690 return GE_FALSE;
00691 }
00692
00693
00694 CurItem = Menu->Head;
00695 while ( CurItem != NULL )
00696 {
00697
00698
00699 if ( CurItem->Identifier == Identifier )
00700 {
00701
00702
00703 MenuItemChecked_T *Data;
00704
00705
00706 assert( CurItem->ItemType == Menu_ItemChecked );
00707 Data = (MenuItemChecked_T *)CurItem->Data;
00708 assert( Data != NULL );
00709
00710 *UserData = Data->UserData;
00711 return GE_TRUE;
00712 }
00713
00714
00715 CurItem = CurItem->Next;
00716 }
00717
00718
00719 return GE_FALSE;
00720
00721 }
00722
00723
00724
00726
00727
00728
00729
00730
00732 Menu_T * Menu_Create(
00733 geEngine *Engine,
00734 int32 Width,
00735 int32 Top,
00736 int32 Bottom,
00737 int32 x,
00738 int32 y,
00739 int32 Identifier )
00740 {
00741
00742
00743 Menu_T *Menu;
00744
00745
00746 if ( ( Engine == NULL ) ||
00747 ( Width <= 0 ) ||
00748 ( Top < 0 ) ||
00749 ( Bottom < Top ) )
00750 {
00751 assert( 0 );
00752 return NULL;
00753 }
00754
00755
00756 Menu = geRam_Allocate( sizeof( *Menu ) );
00757 if ( Menu == NULL )
00758 {
00759 return NULL;
00760 }
00761 memset( Menu, 0, sizeof( *Menu ) );
00762
00763
00764 Menu->Engine = Engine;
00765 Menu->Width = Width;
00766
00767 Menu->Top = Top;
00768 Menu->Bottom = Bottom;
00769 Menu->x = x;
00770 Menu->y = y;
00771 Menu->Identifier = Identifier;
00772
00773
00774 return Menu;
00775
00776 }
00777
00778
00779
00781
00782
00783
00784
00785
00787 geBoolean Menu_Destroy(
00788 Menu_T **Menu )
00789 {
00790
00791
00792 MenuItem_T *CurMenuItem;
00793 MenuItem_T *NextMenuItem;
00794
00795
00796 if ( *Menu == NULL )
00797 {
00798 return GE_FALSE;
00799 }
00800
00801
00802 CurMenuItem = ( *Menu )->Head;
00803 while ( CurMenuItem != NULL )
00804 {
00805 NextMenuItem = CurMenuItem->Next;
00806 geRam_Free( CurMenuItem->Data );
00807 geRam_Free( CurMenuItem );
00808 CurMenuItem = NextMenuItem;
00809 }
00810
00811
00812 geRam_Free( *Menu );
00813 *Menu = NULL;
00814
00815
00816 return GE_TRUE;
00817
00818 }
00819
00820
00821
00823
00824
00825
00826
00827
00829 geBoolean Menu_AddItem(
00830 Menu_T *Menu,
00831 Menu_ItemType ItemType,
00832 int32 Identifier,
00833 void *Data )
00834 {
00835
00836
00837 MenuItem_T *Item;
00838 int32 ItemSize;
00839
00840
00841 if ( ( Menu == NULL ) ||
00842 ( Identifier <= 0 ) ||
00843 ( Data == NULL ) )
00844 {
00845 assert( 0 );
00846 return GE_FALSE;
00847 }
00848
00849
00850 ItemSize = Menu_GetItemSize( ItemType );
00851 if ( ItemSize <= 0 )
00852 {
00853 assert( 0 );
00854 return GE_FALSE;
00855 }
00856
00857
00858 Item = (MenuItem_T *)geRam_Allocate( sizeof( *Item ) );
00859 if ( Item == NULL )
00860 {
00861 return GE_FALSE;
00862 }
00863 memset( Item, 0, sizeof( *Item ) );
00864
00865
00866 Item->Data = geRam_Allocate( ItemSize );
00867 if ( Item->Data == NULL )
00868 {
00869 geRam_Free( Item );
00870 return GE_FALSE;
00871 }
00872 memset( Item->Data, 0, ItemSize );
00873
00874
00875 Item->Identifier = Identifier;
00876 Item->ItemType = ItemType;
00877 memcpy( Item->Data, Data, ItemSize );
00878
00879
00880 switch ( ItemType )
00881 {
00882
00883 case Menu_ItemText:
00884 {
00885
00886
00887 MenuItemText_T *TextData;
00888 int32 Size;
00889
00890
00891 TextData = (MenuItemText_T *)Data;
00892
00893
00894 Size = Text_GetWidth( TextData->NormalFont );
00895 if ( Text_GetWidth( TextData->SelectFont ) > Size )
00896 {
00897 Size = Text_GetWidth( TextData->SelectFont );
00898 }
00899 Item->MaxWidth = Size * TextData->TextLength;
00900
00901
00902 Size = Text_GetHeight( TextData->NormalFont );
00903 if ( Text_GetHeight( TextData->SelectFont ) > Size )
00904 {
00905 Size = Text_GetHeight( TextData->SelectFont );
00906 }
00907 Item->MaxHeight = Size;
00908 break;
00909 }
00910
00911 case Menu_ItemSlider:
00912 {
00913
00914
00915 MenuItemSlider_T *SliderData;
00916 int32 TextWidth;
00917 int32 TextHeight;
00918 int32 SliderWidth;
00919 int32 SliderHeight;
00920 int32 Size;
00921
00922
00923 SliderData = (MenuItemSlider_T *)Data;
00924
00925
00926 Size = Text_GetWidth( SliderData->NormalFont );
00927 if ( Text_GetWidth( SliderData->SelectFont ) > Size )
00928 {
00929 Size = Text_GetWidth( SliderData->SelectFont );
00930 }
00931 TextWidth = Size * SliderData->TextLength;
00932
00933
00934 Size = Text_GetHeight( SliderData->NormalFont );
00935 if ( Text_GetHeight( SliderData->SelectFont ) > Size )
00936 {
00937 Size = Text_GetHeight( SliderData->SelectFont );
00938 }
00939 TextHeight = Size;
00940
00941
00942 SliderWidth = 128;
00943 SliderHeight = 14;
00944
00945
00946 Item->MaxWidth = TextWidth + SliderWidth;
00947 Item->MaxHeight = ( TextHeight > SliderHeight ) ? TextHeight : SliderHeight;
00948 break;
00949 }
00950
00951 case Menu_ItemField:
00952 {
00953
00954
00955 MenuItemField_T *FieldData;
00956 int32 Size;
00957
00958
00959 FieldData = (MenuItemField_T *)Data;
00960
00961
00962 Size = Text_GetWidth( FieldData->NormalFont );
00963 if ( Text_GetWidth( FieldData->SelectFont ) > Size )
00964 {
00965 Size = Text_GetWidth( FieldData->SelectFont );
00966 }
00967 Item->MaxWidth = Size * ( FieldData->FieldNameLength + FieldData->FieldTextDataLength );
00968
00969
00970 Size = Text_GetHeight( FieldData->NormalFont );
00971 if ( Text_GetHeight( FieldData->SelectFont ) > Size )
00972 {
00973 Size = Text_GetHeight( FieldData->SelectFont );
00974 }
00975 Item->MaxHeight = Size;
00976 break;
00977 }
00978
00979 case Menu_ItemString:
00980 {
00981
00982
00983 MenuItemString_T *StringData;
00984 int32 Size;
00985
00986
00987 StringData = (MenuItemString_T *)Data;
00988 assert( StringData != NULL );
00989
00990
00991 Size = Text_GetWidth( StringData->NormalFont );
00992 if ( Text_GetWidth( StringData->SelectFont ) > Size )
00993 {
00994 Size = Text_GetWidth( StringData->SelectFont );
00995 }
00996 Item->MaxWidth = Size * ( StringData->StringLabelLength + StringData->StringDataLength );
00997
00998
00999 Size = Text_GetHeight( StringData->NormalFont );
01000 if ( Text_GetHeight( StringData->SelectFont ) > Size )
01001 {
01002 Size = Text_GetHeight( StringData->SelectFont );
01003 }
01004 Item->MaxHeight = Size;
01005 break;
01006 }
01007
01008 case Menu_ItemGraphic:
01009 {
01010
01011
01012 Item->MaxWidth = 1;
01013 Item->MaxHeight = 1;
01014 break;
01015 }
01016
01017 case Menu_ItemToggle:
01018 {
01019
01020
01021 MenuItemToggle_T *ToggleData;
01022 int32 Size;
01023
01024
01025 ToggleData = (MenuItemToggle_T *)Data;
01026 assert( ToggleData != NULL );
01027
01028
01029 Size = Text_GetWidth( ToggleData->NormalFont );
01030 if ( Text_GetWidth( ToggleData->SelectFont ) > Size )
01031 {
01032 Size = Text_GetWidth( ToggleData->SelectFont );
01033 }
01034 Item->MaxWidth = Size * ( ToggleData->ToggleLabelLength + ToggleData->ToggleData1Length );
01035
01036
01037 Size = Text_GetHeight( ToggleData->NormalFont );
01038 if ( Text_GetHeight( ToggleData->SelectFont ) > Size )
01039 {
01040 Size = Text_GetHeight( ToggleData->SelectFont );
01041 }
01042 Item->MaxHeight = Size;
01043 break;
01044 }
01045
01046 case Menu_ItemChecked:
01047 {
01048
01049
01050 MenuItemChecked_T *CheckedData;
01051 int32 Size;
01052
01053
01054 CheckedData = (MenuItemChecked_T *)Data;
01055 assert( CheckedData != NULL );
01056
01057
01058 Size = Text_GetWidth( CheckedData->NormalFont );
01059 if ( Text_GetWidth( CheckedData->SelectFont ) > Size )
01060 {
01061 Size = Text_GetWidth( CheckedData->SelectFont );
01062 }
01063 Item->MaxWidth = Size * ( CheckedData->LabelLength );
01064
01065
01066 Size = Text_GetHeight( CheckedData->NormalFont );
01067 if ( Text_GetHeight( CheckedData->SelectFont ) > Size )
01068 {
01069 Size = Text_GetHeight( CheckedData->SelectFont );
01070 }
01071 Item->MaxHeight = Size;
01072 break;
01073 }
01074
01075 default:
01076 {
01077 assert( 0 );
01078 geRam_Free( Item );
01079 return GE_FALSE;
01080 }
01081 }
01082
01083
01084 if ( ( Item->MaxWidth <= 0 ) || ( Item->MaxHeight <= 0 ) )
01085 {
01086 assert( 0 );
01087 geRam_Free( Item );
01088 return GE_FALSE;
01089 }
01090
01091
01092 if ( Menu->Current == NULL )
01093 {
01094 Menu->Head = Menu->Current = Item;
01095 Menu->ItemCount = 1;
01096 }
01097
01098 else
01099 {
01100
01101
01102 Menu->Current = Menu->Head;
01103 while ( Menu->Current->Next != NULL )
01104 {
01105 Menu->Current = Menu->Current->Next;
01106 }
01107
01108
01109 Menu->Current->Next = Item;
01110 Item->Prev = Menu->Current;
01111 Menu->ItemCount++;
01112 Menu->Current = Menu->Head;
01113 }
01114
01115
01116 Menu->ItemHeight += Item->MaxHeight;
01117 Menu->ItemWidth = ( Menu->ItemWidth < Item->MaxWidth ) ? Item->MaxWidth : Menu->ItemWidth;
01118
01119 Menu->MaximumSelectedY = Menu->Bottom- MENU_SELECTED_BORDER;
01120 Menu->MinimumSelectedY = Menu->Top + MENU_SELECTED_BORDER;
01121
01122
01123 return GE_TRUE;
01124
01125 }
01126
01127
01128
01130
01131
01132
01133
01134
01136 geBoolean Menu_Draw(
01137 Menu_T *Menu )
01138 {
01139
01140
01141 MenuItem_T *Item;
01142 int32 x, y;
01143 int32 TestY;
01144
01145
01146 if ( Menu == NULL )
01147 {
01148 assert( 0 );
01149 return GE_FALSE;
01150 }
01151
01152
01153 Item = Menu->Head;
01154 if ( Item == NULL )
01155 {
01156 return GE_FALSE;
01157 }
01158
01159
01160 x = ( Menu->Width / 2 );
01161 y = ( (Menu->Bottom+Menu->Top) / 2 ) - ( Menu->ItemHeight / 2 );
01162
01163
01164
01165 TestY = y;
01166 while ( Item != NULL )
01167 {
01168 if (Menu->Current == Item)
01169 break;
01170 TestY += Item->MaxHeight;
01171 Item=Item->Next;
01172 }
01173
01174 if (TestY < Menu->MinimumSelectedY)
01175 {
01176 y += Menu->MinimumSelectedY-TestY;
01177 }
01178 if (TestY + Item->MaxHeight > Menu->MaximumSelectedY)
01179 {
01180 y -= TestY + Item->MaxHeight - Menu->MaximumSelectedY;
01181 }
01182
01183
01184 Item = Menu->Head;
01185
01186 while ( Item != NULL )
01187 {
01188 if ( y + Item->MaxHeight > Menu->Bottom)
01189 break;
01190
01191
01192 switch ( Item->ItemType )
01193 {
01194
01195 case Menu_ItemText:
01196 {
01197
01198
01199 MenuItemText_T *Data;
01200 FontType Font;
01201
01202
01203 Data = (MenuItemText_T *)Item->Data;
01204 if ( Data == NULL )
01205 {
01206 assert( 0 );
01207 break;
01208 }
01209
01210
01211 if ( Menu->Current != Item )
01212 {
01213 Font = Data->NormalFont;
01214 }
01215 else
01216 {
01217 Font = Data->SelectFont;
01218 }
01219
01220
01221 Text_Out( Data->Text, Font, x, y, Style_Center );
01222
01223 y += Item->MaxHeight;
01224 break;
01225 }
01226
01227 case Menu_ItemSlider:
01228 {
01229
01230
01231 MenuItemSlider_T *Data;
01232 FontType Font;
01233 int32 RangeWidth, RangeHeight;
01234 int32 BarWidth, BarHeight;
01235 int32 SliderX, SliderY;
01236
01237
01238 Data = (MenuItemSlider_T *)Item->Data;
01239 if ( Data == NULL )
01240 {
01241 assert( 0 );
01242 break;
01243 }
01244
01245
01246 if ( Menu->Current != Item )
01247 {
01248 Font = Data->NormalFont;
01249 }
01250 else
01251 {
01252 Font = Data->SelectFont;
01253 }
01254
01255
01256 Text_Out( Data->Text, Font, x, y, Style_RightJustify );
01257
01258
01259 RangeHeight = 14;
01260 RangeWidth = 128 - Data->Slack;
01261 BarWidth = 16;
01262 BarHeight = 14;
01263
01264
01265 geEngine_DrawBitmap(Menu->Engine, Data->Range, NULL, x, y - ( RangeHeight / 2 ) );
01266
01267
01268 SliderX = x + ( Data->Slack / 2 ) + (int32)( Data->Percent * (float)RangeWidth ) - ( BarWidth / 2 );
01269 SliderY = y - ( BarHeight / 2 );
01270 geEngine_DrawBitmap( Menu->Engine, Data->Bar, NULL, SliderX, SliderY );
01271 y += Item->MaxHeight;
01272 break;
01273 }
01274
01275 case Menu_ItemField:
01276 {
01277
01278
01279 MenuItemField_T *Data;
01280 FontType Font;
01281
01282
01283 Data = (MenuItemField_T *)Item->Data;
01284 if ( Data == NULL )
01285 {
01286 assert( 0 );
01287 break;
01288 }
01289
01290
01291 if ( Menu->Current != Item )
01292 {
01293 Font = Data->NormalFont;
01294 }
01295 else
01296 {
01297 Font = Data->SelectFont;
01298 }
01299
01300
01301 Text_Out( Data->FieldName, Font, x, y, Style_RightJustify );
01302 if ( Data->AwaitingChange == GE_FALSE )
01303 {
01304 Text_Out( Data->FieldTextData, Font, x, y, Style_LeftJustify );
01305 }
01306 else
01307 {
01308 Text_Out( "PRESS NEW KEY", Font, x, y, Style_LeftJustify );
01309 }
01310 y += Item->MaxHeight;
01311 break;
01312 }
01313
01314 case Menu_ItemString:
01315 {
01316
01317
01318 MenuItemString_T *Data;
01319 FontType Font;
01320
01321
01322 Data = (MenuItemString_T *)Item->Data;
01323 if ( Data == NULL )
01324 {
01325 assert( 0 );
01326 break;
01327 }
01328
01329
01330 if ( Menu->Current != Item )
01331 {
01332 Font = Data->NormalFont;
01333 }
01334 else
01335 {
01336 Font = Data->SelectFont;
01337 }
01338
01339
01340 Text_Out( Data->StringLabel, Font, x, y, Style_RightJustify );
01341 Text_Out( Data->StringData, Font, x, y, Style_LeftJustify );
01342 y += Item->MaxHeight;
01343 break;
01344 }
01345
01346 case Menu_ItemGraphic:
01347 {
01348
01349
01350 MenuItemGraphic_T *Data;
01351
01352
01353 Data = (MenuItemGraphic_T *)Item->Data;
01354 if ( Data == NULL )
01355 {
01356 assert( 0 );
01357 break;
01358 }
01359
01360
01361 geEngine_DrawBitmap( Menu->Engine, Data->Art, NULL, Data->x, Data->y );
01362 break;
01363 }
01364
01365 case Menu_ItemToggle:
01366 {
01367
01368
01369 MenuItemToggle_T *Data;
01370 FontType Font;
01371
01372
01373 Data = (MenuItemToggle_T *)Item->Data;
01374 if ( Data == NULL )
01375 {
01376 assert( 0 );
01377 break;
01378 }
01379
01380
01381 if ( Menu->Current != Item )
01382 {
01383 Font = Data->NormalFont;
01384 }
01385 else
01386 {
01387 Font = Data->SelectFont;
01388 }
01389
01390
01391 Text_Out( Data->ToggleLabel, Font, x, y, Style_RightJustify );
01392 if ( Data->ActiveItem == 0 )
01393 {
01394 Text_Out( Data->ToggleData1, Font, x, y, Style_LeftJustify );
01395 }
01396 else
01397 {
01398 Text_Out( Data->ToggleData2, Font, x, y, Style_LeftJustify );
01399 }
01400 y += Item->MaxHeight;
01401 break;
01402 }
01403 case Menu_ItemChecked:
01404 {
01405
01406
01407 MenuItemChecked_T *Data;
01408 FontType Font;
01409
01410
01411 Data = (MenuItemChecked_T *)Item->Data;
01412 if ( Data == NULL )
01413 {
01414 assert( 0 );
01415 break;
01416 }
01417
01418
01419 if ( Menu->Current != Item )
01420 {
01421 Font = Data->NormalFont;
01422 }
01423 else
01424 {
01425 Font = Data->SelectFont;
01426 }
01427
01428
01429 Text_Out( Data->Label, Font, Data->LabelPosition, y, Style_LeftJustify );
01430 if ( Data->ActiveItem == 1 )
01431 {
01432 Text_Out( MENU_ITEMCHECKED_ACTIVE_STRING, Font, Data->LabelPosition, y, Style_RightJustify );
01433 }
01434 y += Item->MaxHeight;
01435 break;
01436 }
01437
01438 }
01439
01440
01441 Item = Item->Next;
01442 }
01443
01444
01445 return GE_TRUE;
01446
01447 }
01448
01449
01450
01452
01453
01454
01455
01456
01458 int32 Menu_Key(
01459 Menu_T *Menu,
01460 int32 Key )
01461 {
01462
01463
01464 if ( Menu == NULL )
01465 {
01466 assert( 0 );
01467 return -1;
01468 }
01469
01470
01471 switch( Key )
01472 {
01473
01474
01475 case VK_UP:
01476 {
01477
01478
01479 if ( Menu->Current->Prev != NULL )
01480 {
01481 Menu->Current = Menu->Current->Prev;
01482 }
01483
01484 else
01485 {
01486 while ( Menu->Current->Next != NULL )
01487 {
01488 Menu->Current = Menu->Current->Next;
01489 }
01490 }
01491
01492 while (Menu->Current->Identifier == 0xffff)
01493 {
01494
01495 if ( Menu->Current->Prev != NULL )
01496 {
01497 Menu->Current = Menu->Current->Prev;
01498 }
01499
01500 else
01501 {
01502 while ( Menu->Current->Next != NULL )
01503 {
01504 Menu->Current = Menu->Current->Next;
01505 }
01506 }
01507 }
01508 break;
01509 }
01510
01511
01512 case VK_DOWN:
01513 {
01514
01515
01516 if ( Menu->Current->Next != NULL )
01517 {
01518 Menu->Current = Menu->Current->Next;
01519 }
01520
01521 else
01522 {
01523 Menu->Current = Menu->Head;
01524 }
01525
01526 while (Menu->Current->Identifier == 0xffff)
01527 {
01528 if ( Menu->Current->Next != NULL )
01529 {
01530 Menu->Current = Menu->Current->Next;
01531 }
01532 else
01533 {
01534 Menu->Current = Menu->Head;
01535 }
01536 }
01537
01538 break;
01539 }
01540
01541
01542 case VK_LEFT:
01543 {
01544
01545
01546 if ( Menu->Current->ItemType == Menu_ItemSlider )
01547 {
01548
01549
01550 MenuItemSlider_T *Data;
01551
01552
01553 Data = (MenuItemSlider_T *)Menu->Current->Data;
01554 assert( Data != NULL );
01555
01556
01557 Data->Percent -= Data->Increment;
01558 if ( Data->Percent < 0.01f )
01559 {
01560 Data->Percent = 0.0f;
01561 }
01562 }
01563 break;
01564 }
01565
01566
01567 case VK_RIGHT:
01568 {
01569
01570
01571 if ( Menu->Current->ItemType == Menu_ItemSlider )
01572 {
01573
01574
01575 MenuItemSlider_T *Data;
01576
01577
01578 Data = (MenuItemSlider_T *)Menu->Current->Data;
01579 assert( Data != NULL );
01580
01581
01582 Data->Percent += Data->Increment;
01583 if ( Data->Percent > 0.99f )
01584 {
01585 Data->Percent = 1.0f;
01586 }
01587 }
01588 break;
01589 }
01590 }
01591
01592
01593 return Menu->Current->Identifier;
01594
01595 }