From 8155bbd6a21ec4d02cfa09937ed31474177b0cf7 Mon Sep 17 00:00:00 2001 From: Zeno Rogue Date: Mon, 3 Mar 2025 17:26:47 +0100 Subject: [PATCH] rogueviz::seuphorica:: resizable tileboxes --- rogueviz/seuphorica.cpp | 122 +++++++++++++++++++++++++++++----------- 1 file changed, 88 insertions(+), 34 deletions(-) diff --git a/rogueviz/seuphorica.cpp b/rogueviz/seuphorica.cpp index 8fcefe72..deec4ba8 100644 --- a/rogueviz/seuphorica.cpp +++ b/rogueviz/seuphorica.cpp @@ -84,9 +84,12 @@ bool draw(cell *c, const shiftmatrix& V) { return false; } +int hold_mode; /* 1 = from board, 2 = from set, 3 = drag size */ const tile *tile_moved; vector* box_moved; int tile_boxid; +cell *tile_moved_from; +int *drag_what; void render_tile(const shiftmatrix& V, const tile& t, vector* origbox, int boxid) { curvepoint(eupoint(-1, -1)); @@ -103,7 +106,7 @@ void render_tile(const shiftmatrix& V, const tile& t, vector* origbox, int mouseovers = fix(tile_desc(t)); getcstat = dialog::list_fake_key++; dialog::add_key_action(getcstat, [&t, origbox, boxid] { - holdmouse = true; + holdmouse = true; hold_mode = 2; tile_moved = &t; box_moved = origbox; tile_boxid = boxid; }); } @@ -113,11 +116,16 @@ map where_is_tile; vector* current_box; +struct uicoords { + int x0, x1, x2; + int y0, y1, y2, y3; + } ui; + struct tilebox { - int x1, y1, x2, y2; + int *x1, *y1, *x2, *y2; vector *ptset; color_t col; - tilebox(int x1, int y1, int x2, int y2, vector& tset, color_t col) : x1(x1), y1(y1), x2(x2), y2(y2), ptset(&tset), col(col) {} + tilebox(int& x1, int& y1, int& x2, int& y2, vector& tset, color_t col) : x1(&x1), y1(&y1), x2(&x2), y2(&y2), ptset(&tset), col(col) {} int get_margin() { return 40; } int get_space() { return 50; } @@ -133,28 +141,37 @@ struct tilebox { hyperpoint locate_tile(tile& t) { if(where_is_tile.count(t.id)) return where_is_tile[t.id]; int margin = 40, space = 50; - int px = x1 + margin, py = y1 + margin; + int px = *x1 + margin, py = *y1 + margin; while(true) { hyperpoint h = eupoint(px, py); if(good_location(h)) { - println(hlog, tie(x1,y1), " located ", tile_desc(t), " at ", h, " coord = ", tie(x1,y1,x2,y2)); + if(h[1] > *y2 - get_margin()) *y2 = h[1] + get_margin(); return where_is_tile[t.id] = h; } px += space; - if(px > x2 - margin) { px = x1 + margin; py += space; } + if(px > *x2 - margin) { px = *x1 + margin; py += space; } } } void render(const string& title) { - shiftmatrix ASP = atscreenpos(vid.xres - dialog::dwidth, 0); - curvepoint(eupoint(x1+10, y1+10)); - curvepoint(eupoint(x1+10, y2-10)); - curvepoint(eupoint(x2-10, y2-10)); - curvepoint(eupoint(x2-10, y1+10)); - curvepoint(eupoint(x1+10, y1+10)); + shiftmatrix ASP = atscreenpos(0, 0); - auto h1 = inverse_shift_any(atscreenpos(0, 0), ASP * eupoint(x1+10, y1+10)); - auto h2 = inverse_shift_any(atscreenpos(0, 0), ASP * eupoint(x2-10, y2-10)); + for(auto& t: *ptset) { + auto lt = locate_tile(t); + if(lt[0] < *x1 + get_margin() || lt[0] > *x2 - get_margin() || lt[1] < *y1 + get_margin() || lt[1] > *y2 - get_margin()) { + where_is_tile.erase(t.id); + lt = locate_tile(t); + } + } + + curvepoint(eupoint(*x1+10, *y1+10)); + curvepoint(eupoint(*x1+10, *y2-10)); + curvepoint(eupoint(*x2-10, *y2-10)); + curvepoint(eupoint(*x2-10, *y1+10)); + curvepoint(eupoint(*x1+10, *y1+10)); + + auto h1 = inverse_shift_any(atscreenpos(0, 0), ASP * eupoint(*x1+10, *y1+10)); + auto h2 = inverse_shift_any(atscreenpos(0, 0), ASP * eupoint(*x2-10, *y2-10)); if(mousex >= h1[0] + 10 && mousex <= h2[0] - 10 && mousey >= h1[1] + 10 && mousey <= h2[1] + 10) { current_box = ptset; } @@ -162,7 +179,7 @@ struct tilebox { if(1) { dynamicval lw(vid.linewidth, vid.linewidth * 5); queuecurve(ASP, darkena(col, 0, 0xFF), darkena(col, 0, 0x80), PPR::ZERO); - write_in_space(ASP * eupush(x2 - 10, y1 + 20), 72, 50, title, darkena(col, 0, 0xFF), 16, 16); + write_in_space(ASP * eupush(*x2 - 10, *y1 + 20), 72, 50, title, darkena(col, 0, 0xFF), 16, 16); } int idx = 0; @@ -171,16 +188,16 @@ struct tilebox { dynamicval cs(cgi.scalefactor, 1); auto lt = locate_tile(t); if(&t == tile_moved && holdmouse) { idx++; continue; } - if(lt[0] < x1 + get_margin() || lt[0] > x2 - get_margin() || lt[1] < y1 + get_margin() || lt[1] > y2 - get_margin()) { - println(hlog, "relocating ", lt, " due to ", tie(x1,y1,x2,y2)); - where_is_tile.erase(t.id); - lt = locate_tile(t); - } render_tile(ASP * eupush(lt) * euscalexx(20), t, ptset, idx++); } } }; +tilebox tb_deck(ui.x0, ui.y0, ui.x1, ui.y1, deck, 0xFF8000); +tilebox tb_discard(ui.x1, ui.y0, ui.x2, ui.y1, discard, 0xFF0000); +tilebox tb_hand(ui.x0, ui.y1, ui.x2, ui.y2, drawn, 0x00FF00); +tilebox tb_shop(ui.x0, ui.y2, ui.x2, ui.y3, shop, 0xFFD500); + void seuphorica_screen() { getcstat = '-'; @@ -197,45 +214,79 @@ void seuphorica_screen() { dialog::init(); dialog::display(); + if(holdmouse && hold_mode == 3) *drag_what = mousey; + + ui.x0 = vid.xres - dialog::dwidth; ui.x2 = vid.xres; ui.x1 = lerp(ui.x0, ui.x2, .5); + int ymax = vid.yres - 2 * vid.fsize; + ui.y0 = 2 * vid.fsize; + if(!ui.y1) { + ui.y1 = lerp(ui.y0, ymax, .2); + ui.y2 = lerp(ui.y0, ymax, .4); + ui.y3 = lerp(ui.y0, ymax, .6); + } + auto sep = [&] (int& y1, int& y2) { + ld err = (ymax - ui.y0) / 10 - (y2-y1); + if(err < 0) return; + y1 -= err/2; y2 += err/2; + }; + sep(ui.y0, ui.y1); sep(ui.y1, ui.y2); sep(ui.y2, ui.y3); + if(1) { - int x1 = dialog::dwidth; flat_model_enabler fme; initquickqueue(); dynamicval g(geometry, gEuclid); current_box = nullptr; - tilebox(0, 2*vid.fsize, x1/2, vid.yres/5, deck, 0xFF8000).render("bag"); - tilebox(x1/2, 2*vid.fsize, x1, vid.yres/5, discard, 0xFF0000).render("discard"); - tilebox(0, vid.yres/5, x1, vid.yres*2/5, drawn, 0x00FF00).render("hand"); - tilebox(0, vid.yres*2/5, x1, vid.yres*3/5, shop, 0xFFD500).render("shop"); - if(holdmouse) render_tile(atscreenpos(mousex, mousey) * euscalexx(20), *tile_moved, nullptr, 0); + tb_deck.render("bag"); + tb_discard.render("discard"); + tb_hand.render("hand"); + tb_shop.render("shop"); + + for(auto y: {&ui.y1, &ui.y2, &ui.y3}) { + // println(hlog, mousex >= ui.x0, ", ", abs(mousey - *y)); + if(mousex >= ui.x0 && abs(mousey - *y) < 5) { + + dynamicval dl(vid.linewidth, vid.linewidth * 3); + queueline(atscreenpos(ui.x0, *y) * C0, atscreenpos(ui.x2, *y) * C0, 0xFF0000FF, 0); + getcstat = '0'; + dialog::add_key_action('0', [=] { holdmouse = true; hold_mode = 3; drag_what = y; }); + } + } + + if(holdmouse && among(hold_mode, 1, 2)) render_tile(atscreenpos(mousex, mousey) * euscalexx(20), *tile_moved, nullptr, 0); quickqueue(); } stringstream ss; seuphorica::gamestats(ss); ss << ev.current_scoring; - dialog::displayLong(fix(ss.str()), vid.fsize, vid.yres*3/5 + vid.fsize, false); + int size = vid.fsize; + while(true) { + if(size <= 3) break; + auto ny = dialog::displayLong(fix(ss.str()), size, ui.y3, true); + if(ny <= ymax) break; + size = (size * 9) / 10; + } + dialog::displayLong(fix(ss.str()), size, ui.y3 + vid.fsize, false); - int x0 = vid.xres - dialog::dwidth; if(ev.valid_move) { - displayButton(lerp(x0, vid.xres, 1/6.), vid.yres - vid.fsize, just_placed.empty() ? str_skip_turn : str_play, SDLK_RETURN, 8); + displayButton(lerp(ui.x0, ui.x2, 1/6.), vid.yres - vid.fsize, just_placed.empty() ? str_skip_turn : str_play, SDLK_RETURN, 8); dialog::add_key_action(SDLK_RETURN, play); } - displayButton(lerp(x0, vid.xres, 3/6.), vid.yres - vid.fsize, str_view_help, 'H', 8); + displayButton(lerp(ui.x0, ui.x2, 3/6.), vid.yres - vid.fsize, str_view_help, 'H', 8); dialog::add_key_action('H', [] { gotoHelp(fix(seuphorica::rules)); }); - displayButton(lerp(x0, vid.xres, 5/6.), vid.yres - vid.fsize, "menu", 'Q', 8); + displayButton(lerp(ui.x0, ui.x2, 5/6.), vid.yres - vid.fsize, "menu", 'Q', 8); dialog::add_key_action('Q', [] { quitmainloop = true; }); - keyhandler = [] (int sym, int uni) { + keyhandler = [] (int sym, int uni) { handlePanning(sym, uni); dialog::handleNavigation(sym, uni); if(uni == SDLK_ESCAPE) popScreen(); - if(uni == PSEUDOKEY_RELEASE) { + if(uni == PSEUDOKEY_RELEASE && among(hold_mode, 1, 2)) { where_is_tile[tile_moved->id] = eupoint(mousex, mousey); if(box_moved == &shop && current_box == &drawn) { buy(tile_boxid); @@ -244,6 +295,9 @@ void seuphorica_screen() { swap(drawn[tile_boxid], drawn[0]); back_to_shop(); } + if(box_moved == &drawn && current_box == &drawn && tile_moved_from == mouseover && hold_mode == 1) { + /* do nothing, it was already removed from the boaud */ + } if(box_moved == &drawn && current_box == nullptr) { auto at = from(mouseover); if(!board.count(at)) { @@ -262,7 +316,7 @@ void seuphorica_screen() { if(uni == '-' && mouseover && !holdmouse) { auto at = from(mouseover); if(board.count(at)) { - back_from_board(at.x, at.y); + back_from_board(at.x, at.y); hold_mode = 1; tile_moved_from = mouseover; holdmouse = true; tile_moved = &(drawn[0]); tile_boxid = 0; box_moved = &drawn; } else