1334{
1335 bool is_hovered = false;
1336
1337 ImVec2 mousePos = ImGui::GetMousePos();
1338 ImGui::SetNextWindowPos(mousePos, ImGuiCond_Appearing);
1339 ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(0.2f, 0.3f, 0.4f, 1.0f));
1340 ImGui::Begin(
"EditEntity", &
showEditWindow, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoMove);
1341
1342
1343 is_hovered = ImGui::IsWindowHovered();
1344 auto is_popup_open = false;
1346 {
1349
1352
1353 ImGui::BeginGroup();
1354 if (ImGui::Button("+ Size"))
1355 {
1356 if (nm && boardEnt.is_valid())
1357 {
1358 size->width = size->width * 1.1;
1359 size->height = size->height * 1.1;
1361 {
1363 }
1365 {
1367 }
1368 }
1369 }
1370 ImGui::SameLine();
1371 if (ImGui::Button("- Size"))
1372 {
1373 if (nm && boardEnt.is_valid())
1374 {
1375 size->width = size->width * 0.90;
1376 size->height = size->height * 0.90;
1378 {
1380 }
1382 {
1384 }
1385 }
1386 }
1387
1388 ImGui::EndGroup();
1389
1390 auto vis_temp = visibility->isVisible;
1391 if (ImGui::Checkbox("Visible", &vis_temp))
1392 {
1393 if (nm && boardEnt.is_valid())
1394 {
1395 visibility->isVisible = vis_temp;
1397 {
1399 }
1401 {
1403 }
1404 }
1405 }
1406
1407 ImGui::Separator();
1408
1409
1410
1411 if (ImGui::Button("Delete"))
1412 {
1413 ImGui::OpenPopup("Confirm Delete");
1414 is_popup_open = true;
1415 }
1416
1417 if (ImGui::IsPopupOpen("Confirm Delete"))
1418 is_popup_open = true;
1419 if (ImGui::BeginPopupModal("Confirm Delete", nullptr, ImGuiWindowFlags_AlwaysAutoResize))
1420 {
1421 ImGui::Text("Are you sure you want to delete this entity?");
1422 ImGui::Separator();
1423
1424 if (ImGui::Button("Yes", ImVec2(120, 0)))
1425 {
1427 {
1428 if (nm && boardEnt.is_valid())
1429 {
1431 {
1433 }
1435 {
1437 }
1440 }
1441 }
1442 ImGui::CloseCurrentPopup();
1443 }
1444 ImGui::SameLine();
1445 if (ImGui::Button("No", ImVec2(120, 0)))
1446 {
1447 ImGui::CloseCurrentPopup();
1448 }
1449 ImGui::EndPopup();
1450 }
1451 }
1452 else
1453 {
1454 ImGui::Text("Invalid entity or missing components!");
1455 }
1456
1458 {
1462
1463 ImGui::Separator();
1464 ImGui::TextUnformatted("Owner");
1465 ImGui::Spacing();
1466
1467
1468 struct Opt
1469 {
1470 std::string uid;
1471 std::string label;
1472 };
1473 std::vector<Opt> options;
1474 options.push_back(Opt{"", "(none)"});
1475
1476
1477 std::set<std::string> seenUids;
1478 if (nm && idm)
1479 {
1480 for (auto& [peerId, link] : nm->getPeers())
1481 {
1482 if (!link)
1483 continue;
1484 auto uidOpt = idm->uniqueForPeer(peerId);
1485 if (!uidOpt || uidOpt->empty())
1486 continue;
1487
1488 const std::string& uid = *uidOpt;
1489 if (!seenUids.insert(uid).second)
1490 continue;
1491
1492
1493 std::string label = idm->usernameForUnique(uid);
1494 if (label.empty())
1495 label = uid.substr(0, std::min<size_t>(8, uid.size()));
1496 options.push_back(Opt{uid, label});
1497 }
1498 }
1499
1500
1501 if (idm && !mc->ownerUniqueId.empty() && !seenUids.count(mc->ownerUniqueId))
1502 {
1503 std::string label = idm->usernameForUnique(mc->ownerUniqueId);
1504 if (label.empty())
1505 label = mc->ownerUniqueId.substr(0, std::min<size_t>(8, mc->ownerUniqueId.size()));
1506 options.push_back(Opt{mc->ownerUniqueId, label});
1507 }
1508
1509
1510 int selectedIndex = 0;
1511 for (int i = 1; i < (int)options.size(); ++i)
1512 if (options[i].uid == mc->ownerUniqueId)
1513 {
1514 selectedIndex = i;
1515 break;
1516 }
1517
1518
1519 static int ownerPage = 0;
1520 const int rowsPerPage = 6;
1521 const int totalRows = (int)options.size();
1522 const int totalPages = (totalRows + rowsPerPage - 1) / rowsPerPage;
1523 ownerPage = std::clamp(ownerPage, 0, std::max(0, totalPages - 1));
1524 auto ToggleRow = [&](const char* label, bool selected, int id) -> bool
1525 {
1526 ImGui::PushID(id);
1527 if (selected)
1528 {
1529 ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.20f, 0.50f, 0.80f, 1.0f));
1530 ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0.25f, 0.55f, 0.85f, 1.0f));
1531 ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(0.15f, 0.45f, 0.75f, 1.0f));
1532 }
1533 else
1534 {
1535 ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.25f, 0.28f, 0.32f, 1.0f));
1536 ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0.30f, 0.33f, 0.38f, 1.0f));
1537 ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(0.22f, 0.25f, 0.29f, 1.0f));
1538 }
1539 bool clicked = ImGui::Button(label, ImVec2(-FLT_MIN, 0));
1540 ImGui::PopStyleColor(3);
1541 ImGui::PopID();
1542 return clicked;
1543 };
1544
1545 const int start = ownerPage * rowsPerPage;
1546 const int end = std::min(start + rowsPerPage, totalRows);
1547
1548
1549 for (int i = start; i < end; ++i)
1550 {
1551 const bool isSel = (selectedIndex == i);
1552 const char* label = options[i].label.c_str();
1553 if (ToggleRow(label, isSel, i))
1554 {
1555 selectedIndex = i;
1556
1557
1558 const std::string prevOwnerUid = mc->ownerUniqueId;
1559 mc->ownerUniqueId = options[i].uid;
1560 mc->ownerPeerUsername.clear();
1561 if (idm && !mc->ownerUniqueId.empty())
1562 mc->ownerPeerUsername = idm->usernameForUnique(mc->ownerUniqueId);
1563
1564
1566 {
1568 if (prevOwnerUid != mc->ownerUniqueId)
1569 nm->clearDragState(mid);
1570 }
1571
1572
1573 if (nm)
1574 {
1576 if (boardEnt.is_valid())
1578 }
1579 }
1580 }
1581
1582
1583 if (totalPages > 1)
1584 {
1585 ImGui::Spacing();
1586 ImGui::BeginDisabled(ownerPage <= 0);
1587 if (ImGui::Button("< Prev"))
1588 ownerPage--;
1589 ImGui::EndDisabled();
1590 ImGui::SameLine();
1591 ImGui::Text("Page %d / %d", ownerPage + 1, std::max(1, totalPages));
1592 ImGui::SameLine();
1593 ImGui::BeginDisabled(ownerPage >= totalPages - 1);
1594 if (ImGui::Button("Next >"))
1595 ownerPage++;
1596 ImGui::EndDisabled();
1597 }
1598
1599
1600 bool flagsChanged = false;
1601 flagsChanged |= ImGui::Checkbox("Allow all players to move", &mc->allowAllPlayersMove);
1602 flagsChanged |= ImGui::Checkbox("Locked (players cannot move)", &mc->locked);
1603 if (flagsChanged && nm)
1604 {
1606 if (boardEnt.is_valid())
1608 }
1609 }
1610
1611 ImGui::End();
1612 ImGui::PopStyleColor();
1613
1614 if (!is_hovered && ImGui::IsMouseClicked(ImGuiMouseButton_Left) && !is_popup_open)
1615 {
1617 }
1618
1620 {
1622 }
1623
1624}
flecs::entity edit_window_entity
flecs::entity getActiveBoard() const