more OOP-style standard dialogs

This commit is contained in:
Zeno Rogue 2023-08-09 14:01:24 +02:00
parent 4d4874f7ac
commit b6f13b953b
23 changed files with 306 additions and 249 deletions

View File

@ -1714,7 +1714,7 @@ EX void set_sliders() {
dialog::addSelItem(sl.name, fts(sl.current), ch++); dialog::addSelItem(sl.name, fts(sl.current), ch++);
dialog::add_action([&] { dialog::add_action([&] {
dialog::editNumber(sl.current, sl.min, sl.max, 1, sl.zero, sl.name, sl.name); dialog::editNumber(sl.current, sl.min, sl.max, 1, sl.zero, sl.name, sl.name);
dialog::reaction = [] { sliders_changed(false, false); }; dialog::get_di().reaction = [] { sliders_changed(false, false); };
}); });
} }
if(isize(current.intsliders)) if(isize(current.intsliders))
@ -1723,7 +1723,7 @@ EX void set_sliders() {
dialog::addSelItem(sl.name, its(sl.current), ch++); dialog::addSelItem(sl.name, its(sl.current), ch++);
dialog::add_action([&] { dialog::add_action([&] {
dialog::editNumber(sl.current, sl.min, sl.max, 1, sl.zero, sl.name, sl.name); dialog::editNumber(sl.current, sl.min, sl.max, 1, sl.zero, sl.name, sl.name);
dialog::reaction = [] { sliders_changed(true, true); }; dialog::get_di().reaction = [] { sliders_changed(true, true); };
}); });
} }
dialog::addInfo(slider_error); dialog::addInfo(slider_error);

View File

