Skip to content

Commit

Permalink
CourseEdit: allow stages section to be collapsible/hidden, reduce width
Browse files Browse the repository at this point in the history
  • Loading branch information
emoose committed Dec 18, 2024
1 parent 15f06f0 commit 239f5c3
Showing 1 changed file with 119 additions and 115 deletions.
234 changes: 119 additions & 115 deletions src/overlay/course_editor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -267,161 +267,165 @@ void Overlay_CourseEditor()
ImGui::EndDisabled();
}

// TODO: editor should be disabled if playing online, since our lobbyname hack to update clients probably won't update quick enough
// should only really be enabled when in the lobby & user is host, or user is playing offline
bool has_updated = false;
bool editor_disabled = (Game::is_in_game() && Game::pl_car()->is_in_bunki()) || !Overlay::CourseReplacementEnabled;

StageTable_mb* stg_tbl = *Module::exe_ptr<StageTable_mb*>(0x3D3188); // stg_tbl only points to current stage
if (ImGui::TreeNodeEx("Stages", ImGuiTreeNodeFlags_DefaultOpen))
{
// TODO: editor should be disabled if playing online, since our lobbyname hack to update clients probably won't update quick enough
// should only really be enabled when in the lobby & user is host, or user is playing offline

int curPlayingColumn = -1;
if (stg_tbl)
curPlayingColumn = stg_tbl->StageTableIdx_4;
StageTable_mb* stg_tbl = *Module::exe_ptr<StageTable_mb*>(0x3D3188); // stg_tbl only points to current stage

bool editor_disabled = (Game::is_in_game() && Game::pl_car()->is_in_bunki()) || !Overlay::CourseReplacementEnabled;
if (editor_disabled)
ImGui::BeginDisabled();
int curPlayingColumn = -1;
if (stg_tbl)
curPlayingColumn = stg_tbl->StageTableIdx_4;

float comboHeight = ImGui::GetFrameHeight(); // Height of a single combobox
float verticalSpacing = 10.0f; // Additional spacing between comboboxes
float comboWidth = 225.0f; // Width of comboboxes
if (editor_disabled)
ImGui::BeginDisabled();

float windowHeight = ImGui::GetCursorPosY() + floor(comboHeight * 5 + (verticalSpacing * 6));
float comboHeight = ImGui::GetFrameHeight(); // Height of a single combobox
float verticalSpacing = 10.0f; // Additional spacing between comboboxes
float comboWidth = 200.f; // Width of comboboxes

bool has_updated = false;
float windowHeight = ImGui::GetCursorPosY() + (comboHeight * 3) + floor(comboHeight * 5 + (verticalSpacing * 6));

int num = 0;
StageTable_mb* curStage = CustomStageTable.data();
for (int col = 0; col < 5; ++col)
{
float columnHeight = floor((comboHeight + verticalSpacing) * (col + 1) - verticalSpacing);
int num = 0;
StageTable_mb* curStage = CustomStageTable.data();
for (int col = 0; col < 5; ++col)
{
float columnHeight = floor((comboHeight + verticalSpacing) * (col + 1) - verticalSpacing);

// Start a new column for each level of the pyramid
ImGui::BeginGroup();
// Start a new column for each level of the pyramid
ImGui::BeginGroup();

// Center the column vertically
float startY = (windowHeight - columnHeight) * 0.5f;
ImGui::SetCursorPosY(startY);
// Center the column vertically
float startY = (windowHeight - columnHeight) * 0.5f;
ImGui::SetCursorPosY(startY);

// if player is already past this column (or playing it), disable dropdowns
bool col_disabled = (curPlayingColumn >= num) && !editor_disabled && Game::is_in_game();
// if player is already past this column (or playing it), disable dropdowns
bool col_disabled = (curPlayingColumn >= num) && !editor_disabled && Game::is_in_game();

for (int row = 0; row <= col; ++row)
{
if (col_disabled)
ImGui::BeginDisabled();
for (int row = 0; row <= col; ++row)
{
if (col_disabled)
ImGui::BeginDisabled();

bool playingThisStage = (curPlayingColumn == num) && Game::is_in_game();
bool playingThisStage = (curPlayingColumn == num) && Game::is_in_game();

// Highlight the current track
if (playingThisStage)
ImGui::PushStyleColor(ImGuiCol_FrameBg, ImVec4(0.0f, 0.75f, 0.0f, 0.75f));
// Highlight the current track
if (playingThisStage)
ImGui::PushStyleColor(ImGuiCol_FrameBg, ImVec4(0.0f, 0.75f, 0.0f, 0.75f));

ImGui::PushID(col * 10 + row);
ImGui::SetNextItemWidth(comboWidth);
ImGui::PushID(col * 10 + row);
ImGui::SetNextItemWidth(comboWidth);

int selected = curStage->StageUniqueName_0;
int selected = curStage->StageUniqueName_0;

std::string name = std::format("{}.{}", (col + 1), (row + 1));
if (ImGui::Combo(name.c_str(), &selected, Game::StageNames, int(STAGE_COUNT)))
has_updated |= update_stage(num, GameStage(selected));
std::string name = std::format("##{}.{}", (col + 1), (row + 1));
if (ImGui::Combo(name.c_str(), &selected, Game::StageNames, int(STAGE_COUNT)))
has_updated |= update_stage(num, GameStage(selected));

curStage++;
curStage++;

// Add vertical spacing between comboboxes
if (row <= col)
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + verticalSpacing);
// Add vertical spacing between comboboxes
if (row <= col)
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + verticalSpacing);

ImGui::PopID();
ImGui::PopID();

if (playingThisStage)
ImGui::PopStyleColor();
if (playingThisStage)
ImGui::PopStyleColor();

if (col_disabled)
ImGui::EndDisabled();
if (col_disabled)
ImGui::EndDisabled();

num++;
}
num++;
}

ImGui::EndGroup();
ImGui::EndGroup();

if (col + 1 < 5)
ImGui::SameLine(0, 20.0f);
}
if (col + 1 < 5)
ImGui::SameLine(0, 20.0f);
}

