/
hu_lib.h
1346 lines (1077 loc) · 36 KB
/
hu_lib.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/**\file hu_lib.c
*\section License
* License: GPL
* Online License Link: http://www.gnu.org/licenses/gpl.html
*
*\author Copyright © 2005-2013 Jaakko Keränen <jaakko.keranen@iki.fi>
*\author Copyright © 2005-2013 Daniel Swanson <danij@dengine.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301 USA
*/
#ifndef LIBCOMMON_GUI_LIBRARY_H
#define LIBCOMMON_GUI_LIBRARY_H
#if __JDOOM__
# include "jdoom.h"
#elif __JDOOM64__
# include "jdoom64.h"
#elif __JHERETIC__
# include "jheretic.h"
#elif __JHEXEN__
# include "jhexen.h"
#endif
#include "hu_stuff.h"
struct mn_object_s;
struct mn_page_s;
typedef enum menucommand_e {
MCMD_OPEN, // Open the menu.
MCMD_CLOSE, // Close the menu.
MCMD_CLOSEFAST, // Instantly close the menu.
MCMD_NAV_OUT, // Navigate "out" of the current menu/widget (up a level).
MCMD_NAV_LEFT,
MCMD_NAV_RIGHT,
MCMD_NAV_DOWN,
MCMD_NAV_UP,
MCMD_NAV_PAGEDOWN,
MCMD_NAV_PAGEUP,
MCMD_SELECT, // Execute whatever action is attaced to the current item.
MCMD_DELETE
} menucommand_e;
// Menu object types.
typedef enum {
MN_NONE,
MN_RECT,
MN_TEXT,
MN_BUTTON,
MN_EDIT,
MN_LIST,
MN_LISTINLINE,
MN_SLIDER,
MN_COLORBOX,
MN_BINDINGS,
MN_MOBJPREVIEW
} mn_obtype_e;
/**
* @defgroup menuObjectFlags Menu Object Flags
*/
///@{
#define MNF_HIDDEN 0x1
#define MNF_DISABLED 0x2 ///< Can't be interacted with.
#define MNF_PAUSED 0x4 ///< Ticker not called.
#define MNF_CLICKED 0x8
#define MNF_ACTIVE 0x10 ///< Object active.
#define MNF_FOCUS 0x20 ///< Has focus.
#define MNF_NO_FOCUS 0x40 ///< Can't receive focus.
#define MNF_DEFAULT 0x80 ///< Has focus by default.
#define MNF_POSITION_FIXED 0x100 ///< XY position is fixed and predefined; automatic layout does not apply.
#define MNF_LAYOUT_OFFSET 0x200 ///< Predefined XY position is applied to the dynamic layout origin.
//#define MNF_LEFT_ALIGN 0x100
//#define MNF_FADE_AWAY 0x200 // Fade UI away while the control is active.
//#define MNF_NEVER_FADE 0x400
/// @todo We need a new dynamic id allocating mechanism.
#define MNF_ID7 0x1000000
#define MNF_ID6 0x2000000
#define MNF_ID5 0x4000000
#define MNF_ID4 0x8000000
#define MNF_ID3 0x10000000
#define MNF_ID2 0x20000000
#define MNF_ID1 0x40000000
#define MNF_ID0 0x80000000
///@}
typedef enum {
FO_CLEAR,
FO_SET,
FO_TOGGLE
} flagop_t;
/**
* Logical Menu (object) Action identifiers. Associated with/to events which
* produce/result-in callbacks made either automatically by this subsystem,
* or "actioned" through the type-specific event/command responders of the
* various widgets, according to their own widget-specific logic.
*/
typedef enum {
MNA_NONE = -1,
MNACTION_FIRST = 0,
MNA_MODIFIED = MNACTION_FIRST, /// Object's internal "modified" status changed.
MNA_ACTIVEOUT, /// Deactivated i.e., no longer active.
MNA_ACTIVE, /// Becomes "active".
MNA_CLOSE, /// Normally means changed-state to be discarded.
MNA_FOCUSOUT, /// Loses selection "focus".
MNA_FOCUS, /// Gains selection "focus".
MNACTION_LAST = MNA_FOCUS
} mn_actionid_t;
/// Total number of known Menu Actions.
#define MNACTION_COUNT (MNACTION_LAST + 1 - MNACTION_FIRST)
/// Non-zero if the value @a val can be interpreted as a known, valid Menu Action identifier.
#define VALID_MNACTION(val) ((id) >= MNACTION_FIRST && (id) <= MNACTION_LAST)
/**
* Menu Action Info (Record). Holds information about an "actionable" menu
* event, such as an object being activated or upon receiving focus.
*/
typedef struct {
/// Callback to be made when this action is executed. Can be @c NULL in
/// which case attempts to action this will be NOPs.
///
/// @param obj Object being referenced for this callback.
/// @param action Identifier of the Menu Action to be processed.
/// @param paramaters Passed to the callback from event which actioned this.
/// @return Callback return value. Callback should return zero if the action
/// was recognised and processed, regardless of outcome.
int (*callback) (struct mn_object_s* obj, mn_actionid_t action, void* paramaters);
} mn_actioninfo_t;
/**
* MNObject. Abstract base from which all menu page objects must be derived.
*/
typedef struct mn_object_s {
/// Type of the object.
mn_obtype_e _type;
/// Object group identifier.
int _group;
/// @ref menuObjectFlags.
int _flags;
/// Used with the fixed layout method for positioning this object in
/// the owning page's coordinate space.
Point2Raw _origin;
/// DDKEY shortcut used to switch focus to this object directly.
/// @c 0= no shortcut defined.
int _shortcut;
/// Index of the predefined page font to use when drawing this.
int _pageFontIdx;
/// Index of the predefined page color to use when drawing this.
int _pageColorIdx;
/// Process time (the "tick") for this object.
void (*ticker) (struct mn_object_s* ob);
/// Calculate geometry for this when visible on the specified page.
void (*updateGeometry) (struct mn_object_s* ob, struct mn_page_s* page);
/// Draw this at the specified offset within the owning view-space.
/// Can be @c NULL in which case this will never be drawn.
void (*drawer) (struct mn_object_s* ob, const Point2Raw* origin);
/// Info about "actionable event" callbacks.
mn_actioninfo_t actions[MNACTION_COUNT];
/// Respond to the given (menu) @a command. Can be @c NULL.
/// @return @c true if the command is eaten.
int (*cmdResponder) (struct mn_object_s* ob, menucommand_e command);
/// Respond to the given (input) event @a ev. Can be @c NULL.
/// @return @c true if the event is eaten.
int (*responder) (struct mn_object_s* ob, event_t* ev);
/// Respond to the given (input) event @a ev. Can be @c NULL.
/// @return @c true if the event is eaten.
int (*privilegedResponder) (struct mn_object_s* ob, event_t* ev);
void* _typedata; // Type-specific extra data.
// Extra property values.
void* data1;
int data2;
// Auto initialized:
/// Current geometry.
Rect* _geometry;
/// MenuPage which owns this object (if any).
struct mn_page_s* _page;
int timer;
} mn_object_t;
#ifdef __cplusplus
extern "C" {
#endif
mn_obtype_e MNObject_Type(const mn_object_t* obj);
struct mn_page_s* MNObject_Page(const mn_object_t* obj);
int MNObject_Flags(const mn_object_t* obj);
/**
* Retrieve the current geometry of object within the two-dimensioned
* coordinate space of the owning object.
*
* @return Rectangluar region of the parent space.
*/
const Rect* MNObject_Geometry(const mn_object_t* obj);
/**
* Retrieve the origin of the object within the two-dimensioned coordinate
* space of the owning object.
* @return Origin point within the parent space.
*/
const Point2* MNObject_Origin(const mn_object_t* obj);
/**
* Retrieve the boundary dimensions of the object expressed as units of
* the coordinate space of the owning object.
* @return Size of this object in units of the parent's coordinate space.
*/
const Size2* MNObject_Size(const mn_object_t* obj);
/**
* Retreive the current fixed origin coordinates.
*
* @param ob MNObject-derived instance.
* @return Fixed origin.
*/
const Point2Raw* MNObject_FixedOrigin(const mn_object_t* ob);
int MNObject_FixedX(const mn_object_t* ob);
int MNObject_FixedY(const mn_object_t* ob);
/**
* Change the current fixed origin coordinates.
*
* @param ob MNObject-derived instance.
* @param origin New origin coordinates.
* @return Same as @a ob for caller convenience.
*/
mn_object_t* MNObject_SetFixedOrigin(mn_object_t* ob, const Point2Raw* origin);
mn_object_t* MNObject_SetFixedX(mn_object_t* ob, int x);
mn_object_t* MNObject_SetFixedY(mn_object_t* ob, int y);
/// @return Flags value post operation for caller convenience.
int MNObject_SetFlags(mn_object_t* obj, flagop_t op, int flags);
int MNObject_Shortcut(mn_object_t* obj);
void MNObject_SetShortcut(mn_object_t* obj, int ddkey);
/// @return Index of the font used from the owning/active page.
int MNObject_Font(mn_object_t* obj);
/// @return Index of the color used from the owning/active page.
int MNObject_Color(mn_object_t* obj);
dd_bool MNObject_IsGroupMember(const mn_object_t* obj, int group);
int MNObject_DefaultCommandResponder(mn_object_t* obj, menucommand_e command);
/**
* Lookup the unique ActionInfo associated with the identifier @a id.
* @return Associated info if found else @c NULL.
*/
const mn_actioninfo_t* MNObject_Action(mn_object_t*obj, mn_actionid_t action);
/// @return @c true if this object has a registered executeable action
/// associated with the unique identifier @a action.
dd_bool MNObject_HasAction(mn_object_t* obj, mn_actionid_t action);
/**
* Execute the action associated with @a id
* @param action Identifier of the action to be executed (if found).
* @param paramaters Passed to the action callback.
* @return Return value of the executed action else @c -1 if NOP.
*/
int MNObject_ExecAction(mn_object_t* obj, mn_actionid_t action, void* paramaters);
#ifdef __cplusplus
} // extern "C"
#endif
typedef enum {
MENU_COLOR1 = 0,
MENU_COLOR2,
MENU_COLOR3,
MENU_COLOR4,
MENU_COLOR5,
MENU_COLOR6,
MENU_COLOR7,
MENU_COLOR8,
MENU_COLOR9,
MENU_COLOR10,
MENU_COLOR_COUNT
} mn_page_colorid_t;
#define VALID_MNPAGE_COLORID(v) ((v) >= MENU_COLOR1 && (v) < MENU_COLOR_COUNT)
typedef enum {
MENU_FONT1 = 0,
MENU_FONT2,
MENU_FONT3,
MENU_FONT4,
MENU_FONT5,
MENU_FONT6,
MENU_FONT7,
MENU_FONT8,
MENU_FONT9,
MENU_FONT10,
MENU_FONT_COUNT
} mn_page_fontid_t;
#define VALID_MNPAGE_FONTID(v) ((v) >= MENU_FONT1 && (v) < MENU_FONT_COUNT)
/**
* @defgroup menuPageFlags Menu Page Flags
*/
///@{
#define MPF_LAYOUT_FIXED 0x1 ///< Page uses a fixed layout.
#define MPF_NEVER_SCROLL 0x2 ///< Page scrolling is disabled.
///@}
typedef struct mn_page_s {
/// Collection of objects on this page.
mn_object_t* objects;
int objectsCount;
/// "Physical" geometry in fixed 320x200 screen coordinate space.
Point2Raw origin;
Rect* geometry;
/// Previous page else @c NULL
struct mn_page_s* previous;
/// Title of this page.
ddstring_t title;
/// Index of the currently focused object else @c -1
int focus;
/// @ref menuPageFlags
int flags;
/// Predefined fonts objects on this page.
fontid_t fonts[MENU_FONT_COUNT];
/// Predefined colors for objects on this page.
uint colors[MENU_COLOR_COUNT];
/// Process time (the "tick") for this object.
void (*ticker) (struct mn_page_s* page);
/// Page drawing routine.
void (*drawer) (struct mn_page_s* page, const Point2Raw* offset);
/// Menu-command responder routine.
int (*cmdResponder) (struct mn_page_s* page, menucommand_e cmd);
/// User data.
void* userData;
int timer;
} mn_page_t;
#ifdef __cplusplus
extern "C" {
#endif
void MNPage_Initialize(mn_page_t* page);
/// Call the ticker routine for each object.
void MNPage_Ticker(mn_page_t* page);
void MNPage_SetTitle(mn_page_t* page, const char* title);
void MNPage_SetX(mn_page_t* page, int x);
void MNPage_SetY(mn_page_t* page, int y);
void MNPage_SetPreviousPage(mn_page_t* page, mn_page_t* prevPage);
void MNPage_Refocus(mn_page_t* page);
/// @return Currently focused object; otherwise @c 0.
mn_object_t *MNPage_FocusObject(mn_page_t *page);
void MNPage_ClearFocusObject(mn_page_t *page);
/**
* Attempt to give focus to the MNObject @a obj which is thought to be on the
* page. If @a obj is found to present and is not currently in-focus, an out-focus
* action is first sent to the presently focused object, then this page's focused
* object is set before finally executing an in-focus action on the new object.
* If the object is not found on this page then nothing will happen.
*
* @param obj MNObject to be given focus.
*/
void MNPage_SetFocus(mn_page_t *page, mn_object_t *obj);
/**
* Determines the size of the menu cursor for the currently focused widget. If
* no widget is currently focused the default cursor size (i.e., the effective
* line height for @c MENU_FONT1) is used. (Which means this should @em not be
* called to determine whether the cursor is actually in use -- for that purpose,
* use @ref MNPage_FocusObject() instead).
*/
int MNPage_CursorSize(mn_page_t *page);
/**
* Retrieve an object on this page in the specified object group.
*
* @param flags @ref mnobjectFlags used to locate the object. All flags specified
* must be set.
*
* @return Found MNObject else @c NULL
*/
mn_object_t *MNPage_FindObject(mn_page_t *page, int group, int flags);
/**
* Retrieve a predefined color triplet associated with this page by it's logical
* page color identifier.
*
* @param id Unique identifier of the predefined color being retrieved.
* @param rgb Found color values are written here, else set to white.
*/
void MNPage_PredefinedColor(mn_page_t *page, mn_page_colorid_t id, float rgb[3]);
/**
* Retrieve a predefined Doomsday font-identifier associated with this page
* by it's logical page font identifier.
*
* @param id Unique identifier of the predefined font being retrieved.
*
* @return Identifier of the found font else @c 0
*/
fontid_t MNPage_PredefinedFont(mn_page_t *page, mn_page_fontid_t id);
void MNPage_SetPredefinedFont(mn_page_t *page, mn_page_fontid_t id, fontid_t fontId);
/**
* Returns the effective line height for the predefined @c MENU_FONT1.
*
* @param lineOffset If not @c 0 the line offset is written here.
*/
int MNPage_LineHeight2(mn_page_t *page, int *lineOffset);
int MNPage_LineHeight(mn_page_t *page/*, lineOffset = 0*/);
/// @return Current time in tics since page activation.
int MNPage_Timer(mn_page_t* page);
#ifdef __cplusplus
} // extern "C"
#endif
/**
* Rect objects.
*/
typedef struct mndata_rect_s {
/// Dimensions of the rectangle.
Size2Raw dimensions;
/// Background patch.
patchid_t patch;
} mndata_rect_t;
#ifdef __cplusplus
extern "C" {
#endif
mn_object_t* MNRect_New(void);
void MNRect_Delete(mn_object_t* ob);
void MNRect_Ticker(mn_object_t* ob);
void MNRect_Drawer(mn_object_t* ob, const Point2Raw* origin);
void MNRect_UpdateGeometry(mn_object_t* ob, mn_page_t* page);
/**
* Apply the Patch graphic referenced by @a patch as the background for this rect.
*
* @param ob MNObject instance.
* @param patch Unique identifier of the patch. If @c <= 0 the current background
* will be cleared and the Rect will be drawn as a solid color.
*/
void MNRect_SetBackgroundPatch(mn_object_t* ob, patchid_t patch);
#ifdef __cplusplus
} // extern "C"
#endif
/**
* @defgroup mnTextFlags MNText Flags
*/
///@{
#define MNTEXT_NO_ALTTEXT 0x1 ///< Do not use alt text instead of lump.
///@}
/**
* Text objects.
*/
typedef struct mndata_text_s {
char const *text;
/// Patch to be used when drawing this instead of text if Patch Replacement is in use.
patchid_t *patch;
/// @ref mnTextFlags
int flags;
} mndata_text_t;
#ifdef __cplusplus
extern "C" {
#endif
mn_object_t* MNText_New(void);
void MNText_Delete(mn_object_t* ob);
void MNText_Ticker(mn_object_t* ob);
void MNText_Drawer(mn_object_t* ob, const Point2Raw* origin);
void MNText_UpdateGeometry(mn_object_t* ob, mn_page_t* page);
int MNText_SetFlags(mn_object_t* ob, flagop_t op, int flags);
#ifdef __cplusplus
} // extern "C"
#endif
/**
* @defgroup mnButtonFlags MNButton Flags
*/
///@{
#define MNBUTTON_NO_ALTTEXT 0x1 ///< Do not use alt text instead of lump.
///@}
/**
* Buttons.
*/
typedef struct mndata_button_s {
dd_bool staydownMode; /// @c true= this is operating in two-state "staydown" mode.
void *data;
/// Label text.
char const *text;
/// Patch to be used when drawing this instead of text.
patchid_t *patch;
char const *yes, *no;
/// @ref mnButtonFlags
int flags;
} mndata_button_t;
#ifdef __cplusplus
extern "C" {
#endif
mn_object_t* MNButton_New(void);
void MNButton_Delete(mn_object_t* ob);
void MNButton_Ticker(mn_object_t* ob);
void MNButton_Drawer(mn_object_t* ob, const Point2Raw* origin);
int MNButton_CommandResponder(mn_object_t* ob, menucommand_e command);
void MNButton_UpdateGeometry(mn_object_t* ob, mn_page_t* page);
int MNButton_SetFlags(mn_object_t* ob, flagop_t op, int flags);
#ifdef __cplusplus
} // extern "C"
#endif
/**
* Edit field.
*/
#if __JDOOM__ || __JDOOM64__
# define MNDATA_EDIT_TEXT_COLORIDX (0)
# define MNDATA_EDIT_OFFSET_X (0)
# define MNDATA_EDIT_OFFSET_Y (0)
# define MNDATA_EDIT_BACKGROUND_OFFSET_X (-11)
# define MNDATA_EDIT_BACKGROUND_OFFSET_Y (-4)
# define MNDATA_EDIT_BACKGROUND_PATCH_LEFT ("M_LSLEFT")
# define MNDATA_EDIT_BACKGROUND_PATCH_RIGHT ("M_LSRGHT")
# define MNDATA_EDIT_BACKGROUND_PATCH_MIDDLE ("M_LSCNTR")
#elif __JHERETIC__ || __JHEXEN__
# define MNDATA_EDIT_TEXT_COLORIDX (2)
# define MNDATA_EDIT_OFFSET_X (13)
# define MNDATA_EDIT_OFFSET_Y (5)
# define MNDATA_EDIT_BACKGROUND_OFFSET_X (-13)
# define MNDATA_EDIT_BACKGROUND_OFFSET_Y (-5)
//# define MNDATA_EDIT_BACKGROUND_PATCH_LEFT ("")
//# define MNDATA_EDIT_BACKGROUND_PATCH_RIGHT ("")
# define MNDATA_EDIT_BACKGROUND_PATCH_MIDDLE ("M_FSLOT")
#endif
typedef struct mndata_edit_s {
ddstring_t text;
ddstring_t oldtext; // If the current edit is canceled...
uint maxLength;
uint maxVisibleChars;
char const *emptyString; // Drawn when editfield is empty/null.
void *data1;
} mndata_edit_t;
#ifdef __cplusplus
extern "C" {
#endif
mn_object_t* MNEdit_New(void);
void MNEdit_Delete(mn_object_t* ob);
void MNEdit_Ticker(mn_object_t* ob);
void MNEdit_Drawer(mn_object_t* ob, const Point2Raw* origin);
int MNEdit_CommandResponder(mn_object_t* ob, menucommand_e command);
int MNEdit_Responder(mn_object_t* ob, event_t* ev);
void MNEdit_UpdateGeometry(mn_object_t* ob, mn_page_t* page);
uint MNEdit_MaxLength(mn_object_t* ob);
void MNEdit_SetMaxLength(mn_object_t* ob, uint newMaxLength);
/**
* @defgroup mneditSetTextFlags MNEdit Set Text Flags
* @{
*/
#define MNEDIT_STF_NO_ACTION 0x1 /// Do not call any linked action function.
#define MNEDIT_STF_REPLACEOLD 0x2 /// Replace the "old" copy (used for canceled edits).
/**@}*/
/// @return A pointer to an immutable copy of the current contents of the edit field.
const ddstring_t* MNEdit_Text(mn_object_t* ob);
/**
* Change the current contents of the edit field.
* @param flags @ref mneditSetTextFlags
* @param string New text string which will replace the existing string.
*/
void MNEdit_SetText(mn_object_t* ob, int flags, const char* string);
#ifdef __cplusplus
} // extern "C"
#endif
/**
* List selection.
*/
#define MNDATA_LIST_LEADING .5f /// Inter-item leading factor (does not apply to MNListInline_Drawer).
#define MNDATA_LIST_NONSELECTION_LIGHT .7f /// Light value multiplier for non-selected items (does not apply to MNListInline_Drawer).
#define NUMLISTITEMS(x) (sizeof(x)/sizeof(mndata_listitem_t))
typedef struct {
const char* text;
int data;
} mndata_listitem_t;
/// @note Also used for MN_LISTINLINE!
typedef struct mndata_list_s {
void *items;
int count; // Number of items.
void *data;
int mask;
int selection; // Selected item (-1 if none).
int first; // First visible item.
int numvis;
} mndata_list_t;
#ifdef __cplusplus
extern "C" {
#endif
mn_object_t* MNList_New(void);
void MNList_Delete(mn_object_t* ob);
void MNList_Ticker(mn_object_t* ob);
void MNList_Drawer(mn_object_t* ob, const Point2Raw* origin);
int MNList_CommandResponder(mn_object_t* ob, menucommand_e command);
void MNList_UpdateGeometry(mn_object_t* ob, mn_page_t* page);
/// @return Index of the currently selected item else -1.
int MNList_Selection(mn_object_t* ob);
/// @return Data of item at position @a index. 0 if index is out of bounds.
int MNList_ItemData(const mn_object_t* obj, int index);
/// @return @c true if the currently selected item is presently visible.
dd_bool MNList_SelectionIsVisible(mn_object_t* ob);
/// @return Index of the found item associated with @a dataValue else -1.
int MNList_FindItem(const mn_object_t* ob, int dataValue);
mn_object_t* MNListInline_New(void);
void MNListInline_Delete(mn_object_t* ob);
void MNListInline_Ticker(mn_object_t* ob);
void MNListInline_Drawer(mn_object_t* ob, const Point2Raw* origin);
int MNListInline_CommandResponder(mn_object_t* ob, menucommand_e command);
void MNListInline_UpdateGeometry(mn_object_t* ob, mn_page_t* page);
/**
* @defgroup mnlistSelectItemFlags MNList Select Item Flags
*/
///@{
#define MNLIST_SIF_NO_ACTION 0x1 /// Do not call any linked action function.
///@}
/**
* Change the currently selected item.
* @param flags @ref mnlistSelectItemFlags
* @param itemIndex Index of the new selection.
* @return @c true if the selected item changed.
*/
dd_bool MNList_SelectItem(mn_object_t* ob, int flags, int itemIndex);
/**
* Change the currently selected item by looking up its data value.
* @param flags @ref mnlistSelectItemFlags
* @param dataValue Value associated to the candidate item being selected.
* @return @c true if the selected item changed.
*/
dd_bool MNList_SelectItemByValue(mn_object_t* ob, int flags, int itemIndex);
#ifdef __cplusplus
} // extern "C"
#endif
/**
* Color preview box.
*/
#define MNDATA_COLORBOX_WIDTH 4 // Default inner width in fixed 320x200 space.
#define MNDATA_COLORBOX_HEIGHT 4 // Default inner height in fixed 320x200 space.
typedef struct mndata_colorbox_s {
/// Inner dimensions in fixed 320x200 space. If @c <= 0 the default
/// dimensions will be used instead.
int width, height;
float r, g, b, a;
dd_bool rgbaMode;
void *data1;
void *data2;
void *data3;
void *data4;
} mndata_colorbox_t;
#ifdef __cplusplus
extern "C" {
#endif
mn_object_t* MNColorBox_New(void);
void MNColorBox_Delete(mn_object_t* ob);
void MNColorBox_Ticker(mn_object_t* ob);
void MNColorBox_Drawer(mn_object_t* ob, const Point2Raw* origin);
int MNColorBox_CommandResponder(mn_object_t* ob, menucommand_e command);
void MNColorBox_UpdateGeometry(mn_object_t* ob, mn_page_t* page);
/// @return @c true if this colorbox is operating in RGBA mode.
dd_bool MNColorBox_RGBAMode(mn_object_t* ob);
/// @return Current red color component.
float MNColorBox_Redf(const mn_object_t* ob);
/// @return Current green color component.
float MNColorBox_Greenf(const mn_object_t* ob);
/// @return Current blue color component.
float MNColorBox_Bluef(const mn_object_t* ob);
/// @return Current alpha value or @c 1 if this colorbox is not
/// operating in "rgba mode".
float MNColorBox_Alphaf(const mn_object_t* ob);
/**
* @defgroup mncolorboxSetColorFlags MNColorBox Set Color Flags.
*/
///@{
#define MNCOLORBOX_SCF_NO_ACTION 0x1 /// Do not call any linked action function.
///@}
/**
* Change the current color of the color box.
* @param flags @ref mncolorboxSetColorFlags
* @param rgba New color and alpha. Note: will be NOP if this colorbox
* is not operating in "rgba mode".
* @return @c true if the current color changed.
*/
dd_bool MNColorBox_SetColor4fv(mn_object_t* ob, int flags, float rgba[4]);
dd_bool MNColorBox_SetColor4f(mn_object_t* ob, int flags, float red, float green,
float blue, float alpha);
/// Change the current red color component.
/// @return @c true if the value changed.
dd_bool MNColorBox_SetRedf(mn_object_t* ob, int flags, float red);
/// Change the current green color component.
/// @return @c true if the value changed.
dd_bool MNColorBox_SetGreenf(mn_object_t* ob, int flags, float green);
/// Change the current blue color component.
/// @return @c true if the value changed.
dd_bool MNColorBox_SetBluef(mn_object_t* ob, int flags, float blue);
/// Change the current alpha value. Note: will be NOP if this colorbox
/// is not operating in "rgba mode".
/// @return @c true if the value changed.
dd_bool MNColorBox_SetAlphaf(mn_object_t* ob, int flags, float alpha);
/**
* Copy the current color from @a other.
* @param flags @ref mncolorboxSetColorFlags
* @return @c true if the current color changed.
*/
dd_bool MNColorBox_CopyColor(mn_object_t* ob, int flags, const mn_object_t* otherObj);
#ifdef __cplusplus
} // extern "C"
#endif
/**
* Graphical slider.
*/
#define MNDATA_SLIDER_SLOTS (10)
#define MNDATA_SLIDER_SCALE (.75f)
#if __JDOOM__ || __JDOOM64__
# define MNDATA_SLIDER_OFFSET_X (0)
# define MNDATA_SLIDER_OFFSET_Y (0)
# define MNDATA_SLIDER_PATCH_LEFT ("M_THERML")
# define MNDATA_SLIDER_PATCH_RIGHT ("M_THERMR")
# define MNDATA_SLIDER_PATCH_MIDDLE ("M_THERMM")
# define MNDATA_SLIDER_PATCH_HANDLE ("M_THERMO")
#elif __JHERETIC__ || __JHEXEN__
# define MNDATA_SLIDER_OFFSET_X (0)
# define MNDATA_SLIDER_OFFSET_Y (1)
# define MNDATA_SLIDER_PATCH_LEFT ("M_SLDLT")
# define MNDATA_SLIDER_PATCH_RIGHT ("M_SLDRT")
# define MNDATA_SLIDER_PATCH_MIDDLE ("M_SLDMD1")
# define MNDATA_SLIDER_PATCH_HANDLE ("M_SLDKB")
#endif
typedef struct mndata_slider_s {
float min, max;
float value;
float step; // Button step.
dd_bool floatMode; // Otherwise only integers are allowed.
/// @todo Turn this into a property record or something.
void *data1;
void *data2;
void *data3;
void *data4;
void *data5;
} mndata_slider_t;
#ifdef __cplusplus
extern "C" {
#endif
mn_object_t* MNSlider_New(void);
void MNSlider_Delete(mn_object_t* ob);
void MNSlider_Ticker(mn_object_t* ob);
void MNSlider_Drawer(mn_object_t* ob, const Point2Raw* origin);
void MNSlider_TextualValueDrawer(mn_object_t* ob, const Point2Raw* origin);
int MNSlider_CommandResponder(mn_object_t* ob, menucommand_e command);
void MNSlider_UpdateGeometry(mn_object_t* ob, mn_page_t* page);
void MNSlider_TextualValueUpdateGeometry(mn_object_t* ob, mn_page_t* page);
int MNSlider_ThumbPos(const mn_object_t* ob);
/// @return Current value represented by the slider.
float MNSlider_Value(const mn_object_t* ob);
/**
* @defgroup mnsliderSetValueFlags MNSlider Set Value Flags
*/
///@{
#define MNSLIDER_SVF_NO_ACTION 0x1 /// Do not call any linked action function.
///@}
/**
* Change the current value represented by the slider.
* @param flags @ref mnsliderSetValueFlags
* @param value New value.
*/
void MNSlider_SetValue(mn_object_t* ob, int flags, float value);
#ifdef __cplusplus
} // extern "C"
#endif
/**
* Mobj preview visual.
*/
#define MNDATA_MOBJPREVIEW_WIDTH 44
#define MNDATA_MOBJPREVIEW_HEIGHT 66
typedef struct mndata_mobjpreview_s {
int mobjType;
/// Color translation class and map.
int tClass, tMap;
int plrClass; /// Player class identifier.
} mndata_mobjpreview_t;
#ifdef __cplusplus
extern "C" {
#endif
mn_object_t* MNMobjPreview_New(void);
void MNMobjPreview_Delete(mn_object_t* ob);
void MNMobjPreview_Ticker(mn_object_t* ob);
void MNMobjPreview_SetMobjType(mn_object_t* ob, int mobjType);
void MNMobjPreview_SetPlayerClass(mn_object_t* ob, int plrClass);
void MNMobjPreview_SetTranslationClass(mn_object_t* ob, int tClass);
void MNMobjPreview_SetTranslationMap(mn_object_t* ob, int tMap);
void MNMobjPreview_Drawer(mn_object_t* ob, const Point2Raw* origin);
void MNMobjPreview_UpdateGeometry(mn_object_t* ob, mn_page_t* page);
#ifdef __cplusplus
} // extern "C"
#endif
// Menu render state:
typedef struct mn_rendstate_s {
float pageAlpha;
float textGlitter;
float textShadow;
float textColors[MENU_COLOR_COUNT][4];
fontid_t textFonts[MENU_FONT_COUNT];
} mn_rendstate_t;
DENG_EXTERN_C mn_rendstate_t const *mnRendState;
/**
* @defgroup menuEffectFlags Menu Effect Flags
*/
///@{
#define MEF_TEXT_TYPEIN (DTF_NO_TYPEIN)
#define MEF_TEXT_SHADOW (DTF_NO_SHADOW)
#define MEF_TEXT_GLITTER (DTF_NO_GLITTER)
#define MEF_EVERYTHING (MEF_TEXT_TYPEIN|MEF_TEXT_SHADOW|MEF_TEXT_GLITTER)
///@}
#ifdef __cplusplus
extern "C" {
#endif
short MN_MergeMenuEffectWithDrawTextFlags(short f);
mn_object_t* MN_MustFindObjectOnPage(mn_page_t* page, int group, int flags);
void MN_DrawPage(mn_page_t* page, float alpha, dd_bool showFocusCursor);
/**
* Execute a menu navigation/action command.
*/
void Hu_MenuCommand(menucommand_e cmd);
#ifdef __cplusplus
} // extern "C"
#endif
typedef enum {
GUI_NONE,
GUI_BOX,
GUI_GROUP,
GUI_HEALTH,
GUI_ARMOR,
GUI_KEYS,
GUI_READYAMMO,
GUI_FRAGS,
GUI_LOG,
GUI_CHAT,
#if __JDOOM__
GUI_AMMO,
GUI_WEAPONSLOT,