@ -83,7 +83,7 @@ struct setting {
#endif #endif
setting *setting::set_extra(const reaction_t& r) { setting *setting::set_extra(const reaction_t& r) {
auto s = sets; set_sets([s, r] { if(s) s(); dialog::extra_options = r; }); return this; auto s = sets; set_sets([s, r] { if(s) s(); dialog::get_di().extra_options = r; }); return this;
} }
setting *setting::set_reaction(const reaction_t& r) { setting *setting::set_reaction(const reaction_t& r) {
@ -506,8 +506,8 @@ void float_setting::show_edit_option(int key) {
add_to_changed(this); add_to_changed(this);
dialog::editNumber(*value, min_value, max_value, step, dft, XLAT(menu_item_name), help_text); dialog::editNumber(*value, min_value, max_value, step, dft, XLAT(menu_item_name), help_text);
if(sets) sets(); if(sets) sets();
if(reaction) dialog::reaction = reaction; if(reaction) dialog::get_di().reaction = reaction;
if(!is_editable) dialog::extra_options = non_editable; if(!is_editable) dialog::get_di().extra_options = non_editable;
}); });
} }
@ -520,10 +520,10 @@ void float_setting_dft::show_edit_option(int key) {
if(*value == use_the_default_value) *value = get_hint(); if(*value == use_the_default_value) *value = get_hint();
dialog::editNumber(*value, min_value, max_value, step, dft, XLAT(menu_item_name), help_text); dialog::editNumber(*value, min_value, max_value, step, dft, XLAT(menu_item_name), help_text);
if(sets) sets(); if(sets) sets();
if(reaction) dialog::reaction = reaction; if(reaction) dialog::get_di().reaction = reaction;
if(!is_editable) dialog::extra_options = non_editable; if(!is_editable) dialog::get_di().extra_options = non_editable;
auto eo = dialog::extra_options; auto eo = dialog::get_di().extra_options;
dialog::extra_options = [eo, this] { dialog::get_di().extra_options = [eo, this] {
dialog::addSelItem(XLAT("use the default value"), "", 'D'); dialog::addSelItem(XLAT("use the default value"), "", 'D');
dialog::add_action([this] { *value = use_the_default_value; }); dialog::add_action([this] { *value = use_the_default_value; });
if(eo) eo(); if(eo) eo();
@ -538,8 +538,8 @@ void int_setting::show_edit_option(int key) {
add_to_changed(this); add_to_changed(this);
dialog::editNumber(*value, min_value, max_value, step, dft, XLAT(menu_item_name), help_text); dialog::editNumber(*value, min_value, max_value, step, dft, XLAT(menu_item_name), help_text);
if(sets) sets(); if(sets) sets();
if(reaction) dialog::reaction = reaction; if(reaction) dialog::get_di().reaction = reaction;
if(!is_editable) dialog::extra_options = non_editable; if(!is_editable) dialog::get_di().extra_options = non_editable;
}); });
} }
@ -557,7 +557,7 @@ void color_setting::show_edit_option(int key) {
dialog::add_action([this] () { dialog::add_action([this] () {
dialog::openColorDialog(*value); dialog::openColorDialog(*value);
dialog::colorAlpha = has_alpha; dialog::colorAlpha = has_alpha;
dialog::dialogflags |= sm::SIDE; dialog::get_di().dialogflags |= sm::SIDE;
}); });
} }
@ -1029,11 +1029,11 @@ EX void initConfig() {
param_b(less_in_landscape, "less_in_landscape", false) param_b(less_in_landscape, "less_in_landscape", false)
->editable("less items/kills in landscape", 'L') ->editable("less items/kills in landscape", 'L')
-> set_sets([] { dialog::reaction_final = [] { println(hlog, "Reset"); vid.killreduction = 0; }; }); -> set_sets([] { dialog::get_di().reaction_final = [] { println(hlog, "Reset"); vid.killreduction = 0; }; });
param_b(less_in_portrait, "less_in_portrait", false) param_b(less_in_portrait, "less_in_portrait", false)
->editable("less items/kills in portrait", 'P') ->editable("less items/kills in portrait", 'P')
-> set_sets([] { dialog::reaction_final = [] { println(hlog, "Reset"); vid.killreduction = 0; }; }); -> set_sets([] { dialog::get_di().reaction_final = [] { println(hlog, "Reset"); vid.killreduction = 0; }; });
// basic graphics // basic graphics
@ -1059,7 +1059,7 @@ EX void initConfig() {
param_i(menu_darkening, "menu_darkening", 2) param_i(menu_darkening, "menu_darkening", 2)
-> editable(0, 8, 1, "menu map darkening", "A larger number means darker game map in the background. Set to 8 to disable the background.", 'd') -> editable(0, 8, 1, "menu map darkening", "A larger number means darker game map in the background. Set to 8 to disable the background.", 'd')
-> set_sets([] { dialog::bound_low(0); dialog::bound_up(8); dialog::dialogflags |= sm::DARKEN; }); -> set_sets([] { dialog::bound_low(0); dialog::bound_up(8); dialog::get_di().dialogflags |= sm::DARKEN; });
param_b(centered_menus, "centered_menus", false) param_b(centered_menus, "centered_menus", false)
-> editable("centered menus in widescreen", 'c'); -> editable("centered menus in widescreen", 'c');
@ -1084,15 +1084,15 @@ EX void initConfig() {
) )
-> set_extra([] { -> set_extra([] {
dialog::addSelItem(XLAT("chevron (periodic)"), "0", 'C'); dialog::addSelItem(XLAT("chevron (periodic)"), "0", 'C');
dialog::add_action([] { dialog::ne.s = "0"; dialog::apply_edit(); }); dialog::add_action([] { dialog::get_ne().s = "0"; dialog::get_ne().apply_edit(); });
dialog::addSelItem(XLAT("hat"), "1", 'H'); dialog::addSelItem(XLAT("hat"), "1", 'H');
dialog::add_action([] { dialog::ne.s = "1"; dialog::apply_edit(); }); dialog::add_action([] { dialog::get_ne().s = "1"; dialog::get_ne().apply_edit(); });
dialog::addSelItem(XLAT("spectre"), "3-√3", 'T'); dialog::addSelItem(XLAT("spectre"), "3-√3", 'T');
dialog::add_action([] { dialog::ne.s = "3 - sqrt(3)"; dialog::apply_edit(); }); dialog::add_action([] { dialog::get_ne().s = "3 - sqrt(3)"; dialog::get_ne().apply_edit(); });
dialog::addSelItem(XLAT("turtle"), "1.5", 'T'); dialog::addSelItem(XLAT("turtle"), "1.5", 'T');
dialog::add_action([] { dialog::ne.s = "1.5"; dialog::apply_edit(); }); dialog::add_action([] { dialog::get_ne().s = "1.5"; dialog::get_ne().apply_edit(); });
dialog::addSelItem(XLAT("comma (periodic)"), "2", ','); dialog::addSelItem(XLAT("comma (periodic)"), "2", ',');
dialog::add_action([] { dialog::ne.s = "2"; dialog::apply_edit(); }); dialog::add_action([] { dialog::get_ne().s = "2"; dialog::get_ne().apply_edit(); });
}) })
-> set_reaction(hat::reshape); -> set_reaction(hat::reshape);
@ -1122,27 +1122,27 @@ EX void initConfig() {
param_i(vid.fullscreen_x, "fullscreen_x", 1280) param_i(vid.fullscreen_x, "fullscreen_x", 1280)
-> editable(640, 3840, 640, "fullscreen resolution to use (X)", "", 'x') -> editable(640, 3840, 640, "fullscreen resolution to use (X)", "", 'x')
-> set_sets([] { dialog::bound_low(640); dialog::reaction_final = do_request_resolution_change; }); -> set_sets([] { dialog::bound_low(640); dialog::get_di().reaction_final = do_request_resolution_change; });
param_i(vid.fullscreen_y, "fullscreen_y", 1024) param_i(vid.fullscreen_y, "fullscreen_y", 1024)
-> editable(480, 2160, 480, "fullscreen resolution to use (Y)", "", 'x') -> editable(480, 2160, 480, "fullscreen resolution to use (Y)", "", 'x')
-> set_sets([] { dialog::bound_low(480); dialog::reaction_final = do_request_resolution_change; }); -> set_sets([] { dialog::bound_low(480); dialog::get_di().reaction_final = do_request_resolution_change; });
param_i(vid.window_x, "window_x", 1280) param_i(vid.window_x, "window_x", 1280)
-> editable(160, 3840, 160, "window resolution to use (X)", "", 'x') -> editable(160, 3840, 160, "window resolution to use (X)", "", 'x')
-> set_sets([] { dialog::bound_low(160); dialog::reaction_final = do_request_resolution_change; }); -> set_sets([] { dialog::bound_low(160); dialog::get_di().reaction_final = do_request_resolution_change; });
param_i(vid.window_y, "window_y", 1024) param_i(vid.window_y, "window_y", 1024)
-> editable(120, 2160, 120, "window resolution to use (Y)", "", 'x') -> editable(120, 2160, 120, "window resolution to use (Y)", "", 'x')
-> set_sets([] { dialog::bound_low(120); dialog::reaction_final = do_request_resolution_change; }); -> set_sets([] { dialog::bound_low(120); dialog::get_di().reaction_final = do_request_resolution_change; });
param_f(vid.window_rel_x, "window_rel_x", .9) param_f(vid.window_rel_x, "window_rel_x", .9)
-> editable(.1, 1, .1, "screen size percentage to use (X)", "", 'x') -> editable(.1, 1, .1, "screen size percentage to use (X)", "", 'x')
-> set_sets([] { dialog::bound_low(.1); dialog::reaction_final = do_request_resolution_change; }); -> set_sets([] { dialog::bound_low(.1); dialog::get_di().reaction_final = do_request_resolution_change; });
param_f(vid.window_rel_y, "window_rel_y", .9) param_f(vid.window_rel_y, "window_rel_y", .9)
-> editable(.1, 1, .1, "screen size percentage to use (Y)", "", 'x') -> editable(.1, 1, .1, "screen size percentage to use (Y)", "", 'x')
-> set_sets([] { dialog::bound_low(.1); dialog::reaction_final = do_request_resolution_change; }); -> set_sets([] { dialog::bound_low(.1); dialog::get_di().reaction_final = do_request_resolution_change; });
param_b(vid.darkhepta, "mark heptagons", false); param_b(vid.darkhepta, "mark heptagons", false);
@ -1763,7 +1763,7 @@ EX void menuitem_sightrange_bonus(char c) {
XLAT("Roughly 42% cells are on the edge of your sight range. Reducing " XLAT("Roughly 42% cells are on the edge of your sight range. Reducing "
"the sight range makes HyperRogue work faster, but also makes " "the sight range makes HyperRogue work faster, but also makes "
"the game effectively harder.")); "the game effectively harder."));
dialog::reaction = doOvergenerate; dialog::get_di().reaction = doOvergenerate;
dialog::bound_low(1-getDistLimit()); dialog::bound_low(1-getDistLimit());
dialog::bound_up(allowIncreasedSight() ? euclid ? 99 : gp::dist_2() * 5 : 0); dialog::bound_up(allowIncreasedSight() ? euclid ? 99 : gp::dist_2() * 5 : 0);
}); });
@ -1899,9 +1899,9 @@ EX void menuitem_sightrange(char c IS('c')) {
EX void sets_sfx_volume() { EX void sets_sfx_volume() {
#if CAP_AUDIO #if CAP_AUDIO
dialog::dialogflags = sm::NOSCR; dialog::get_di().dialogflags = sm::NOSCR;
#if ISANDROID #if ISANDROID
dialog::reaction = [] () { dialog::get_di().reaction = [] () {
settingsChanged = true; settingsChanged = true;
}; };
#endif #endif
@ -1912,8 +1912,8 @@ EX void sets_sfx_volume() {
EX void sets_music_volume() { EX void sets_music_volume() {
#if CAP_AUDIO #if CAP_AUDIO
dialog::dialogflags = sm::NOSCR; dialog::get_di().dialogflags = sm::NOSCR;
dialog::reaction = [] () { dialog::get_di().reaction = [] () {
#if CAP_SDLAUDIO #if CAP_SDLAUDIO
Mix_VolumeMusic(musicvolume); Mix_VolumeMusic(musicvolume);
#endif #endif
@ -1924,7 +1924,7 @@ EX void sets_music_volume() {
dialog::bound_low(0); dialog::bound_low(0);
dialog::bound_up(MIX_MAX_VOLUME); dialog::bound_up(MIX_MAX_VOLUME);
#if CAP_SDLAUDIO #if CAP_SDLAUDIO
dialog::extra_options = [] { dialog::get_di().extra_options = [] {
dialog::addBoolItem_action(XLAT("play music when out of focus"), music_out_of_focus, 'A'); dialog::addBoolItem_action(XLAT("play music when out of focus"), music_out_of_focus, 'A');
}; };
#endif #endif
@ -2165,7 +2165,7 @@ EX void edit_whatever(char type, int index) {
dialog::editNumber(whateveri[index], -10, 10, 1, 0, XLAT("whatever"), dialog::editNumber(whateveri[index], -10, 10, 1, 0, XLAT("whatever"),
"i:" + its(index)); "i:" + its(index));
} }
dialog::extra_options = [type, index] { dialog::get_di().extra_options = [type, index] {
dialog::addItem(XLAT("integer"), 'X'); dialog::addItem(XLAT("integer"), 'X');
dialog::add_action( [index] { popScreen(); edit_whatever('i', index); }); dialog::add_action( [index] { popScreen(); edit_whatever('i', index); });
dialog::addItem(XLAT("float"), 'Y'); dialog::addItem(XLAT("float"), 'Y');
@ -2265,7 +2265,7 @@ EX void configureInterface() {
"as it precisely shows the direction we are going. However, the option is available in all modes." "as it precisely shows the direction we are going. However, the option is available in all modes."
)); ));
dialog::bound_low(0); dialog::bound_low(0);
dialog::extra_options = [] { dialog::get_di().extra_options = [] {
dialog::addColorItem(XLAT("crosshair color"), crosshair_color, 'X'); dialog::addColorItem(XLAT("crosshair color"), crosshair_color, 'X');
dialog::add_action([] { dialog::openColorDialog(crosshair_color); }); dialog::add_action([] { dialog::openColorDialog(crosshair_color); });
}; };
@ -2343,7 +2343,7 @@ EX void projectionDialog() {
"and the Gans model is obtained by orthogonal projection. " "and the Gans model is obtained by orthogonal projection. "
"See also the conformal mode (in the special modes menu) " "See also the conformal mode (in the special modes menu) "
"for more models.")); "for more models."));
dialog::extra_options = [] () { dialog::get_di().extra_options = [] () {
dialog::addBreak(100); dialog::addBreak(100);
if(GDIM == 2) dialog::addHelp(XLAT( if(GDIM == 2) dialog::addHelp(XLAT(
"If we are viewing an equidistant g absolute units below a plane, " "If we are viewing an equidistant g absolute units below a plane, "
@ -2352,17 +2352,17 @@ EX void projectionDialog() {
"tanh(g)/tanh(c) units below the center. This in turn corresponds to " "tanh(g)/tanh(c) units below the center. This in turn corresponds to "
"the Poincaré model for g=c, and Klein-Beltrami model for g=0.")); "the Poincaré model for g=c, and Klein-Beltrami model for g=0."));
dialog::addSelItem(sphere ? "stereographic" : "Poincaré model", "1", 'P'); dialog::addSelItem(sphere ? "stereographic" : "Poincaré model", "1", 'P');
dialog::add_action([] () { *dialog::ne.editwhat = 1; vpconf.scale = 1; dialog::ne.s = "1"; }); dialog::add_action([] () { *dialog::get_ne().editwhat = 1; vpconf.scale = 1; dialog::get_ne().s = "1"; });
dialog::addSelItem(sphere ? "gnomonic" : "Klein model", "0", 'K'); dialog::addSelItem(sphere ? "gnomonic" : "Klein model", "0", 'K');
dialog::add_action([] () { *dialog::ne.editwhat = 0; vpconf.scale = 1; dialog::ne.s = "0"; }); dialog::add_action([] () { *dialog::get_ne().editwhat = 0; vpconf.scale = 1; dialog::get_ne().s = "0"; });
if(hyperbolic) { if(hyperbolic) {
dialog::addSelItem("inverted Poincaré model", "-1", 'I'); dialog::addSelItem("inverted Poincaré model", "-1", 'I');
dialog::add_action([] () { *dialog::ne.editwhat = -1; vpconf.scale = 1; dialog::ne.s = "-1"; }); dialog::add_action([] () { *dialog::get_ne().editwhat = -1; vpconf.scale = 1; dialog::get_ne().s = "-1"; });
} }
dialog::addItem(sphere ? "orthographic" : "Gans model", 'O'); dialog::addItem(sphere ? "orthographic" : "Gans model", 'O');
dialog::add_action([] () { vpconf.alpha = vpconf.scale = 999; dialog::ne.s = dialog::disp(vpconf.alpha); }); dialog::add_action([] () { vpconf.alpha = vpconf.scale = 999; dialog::get_ne().s = dialog::disp(vpconf.alpha); });
dialog::addItem(sphere ? "towards orthographic" : "towards Gans model", 'T'); dialog::addItem(sphere ? "towards orthographic" : "towards Gans model", 'T');
dialog::add_action([] () { double d = 1.1; vpconf.alpha *= d; vpconf.scale *= d; dialog::ne.s = dialog::disp(vpconf.alpha); }); dialog::add_action([] () { double d = 1.1; vpconf.alpha *= d; vpconf.scale *= d; dialog::get_ne().s = dialog::disp(vpconf.alpha); });
}; };
} }
@ -2413,7 +2413,7 @@ EX void add_edit_fov(char key IS('f'), bool pop IS(false)) {
"a quick implementation, so parameter values too close to 1 may " "a quick implementation, so parameter values too close to 1 may "
"be buggy (outside of raycasting); try e.g. 0.9 instead." "be buggy (outside of raycasting); try e.g. 0.9 instead."
); );
dialog::extra_options = [quick] { dialog::get_di().extra_options = [quick] {
dialog::addSelItem(XLAT("Panini projection"), fts(panini_alpha), 'P'); dialog::addSelItem(XLAT("Panini projection"), fts(panini_alpha), 'P');
dialog::add_action([quick] { dialog::add_action([quick] {
popScreen(); popScreen();
@ -2423,9 +2423,9 @@ EX void add_edit_fov(char key IS('f'), bool pop IS(false)) {
"which allows very wide field-of-view values.\n\n") + quick "which allows very wide field-of-view values.\n\n") + quick
); );
#if CAP_GL #if CAP_GL
dialog::reaction = reset_all_shaders; dialog::get_di().reaction = reset_all_shaders;
#endif #endif
dialog::extra_options = [] { dialog::get_di().extra_options = [] {
add_edit_fov('F', true); add_edit_fov('F', true);
}; };
}); });
@ -2438,9 +2438,9 @@ EX void add_edit_fov(char key IS('f'), bool pop IS(false)) {
"which allows very wide field-of-view values.\n\n") + quick "which allows very wide field-of-view values.\n\n") + quick
); );
#if CAP_GL #if CAP_GL
dialog::reaction = reset_all_shaders; dialog::get_di().reaction = reset_all_shaders;
#endif #endif
dialog::extra_options = [] { dialog::get_di().extra_options = [] {
add_edit_fov('F', true); add_edit_fov('F', true);
}; };
}); });
@ -2539,7 +2539,7 @@ EX void add_edit_wall_quality(char c) {
); );
dialog::bound_low(1); dialog::bound_low(1);
dialog::bound_up(128); dialog::bound_up(128);
dialog::reaction = [] { dialog::get_di().reaction = [] {
#if MAXMDIM >= 4 #if MAXMDIM >= 4
if(floor_textures) { if(floor_textures) {
delete floor_textures; delete floor_textures;
@ -2561,8 +2561,8 @@ EX void edit_levellines(char c) {
"This feature superimposes level lines on the rendered screen. These lines depend on the Z coordinate. In 3D hyperbolic the Z coordinate is taken from the Klein model. " "This feature superimposes level lines on the rendered screen. These lines depend on the Z coordinate. In 3D hyperbolic the Z coordinate is taken from the Klein model. "
"Level lines can be used to observe the curvature: circles correspond to positive curvature, while hyperbolas correspond to negative. See e.g. the Hypersian Rug mode.") "Level lines can be used to observe the curvature: circles correspond to positive curvature, while hyperbolas correspond to negative. See e.g. the Hypersian Rug mode.")
); );
dialog::reaction = ray::reset_raycaster; dialog::get_di().reaction = ray::reset_raycaster;
dialog::extra_options = [] { dialog::get_di().extra_options = [] {
dialog::addBoolItem(XLAT("disable textures"), disable_texture, 'T'); dialog::addBoolItem(XLAT("disable textures"), disable_texture, 'T');
dialog::add_action([] { ray::reset_raycaster(); disable_texture = !disable_texture; }); dialog::add_action([] { ray::reset_raycaster(); disable_texture = !disable_texture; });
dialog::addItem(XLAT("disable level lines"), 'D'); dialog::addItem(XLAT("disable level lines"), 'D');
@ -2833,7 +2833,7 @@ EX void show3D() {
XLAT("Rotate the camera. Can be used to obtain a first person perspective, " XLAT("Rotate the camera. Can be used to obtain a first person perspective, "
"or third person perspective when combined with Y shift.") "or third person perspective when combined with Y shift.")
); );
dialog::extra_options = [] { dialog::get_di().extra_options = [] {
dialog::addBoolItem(XLAT("render behind the camera"), vpconf.back_and_front, 'R'); dialog::addBoolItem(XLAT("render behind the camera"), vpconf.back_and_front, 'R');
dialog::add_action([] { vpconf.back_and_front = !vpconf.back_and_front; }); dialog::add_action([] { vpconf.back_and_front = !vpconf.back_and_front; });
}; };
@ -2844,7 +2844,7 @@ EX void show3D() {
dialog::add_action([] () { vid.fixed_facing = !vid.fixed_facing; dialog::add_action([] () { vid.fixed_facing = !vid.fixed_facing;
if(vid.fixed_facing) { if(vid.fixed_facing) {
dialog::editNumber(vid.fixed_facing_dir, 0, 360, 15, 90, "", ""); dialog::editNumber(vid.fixed_facing_dir, 0, 360, 15, 90, "", "");
dialog::dialogflags |= sm::CENTER; dialog::get_di().dialogflags |= sm::CENTER;
} }
}); });
} }
@ -2875,7 +2875,7 @@ EX void show3D() {
dialog::addSelItem(XLAT("radar size"), fts(vid.radarsize), 'r'); dialog::addSelItem(XLAT("radar size"), fts(vid.radarsize), 'r');
dialog::add_action([] () { dialog::add_action([] () {
dialog::editNumber(vid.radarsize, 0, 360, 15, 90, "", XLAT("set to 0 to disable")); dialog::editNumber(vid.radarsize, 0, 360, 15, 90, "", XLAT("set to 0 to disable"));
dialog::extra_options = [] () { draw_radar(true); }; dialog::get_di().extra_options = [] () { draw_radar(true); };
}); });
} }
@ -2902,7 +2902,7 @@ EX void show3D() {
dialog::addSelItem(XLAT("radar range"), fts(vid.radarrange), 'R'); dialog::addSelItem(XLAT("radar range"), fts(vid.radarrange), 'R');
dialog::add_action([] () { dialog::add_action([] () {
dialog::editNumber(vid.radarrange, 0, 10, 0.5, 2, "", XLAT("")); dialog::editNumber(vid.radarrange, 0, 10, 0.5, 2, "", XLAT(""));
dialog::extra_options = [] () { draw_radar(true); }; dialog::get_di().extra_options = [] () { draw_radar(true); };
}); });
} }
if(GDIM == 3) add_edit_wall_quality('W'); if(GDIM == 3) add_edit_wall_quality('W');
@ -2944,13 +2944,13 @@ EX int config3 = addHook(hooks_configfile, 100, [] {
param_f(vid.eye, "eyelevel", 0) param_f(vid.eye, "eyelevel", 0)
->editable(-5, 5, .1, "eye level", "", 'E') ->editable(-5, 5, .1, "eye level", "", 'E')
->set_extra([] { ->set_extra([] {
dialog::dialogflags |= sm::CENTER; dialog::get_di().dialogflags |= sm::CENTER;
vid.tc_camera = ticks; vid.tc_camera = ticks;
dialog::addHelp(XLAT("In the FPP mode, the camera will be set at this altitude (before applying shifts).")); dialog::addHelp(XLAT("In the FPP mode, the camera will be set at this altitude (before applying shifts)."));
dialog::addBoolItem(XLAT("auto-adjust to eyes on the player model"), vid.auto_eye, 'O'); dialog::addBoolItem(XLAT("auto-adjust to eyes on the player model"), vid.auto_eye, 'O');
dialog::reaction = [] { vid.auto_eye = false; }; dialog::get_di().reaction = [] { vid.auto_eye = false; };
dialog::add_action([] () { dialog::add_action([] () {
vid.auto_eye = !vid.auto_eye; vid.auto_eye = !vid.auto_eye;
geom3::do_auto_eye(); geom3::do_auto_eye();
@ -3315,9 +3315,9 @@ EX void edit_color_table(colortable& ct, const reaction_t& r IS(reaction_t()), b
if(!(ct[i] & 0x1000000)) return; if(!(ct[i] & 0x1000000)) return;
} }
dialog::openColorDialog(ct[i]); dialog::openColorDialog(ct[i]);
dialog::reaction = r; dialog::get_di().reaction = r;
dialog::colorAlpha = false; dialog::colorAlpha = false;
dialog::dialogflags |= sm::SIDE; dialog::get_di().dialogflags |= sm::SIDE;
}); });
} }
@ -3346,28 +3346,28 @@ EX void show_color_dialog() {
dialog::init(XLAT("colors & aura")); dialog::init(XLAT("colors & aura"));
dialog::addColorItem(XLAT("background"), addalpha(backcolor), 'b'); dialog::addColorItem(XLAT("background"), addalpha(backcolor), 'b');
dialog::add_action([] () { dialog::openColorDialog(backcolor); dialog::colorAlpha = false; dialog::dialogflags |= sm::SIDE; }); dialog::add_action([] () { dialog::openColorDialog(backcolor); dialog::colorAlpha = false; dialog::get_di().dialogflags |= sm::SIDE; });
if(WDIM == 2 && GDIM == 3 && hyperbolic) if(WDIM == 2 && GDIM == 3 && hyperbolic)
dialog::addBoolItem_action(XLAT("cool fog effect"), context_fog, 'B'); dialog::addBoolItem_action(XLAT("cool fog effect"), context_fog, 'B');
dialog::addColorItem(XLAT("foreground"), addalpha(forecolor), 'f'); dialog::addColorItem(XLAT("foreground"), addalpha(forecolor), 'f');
dialog::add_action([] () { dialog::openColorDialog(forecolor); dialog::colorAlpha = false; dialog::dialogflags |= sm::SIDE; }); dialog::add_action([] () { dialog::openColorDialog(forecolor); dialog::colorAlpha = false; dialog::get_di().dialogflags |= sm::SIDE; });
dialog::addColorItem(XLAT("borders"), addalpha(bordcolor), 'o'); dialog::addColorItem(XLAT("borders"), addalpha(bordcolor), 'o');
dialog::add_action([] () { dialog::openColorDialog(bordcolor); dialog::colorAlpha = false; dialog::dialogflags |= sm::SIDE; }); dialog::add_action([] () { dialog::openColorDialog(bordcolor); dialog::colorAlpha = false; dialog::get_di().dialogflags |= sm::SIDE; });
dialog::addColorItem(XLAT("projection boundary"), ringcolor, 'r'); dialog::addColorItem(XLAT("projection boundary"), ringcolor, 'r');
dialog::add_action([] () { dialog::openColorDialog(ringcolor); dialog::dialogflags |= sm::SIDE; }); dialog::add_action([] () { dialog::openColorDialog(ringcolor); dialog::get_di().dialogflags |= sm::SIDE; });
dialog::addSelItem(XLAT("boundary width multiplier"), fts(vid.multiplier_ring), 'R'); dialog::addSelItem(XLAT("boundary width multiplier"), fts(vid.multiplier_ring), 'R');
dialog::add_action([] () { dialog::editNumber(vid.multiplier_ring, 0, 10, 1, 1, XLAT("boundary width multiplier"), ""); }); dialog::add_action([] () { dialog::editNumber(vid.multiplier_ring, 0, 10, 1, 1, XLAT("boundary width multiplier"), ""); });
dialog::addColorItem(XLAT("projection background"), modelcolor, 'c'); dialog::addColorItem(XLAT("projection background"), modelcolor, 'c');
dialog::add_action([] () { dialog::openColorDialog(modelcolor); dialog::dialogflags |= sm::SIDE; }); dialog::add_action([] () { dialog::openColorDialog(modelcolor); dialog::get_di().dialogflags |= sm::SIDE; });
dialog::addColorItem(XLAT("standard grid color"), stdgridcolor, 'g'); dialog::addColorItem(XLAT("standard grid color"), stdgridcolor, 'g');
dialog::add_action([] () { vid.grid = true; dialog::openColorDialog(stdgridcolor); dialog::dialogflags |= sm::SIDE; }); dialog::add_action([] () { vid.grid = true; dialog::openColorDialog(stdgridcolor); dialog::get_di().dialogflags |= sm::SIDE; });
dialog::addSelItem(XLAT("grid width multiplier"), fts(vid.multiplier_grid), 'G'); dialog::addSelItem(XLAT("grid width multiplier"), fts(vid.multiplier_grid), 'G');
dialog::add_action([] () { dialog::editNumber(vid.multiplier_grid, 0, 10, 1, 1, XLAT("grid width multiplier"), ""); }); dialog::add_action([] () { dialog::editNumber(vid.multiplier_grid, 0, 10, 1, 1, XLAT("grid width multiplier"), ""); });
@ -3377,10 +3377,10 @@ EX void show_color_dialog() {
XLAT("In the orthogonal projection, objects on the other side of the sphere are drawn darker.")); dialog::bound_low(0); }); XLAT("In the orthogonal projection, objects on the other side of the sphere are drawn darker.")); dialog::bound_low(0); });
dialog::addColorItem(XLAT("projection period"), periodcolor, 'p'); dialog::addColorItem(XLAT("projection period"), periodcolor, 'p');
dialog::add_action([] () { dialog::openColorDialog(periodcolor); dialog::dialogflags |= sm::SIDE; }); dialog::add_action([] () { dialog::openColorDialog(periodcolor); dialog::get_di().dialogflags |= sm::SIDE; });
dialog::addColorItem(XLAT("dialogs"), addalpha(dialog::dialogcolor), 'd'); dialog::addColorItem(XLAT("dialogs"), addalpha(dialog::dialogcolor), 'd');
dialog::add_action([] () { dialog::openColorDialog(dialog::dialogcolor); dialog::colorAlpha = false; dialog::dialogflags |= sm::SIDE; }); dialog::add_action([] () { dialog::openColorDialog(dialog::dialogcolor); dialog::colorAlpha = false; dialog::get_di().dialogflags |= sm::SIDE; });
dialog::addBreak(50); dialog::addBreak(50);
if(specialland == laCanvas && colortables.count(patterns::whichCanvas)) { if(specialland == laCanvas && colortables.count(patterns::whichCanvas)) {
@ -3449,7 +3449,7 @@ EX void show_color_dialog() {
else else
dialog::openColorDialog(floorcolors[c->land]); dialog::openColorDialog(floorcolors[c->land]);
dialog::colorAlpha = false; dialog::colorAlpha = false;
dialog::dialogflags |= sm::SIDE; dialog::get_di().dialogflags |= sm::SIDE;
return; return;
} }
else dialog::handleNavigation(sym, uni); else dialog::handleNavigation(sym, uni);
@ -3577,7 +3577,7 @@ EX void configureMouse() {
dialog::add_action([] { dialog::add_action([] {
dialog::editNumber(vid.mobilecompasssize, 0, 100, 10, 20, XLAT("compass size"), XLAT("0 to disable")); dialog::editNumber(vid.mobilecompasssize, 0, 100, 10, 20, XLAT("compass size"), XLAT("0 to disable"));
// we need to check the moves // we need to check the moves
dialog::reaction = checkmove; dialog::get_di().reaction = checkmove;
dialog::bound_low(0); dialog::bound_low(0);
}); });

View File

@ -1500,7 +1500,7 @@ EX void show() {
dialog::add_action([]() { dialog::add_action([]() {
draw_cut = true; draw_cut = true;
dialog::editNumber(cut_level, -1, 1, 0.1, 0, XLAT("cut level"), ""); dialog::editNumber(cut_level, -1, 1, 0.1, 0, XLAT("cut level"), "");
dialog::extra_options = [] { dialog::get_di().extra_options = [] {
dialog::addItem(XLAT("disable"), 'D'); dialog::addItem(XLAT("disable"), 'D');
dialog::add_action([] { draw_cut = false; popScreen(); }); dialog::add_action([] { draw_cut = false; popScreen(); });
}; };
@ -1512,7 +1512,7 @@ EX void show() {
dialog::add_action([] { dialog::add_action([] {
dialog::editNumber(crystal_period, 0, 16, 2, 0, XLAT("Crystal torus"), dialog::editNumber(crystal_period, 0, 16, 2, 0, XLAT("Crystal torus"),
XLAT("Z_k^d instead of Z^d. Only works with k even.")); XLAT("Z_k^d instead of Z^d. Only works with k even."));
dialog::reaction_final = [] { dialog::get_di().reaction_final = [] {
if(cryst) stop_game(); if(cryst) stop_game();
set_crystal_period_flags(); set_crystal_period_flags();
if(cryst) start_game(); if(cryst) start_game();

View File

@ -280,7 +280,7 @@ int bitfield_v;
template<class T> void bitfield_editor(int val, T setter, string help = "") { template<class T> void bitfield_editor(int val, T setter, string help = "") {
bitfield_v = val; bitfield_v = val;
dialog::editNumber(bitfield_v, 0, 100, 1, bitfield_v, help, ""); dialog::editNumber(bitfield_v, 0, 100, 1, bitfield_v, help, "");
dialog::reaction = [setter] () { setter(bitfield_v); }; dialog::get_di().reaction = [setter] () { setter(bitfield_v); };
} }
struct debugScreen { struct debugScreen {
@ -326,7 +326,7 @@ struct debugScreen {
static ld d = HEAT(what); static ld d = HEAT(what);
dialog::editNumber(d, -2, 2, 0.1, d, "landparam", dialog::editNumber(d, -2, 2, 0.1, d, "landparam",
"Extra value that is important in some lands. The specific meaning depends on the land."); "Extra value that is important in some lands. The specific meaning depends on the land.");
dialog::reaction = [what] () { HEAT(what) = d; }; dialog::get_di().reaction = [what] () { HEAT(what) = d; };
}); });
dialog::addSelItem("land flags", its(what->landflags)+"/"+itsh2(what->landflags), 'f'); dialog::addSelItem("land flags", its(what->landflags)+"/"+itsh2(what->landflags), 'f');
dialog::add_action([what] () { dialog::add_action([what] () {
@ -421,7 +421,7 @@ struct debugScreen {
dialog::add_action([what] () { dialog::add_action([what] () {
bitfield_editor(what->mondir, [what] (int i) { what->mondir = i; }, bitfield_editor(what->mondir, [what] (int i) { what->mondir = i; },
"monster direction"); "monster direction");
dialog::extra_options = [what] () { dialog::get_di().extra_options = [what] () {
dialog::addBoolItem(XLAT("mirrored"), what->monmirror, 'M'); dialog::addBoolItem(XLAT("mirrored"), what->monmirror, 'M');
}; };
}); });

View File

@ -47,23 +47,51 @@ EX namespace dialog {
const static scaler asinhic = {asinh, sinh, false}; const static scaler asinhic = {asinh, sinh, false};
const static scaler asinhic100 = {[] (ld x) { return asinh(x*100); }, [] (ld x) { return sinh(x)/100; }, false}; const static scaler asinhic100 = {[] (ld x) { return asinh(x*100); }, [] (ld x) { return sinh(x)/100; }, false};
struct numberEditor { /** extendable dialog */
struct extdialog {
string title, help;
int dialogflags;
reaction_t reaction;
reaction_t reaction_final;
reaction_t extra_options;
virtual void draw() = 0;
void operator() () { draw(); }
virtual ~extdialog() {};
extdialog();
/** Pop screen, then call the final reaction. A bit more complex because it eeds to backup reaction_final due to popScreen */
void popfinal() { auto rf = std::move(reaction_final); popScreen(); if(rf) rf(); }
};
/** number dialog */
struct number_dialog : extdialog {
ld *editwhat; ld *editwhat;
string s; string s;
ld vmin, vmax, step, dft; ld vmin, vmax, step, dft;
string title, help;
scaler sc; scaler sc;
int *intval; ld intbuf; int *intval; ld intbuf;
bool animatable; bool animatable;
void draw() override;
void apply_edit();
void apply_slider();
}; };
extern numberEditor ne;
inline void scaleLog() { ne.sc = logarithmic; }
inline void scaleSinh() { ne.sc = asinhic; }
inline void scaleSinh100() { ne.sc = asinhic100; }
#endif #endif
EX number_dialog& get_ne() {
auto ptr = screens.back().target<number_dialog>();
if(!ptr) throw hr_exception("get_ne() called without number dialog");
return *ptr;
}
EX extdialog& get_di() {
auto ptr = screens.back().target<extdialog>();
if(!ptr) throw hr_exception("get_di() called without extdialog");
return *ptr;
}
EX void scaleLog() { get_ne().sc = logarithmic; }
EX void scaleSinh() { get_ne().sc = asinhic; }
EX void scaleSinh100() { get_ne().sc = asinhic100; }
EX color_t dialogcolor = 0xC0C0C0; EX color_t dialogcolor = 0xC0C0C0;
EX color_t dialogcolor_clicked = 0xFF8000; EX color_t dialogcolor_clicked = 0xFF8000;
EX color_t dialogcolor_selected = 0xFFD500; EX color_t dialogcolor_selected = 0xFFD500;
@ -354,8 +382,6 @@ EX namespace dialog {
EX int dcenter, dwidth; EX int dcenter, dwidth;
EX int dialogflags;
EX int displayLong(string str, int siz, int y, bool measure) { EX int displayLong(string str, int siz, int y, bool measure) {
int last = 0; int last = 0;
@ -970,8 +996,12 @@ EX namespace dialog {
int colorp = 0; int colorp = 0;
color_t *colorPointer; color_t *colorPointer;
struct color_dialog : extdialog {
void draw() override;
};
EX void handleKeyColor(int sym, int uni) { EX void handleKeyColor(int sym, int uni, struct color_dialog& ne) {
unsigned& color = *colorPointer; unsigned& color = *colorPointer;
int shift = colorAlpha ? 0 : 8; int shift = colorAlpha ? 0 : 8;
@ -986,9 +1016,8 @@ EX namespace dialog {
for(int i=0; i<10; i++) if(colorhistory[i] == (color << shift)) for(int i=0; i<10; i++) if(colorhistory[i] == (color << shift))
inHistory = true; inHistory = true;
if(!inHistory) { colorhistory[lch] = (color << shift); lch++; lch %= 10; } if(!inHistory) { colorhistory[lch] = (color << shift); lch++; lch %= 10; }
popScreen(); if(ne.reaction) ne.reaction();
if(reaction) reaction(); ne.popfinal();
if(reaction_final) reaction_final();
} }
else if(uni >= '0' && uni <= '9') { else if(uni >= '0' && uni <= '9') {
color = colorhistory[uni - '0'] >> shift; color = colorhistory[uni - '0'] >> shift;
@ -1010,15 +1039,12 @@ EX namespace dialog {
unsigned char* pts = (unsigned char*) &color; unsigned char* pts = (unsigned char*) &color;
pts[colorp] += abs(shiftmul) < .6 ? 1 : 17; pts[colorp] += abs(shiftmul) < .6 ? 1 : 17;
} }
else if(doexiton(sym, uni)) { else if(doexiton(sym, uni)) ne.popfinal();
popScreen();
if(reaction_final) reaction_final();
}
} }
EX bool colorAlpha; EX bool colorAlpha;
EX void drawColorDialog() { void color_dialog::draw() {
cmode = sm::NUMBER | dialogflags; cmode = sm::NUMBER | dialogflags;
if(cmode & sm::SIDE) gamescreen(); if(cmode & sm::SIDE) gamescreen();
else emptyscreen(); else emptyscreen();
@ -1081,21 +1107,58 @@ EX namespace dialog {
if(extra_options) extra_options(); if(extra_options) extra_options();
keyhandler = handleKeyColor; keyhandler = [this] (int sym, int uni) { return handleKeyColor(sym, uni, self); };
} }
EX void openColorDialog(unsigned int& col, unsigned int *pal IS(palette)) { EX void openColorDialog(unsigned int& col, unsigned int *pal IS(palette)) {
color_dialog cd;
colorPointer = &col; palette = pal; colorPointer = &col; palette = pal;
colorAlpha = true; colorAlpha = true;
dialogflags = 0; pushScreen(cd);
pushScreen(drawColorDialog);
reaction = reaction_t();
extra_options = reaction_t();
} }
EX numberEditor ne; #if HDR
struct matrix_dialog : extdialog {
trans23 *edit_matrix;
void draw() override;
};
#endif
void matrix_dialog::draw() {
cmode = dialogflags;
gamescreen();
init(title);
addInfo(help);
addCustom(500, [this] {
int siz = dfsize * 5;
int mid = (top + tothei) / 2;
visualize_matrix(*edit_matrix, dcenter, mid, siz/2);
});
addBreak(100);
addItem("enter angle", 'a');
dialog::add_action([this] {
static ld angle = as_degrees(edit_matrix->get());
editNumber(angle, -180, 180, 90, 0, title, help);
auto& ne = get_ne();
auto re = reaction;
ne.reaction = [re, this] { *edit_matrix = spin(angle * degree); if(re) re(); };
ne.reaction_final = reaction;
ne.animatable = false;
});
addBack();
display();
}
EX void editMatrix(trans23& T, string t, string h) {
matrix_dialog m;
m.edit_matrix = &T;
m.title = t;
m.help = h;
pushScreen(m);
}
EX bool editingDetail() { EX bool editingDetail() {
auto& ne = get_ne();
return ne.editwhat == &vid.highdetail || ne.editwhat == &vid.middetail; return ne.editwhat == &vid.highdetail || ne.editwhat == &vid.middetail;
} }
@ -1105,18 +1168,16 @@ EX namespace dialog {
} }
EX string disp(ld x) { EX string disp(ld x) {
if(dialogflags & sm::HEXEDIT) return "0x" + itsh((unsigned long long)(x)); auto& ne = get_ne();
else if(ne.intval) return its(ldtoint(x)); if(ne.dialogflags & sm::HEXEDIT) return "0x" + itsh((unsigned long long)(x));
else return fts(x); } if(ne.intval) return its(ldtoint(x));
return fts(x);
}
EX reaction_t reaction; void number_dialog::apply_slider() {
EX reaction_t reaction_final; auto &ne = self;
EX reaction_t extra_options;
EX void apply_slider() {
if(ne.intval) *ne.intval = ldtoint(*ne.editwhat); if(ne.intval) *ne.intval = ldtoint(*ne.editwhat);
if(reaction) reaction(); if(ne.reaction) ne.reaction();
if(ne.intval) *ne.editwhat = *ne.intval; if(ne.intval) *ne.editwhat = *ne.intval;
ne.s = disp(*ne.editwhat); ne.s = disp(*ne.editwhat);
#if CAP_ANIMATIONS #if CAP_ANIMATIONS
@ -1125,11 +1186,13 @@ EX namespace dialog {
} }
EX void use_hexeditor() { EX void use_hexeditor() {
dialogflags |= sm::HEXEDIT; auto& ne = get_ne();
ne.dialogflags |= sm::HEXEDIT;
ne.s = disp(*ne.editwhat); ne.s = disp(*ne.editwhat);
} }
EX void apply_edit() { void number_dialog::apply_edit() {
auto& ne = self;
try { try {
exp_parser ep; exp_parser ep;
ep.s = ne.s; ep.s = ne.s;
@ -1150,8 +1213,9 @@ EX namespace dialog {
} }
EX void bound_low(ld val) { EX void bound_low(ld val) {
auto r = reaction; auto& ne = get_ne();
reaction = [r, val] () { auto r = ne.reaction;
ne.reaction = [r, val, &ne] () {
if(*ne.editwhat < val) { if(*ne.editwhat < val) {
*ne.editwhat = val; *ne.editwhat = val;
if(ne.intval) *ne.intval = ldtoint(*ne.editwhat); if(ne.intval) *ne.intval = ldtoint(*ne.editwhat);
@ -1161,8 +1225,9 @@ EX namespace dialog {
} }
EX void bound_up(ld val) { EX void bound_up(ld val) {
auto r = reaction; auto& ne = get_ne();
reaction = [r, val] () { auto r = ne.reaction;
ne.reaction = [r, val, &ne] () {
if(*ne.editwhat > val) { if(*ne.editwhat > val) {
*ne.editwhat = val; *ne.editwhat = val;
if(ne.intval) *ne.intval = ldtoint(*ne.editwhat); if(ne.intval) *ne.intval = ldtoint(*ne.editwhat);
@ -1182,7 +1247,13 @@ EX namespace dialog {
EX bool onscreen_keyboard = ISMOBILE; EX bool onscreen_keyboard = ISMOBILE;
EX void number_dialog_help() { struct number_dialog_help {
number_dialog *ptr;
void operator() ();
};
void number_dialog_help :: operator() () {
auto ne = *ptr;
init("number dialog help"); init("number dialog help");
dialog::addBreak(100); dialog::addBreak(100);
dialog::addHelp(XLAT("You can enter formulas in this dialog.")); dialog::addHelp(XLAT("You can enter formulas in this dialog."));
@ -1192,7 +1263,7 @@ EX namespace dialog {
dialog::addBreak(100); dialog::addBreak(100);
dialog::addHelp(XLAT("Constants and variables available:")); dialog::addHelp(XLAT("Constants and variables available:"));
addHelp(available_constants()); addHelp(available_constants());
if(ne.animatable) { if(ptr && ne.animatable) {
dialog::addBreak(100); dialog::addBreak(100);
dialog::addHelp(XLAT("Animations:")); dialog::addHelp(XLAT("Animations:"));
dialog::addHelp(XLAT("a..b -- animate linearly from a to b")); dialog::addHelp(XLAT("a..b -- animate linearly from a to b"));
@ -1207,7 +1278,7 @@ EX namespace dialog {
#if CAP_ANIMATIONS #if CAP_ANIMATIONS
dialog::addBreak(50); dialog::addBreak(50);
auto f = find_edit(ne.intval ? (void*) ne.intval : (void*) ne.editwhat); auto f = find_edit(!ptr ? nullptr : ne.intval ? (void*) ne.intval : (void*) ne.editwhat);
if(f) if(f)
dialog::addHelp(XLAT("Parameter names, e.g. '%1'", f->parameter_name)); dialog::addHelp(XLAT("Parameter names, e.g. '%1'", f->parameter_name));
else else
@ -1223,17 +1294,18 @@ EX namespace dialog {
} }
EX void parser_help() { EX void parser_help() {
ne.editwhat = nullptr; number_dialog_help ndh;
ne.intval = nullptr; ndh.ptr = nullptr;
addItem("help", SDLK_F1); addItem("help", SDLK_F1);
add_action_push(number_dialog_help); add_action_push(ndh);
} }
EX void drawNumberDialog() { void number_dialog::draw() {
cmode = sm::NUMBER | dialogflags; cmode = sm::NUMBER | dialogflags;
gamescreen(); gamescreen();
init(ne.title); init(title);
addInfo(ne.s); addInfo(s);
auto& ne = self;
if(ne.intval && ne.sc.direct == &identity_f) if(ne.intval && ne.sc.direct == &identity_f)
addIntSlider(int(ne.vmin), int(*ne.editwhat), int(ne.vmax), 500); addIntSlider(int(ne.vmin), int(*ne.editwhat), int(ne.vmax), 500);
else else
@ -1248,7 +1320,7 @@ EX namespace dialog {
addSelItem(XLAT("default value"), disp(ne.dft), SDLK_HOME); addSelItem(XLAT("default value"), disp(ne.dft), SDLK_HOME);
add_edit(onscreen_keyboard); add_edit(onscreen_keyboard);
addItem("help", SDLK_F1); addItem("help", SDLK_F1);
add_action_push(number_dialog_help); add_action([this] { number_dialog_help ndh; ndh.ptr = this; pushScreen(ndh); });
addBreak(100); addBreak(100);
@ -1267,7 +1339,7 @@ EX namespace dialog {
display(); display();
keyhandler = [] (int sym, int uni) { keyhandler = [this, &ne] (int sym, int uni) {
handleNavigation(sym, uni); handleNavigation(sym, uni);
if((uni >= '0' && uni <= '9') || among(uni, '.', '+', '-', '*', '/', '^', '(', ')', ',', '|', 3) || (uni >= 'a' && uni <= 'z')) { if((uni >= '0' && uni <= '9') || among(uni, '.', '+', '-', '*', '/', '^', '(', ')', ',', '|', 3) || (uni >= 'a' && uni <= 'z')) {
if(uni == 3) ne.s += "pi"; if(uni == 3) ne.s += "pi";
@ -1322,7 +1394,7 @@ EX namespace dialog {
apply_slider(); apply_slider();
} }
else if(doexiton(sym, uni)) { popScreen(); if(reaction_final) reaction_final(); } else if(doexiton(sym, uni)) ne.popfinal();
}; };
} }
@ -1377,7 +1449,16 @@ EX namespace dialog {
return true; return true;
} }
extdialog::extdialog() {
dialogflags = 0;
if(cmode & sm::SIDE) dialogflags |= sm::MAYDARK | sm::SIDE;
reaction = reaction_t();
reaction_final = reaction_t();
extra_options = reaction_t();
}
EX void editNumber(ld& x, ld vmin, ld vmax, ld step, ld dft, string title, string help) { EX void editNumber(ld& x, ld vmin, ld vmax, ld step, ld dft, string title, string help) {
number_dialog ne;
ne.editwhat = &x; ne.editwhat = &x;
ne.s = disp(x); ne.s = disp(x);
ne.vmin = vmin; ne.vmin = vmin;
@ -1388,45 +1469,19 @@ EX namespace dialog {
ne.help = help; ne.help = help;
ne.sc = identity; ne.sc = identity;
ne.intval = NULL; ne.intval = NULL;
dialogflags = 0;
if(cmode & sm::SIDE) dialogflags |= sm::MAYDARK | sm::SIDE;
cmode |= sm::NUMBER;
pushScreen(drawNumberDialog);
reaction = reaction_t();
reaction_final = reaction_t();
extra_options = reaction_t();
ne.animatable = true; ne.animatable = true;
#if CAP_ANIMATIONS #if CAP_ANIMATIONS
anims::get_parameter_animation(anims::find_param(&x), ne.s); anims::get_parameter_animation(anims::find_param(&x), ne.s);
#endif #endif
} pushScreen(ne);
EX void editMatrix(trans23& x, string title, string help) {
static ld angle = as_degrees(x.get());
ne.editwhat = &angle;
ne.s = disp(angle);
ne.vmin = -180;
ne.vmax = 180;
ne.step = 90;
ne.dft = 0;
ne.title = title;
ne.help = help;
ne.sc = identity;
ne.intval = NULL;
dialogflags = 0;
if(cmode & sm::SIDE) dialogflags |= sm::MAYDARK | sm::SIDE;
cmode |= sm::NUMBER;
pushScreen(drawNumberDialog);
reaction = [&] { x = spin(angle * degree); };
reaction_final = reaction;
extra_options = reaction_t();
ne.animatable = false;
} }
EX void editNumber(int& x, int vmin, int vmax, ld step, int dft, string title, string help) { EX void editNumber(int& x, int vmin, int vmax, ld step, int dft, string title, string help) {
editNumber(ne.intbuf, vmin, vmax, step, dft, title, help); ld tmp;
ne.intbuf = x; ne.intval = &x; ne.s = its(x); editNumber(tmp, vmin, vmax, step, dft, title, help);
ne.animatable = true; auto& ne = dialog::get_ne();
ne.editwhat = &ne.intbuf; ne.intbuf = x; ne.intval = &x; ne.s = its(x);
anims::get_parameter_animation(anims::find_param(&x), ne.s);
} }
EX void helpToEdit(int& x, int vmin, int vmax, int step, int dft) { EX void helpToEdit(int& x, int vmin, int vmax, int step, int dft) {
@ -1464,7 +1519,11 @@ EX namespace dialog {
bool search_mode; bool search_mode;
EX void drawFileDialog() { struct file_dialog : extdialog {
void draw() override;
};
void file_dialog::draw() {
cmode = sm::NUMBER | dialogflags | sm::DIALOG_WIDE; cmode = sm::NUMBER | dialogflags | sm::DIALOG_WIDE;
gamescreen(); gamescreen();
init(filecaption); init(filecaption);
@ -1541,8 +1600,8 @@ EX namespace dialog {
else { else {
str1 = where + vf; str1 = where + vf;
if(s == str1) { if(s == str1) {
popScreen(); bool ac = file_action();
if(!file_action()) pushScreen(drawFileDialog); if(ac) popScreen();
} }
s = str1; s = str1;
} }
@ -1570,9 +1629,8 @@ EX namespace dialog {
popScreen(); popScreen();
} }
else if(sym == SDLK_RETURN || sym == SDLK_KP_ENTER) { else if(sym == SDLK_RETURN || sym == SDLK_KP_ENTER) {
// we pop and re-push, in case if action opens something bool ac = file_action();
popScreen(); if(ac) popScreen();
if(!file_action()) pushScreen(drawFileDialog);
} }
else if(sym == SDLK_BACKSPACE && i) { else if(sym == SDLK_BACKSPACE && i) {
s.erase(i-1, 1); s.erase(i-1, 1);
@ -1588,11 +1646,12 @@ EX namespace dialog {
} }
EX void openFileDialog(string& filename, string fcap, string ext, bool_reaction_t action) { EX void openFileDialog(string& filename, string fcap, string ext, bool_reaction_t action) {
file_dialog fd;
cfileptr = &filename; cfileptr = &filename;
filecaption = fcap; filecaption = fcap;
cfileext = ext; cfileext = ext;
file_action = action; file_action = action;
pushScreen(dialog::drawFileDialog); pushScreen(fd);
} }
// infix/v/vpush // infix/v/vpush
@ -1695,11 +1754,15 @@ EX namespace dialog {
else return false; else return false;
return true; return true;
} }
struct string_dialog : extdialog {
void draw();
};
EX void string_edit_dialog() { void string_dialog::draw() {
cmode = sm::NUMBER | dialogflags; cmode = sm::NUMBER | dialogflags;
gamescreen(); gamescreen();
init(ne.title); init(title);
addInfo(view_edited_string()); addInfo(view_edited_string());
addBreak(100); addBreak(100);
formula_keyboard(true); formula_keyboard(true);
@ -1707,34 +1770,27 @@ EX namespace dialog {
dialog::addBack(); dialog::addBack();
addBreak(100); addBreak(100);
if(ne.help != "") { if(help != "") {
addHelp(ne.help); addHelp(help);
} }
if(extra_options) extra_options(); if(extra_options) extra_options();
display(); display();
keyhandler = [] (int sym, int uni) { keyhandler = [this] (int sym, int uni) {
handleNavigation(sym, uni); handleNavigation(sym, uni);
if(handle_edit_string(sym, uni)) ; if(handle_edit_string(sym, uni)) ;
else if(doexiton(sym, uni)) { else if(doexiton(sym, uni)) popfinal();
popScreen();
if(reaction_final) reaction_final();
}
}; };
} }
EX void edit_string(string& s, string title, string help) { EX void edit_string(string& s, string title, string help) {
start_editing(s); start_editing(s);
string_dialog ne;
ne.title = title; ne.title = title;
ne.help = help; ne.help = help;
dialogflags = 0; pushScreen(ne);
if(cmode & sm::SIDE) dialogflags |= sm::MAYDARK | sm::SIDE;
cmode |= sm::NUMBER;
pushScreen(string_edit_dialog);
reaction = reaction_t();
extra_options = reaction_t();
} }
EX void confirm_dialog(const string& text, const reaction_t& act) { EX void confirm_dialog(const string& text, const reaction_t& act) {

View File

@ -963,7 +963,7 @@ EX namespace euc {
dialog::addItem("special manifolds", 'S'); dialog::addItem("special manifolds", 'S');
dialog::add_action([] { dialog::add_action([] {
dialog::editNumber(quotient_size, 1, 12, 1, 2, "special manifold size", ""); dialog::editNumber(quotient_size, 1, 12, 1, 2, "special manifold size", "");
dialog::extra_options = [] { dialog::get_di().extra_options = [] {
auto q = quotient_size; auto q = quotient_size;
torus_config_option(XLAT("third-turn space"), 'A', make_third_turn(q,0,q)); torus_config_option(XLAT("third-turn space"), 'A', make_third_turn(q,0,q));
torus_config_option(XLAT("quarter-turn space"), 'B', make_quarter_turn(q,0,q)); torus_config_option(XLAT("quarter-turn space"), 'B', make_quarter_turn(q,0,q));
@ -1046,7 +1046,7 @@ EX namespace euc {
"not implemented.)" "not implemented.)"
) )
); );
dialog::extra_options = show_fundamental; dialog::get_di().extra_options = show_fundamental;
}); });
} }
} }

View File

@ -809,7 +809,7 @@ void expansion_analyzer::view_distances_dialog() {
scrolling_distances = false; scrolling_distances = false;
dialog::editNumber(last_distance, 0, 3000, 1, 0, XLAT("display distances up to"), ""); dialog::editNumber(last_distance, 0, 3000, 1, 0, XLAT("display distances up to"), "");
dialog::bound_low(0); dialog::bound_low(0);
dialog::extra_options = [] { dialog::get_di().extra_options = [] {
add_edit(auto_extend); add_edit(auto_extend);
}; };
}); });

View File

@ -731,10 +731,10 @@ EX void configure() {
"the number of cells around an edge.\n\n" "the number of cells around an edge.\n\n"
); );
if(fake::in()) if(fake::in())
dialog::reaction = change_around; dialog::get_di().reaction = change_around;
else else
dialog::reaction_final = change_around; dialog::get_di().reaction_final = change_around;
dialog::extra_options = [] { dialog::get_di().extra_options = [] {
ld e = compute_euclidean(); ld e = compute_euclidean();
dialog::addSelItem("Euclidean", fts(e), 'E'); dialog::addSelItem("Euclidean", fts(e), 'E');
dialog::add_action([e] { dialog::add_action([e] {

View File

@ -690,7 +690,7 @@ EX void menuitem_binary_width(char key) {
dialog::addSelItem(XLAT("binary tiling width"), fts(vid.binary_width), key); dialog::addSelItem(XLAT("binary tiling width"), fts(vid.binary_width), key);
dialog::add_action([] { dialog::add_action([] {
dialog::editNumber(vid.binary_width, 0, 2, 0.1, 1, XLAT("binary tiling width"), ""); dialog::editNumber(vid.binary_width, 0, 2, 0.1, 1, XLAT("binary tiling width"), "");
dialog::reaction = [] () { dialog::get_ne().reaction = [] () {
#if CAP_TEXTURE #if CAP_TEXTURE
texture::config.remap(); texture::config.remap();
#endif #endif
@ -705,7 +705,7 @@ EX void menuitem_nilwidth(char key) {
dialog::addSelItem(XLAT("Nil width"), fts(nilv::nilwidth), key); dialog::addSelItem(XLAT("Nil width"), fts(nilv::nilwidth), key);
dialog::add_action([] { dialog::add_action([] {
dialog::editNumber(nilv::nilwidth, 0.01, 2, 0.1, 1, XLAT("Nil width"), ""); dialog::editNumber(nilv::nilwidth, 0.01, 2, 0.1, 1, XLAT("Nil width"), "");
dialog::reaction = ray::reset_raycaster; dialog::get_ne().reaction = ray::reset_raycaster;
dialog::bound_low(0.01); dialog::bound_low(0.01);
}); });
} }
@ -719,7 +719,7 @@ EX void edit_stretch() {
"Value of 0 means not stretched, -1 means S2xE or H2xE (works only in the limit). (Must be > -1)" "Value of 0 means not stretched, -1 means S2xE or H2xE (works only in the limit). (Must be > -1)"
) )
); );
dialog::reaction = [] { if(abs(stretch::factor+1) < 1e-3) stretch::factor = -.9; ray::reset_raycaster(); }; dialog::get_ne().reaction = [] { if(abs(stretch::factor+1) < 1e-3) stretch::factor = -.9; ray::reset_raycaster(); };
} }
#if HDR #if HDR
@ -1013,7 +1013,7 @@ EX void showEuclideanMenu() {
dialog::addSelItem(XLAT("Z-level height factor"), fts(vid.plevel_factor), 'Z'); dialog::addSelItem(XLAT("Z-level height factor"), fts(vid.plevel_factor), 'Z');
dialog::add_action([] { dialog::add_action([] {
dialog::editNumber(vid.plevel_factor, 0, 2, 0.1, 0.7, XLAT("Z-level height factor"), ""); dialog::editNumber(vid.plevel_factor, 0, 2, 0.1, 0.7, XLAT("Z-level height factor"), "");
dialog::reaction = ray::reset_raycaster; dialog::get_ne().reaction = ray::reset_raycaster;
}); });
} }
else if(mhybrid) { else if(mhybrid) {
@ -1067,7 +1067,7 @@ EX void showEuclideanMenu() {
); );
dialog::bound_low(0); dialog::bound_low(0);
dialog::bound_up(1); dialog::bound_up(1);
dialog::extra_options = [] () { rots::draw_underlying(true); }; dialog::get_di().extra_options = [] () { rots::draw_underlying(true); };
}); });
} }
#endif #endif
@ -1086,11 +1086,11 @@ EX void showEuclideanMenu() {
dialog::add_action([] { dialog::add_action([] {
dialog::editNumber(bounded_mine_quantity, 0, bounded_mine_max, 1, (bounded_mine_max+5)/10, dialog::editNumber(bounded_mine_quantity, 0, bounded_mine_max, 1, (bounded_mine_max+5)/10,
XLAT("number of mines"), ""); XLAT("number of mines"), "");
dialog::reaction = [] { dialog::get_ne().reaction = [] {
if(bounded_mine_quantity < 0) bounded_mine_quantity = 0; if(bounded_mine_quantity < 0) bounded_mine_quantity = 0;
if(bounded_mine_quantity > bounded_mine_max) bounded_mine_quantity = bounded_mine_max; if(bounded_mine_quantity > bounded_mine_max) bounded_mine_quantity = bounded_mine_max;
}; };
dialog::reaction_final = [] { dialog::get_ne().reaction_final = [] {
bounded_mine_percentage = bounded_mine_quantity * 1. / bounded_mine_max; bounded_mine_percentage = bounded_mine_quantity * 1. / bounded_mine_max;
stop_game(); stop_game();
start_game(); start_game();

View File

@ -207,6 +207,7 @@ constexpr transmatrix Zero = diag(0,0,0,0);
struct trans23 { struct trans23 {
transmatrix v2, v3; transmatrix v2, v3;
transmatrix& get() { return MDIM == 3 ? v2 : v3; } transmatrix& get() { return MDIM == 3 ? v2 : v3; }
const transmatrix& get() const { return MDIM == 3 ? v2 : v3; }
trans23() { v2 = Id; v3 = Id; } trans23() { v2 = Id; v3 = Id; }
trans23(const transmatrix& T) { v2 = T; v3 = T; } trans23(const transmatrix& T) { v2 = T; v3 = T; }
trans23(const transmatrix& T2, const transmatrix& T3) { v2 = T2; v3 = T3; } trans23(const transmatrix& T2, const transmatrix& T3) { v2 = T2; v3 = T3; }

View File

@ -873,7 +873,7 @@ void show_gridmaker() {
dialog::addSelItem(XLAT("density"), fts(density), 'd'); dialog::addSelItem(XLAT("density"), fts(density), 'd');
dialog::add_action([] { dialog::add_action([] {
dialog::editNumber(density, 1, 10, .1, 4, XLAT("density"), XLAT(irrhelp)); dialog::editNumber(density, 1, 10, .1, 4, XLAT("density"), XLAT(irrhelp));
dialog::reaction = [] () { dialog::get_di().reaction = [] () {
int s = cellcount; int s = cellcount;
if(density < 1) density = 1; if(density < 1) density = 1;
cellcount = int(isize(currentmap->allcells()) * density + .5); cellcount = int(isize(currentmap->allcells()) * density + .5);
@ -888,7 +888,7 @@ void show_gridmaker() {
"The smallest allowed ratio of edge length to median edge length. " "The smallest allowed ratio of edge length to median edge length. "
"Tilings with low values are easier to generate, but tend to be more ugly." "Tilings with low values are easier to generate, but tend to be more ugly."
)); ));
dialog::reaction = [] () { dialog::get_di().reaction = [] () {
println(hlog, "quality = ", density); println(hlog, "quality = ", density);
if(runlevel > 4) runlevel = 4; if(runlevel > 4) runlevel = 4;
}; };
@ -931,7 +931,7 @@ void show_gridmaker() {
dialog::add_action([] () { dialog::add_action([] () {
dialog::editNumber(bitruncations_requested, 0, 5, 1, 1, XLAT("bitruncation const"), dialog::editNumber(bitruncations_requested, 0, 5, 1, 1, XLAT("bitruncation const"),
XLAT("Bitruncation introduces some regularity, allowing more sophisticated floor tilings and textures.")); XLAT("Bitruncation introduces some regularity, allowing more sophisticated floor tilings and textures."));
dialog::reaction = [] () { dialog::get_di().reaction = [] () {
if(bitruncations_requested > bitruncations_performed && runlevel > 5) runlevel = 5; if(bitruncations_requested > bitruncations_performed && runlevel > 5) runlevel = 5;
if(bitruncations_requested < bitruncations_performed) runlevel = 0; if(bitruncations_requested < bitruncations_performed) runlevel = 0;
}; };

View File

@ -2725,7 +2725,7 @@ EX namespace mapeditor {
if(uni == 'z' && GDIM == 3) { if(uni == 'z' && GDIM == 3) {
dialog::editNumber(front_edit, 0, 5, 0.1, 0.5, XLAT("z-level"), ""); dialog::editNumber(front_edit, 0, 5, 0.1, 0.5, XLAT("z-level"), "");
dialog::extra_options = [] () { dialog::get_di().extra_options = [] () {
dialog::addBoolItem(XLAT("The distance from the camera to added points."), front_config == eFront::sphere_camera, 'A'); dialog::addBoolItem(XLAT("The distance from the camera to added points."), front_config == eFront::sphere_camera, 'A');
dialog::add_action([] { front_config = eFront::sphere_camera; }); dialog::add_action([] { front_config = eFront::sphere_camera; });
dialog::addBoolItem(XLAT("place points at fixed radius"), front_config == eFront::sphere_center, 'B'); dialog::addBoolItem(XLAT("place points at fixed radius"), front_config == eFront::sphere_center, 'B');
@ -2854,7 +2854,7 @@ EX namespace mapeditor {
static string text = ""; static string text = "";
dialog::edit_string(text, "", ""); dialog::edit_string(text, "", "");
shiftpoint h = mh; shiftpoint h = mh;
dialog::reaction_final = [h] { dialog::get_di().reaction_final = [h] {
if(text != "") if(text != "")
dt_add_text(h, dtwidth * 50, text); dt_add_text(h, dtwidth * 50, text);
}; };
@ -2956,7 +2956,7 @@ EX namespace mapeditor {
if(uni == 'p') { if(uni == 'p') {
dialog::openColorDialog(colortouse); dialog::openColorDialog(colortouse);
dialog::reaction = [] () { dialog::get_di().reaction = [] () {
drawHandleKey(COLORKEY, COLORKEY); drawHandleKey(COLORKEY, COLORKEY);
}; };
} }

View File

@ -181,7 +181,7 @@ EX void showOverview() {
gotoHelp(generateHelpForItem(eItem(umod))); gotoHelp(generateHelpForItem(eItem(umod)));
if(cheater) { if(cheater) {
dialog::helpToEdit(items[umod], 0, 200, 10, 10); dialog::helpToEdit(items[umod], 0, 200, 10, 10);
dialog::reaction = [] () { dialog::get_ne().reaction = [] () {
if(hardcore) canmove = true; if(hardcore) canmove = true;
else checkmove(); else checkmove();
cheater++; cheater++;

View File

@ -293,7 +293,7 @@ EX namespace models {
}); });
if(spiral_id > isize(torus_zeros)) spiral_id = 0; if(spiral_id > isize(torus_zeros)) spiral_id = 0;
dialog::editNumber(spiral_id, 0, isize(torus_zeros)-1, 1, 10, XLAT("match the period of the torus"), ""); dialog::editNumber(spiral_id, 0, isize(torus_zeros)-1, 1, 10, XLAT("match the period of the torus"), "");
dialog::reaction = [] () { dialog::get_di().reaction = [] () {
auto& co = torus_zeros[spiral_id]; auto& co = torus_zeros[spiral_id];
vpconf.spiral_x = co.first; vpconf.spiral_x = co.first;
vpconf.spiral_y = co.second; vpconf.spiral_y = co.second;
@ -312,7 +312,7 @@ EX namespace models {
) )
); );
#if CAP_QUEUE && CAP_CURVE #if CAP_QUEUE && CAP_CURVE
dialog::extra_options = [] () { dialog::get_di().extra_options = [] () {
dialog::parser_help(); dialog::parser_help();
initquickqueue(); initquickqueue();
queuereset(mdPixel, PPR::LINE); queuereset(mdPixel, PPR::LINE);
@ -328,7 +328,7 @@ EX namespace models {
quickqueue(); quickqueue();
}; };
#endif #endif
dialog::reaction_final = [] () { dialog::get_di().reaction_final = [] () {
vpconf.model = mdFormula; vpconf.model = mdFormula;
}; };
} }
@ -339,8 +339,8 @@ EX namespace models {
"It affects the line animation in the history mode, and " "It affects the line animation in the history mode, and "
"lands which have a special direction. Note that if finding this special direction is a part of the puzzle, " "lands which have a special direction. Note that if finding this special direction is a part of the puzzle, "
"it works only in the cheat mode."); "it works only in the cheat mode.");
dialog::dialogflags |= sm::CENTER; dialog::get_di().dialogflags |= sm::CENTER;
dialog::extra_options = [] () { dialog::get_di().extra_options = [] () {
dialog::addBreak(100); dialog::addBreak(100);
dialog::addBoolItem_choice("line animation only", models::do_rotate, 0, 'N'); dialog::addBoolItem_choice("line animation only", models::do_rotate, 0, 'N');
dialog::addBoolItem_choice("gravity lands", models::do_rotate, 1, 'G'); dialog::addBoolItem_choice("gravity lands", models::do_rotate, 1, 'G');
@ -398,7 +398,7 @@ EX namespace models {
dialog::addBreak(100); dialog::addBreak(100);
if(sphere && pmodel == mdBandEquiarea) { if(sphere && pmodel == mdBandEquiarea) {
dialog::addBoolItem("Gall-Peters", vpconf.stretch == 2, 'O'); dialog::addBoolItem("Gall-Peters", vpconf.stretch == 2, 'O');
dialog::add_action([] { vpconf.stretch = 2; dialog::ne.s = "2"; }); dialog::add_action([] { vpconf.stretch = 2; dialog::get_ne().s = "2"; });
} }
if(pmodel == mdBandEquiarea) { if(pmodel == mdBandEquiarea) {
// y = K * sin(phi) // y = K * sin(phi)
@ -558,17 +558,17 @@ EX namespace models {
dialog::addSelItem(XLAT("polygon sides"), its(polygonal::SI), 'x'); dialog::addSelItem(XLAT("polygon sides"), its(polygonal::SI), 'x');
dialog::add_action([] () { dialog::add_action([] () {
dialog::editNumber(polygonal::SI, 3, 10, 1, 4, XLAT("polygon sides"), ""); dialog::editNumber(polygonal::SI, 3, 10, 1, 4, XLAT("polygon sides"), "");
dialog::reaction = polygonal::solve; dialog::get_di().reaction = polygonal::solve;
}); });
dialog::addSelItem(XLAT("star factor"), fts(polygonal::STAR), 'y'); dialog::addSelItem(XLAT("star factor"), fts(polygonal::STAR), 'y');
dialog::add_action([]() { dialog::add_action([]() {
dialog::editNumber(polygonal::STAR, -1, 1, .1, 0, XLAT("star factor"), ""); dialog::editNumber(polygonal::STAR, -1, 1, .1, 0, XLAT("star factor"), "");
dialog::reaction = polygonal::solve; dialog::get_di().reaction = polygonal::solve;
}); });
dialog::addSelItem(XLAT("degree of the approximation"), its(polygonal::deg), 'n'); dialog::addSelItem(XLAT("degree of the approximation"), its(polygonal::deg), 'n');
dialog::add_action([](){ dialog::add_action([](){
dialog::editNumber(polygonal::deg, 2, polygonal::MSI-1, 1, 2, XLAT("degree of the approximation"), ""); dialog::editNumber(polygonal::deg, 2, polygonal::MSI-1, 1, 2, XLAT("degree of the approximation"), "");
dialog::reaction = polygonal::solve; dialog::get_di().reaction = polygonal::solve;
dialog::bound_low(0); dialog::bound_up(polygonal::MSI-1); dialog::bound_low(0); dialog::bound_up(polygonal::MSI-1);
}); });
} }

View File

@ -1626,7 +1626,7 @@ EX namespace hybrid {
start_game(); start_game();
}; };
}; };
dialog::extra_options = [=] () { dialog::get_di().extra_options = [=] () {
if(rotspace) { if(rotspace) {
int e_steps = cgi.psl_steps / gcd(cgi.single_step, cgi.psl_steps); int e_steps = cgi.psl_steps / gcd(cgi.single_step, cgi.psl_steps);
bool ubounded = PIU(closed_manifold); bool ubounded = PIU(closed_manifold);
@ -1645,7 +1645,7 @@ EX namespace hybrid {
dialog::addSelItem( XLAT("non-periodic"), its(0), 'N'); dialog::addSelItem( XLAT("non-periodic"), its(0), 'N');
dialog::add_action(set_s(0, true)); dialog::add_action(set_s(0, true));
} }
dialog::reaction_final = set_s(s, false); dialog::get_di().reaction_final = set_s(s, false);
}; };
} }
@ -1787,7 +1787,7 @@ EX namespace product {
dialog::editNumber(s, 0, 16, 1, 0, XLAT("rotation", "Z"), dialog::editNumber(s, 0, 16, 1, 0, XLAT("rotation", "Z"),
XLAT("Works if the underlying space is symmetric.") XLAT("Works if the underlying space is symmetric.")
); );
dialog::reaction_final = [] { dialog::get_di().reaction_final = [] {
if(s == cspin) return; if(s == cspin) return;
stop_game(); stop_game();
cspin = s; cspin = s;

View File

@ -1783,7 +1783,7 @@ EX namespace patterns {
EX void edit_rwalls() { EX void edit_rwalls() {
if(WDIM == 2) return; if(WDIM == 2) return;
dialog::editNumber(rwalls, 0, 100, 10, 50, XLAT("probability of a wall (%)"), ""); dialog::editNumber(rwalls, 0, 100, 10, 50, XLAT("probability of a wall (%)"), "");
dialog::reaction = [] { stop_game(); start_game(); }; dialog::get_di().reaction = [] { stop_game(); start_game(); };
} }
EX int generateCanvas(cell *c) { EX int generateCanvas(cell *c) {
@ -2115,7 +2115,7 @@ EX namespace patterns {
6, 0xFFFFFFFF, 0x101010FF, 0x404040FF, 0x808080FF, 0x800000FF, unsigned(linf[laCanvas].color >> 2) << 8 6, 0xFFFFFFFF, 0x101010FF, 0x404040FF, 0x808080FF, 0x800000FF, unsigned(linf[laCanvas].color >> 2) << 8
}; };
dialog::openColorDialog(c, canvasbacks); dialog::openColorDialog(c, canvasbacks);
dialog::reaction = [instant] () { dialog::get_di().reaction = [instant] () {
if(instant) { if(instant) {
stop_game(); stop_game();
whichCanvas = 'g'; whichCanvas = 'g';
@ -2128,7 +2128,7 @@ EX namespace patterns {
canvasback = c >> 8; canvasback = c >> 8;
} }
}; };
dialog::reaction_final = edit_rwalls; dialog::get_di().reaction_final = edit_rwalls;
} }
else if(uni == 'i') { else if(uni == 'i') {
if(instant) if(instant)
@ -2171,8 +2171,8 @@ EX namespace patterns {
dialog::edit_string(color_formula, "formula", s); dialog::edit_string(color_formula, "formula", s);
dialog::extra_options = dialog::parser_help; dialog::get_di().extra_options = dialog::parser_help;
dialog::reaction_final = [instant] () { dialog::get_di().reaction_final = [instant] () {
if(instant) stop_game(); if(instant) stop_game();
whichCanvas = 'f'; whichCanvas = 'f';
if(instant) { if(instant) {
@ -3102,7 +3102,7 @@ EX namespace linepatterns {
dialog::addColorItem(name, lp->color, 'a'+(id++)); dialog::addColorItem(name, lp->color, 'a'+(id++));
dialog::add_action([lp] () { dialog::add_action([lp] () {
dialog::openColorDialog(lp->color, NULL); dialog::openColorDialog(lp->color, NULL);
dialog::dialogflags |= sm::MAYDARK | sm::SIDE; dialog::get_di().dialogflags |= sm::MAYDARK | sm::SIDE;
}); });
} }
else { else {

View File

@ -1039,8 +1039,8 @@ void race_projection() {
dialog::add_action([] () { dialog::add_action([] () {
dialog::editMatrix(race_angle, XLAT("model orientation"), ""); dialog::editMatrix(race_angle, XLAT("model orientation"), "");
auto q = rot_inverse(race_angle) * pconf.mori(); auto q = rot_inverse(race_angle) * pconf.mori();
auto last = dialog::reaction; auto last = dialog::get_ne().reaction;
dialog::reaction = [q, last] () { last(); pconf.mori() = race_angle * q; }; dialog::get_ne().reaction = [q, last] () { last(); pconf.mori() = race_angle * q; };
}); });
} }

View File

@ -2828,7 +2828,7 @@ EX void menu() {
dialog::addSelItem(XLAT("intensity of random coloring"), its(intensity), 'i'); dialog::addSelItem(XLAT("intensity of random coloring"), its(intensity), 'i');
dialog::add_action([] { dialog::add_action([] {
dialog::editNumber(intensity, 0, 255, 5, 15, "", ""); dialog::editNumber(intensity, 0, 255, 5, 15, "", "");
dialog::reaction = random_fog; dialog::get_di().reaction = random_fog;
}); });
dialog::addItem(XLAT("color randomly"), 'r'); dialog::addItem(XLAT("color randomly"), 'r');
@ -2838,14 +2838,14 @@ EX void menu() {
dialog::add_action([&] { dialog::add_action([&] {
enable(); enable();
dialog::openColorDialog(vmap[centerover]); dialog::openColorDialog(vmap[centerover]);
dialog::dialogflags |= sm::SIDE; dialog::get_di().dialogflags |= sm::SIDE;
}); });
dialog::addColorItem("color cell under player", vmap.count(cwt.at) ? vmap[cwt.at] : 0, 'p'); dialog::addColorItem("color cell under player", vmap.count(cwt.at) ? vmap[cwt.at] : 0, 'p');
dialog::add_action([&] { dialog::add_action([&] {
enable(); enable();
dialog::openColorDialog(vmap[cwt.at]); dialog::openColorDialog(vmap[cwt.at]);
dialog::dialogflags |= sm::SIDE; dialog::get_di().dialogflags |= sm::SIDE;
}); });
dialog::addBreak(150); dialog::addBreak(150);
@ -2895,8 +2895,8 @@ EX void configure() {
dialog::add_action([&] { dialog::add_action([&] {
if(hard_limit >= NO_LIMIT) hard_limit = 10; if(hard_limit >= NO_LIMIT) hard_limit = 10;
dialog::editNumber(hard_limit, 0, 100, 1, 10, XLAT("hard limit"), ""); dialog::editNumber(hard_limit, 0, 100, 1, 10, XLAT("hard limit"), "");
dialog::reaction = reset_raycaster; dialog::get_di().reaction = reset_raycaster;
dialog::extra_options = [] { dialog::get_di().extra_options = [] {
dialog::addItem("no limit", 'N'); dialog::addItem("no limit", 'N');
dialog::add_action([] { hard_limit = NO_LIMIT; reset_raycaster(); }); dialog::add_action([] { hard_limit = NO_LIMIT; reset_raycaster(); });
}; };
@ -2906,7 +2906,7 @@ EX void configure() {
dialog::addSelItem(XLAT("reflective walls"), fts(reflect_val), 'R'); dialog::addSelItem(XLAT("reflective walls"), fts(reflect_val), 'R');
dialog::add_action([&] { dialog::add_action([&] {
dialog::editNumber(reflect_val, 0, 1, 0.1, 0, XLAT("reflective walls"), ""); dialog::editNumber(reflect_val, 0, 1, 0.1, 0, XLAT("reflective walls"), "");
dialog::reaction = reset_raycaster; dialog::get_di().reaction = reset_raycaster;
}); });
} }
@ -2920,7 +2920,7 @@ EX void configure() {
XLAT("max step"), "affects the precision of solving the geodesic equation in Solv"); XLAT("max step"), "affects the precision of solving the geodesic equation in Solv");
dialog::scaleLog(); dialog::scaleLog();
dialog::bound_low(1e-9); dialog::bound_low(1e-9);
dialog::reaction = reset_raycaster; dialog::get_di().reaction = reset_raycaster;
}); });
dialog::addSelItem(XLAT("min step"), fts(minstep), 'n'); dialog::addSelItem(XLAT("min step"), fts(minstep), 'n');
@ -2928,7 +2928,7 @@ EX void configure() {
dialog::editNumber(minstep, 1e-6, 1, 0.1, 0.001, XLAT("min step"), "how precisely should we find out when do cross the cell boundary"); dialog::editNumber(minstep, 1e-6, 1, 0.1, 0.001, XLAT("min step"), "how precisely should we find out when do cross the cell boundary");
dialog::scaleLog(); dialog::scaleLog();
dialog::bound_low(1e-9); dialog::bound_low(1e-9);
dialog::reaction = reset_raycaster; dialog::get_di().reaction = reset_raycaster;
}); });
} }
@ -2938,19 +2938,19 @@ EX void configure() {
dialog::addSelItem(XLAT("iterations"), its(max_iter_current()), 's'); dialog::addSelItem(XLAT("iterations"), its(max_iter_current()), 's');
dialog::add_action([&] { dialog::add_action([&] {
dialog::editNumber(max_iter_current(), 0, 600, 1, 60, XLAT("iterations"), "in H3/H2xE/E3 this is the number of cell boundaries; in nonisotropic, the number of simulation steps"); dialog::editNumber(max_iter_current(), 0, 600, 1, 60, XLAT("iterations"), "in H3/H2xE/E3 this is the number of cell boundaries; in nonisotropic, the number of simulation steps");
dialog::reaction = reset_raycaster; dialog::get_di().reaction = reset_raycaster;
}); });
dialog::addSelItem(XLAT("max cells"), its(max_cells), 's'); dialog::addSelItem(XLAT("max cells"), its(max_cells), 's');
dialog::add_action([&] { dialog::add_action([&] {
dialog::editNumber(max_cells, 16, 131072, 0.1, 4096, XLAT("max cells"), ""); dialog::editNumber(max_cells, 16, 131072, 0.1, 4096, XLAT("max cells"), "");
dialog::scaleLog(); dialog::scaleLog();
dialog::extra_options = [] { dialog::get_di().extra_options = [] {
dialog::addBoolItem_action("generate", rays_generate, 'G'); dialog::addBoolItem_action("generate", rays_generate, 'G');
dialog::addColorItem(XLAT("out-of-range color"), color_out_of_range, 'X'); dialog::addColorItem(XLAT("out-of-range color"), color_out_of_range, 'X');
dialog::add_action([] { dialog::add_action([] {
dialog::openColorDialog(color_out_of_range); dialog::openColorDialog(color_out_of_range);
dialog::dialogflags |= sm::SIDE; dialog::get_di().dialogflags |= sm::SIDE;
}); });
}; };
}); });

12
rug.cpp
View File

@ -1635,7 +1635,7 @@ EX void show() {
renderonce = !renderonce; renderonce = !renderonce;
else if(uni == 'G') { else if(uni == 'G') {
dialog::editNumber(move_on_touch, -1, 1, .1, 0, XLAT("move on touch"), ""); dialog::editNumber(move_on_touch, -1, 1, .1, 0, XLAT("move on touch"), "");
dialog::extra_options = anims::rug_angle_options; dialog::get_ne().extra_options = anims::rug_angle_options;
} }
else if(uni == 'A') { else if(uni == 'A') {
dialog::editNumber(anticusp_factor, 0, 1.5, .1, 0, XLAT("anti-crossing"), dialog::editNumber(anticusp_factor, 0, 1.5, .1, 0, XLAT("anti-crossing"),
@ -1649,7 +1649,7 @@ EX void show() {
XLAT("The more vertices, the more accurate the Hypersian Rug model is. " XLAT("The more vertices, the more accurate the Hypersian Rug model is. "
"However, a number too high might make the model slow to compute and render.") "However, a number too high might make the model slow to compute and render.")
); );
dialog::reaction = [] () { err_zero_current = err_zero; }; dialog::get_ne().reaction = [] () { err_zero_current = err_zero; };
} }
else if(uni == 'r') else if(uni == 'r')
addMessage(XLAT("This just shows the 'z' coordinate of the selected point.")); addMessage(XLAT("This just shows the 'z' coordinate of the selected point."));
@ -1667,7 +1667,7 @@ EX void show() {
static bool adjust_distance = true; static bool adjust_distance = true;
static ld last; static ld last;
last = modelscale; last = modelscale;
dialog::extra_options = [] () { dialog::get_ne().extra_options = [] () {
dialog::addBoolItem_action(XLAT("adjust points"), adjust_points, 'P'); dialog::addBoolItem_action(XLAT("adjust points"), adjust_points, 'P');
if(adjust_points) if(adjust_points)
dialog::addBoolItem_action(XLAT("center on camera"), camera_center, 'C'); dialog::addBoolItem_action(XLAT("center on camera"), camera_center, 'C');
@ -1676,7 +1676,7 @@ EX void show() {
dialog::addBoolItem_action(XLAT("adjust edges"), adjust_edges, 'E'); dialog::addBoolItem_action(XLAT("adjust edges"), adjust_edges, 'E');
dialog::addBoolItem_action(XLAT("adjust distance"), adjust_distance, 'D'); dialog::addBoolItem_action(XLAT("adjust distance"), adjust_distance, 'D');
}; };
dialog::reaction = [] () { dialog::get_ne().reaction = [] () {
if(!last || !modelscale) return; if(!last || !modelscale) return;
if(!camera_center) push_all_points(2, model_distance); if(!camera_center) push_all_points(2, model_distance);
for(auto p:points) { for(auto p:points) {
@ -1700,7 +1700,7 @@ EX void show() {
"In the orthogonal projection this just controls the scale.") "In the orthogonal projection this just controls the scale.")
); );
old_distance = model_distance; old_distance = model_distance;
dialog::reaction = [] () { dialog::get_di().reaction = [] () {
if(rug::rugged && perspective()) { if(rug::rugged && perspective()) {
using_rugview rv; using_rugview rv;
shift_view(ztangent(old_distance - model_distance)); shift_view(ztangent(old_distance - model_distance));
@ -1713,7 +1713,7 @@ EX void show() {
XLAT("New points are added when the current error in the model is smaller than this value.") XLAT("New points are added when the current error in the model is smaller than this value.")
); );
dialog::scaleLog(); dialog::scaleLog();
dialog::reaction = [] () { err_zero_current = err_zero; }; dialog::get_di().reaction = [] () { err_zero_current = err_zero; };
} }
else if(uni == 'f') else if(uni == 'f')
pushScreen(showStereo); pushScreen(showStereo);

View File

@ -273,7 +273,7 @@ EX void show_memory_menu() {
); );
dialog::bound_low(0); dialog::bound_low(0);
dialog::bound_up(max_reserve); dialog::bound_up(max_reserve);
dialog::reaction = apply_memory_reserve; dialog::get_di().reaction = apply_memory_reserve;
}); });
#endif #endif

View File

@ -1065,8 +1065,8 @@ EX void menu() {
dialog::add_action([] { dialog::add_action([] {
dialog::editNumber(vid.fixed_facing_dir, 0, 360, 15, 90, XLAT("centering"), dialog::editNumber(vid.fixed_facing_dir, 0, 360, 15, 90, XLAT("centering"),
XLAT("You can pick the angle. Note: the direction the PC is facing matters.")); XLAT("You can pick the angle. Note: the direction the PC is facing matters."));
dialog::reaction = fullcenter; dialog::get_di().reaction = fullcenter;
dialog::extra_options = [] () { dialog::get_di().extra_options = [] () {
dialog::addBoolItem(XLAT("rotate PC"), centering == eCentering::face, 'R'); dialog::addBoolItem(XLAT("rotate PC"), centering == eCentering::face, 'R');
dialog::add_action([] { dialog::add_action([] {
flipplayer = false; flipplayer = false;
@ -1565,8 +1565,8 @@ EX void show() {
dialog::editNumber(animation_period, 0, 10000, 1000, 1000, XLAT("game animation period"), dialog::editNumber(animation_period, 0, 10000, 1000, 1000, XLAT("game animation period"),
XLAT("Least common multiple of the animation periods of all the game objects on screen, such as rotating items.") XLAT("Least common multiple of the animation periods of all the game objects on screen, such as rotating items.")
); );
dialog::reaction = [] () { animation_factor = TAU * animation_lcm / animation_period; }; dialog::get_di().reaction = [] () { animation_factor = TAU * animation_lcm / animation_period; };
dialog::extra_options = [] () { dialog::get_di().extra_options = [] () {
dialog::addItem("default", 'D'); dialog::addItem("default", 'D');
dialog::add_action([] () { dialog::add_action([] () {
animation_factor = 1; animation_factor = 1;
@ -1601,7 +1601,7 @@ EX void show() {
dialog::addSelItem(XLAT("circle radius"), fts(circle_radius), 'c'); dialog::addSelItem(XLAT("circle radius"), fts(circle_radius), 'c');
dialog::add_action([] () { dialog::add_action([] () {
dialog::editNumber(circle_radius, 0, 10, 0.1, acosh(1.), XLAT("circle radius"), ""); dialog::editNumber(circle_radius, 0, 10, 0.1, acosh(1.), XLAT("circle radius"), "");
dialog::extra_options = [] () { dialog::get_di().extra_options = [] () {
if(hyperbolic) { if(hyperbolic) {
// area = 2pi (cosh(r)-1) // area = 2pi (cosh(r)-1)
dialog::addSelItem(XLAT("double spin"), fts(acosh(2.)), 'A'); dialog::addSelItem(XLAT("double spin"), fts(acosh(2.)), 'A');
@ -1633,7 +1633,7 @@ EX void show() {
dialog::addSelItem(XLAT("cycle length"), fts(cycle_length), 'c'); dialog::addSelItem(XLAT("cycle length"), fts(cycle_length), 'c');
dialog::add_action([] () { dialog::add_action([] () {
dialog::editNumber(cycle_length, 0, 10, 0.1, TAU, "shift", ""); dialog::editNumber(cycle_length, 0, 10, 0.1, TAU, "shift", "");
dialog::extra_options = [] () { dialog::get_di().extra_options = [] () {
dialog::addSelItem(XLAT("full circle"), fts(TAU), 'A'); dialog::addSelItem(XLAT("full circle"), fts(TAU), 'A');
dialog::add_action([] () { cycle_length = TAU; }); dialog::add_action([] () { cycle_length = TAU; });
dialog::addSelItem(XLAT("Zebra period"), fts(2.898149445355172), 'B'); dialog::addSelItem(XLAT("Zebra period"), fts(2.898149445355172), 'B');
@ -1705,7 +1705,7 @@ EX void show() {
animator(XLAT("automatic move speed"), rug_forward, 'M'); animator(XLAT("automatic move speed"), rug_forward, 'M');
dialog::add_action([] () { dialog::add_action([] () {
dialog::editNumber(rug_forward, 0, 10, 1, 1, XLAT("automatic move speed"), XLAT("Move automatically without pressing any keys.")); dialog::editNumber(rug_forward, 0, 10, 1, 1, XLAT("automatic move speed"), XLAT("Move automatically without pressing any keys."));
dialog::extra_options = [] () { dialog::get_di().extra_options = [] () {
if(among(rug::gwhere, gSphere, gElliptic)) { if(among(rug::gwhere, gSphere, gElliptic)) {
dialog::addItem(XLAT("synchronize"), 'S'); dialog::addItem(XLAT("synchronize"), 'S');
dialog::add_action([] () { rug_forward = TAU; popScreen(); }); dialog::add_action([] () { rug_forward = TAU; popScreen(); });

View File

@ -757,7 +757,7 @@ EX void show_surfaces() {
dialog::editNumber(hyper_b, -1, 1, .05, 1, XLAT("parameter"), dialog::editNumber(hyper_b, -1, 1, .05, 1, XLAT("parameter"),
XLAT("Controls the inner radius.") XLAT("Controls the inner radius.")
); );
dialog::reaction = [] () { dialog::get_ne().reaction = [] () {
if(sh == dsHyperlike) run_shape(sh); if(sh == dsHyperlike) run_shape(sh);
}; };
} }
@ -772,7 +772,7 @@ EX void show_surfaces() {
dialog::editNumber(precision, 1, 10000, 0, 100, XLAT("precision"), dialog::editNumber(precision, 1, 10000, 0, 100, XLAT("precision"),
XLAT("Computing these models involves integrals and differential equations, which are currently solved numerically. This controls the precision.") XLAT("Computing these models involves integrals and differential equations, which are currently solved numerically. This controls the precision.")
); );
dialog::ne.step = .1; dialog::get_ne().step = .1;
dialog::scaleLog(); dialog::scaleLog();
} }
else if(uni == 'c') { else if(uni == 'c') {

View File

@ -1441,7 +1441,7 @@ EX void showMenu() {
dialog::add_action([] { dialog::add_action([] {
dialog::editNumber(config.gsplits, 0, 4, 1, 1, XLAT("precision"), dialog::editNumber(config.gsplits, 0, 4, 1, 1, XLAT("precision"),
XLAT("precision")); XLAT("precision"));
if(config.tstate == tsActive) dialog::reaction = [] () { config.finish_mapping(); if(config.tstate == tsActive) dialog::get_di().reaction = [] () { config.finish_mapping();
}; };
}); });
dialog::addHelp(); dialog::addHelp();