char* ShareCode = Overlay::CourseReplacementCode;
char* ShareCode = Overlay::CourseReplacementCode;

ImGui::Text("Share Code: ");
ImGui::SameLine();
ImGui::SetNextItemWidth(500.f);
ImGui::InputText("##ShareCode", ShareCode, 256);
ImGui::SameLine();
if (ImGui::Button("Apply Code"))
{
has_updated = true;
sharecode_apply();
}
ImGui::SameLine();
if (ImGui::Button("Copy Code"))
{
HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, strlen(ShareCode) + 1);
if (hMem)
ImGui::Text("Share Code: ");
ImGui::SameLine();
ImGui::SetNextItemWidth(500.f);
ImGui::InputText("##ShareCode", ShareCode, 256);
ImGui::SameLine();
if (ImGui::Button("Apply Code"))
{
memcpy(GlobalLock(hMem), ShareCode, strlen(ShareCode) + 1);
GlobalUnlock(hMem);
OpenClipboard(0);
EmptyClipboard();
SetClipboardData(CF_TEXT, hMem);
CloseClipboard();
has_updated = true;
sharecode_apply();
}
}
ImGui::SameLine();
if (ImGui::Button("Paste Code"))
{
if (OpenClipboard(0))
ImGui::SameLine();
if (ImGui::Button("Copy Code"))
{
HANDLE hClipboardData = GetClipboardData(CF_UNICODETEXT);
if (hClipboardData == nullptr)
hClipboardData = GetClipboardData(CF_TEXT);

if (hClipboardData != nullptr)
HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, strlen(ShareCode) + 1);
if (hMem)
{
memcpy(GlobalLock(hMem), ShareCode, strlen(ShareCode) + 1);
GlobalUnlock(hMem);
OpenClipboard(0);
EmptyClipboard();
SetClipboardData(CF_TEXT, hMem);
CloseClipboard();
}
}
ImGui::SameLine();
if (ImGui::Button("Paste Code"))
{
if (OpenClipboard(0))
{
void* clipboardData = GlobalLock(hClipboardData);
if (clipboardData)
HANDLE hClipboardData = GetClipboardData(CF_UNICODETEXT);
if (hClipboardData == nullptr)
hClipboardData = GetClipboardData(CF_TEXT);

if (hClipboardData != nullptr)
{
if (hClipboardData == GetClipboardData(CF_UNICODETEXT))
void* clipboardData = GlobalLock(hClipboardData);
if (clipboardData)
{
wchar_t* wideText = static_cast<wchar_t*>(clipboardData);

// Convert unicode to char
int bufferSize = WideCharToMultiByte(CP_UTF8, 0, wideText, -1, nullptr, 0, nullptr, nullptr);
if (bufferSize > 0 && bufferSize < sizeof(ShareCode))
WideCharToMultiByte(CP_UTF8, 0, wideText, -1, ShareCode, bufferSize, nullptr, nullptr);
else
if (hClipboardData == GetClipboardData(CF_UNICODETEXT))
{
// Handle the case where the buffer is too small, truncate if necessary
WideCharToMultiByte(CP_UTF8, 0, wideText, -1, ShareCode, sizeof(ShareCode) - 1, nullptr, nullptr);
ShareCode[sizeof(ShareCode) - 1] = '\0'; // Null-terminate
wchar_t* wideText = static_cast<wchar_t*>(clipboardData);

// Convert unicode to char
int bufferSize = WideCharToMultiByte(CP_UTF8, 0, wideText, -1, nullptr, 0, nullptr, nullptr);
if (bufferSize > 0 && bufferSize < sizeof(ShareCode))
WideCharToMultiByte(CP_UTF8, 0, wideText, -1, ShareCode, bufferSize, nullptr, nullptr);
else
{
// Handle the case where the buffer is too small, truncate if necessary
WideCharToMultiByte(CP_UTF8, 0, wideText, -1, ShareCode, sizeof(ShareCode) - 1, nullptr, nullptr);
ShareCode[sizeof(ShareCode) - 1] = '\0'; // Null-terminate
}
}
}
else if (hClipboardData == GetClipboardData(CF_TEXT))
{
char* asciiText = static_cast<char*>(clipboardData);

if (strlen(asciiText) < sizeof(ShareCode))
strcpy(ShareCode, asciiText);
else
else if (hClipboardData == GetClipboardData(CF_TEXT))
{
// If the clipboard text is too large, truncate
strncpy(ShareCode, asciiText, sizeof(ShareCode) - 1);
ShareCode[sizeof(ShareCode) - 1] = '\0'; // Null-terminate
char* asciiText = static_cast<char*>(clipboardData);

if (strlen(asciiText) < sizeof(ShareCode))
strcpy(ShareCode, asciiText);
else
{
// If the clipboard text is too large, truncate
strncpy(ShareCode, asciiText, sizeof(ShareCode) - 1);
ShareCode[sizeof(ShareCode) - 1] = '\0'; // Null-terminate
}
}
}
sharecode_apply();
sharecode_apply();

GlobalUnlock(hClipboardData);
GlobalUnlock(hClipboardData);
}
}
CloseClipboard();
}
CloseClipboard();
}
ImGui::TreePop();
}

if (ImGui::TreeNode("Randomizer"))
Expand Down

3 comments on commit 239f5c3

@Zoukambada
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This feature is bugged right? I tested and the imgui overlay reproduces a RED warning here.

@emoose
Copy link
Owner Author

@emoose emoose commented on 239f5c3 Dec 25, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm haven't seen any red warning on my end, you got a pic?

@Zoukambada
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I ran this build below:
https://github.com/emoose/OutRun2006Tweaks/actions/runs/12385456969

And when I press F11 then I click to hide the stages I get this error:
Image

Please sign in to comment.