Changeset 27
- Timestamp:
- 03/31/07 14:11:05 (2 years ago)
- Files:
-
- trunk/src/Makefile.std (modified) (1 diff)
- trunk/src/birth.c (modified) (6 diffs)
- trunk/src/cmd4.c (modified) (20 diffs)
- trunk/src/dungeon.c (modified) (1 diff)
- trunk/src/externs.h (modified) (2 diffs)
- trunk/src/init2.c (modified) (1 diff)
- trunk/src/ui.c (modified) (21 diffs)
- trunk/src/ui.h (modified) (10 diffs)
- trunk/src/util.c (modified) (4 diffs)
- trunk/src/z-term.c (modified) (5 diffs)
- trunk/src/z-term.h (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/src/Makefile.std
r16 r27 128 128 #### Targets and objects ##### 129 129 130 # Set a target here 131 default: $(EXE) 130 # By default, copy the executable to ../ so that you don't find 131 # yourself debugging a stale copy. 132 default: install 132 133 133 134 # Makefile.inc contains an up-to-date set of object files to compile, so trunk/src/birth.c
r22 r27 687 687 static region class_region = {CLASS_COL, TABLE_ROW, 19, -2}; 688 688 689 static void show_help(cptr helpfile, cptr topic) { 690 char buf[80]; 691 strnfmt(buf, sizeof(buf), "%s#%s", helpfile, topic); 692 screen_save(); 693 show_file(buf, NULL, 0, 0); 694 screen_load(); 689 690 /* Event handler implementation */ 691 static bool handler_aux(char cmd, int oid, byte *val, int max, int mask, cptr topic) 692 { 693 if(cmd == '\xff' || cmd == '\r') { 694 *val = oid; 695 } 696 else if(cmd == '*') { 697 for(;;) { 698 oid = rand_int(max); 699 *val = oid; 700 if(mask & (1L << oid)) break; 701 } 702 } 703 else if(cmd == '=') do_cmd_options(); 704 else if(cmd == KTRL('X')) quit(NULL); 705 else if(cmd == '?') { 706 char buf[80]; 707 strnfmt(buf, sizeof(buf), "%s#%s", "birth.txt", topic); 708 screen_save(); 709 show_file(buf, NULL, 0, 0); 710 screen_load(); 711 } 712 else return FALSE; 713 714 sp_ptr = &sex_info[p_ptr->psex]; 715 rp_ptr = &p_info[p_ptr->prace]; 716 cp_ptr = &c_info[p_ptr->pclass]; 717 mp_ptr = &cp_ptr->spells; 718 return TRUE; 695 719 } 696 720 697 721 /* GENDER */ 698 /* Could make a general purpose display, but see no point.*/722 /* Display a gender */ 699 723 static void display_gender(menu_type *menu, int oid, bool cursor, 700 724 int row, int col, int width) … … 704 728 } 705 729 706 /* Not worth writing a general purpose handler */707 730 static bool gender_handler(char cmd, const void *db, int oid) 708 731 { 709 if(cmd == '\xff' || cmd == '\r') { 710 p_ptr->psex = oid; 711 sp_ptr = &sex_info[p_ptr->psex]; 712 } 713 else if(cmd == '*') { 714 p_ptr->psex = rand_int(SEX_MALE+1); 715 sp_ptr = &sex_info[p_ptr->psex]; 716 } 717 else if(cmd == '=') do_cmd_options(); 718 else if(cmd == KTRL('X')) quit(NULL); 719 else if(cmd == '?') show_help("birth.txt", sex_info[oid].title); 720 else return FALSE; 721 return TRUE; 732 return handler_aux(cmd, oid, &p_ptr->psex, SEX_MALE+1, 733 0xffffffff, sex_info[oid].title); 722 734 } 723 735 … … 732 744 static bool race_handler(char cmd, const void *db, int oid) 733 745 { 734 if(cmd == '\xff' || cmd == '\r') { 735 p_ptr->prace = oid; 736 rp_ptr = &p_info[p_ptr->prace]; 737 } 738 else if(cmd == '*') { 739 p_ptr->prace = rand_int(z_info->p_max); 740 rp_ptr = &p_info[p_ptr->prace]; 741 } 742 else if(cmd == '=') do_cmd_options(); 743 else if(cmd == KTRL('X')) quit(NULL); 744 else if(cmd == '?') show_help("birth.txt", p_name+p_info[oid].name); 745 else return FALSE; 746 return TRUE; 747 } 748 746 return handler_aux(cmd, oid, &p_ptr->prace, z_info->p_max, 747 0xffffffff, p_name+p_info[oid].name); 748 } 749 749 750 750 /* CLASS */ … … 758 758 static bool class_handler(char cmd, const void *db, int oid) 759 759 { 760 if(cmd == '\xff' || cmd == '\r') { 761 p_ptr->pclass = oid; 762 cp_ptr = &c_info[p_ptr->pclass]; 763 mp_ptr = &cp_ptr->spells; 764 } 765 else if(cmd == '*') { 766 for(;;) { 767 oid = rand_int(z_info->c_max); 768 p_ptr->pclass = oid; 769 cp_ptr = &c_info[p_ptr->pclass]; 770 mp_ptr = &cp_ptr->spells; 771 if((rp_ptr->choice & (1L << oid))) 772 break; 773 } 774 } 775 else if(cmd == '=') do_cmd_options(); 776 else if(cmd == KTRL('X')) quit(NULL); 777 else if(cmd == '?') show_help("birth.txt", c_name+c_info[oid].name); 778 else return FALSE; 779 return TRUE; 780 } 781 782 783 static const menu_class menu_defs[] = { 760 return handler_aux(cmd, oid, &p_ptr->pclass, z_info->c_max, 761 (rp_ptr->choice), c_name+c_info[oid].name); 762 } 763 764 765 static const menu_iter menu_defs[] = { 784 766 {0, 0, 0, display_gender, gender_handler }, 785 767 {0, 0, 0, display_race, race_handler }, … … 805 787 menu_type menu; 806 788 WIPE(&menu, menu); 807 menu.cmd_keys = "? *\r\x18"; /* ?,*, \n, <ctl-X> */789 menu.cmd_keys = "?=*\r\n\x18"; /* ?, ,= *, \n, <ctl-X> */ 808 790 809 791 i = 0; 810 792 while(i < N_ELEMENTS(menu_defs)) 811 793 { 812 menu.flags = MN_NO_TAGS | MN_DBL_TAP;813 menu_init(&menu);814 794 key_event cx; 815 795 int cursor = *values[i]; 796 menu.flags = MN_NO_TAGS | MN_DBL_TAP; 797 menu.count = limits[i]; 798 menu.browse_hook = browse[i]; 799 menu_init2(&menu, find_menu_skin(MN_SCROLL), &menu_defs[i], regions[i]); 816 800 clear_question(); 801 817 802 Term_putstr(QUESTION_COL, QUESTION_ROW, -1, TERM_YELLOW, hints[i]); 818 menu.count = limits[i]; 819 menu_set_class(&menu, &menu_defs[i]); 820 menu.browse_hook = browse[i]; 821 822 cx = menu_select(&menu, 0, menu.count, &cursor, *regions[i]); 803 cx = menu_select(&menu, &cursor, 0); 823 804 if(cx.key == ESCAPE) { 824 805 return FALSE; /* restart */ 825 806 } 826 807 else if(cx.type == EVT_BACK) { 808 *values[i] = cursor; 827 809 region_erase(regions[i]); 828 810 i--; … … 836 818 } 837 819 return TRUE; 838 839 820 } 840 821 trunk/src/cmd4.c
r23 r27 1628 1628 } 1629 1629 1630 void do_cmd_resize() { 1631 /* Escape to main screen on resize */ 1632 Term_key_push(ESCAPE); 1633 do_cmd_redraw(); 1634 } 1630 1635 1631 1636 … … 2021 2026 2022 2027 2023 static void display_option(menu_type *menu, int oid, bool cursor,2024 int row, int col, int width)2028 static void display_option(menu_type *menu, int oid, 2029 bool cursor, int row, int col, int width) 2025 2030 { 2026 2031 byte attr = curs_attrs[CURS_KNOWN][(int)cursor]; … … 2042 2047 op_ptr->opt[oid] = FALSE; 2043 2048 break; 2044 case 'T': case '5': 2049 case 'T': case '5': case '\xff': 2045 2050 op_ptr->opt[oid] = !op_ptr->opt[oid]; 2046 2051 break; … … 2055 2060 } 2056 2061 2062 static const menu_iter options_iter = { 2063 0, 2064 NULL, 2065 NULL, 2066 display_option, /* label */ 2067 update_option /* updater */ 2068 }; 2069 2070 static menu_type option_toggle_menu; 2071 2057 2072 2058 2073 /* … … 2066 2081 int cursor_pos = 0; 2067 2082 2068 /* TODO: make an initializer that takes a few common args */ 2069 /* Title, prompt, cmd, choices, and flags -- everything else is ignored */ 2070 /* for MN_ONCE */ 2071 menu_type menu = { 2072 0, /* menu_id */ 2073 info, /* title */ 2074 "Set option (y/n/t) '?' for information", /* prompt */ 2075 "?5YyNnTt", /* cmd_keys */ 2076 default_choice, /* selections */ 2077 MN_REL_TAGS|MN_SCROLL|MN_NO_ACT|MN_ONCE, /* flags */ 2078 0, /* count */ 2079 2080 vpage, /* menu data */ 2081 update_option, /* updater */ 2082 NULL, /* browse */ 2083 display_option, /* label */ 2084 0, /* tagger */ 2085 0, /* skin */ 2086 }; 2087 2083 menu_type *menu = &option_toggle_menu; 2084 menu->title = info; 2085 menu_layout(menu, &SCREEN_REGION); 2086 2088 2087 screen_save(); 2089 2088 Term_clear(); … … 2097 2096 } 2098 2097 } 2099 menu.count = n; 2098 menu_set_filter(menu, opt, n); 2099 menu->menu_data = vpage; 2100 2101 menu_layout(menu, &SCREEN_REGION); 2102 2100 2103 for(;;) 2101 2104 { 2102 2105 key_event cx; 2103 cx = menu_select( &menu, opt, n, &cursor_pos, SCREEN_REGION);2104 if ( ESCAPE == cx.key) break;2106 cx = menu_select(menu, &cursor_pos, EVT_MOVE); 2107 if (cx.type == EVT_BACK || ESCAPE == cx.key) break; 2105 2108 if(cx.type == EVT_MOVE) cursor_pos = cx.index; 2106 else if(cx.key != '\xff') { 2107 update_option(cx.key, vpage, opt[cursor_pos]); 2108 if(strchr("YNyn", cx.key)) cursor_pos++; 2109 } 2109 if(cx.type == EVT_SELECT && strchr("YN", toupper(cx.key))) 2110 cursor_pos++; 2110 2111 cursor_pos = (cursor_pos+n)%n; 2111 2112 } … … 2828 2829 }; 2829 2830 2830 static menu_type macro_menu = { 2831 'mcro', 2832 0, 2833 0, 2834 0, 2835 default_choice, 2836 2837 MN_EVT, 2838 N_ELEMENTS(macro_actions), 2839 macro_actions 2840 /* ,0,0,0,0*/ 2841 }; 2831 static menu_type macro_menu; 2842 2832 2843 2833 … … 2868 2858 FILE_TYPE(FILE_TYPE_TEXT); 2869 2859 2860 2870 2861 screen_save(); 2862 2863 region loc = {0, 1, 0, 11}; 2864 menu_layout(¯o_menu, &loc); 2871 2865 2872 2866 /* Process requests until done */ 2873 2867 while (1) 2874 2868 { 2875 region loc = {0, 1, 0, 11};2876 2869 key_event c; 2877 2870 int evt; … … 2887 2880 /* Display the current action */ 2888 2881 prt(tmp, 13, 0); 2889 c = menu_select(¯o_menu, 0, macro_menu.count, &cursor, loc);2882 c = menu_select(¯o_menu, &cursor, EVT_CMD); 2890 2883 2891 2884 if(ESCAPE == c.key) … … 3340 3333 }; 3341 3334 3342 static menu_type visual_menu = { 3343 'visu', 3344 "Interact with visuals", 3345 "", 3346 "Command: ", 3347 default_choice, 3348 MN_EVT, 3349 N_ELEMENTS(visual_menu_items), 3350 visual_menu_items 3351 /* ,0,0,0,0 */ 3352 }; 3335 static menu_type visual_menu; 3353 3336 3354 3337 … … 3363 3346 screen_save(); 3364 3347 3348 menu_layout(&visual_menu, &SCREEN_REGION); 3365 3349 3366 3350 /* Interact until done */ … … 3370 3354 int evt = -1; 3371 3355 Term_clear(); 3372 key = menu_select(&visual_menu, 0, visual_menu.count, &cursor, SCREEN_REGION);3356 key = menu_select(&visual_menu, &cursor, EVT_CMD); 3373 3357 if(key.key == ESCAPE) 3374 3358 break; … … 3516 3500 }; 3517 3501 3518 static menu_type color_menu = { 3519 'colr', 3520 "Interact with colors", 3521 "Command: ", 3522 0, 3523 default_choice, 3524 MN_EVT, 3525 N_ELEMENTS(color_events), 3526 color_events 3527 /* 0,0,0,0 */ 3528 }; 3529 3502 static menu_type color_menu; 3530 3503 3531 3504 … … 3545 3518 screen_save(); 3546 3519 3520 menu_layout(&color_menu, &SCREEN_REGION); 3547 3521 /* Interact until done */ 3548 3522 while (1) … … 3551 3525 int evt; 3552 3526 Term_clear(); 3553 key = menu_select(&color_menu, 0, color_menu.count, &cursor, SCREEN_REGION);3527 key = menu_select(&color_menu, &cursor, EVT_CMD); 3554 3528 3555 3529 /* Done */ … … 4156 4130 }; 4157 4131 4158 static menu_type option_menu = { 4159 'opti', 4160 "Display Options", 4161 "Prompt: ", 4162 0, 4163 0, 4164 MN_ACT, 4165 N_ELEMENTS(option_actions), 4166 option_actions 4167 /* ,0,0,0,0 */ 4168 }; 4132 static menu_type option_menu; 4169 4133 4170 4134 static menu_item knowledge_actions[] = … … 4181 4145 }; 4182 4146 4183 static menu_type knowledge_menu = { 4184 'know', 4185 "Display current options", 4186 "Prompt: ", 4187 0, 4188 0, 4189 MN_ACT, 4190 N_ELEMENTS(knowledge_actions), 4191 knowledge_actions 4192 }; 4147 static menu_type knowledge_menu; 4148 4193 4149 4194 4150 /* Keep macro counts happy. */ … … 4203 4159 screen_save(); 4204 4160 4161 menu_layout(&option_menu, &SCREEN_REGION); 4205 4162 for(;;) { 4206 4163 key_event c; 4207 4164 Term_clear(); 4208 c = menu_select(&option_menu, 0, option_menu.count, &cursor, SCREEN_REGION);4165 c = menu_select(&option_menu, &cursor, 0); 4209 4166 if(ESCAPE == c.key) break; 4210 4167 } … … 4217 4174 int cursor = -1; 4218 4175 4219 /* initialize static variables */ 4176 screen_save(); 4177 4178 menu_layout(&knowledge_menu, &SCREEN_REGION); 4179 for(;;) { 4180 key_event c; 4181 Term_clear(); 4182 c = menu_select(&knowledge_menu, &cursor, 0); 4183 if(ESCAPE == c.key) break; 4184 } 4185 4186 screen_load(); 4187 } 4188 4189 4190 void init_cmd4_c(void) 4191 { 4192 /* Initialize the menus */ 4193 menu_type *menu; 4194 4195 /* Initialize the options toggle menu */ 4196 menu = &option_toggle_menu; 4197 WIPE(menu, menu_type); 4198 menu->prompt = "Set option (y/n/t), '?' for information"; 4199 menu->cmd_keys = "?YyNnTt"; 4200 menu->selections = default_choice; 4201 menu->count = OPT_PAGE_PER; 4202 menu->flags = MN_DBL_TAP; 4203 menu_init2(menu, find_menu_skin(MN_SCROLL), &options_iter, &SCREEN_REGION); 4204 4205 /* options screen selection menu */ 4206 menu = &option_menu; 4207 WIPE(menu, menu_type); 4208 menu_set_id(menu, 'opti'); 4209 menu->title = "Options Menu"; 4210 menu->count = N_ELEMENTS(option_actions); 4211 menu->menu_data = option_actions; 4212 menu_init(menu, MN_SCROLL, MN_ACT, &SCREEN_REGION); 4213 4214 /* knowledge menu */ 4215 menu = &knowledge_menu; 4216 WIPE(menu, menu_type); 4217 menu_set_id(menu, 'know'); 4218 menu->title = "Display current knowledge"; 4219 menu->count = N_ELEMENTS(knowledge_actions), 4220 menu->menu_data = knowledge_actions; 4221 menu_init(menu, MN_SCROLL, MN_ACT, &SCREEN_REGION); 4222 4223 /* visuals menu */ 4224 menu = &visual_menu; 4225 WIPE(menu, menu_type); 4226 menu_set_id(menu, 'visu'); 4227 menu->title = "Interact with visuals"; 4228 menu->selections = default_choice; 4229 menu->count = N_ELEMENTS(visual_menu_items); 4230 menu->menu_data = visual_menu_items; 4231 menu_init(menu, MN_SCROLL, MN_EVT, &SCREEN_REGION); 4232 4233 /* colors menu */ 4234 menu = &color_menu; 4235 WIPE(menu, menu_type); 4236 menu_set_id(menu, 'colr'); 4237 menu->title = "Interact with colors"; 4238 menu->selections = default_choice; 4239 menu->count = N_ELEMENTS(color_events), 4240 menu->menu_data = color_events; 4241 menu_init(menu, MN_SCROLL, MN_EVT, &SCREEN_REGION); 4242 4243 /* initialize other static variables */ 4220 4244 if(!obj_group_order) { 4221 4245 int i; … … 4230 4254 } 4231 4255 } 4232 4233 screen_save(); 4234 4235 for(;;) { 4236 key_event c; 4237 Term_clear(); 4238 c = menu_select(&knowledge_menu, 0, knowledge_menu.count, &cursor, SCREEN_REGION); 4239 if(ESCAPE == c.key) break; 4240 } 4241 4242 screen_load(); 4243 } 4256 } trunk/src/dungeon.c
r24 r27 2730 2730 2731 2731 /* Set screen resize hook */ 2732 Term_set_resize_hook(do_cmd_re draw);2732 Term_set_resize_hook(do_cmd_resize); 2733 2733 2734 2734 /* Attempt to load */ trunk/src/externs.h
r24 r27 345 345 /* cmd4.c */ 346 346 extern void do_cmd_redraw(void); 347 extern void do_cmd_resize(void); 347 348 extern void do_cmd_change_name(void); 348 349 extern void do_cmd_message_one(void); … … 359 360 extern void do_cmd_save_screen(void); 360 361 extern void do_cmd_knowledge(void); 362 extern void init_cmd4_c(void); 361 363 362 364 /* cmd5.c */ trunk/src/init2.c
r16 r27 2010 2010 2011 2011 2012 /* initialize the menus. This must occur before preference files are read */ 2013 init_cmd4_c(); 2014 2012 2015 /*** Initialize some arrays ***/ 2016 2013 2017 2014 2018 /* Initialize size info */ trunk/src/ui.c
r22 r27 7 7 * incorporate modifications in all Angband variants as defined in the 8 8 * Angband variants FAQ. See rec.games.roguelike.angband for FAQ. 9 * 10 */ 9 */ 10 11 /* 12 Description: 13 Implementation of Extremely Basic Event Model. 14 Limits: 15 all events are of the concrete type key_event (see z-util.h), 16 which are supposed to model simple UI actions: 17 - < escape > 18 - keystroke 19 - mousepress 20 - select menu element 21 - move menu cursor 22 - back to parent (hierarchical menu escape) 23 24 There are 3 basic event-related classes: 25 The key_event. 26 Concrete event, with at most 32 distinct types. 27 28 The event_listener observer for key events 29 30 The event_target The registrar for event_listeners. 31 For convenience, the event target is also an event_listener. 32 33 34 */ 11 35 12 36 #include "angband.h" 13 37 38 /* Some useful constants */ 14 39 15 40 const char default_choice[] = … … 20 45 int jumpscroll = 0; 21 46 int menu_width = 23; 47 48 /* forward declarations */ 49 static void display_menu_row(menu_type *menu, int pos, int top, 50 bool cursor, int row, int col, int width); 51 52 /* =================== GEOMETRY ================= */ 22 53 23 54 void region_erase(const region *loc) … … 36 67 } 37 68 38 static void display_menu_row(menu_type *menu, const int object_list[], int pos, 39 int top, bool cursor, int row, int col, int width); 40 41 /* Display an event, with posssble preference overrides */ 42 69 bool region_inside(const region *loc, const key_event *key) 70 { 71 if((loc->col > key->mousex) || (loc->col + loc->width <= key->mousex)) 72 return FALSE; 73 if((loc->row > key->mousey) || (loc->row + loc->page_rows <= key->mousey)) 74 return FALSE; 75 return TRUE; 76 } 77 78 /* ======================= EVENTS ======================== */ 79 80 /* Helper class for event_target */ 81 struct listener_list 82 { 83 event_listener *listener; 84 struct listener_list *next; 85 }; 86 87 88 void stop_event_loop() 89 { 90 key_event stop = { EVT_STOP }; 91 /* Stop right away! */ 92 Term_event_push(&stop); 93 } 94 95 /* 96 * Primitive event loop. 97 * - target = the event target 98 * - forever - if false, stop at first unhandled event. Otherwise, stop only 99 * for STOP events 100 * - start - optional initial event that allows you to prime the loop without 101 * pushing the event queue. 102 * Returns: 103 * EVT_STOP - the loop was halted. 104 * EVT_AGAIN - start was not handled, and forever is false 105 * The first unhandled event - forever is false. 106 */ 107 key_event run_event_loop(event_target *target, bool forever, const key_event *start) 108 { 109 key_event ke; 110 bool handled = TRUE; 111 while (forever || handled) { 112 listener_list *list = target->observers; 113 handled = FALSE; 114 if(start) ke = *start; 115 else ke = inkey_ex(); 116 if(ke.type == EVT_STOP) 117 break; 118 119 handled = target->self.handler(target->self.object, &ke); 120 if(target->is_modal) 121 continue; 122 123 while(list && !handled) { 124 if(ke.type & list->listener->events.evt_flags) { 125 handled = list->listener->handler(list->listener->object, &ke); 126 } 127 list = list->next; 128 } 129 if(handled) start = NULL; 130 } 131 if(start) { 132 ke.type = EVT_AGAIN; 133 ke.key = '\xff'; 134 } 135 return ke; 136 } 137 138 void add_listener(event_target *target, event_listener *observer) 139 { 140 listener_list *link; 141 MAKE(link, listener_list); 142 link->listener = observer; 143 link->next = target->observers; 144 target->observers = link; 145 } 146 147 void remove_listener(event_target *target, event_listener *observer) 148 { 149 listener_list *cur = target->observers; 150 listener_list **prev = &target->observers; 151 while(cur) { 152 if(cur->listener == observer) { 153 *prev = cur->next; 154 FREE(cur); 155 break; 156 } 157 } 158 bell("remove_listener: no such observer"); 159 } 160 161 162 163 /* ======================= MN_EVT HELPER FUNCTIONS ====================== */ 164 165 /* Display an event, with possible preference overrides */ 43 166 static void display_event_aux(event_action *event, int menuID, byte color, 44 167 int row, int col, int wid) … … 51 174 } 52 175 53 static bool inside(const region *loc, const key_event *key)54 {55 if((loc->col > key->mousex) || (loc->col + loc->width <= key->mousex))56 return FALSE;57 if((loc->row > key->mousey) || (loc->row + loc->page_rows <= key->mousey))58 return FALSE;59 return TRUE;60 }61 62 /*======================= MN_EVT HELPER FUNCTIONS ====================== */63 64 176 static void display_event(menu_type *menu, int oid, bool cursor, 65 177 int row, int col, int width) … … 67 179 event_action *evts = (event_action*)menu->menu_data; 68 180 byte color = curs_attrs[CURS_KNOWN][0 != cursor]; 69 display_event_aux(&evts[oid], menu-> menuID, color, row, col, width);181 display_event_aux(&evts[oid], menu->target.self.object_id, color, row, col, width); 70 182 } 71 183 … … 91 203 92 204 /* Virtual function table for action_events */ 93 static const menu_ class class_menu_event = {205 static const menu_iter menu_iter_event = { 94 206 MN_EVT, 95 207 0, … … 114 226 byte color = 115 227 curs_attrs[!(items[oid].flags & (MN_GRAYED|MN_DISABLED))][0 != cursor]; 116 display_event_aux(&items[oid].evt, menu-> menuID, color, row, col, width);228 display_event_aux(&items[oid].evt, menu->target.self.object_id, color, row, col, width); 117 229 } 118 230 … … 141 253 142 254 /* Virtual function table for menu items */ 143 static menu_class class_menu_item = {255 static const menu_iter menu_iter_item = { 144 256 MN_ACT, 145 257 tag_menu_item, … … 147 259 display_menu_item, 148 260 handle_menu_item 149 150 261 }; 151 262 … … 155 266 156 267 /* Scrolling menu */ 157 static int scrolling_get_cursor(int row, int col, int n, 158 int top, region *loc)268 /* Find the position of a cursor given a screen address */ 269 static int scrolling_get_cursor(int row, int col, int n, int top, region *loc) 159 270 { 160 271 int cursor = row - loc->row + top; … … 168 279 169 280 170 void display_scrolling (menu_type *menu, const int object_list[], int n, 171 int cursor, int *top, region *loc)281 /* Display current view of a skin */ 282 static void display_scrolling (menu_type *menu, int cursor, int *top, region *loc) 172 283 { 173 284 int col = loc->col; 174 285 int row = loc->row; 175 286 int rows_per_page = loc->page_rows; 287 int n = menu->filter_count; 176 288 int i; 177 289 178 if(cursor < *top)179 *top = cursor - jumpscroll ;180 if(cursor >= *top + rows_per_page)181 *top = cursor - rows_per_page-1 + jumpscroll;290 if(cursor <= *top && *top > 0) 291 *top = cursor - jumpscroll - 1; 292 if(cursor >= *top + (rows_per_page-1)) 293 *top = cursor - (rows_per_page-1) + 1 + jumpscroll; 182 294 if(*top > n - rows_per_page) *top = n - rows_per_page; 183 295 if(*top < 0) *top = 0; … … 186 298 { 187 299 bool is_curs = (cursor == i - *top); 188 display_menu_row(menu, object_list,i, *top, is_curs, row+i, col, loc->width);300 display_menu_row(menu, i, *top, is_curs, row+i, col, loc->width); 189 301 } 190 302 if(cursor >= 0) { 191 303 Term_gotoxy(col, row + cursor-*top); 192 304 } 305 } 306 307 static char scroll_get_tag(menu_type *menu, int pos) 308 { 309 return pos - menu->top; 193 310 } 194 311 … … 197 314 MN_SCROLL, 198 315 scrolling_get_cursor, 199 display_scrolling 316 display_scrolling, 317 scroll_get_tag 200 318 }; 201 202 203 /* multi-column menu */ 319 320 321 /* Multi-column menu */ 322 /* Find the position of a cursor given a screen address */ 204 323 static int columns_get_cursor(int row, int col, int n, int top, region *loc) 205 324 { … … 214 333 } 215 334 216 void display_columns (menu_type *menu, const int object_list[], int n, 217 int cursor, int *top, region *loc) 335 void display_columns (menu_type *menu, int cursor, int *top, region *loc) 218 336 { 219 337 int c, r; 220 338 int w, h; 339 int n = menu->filter_count; 221 340 int col = loc->col; 222 341 int row = loc->row; … … 232 351 int pos = c*rows_per_page + r; 233 352 bool is_cursor = (pos == cursor); 234 display_menu_row(menu, object_list, pos, 0, is_cursor, 235 row+r, col+c*colw, colw); 236 } 237 } 353 display_menu_row(menu, pos, 0, is_cursor, row+r, col+c*colw, colw); 354 } 355 } 356 } 357 358 static char column_get_tag(menu_type *menu, int pos) 359 { 360 return pos; 238 361 } 239 362 … … 242 365 MN_COLUMNS, 243 366 columns_get_cursor, 244 display_columns 367 display_columns, 368 column_get_tag 245 369 }; 246 370 247 371 /* ================== IMPLICIT MENU FOR KEY SELECTION ================== */ 248 372 249 static void display_nothing (menu_type *menu, const int object_list[], int n, 250 int cursor, int *top, region *loc) 373 static void display_nothing (menu_type *menu, int cursor, int *top, region *loc) 251 374 { 252 375 } … … 264 387 265 388 266 267 389 /* ================== GENERIC HELPER FUNCTIONS ============== */ 268 390 269 static char dummy_get_tag(menu_type *menu, int cursor) 270 { 271 return menu->selections[cursor]; 272 } 273 274 static bool is_valid_row(menu_type *menu, const int object_list[], int cursor) 391 static bool is_valid_row(menu_type *menu, int cursor) 275 392 { 276 393 int oid = cursor; 277 if(cursor < 0 || cursor > menu->count) return FALSE; 278 if(!menu->valid_row) return TRUE; 279 if(object_list) { 280 oid = object_list[cursor]; 281 } 282 return menu->valid_row(menu, oid); 283 } 284 285 static int get_cursor_key(menu_type *menu, const int object_index[], int n, 286 int top, char key) 394 if(cursor < 0 || cursor >= menu->filter_count) return FALSE; 395 if(menu->object_list) { 396 oid = menu->object_list[cursor]; 397 } 398 if(!menu->row_funcs->valid_row) return TRUE; 399 return menu->row_funcs->valid_row(menu, oid); 400 } 401 402 static int get_cursor_key(menu_type *menu, int top, char key) 287 403 { 288 404 int i; 289 if(menu->flags & MN_REL_TAGS) { 405 int n = menu->filter_count; 406 if(menu->flags & MN_NO_TAGS) return -1; 407 else if(menu->flags & MN_REL_TAGS) { 290 408 for(i = 0; i < n; i++) { 291 char c = menu-> get_tag(menu, i);409 char c = menu->skin->get_tag(menu, i); 292 410 if(c && c == key) 293 return i + top; 294 } 295 } 296 for(i = 0; i < n; i++) { 297 int oid = object_index ? object_index[i] : i; 298 char c = menu->get_tag(menu, oid); 299 if(c && c == key) 300 return i; 411 return i + menu->top; 412 } 413 } 414 else if(!(menu->flags & MN_PVT_TAGS) && menu->selections) { 415 for(i = 0; menu->selections[i] ; i++) 416 if(menu->selections[i] == key) return i; 417 } 418 else if(menu->row_funcs->get_tag) { 419 for(i = 0; i < n; i++) { 420 int oid = menu->object_list ? menu->object_list[i] : i; 421 char c = menu->row_funcs->get_tag(menu, oid); 422 if(c && c == key) 423 return i; 424 } 301 425 } 302 426 return -1; … … 307 431 * Filters unhandled keys & conditions 308 432 */ 309 static bool handle_menu_key(char cmd, menu_type *menu, int oid) 310 { 433 static bool handle_menu_key(char cmd, menu_type *menu, int cursor) 434 { 435 int oid = cursor; 436 if(menu->object_list) oid = menu->object_list[cursor]; 311 437 int flags = menu->flags; 312 438 if(flags & MN_NO_ACT) return FALSE; … … 318 444 return FALSE; 319 445 320 if(menu->handler) 321 return menu->handler(cmd, menu->menu_data, oid); 446 if(menu->row_funcs->row_handler && 447 menu->row_funcs->row_handler(cmd, menu->menu_data, oid)) { 448 key_event ke; 449 ke.type = EVT_SELECT; 450 ke.key = cmd; 451 ke.index = cursor; 452 Term_event_push(&ke); 453 return TRUE; 454 } 322 455 return FALSE; 323 456 } 324 457 325 326 static void display_menu_row(menu_type *menu, const int object_list[], int pos,327 int top,bool cursor, int row, int col, int width)458 /* Modal display of menu */ 459 static void display_menu_row(menu_type *menu, int pos, int top, 460 bool cursor, int row, int col, int width) 328 461 { 329 462 int flags = menu->flags; 330 463 char sel = 0; 33
