diff --git a/.vscode/settings.json b/.vscode/settings.json index 108e7e7..bfc5f93 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -76,6 +76,7 @@ "xutility": "cpp", "*.rh": "cpp", "csignal": "cpp", - "coroutine": "cpp" + "coroutine": "cpp", + "any": "cpp" } } \ No newline at end of file diff --git a/depend/imgui/imgui.cpp b/depend/imgui/imgui.cpp index 3680f33..43333d5 100644 --- a/depend/imgui/imgui.cpp +++ b/depend/imgui/imgui.cpp @@ -3036,7 +3036,7 @@ ImGuiWindow::ImGuiWindow(ImGuiContext* context, const char* name) : DrawListInst NameBufLen = (int)strlen(name) + 1; ID = ImHashStr(name); IDStack.push_back(ID); - MoveId = GetID("#MOVE"); + MoveId = GetPageID("#MOVE"); ScrollTarget = ImVec2(FLT_MAX, FLT_MAX); ScrollTargetCenterRatio = ImVec2(0.5f, 0.5f); AutoFitFramesX = AutoFitFramesY = -1; @@ -3059,7 +3059,7 @@ ImGuiWindow::~ImGuiWindow() ColumnsStorage.clear_destruct(); } -ImGuiID ImGuiWindow::GetID(const char* str, const char* str_end) +ImGuiID ImGuiWindow::GetPageID(const char* str, const char* str_end) { ImGuiID seed = IDStack.back(); ImGuiID id = ImHashStr(str, str_end ? (str_end - str) : 0, seed); @@ -3070,7 +3070,7 @@ ImGuiID ImGuiWindow::GetID(const char* str, const char* str_end) return id; } -ImGuiID ImGuiWindow::GetID(const void* ptr) +ImGuiID ImGuiWindow::GetPageID(const void* ptr) { ImGuiID seed = IDStack.back(); ImGuiID id = ImHashData(&ptr, sizeof(void*), seed); @@ -3081,7 +3081,7 @@ ImGuiID ImGuiWindow::GetID(const void* ptr) return id; } -ImGuiID ImGuiWindow::GetID(int n) +ImGuiID ImGuiWindow::GetPageID(int n) { ImGuiID seed = IDStack.back(); ImGuiID id = ImHashData(&n, sizeof(n), seed); @@ -5187,7 +5187,7 @@ bool ImGui::BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, b bool ImGui::BeginChild(const char* str_id, const ImVec2& size_arg, bool border, ImGuiWindowFlags extra_flags) { ImGuiWindow* window = GetCurrentWindow(); - return BeginChildEx(str_id, window->GetID(str_id), size_arg, border, extra_flags); + return BeginChildEx(str_id, window->GetPageID(str_id), size_arg, border, extra_flags); } bool ImGui::BeginChild(ImGuiID id, const ImVec2& size_arg, bool border, ImGuiWindowFlags extra_flags) @@ -5586,7 +5586,7 @@ static bool ImGui::UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& s ImRect resize_rect(corner - def.InnerDir * grip_hover_outer_size, corner + def.InnerDir * grip_hover_inner_size); if (resize_rect.Min.x > resize_rect.Max.x) ImSwap(resize_rect.Min.x, resize_rect.Max.x); if (resize_rect.Min.y > resize_rect.Max.y) ImSwap(resize_rect.Min.y, resize_rect.Max.y); - ImGuiID resize_grip_id = window->GetID(resize_grip_n); // == GetWindowResizeCornerID() + ImGuiID resize_grip_id = window->GetPageID(resize_grip_n); // == GetWindowResizeCornerID() ButtonBehavior(resize_rect, resize_grip_id, &hovered, &held, ImGuiButtonFlags_FlattenChildren | ImGuiButtonFlags_NoNavFocus); //GetForegroundDrawList(window)->AddRect(resize_rect.Min, resize_rect.Max, IM_COL32(255, 255, 0, 255)); if (hovered || held) @@ -5621,7 +5621,7 @@ static bool ImGui::UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& s bool hovered, held; ImRect border_rect = GetResizeBorderRect(window, border_n, grip_hover_inner_size, WINDOWS_HOVER_PADDING); - ImGuiID border_id = window->GetID(border_n + 4); // == GetWindowResizeBorderID() + ImGuiID border_id = window->GetPageID(border_n + 4); // == GetWindowResizeBorderID() ButtonBehavior(border_rect, border_id, &hovered, &held, ImGuiButtonFlags_FlattenChildren | ImGuiButtonFlags_NoNavFocus); //GetForegroundDrawLists(window)->AddRect(border_rect.Min, border_rect.Max, IM_COL32(255, 255, 0, 255)); if ((hovered && g.HoveredIdTimer > WINDOWS_RESIZE_FROM_EDGES_FEEDBACK_TIMER) || held) @@ -5841,12 +5841,12 @@ void ImGui::RenderWindowTitleBarContents(ImGuiWindow* window, const ImRect& titl // Collapse button (submitting first so it gets priority when choosing a navigation init fallback) if (has_collapse_button) - if (CollapseButton(window->GetID("#COLLAPSE"), collapse_button_pos)) + if (CollapseButton(window->GetPageID("#COLLAPSE"), collapse_button_pos)) window->WantCollapseToggle = true; // Defer actual collapsing to next frame as we are too far in the Begin() function // Close button if (has_close_button) - if (CloseButton(window->GetID("#CLOSE"), close_button_pos)) + if (CloseButton(window->GetPageID("#CLOSE"), close_button_pos)) *p_open = false; window->DC.NavLayerCurrent = ImGuiNavLayer_Main; @@ -6536,7 +6536,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) } // Pull/inherit current state - window->DC.NavFocusScopeIdCurrent = (flags & ImGuiWindowFlags_ChildWindow) ? parent_window->DC.NavFocusScopeIdCurrent : window->GetID("#FOCUSSCOPE"); // Inherit from parent only // -V595 + window->DC.NavFocusScopeIdCurrent = (flags & ImGuiWindowFlags_ChildWindow) ? parent_window->DC.NavFocusScopeIdCurrent : window->GetPageID("#FOCUSSCOPE"); // Inherit from parent only // -V595 PushClipRect(window->InnerClipRect.Min, window->InnerClipRect.Max, true); @@ -7425,22 +7425,22 @@ void ImGui::PopID() window->IDStack.pop_back(); } -ImGuiID ImGui::GetID(const char* str_id) +ImGuiID ImGui::GetPageID(const char* str_id) { ImGuiWindow* window = GImGui->CurrentWindow; - return window->GetID(str_id); + return window->GetPageID(str_id); } -ImGuiID ImGui::GetID(const char* str_id_begin, const char* str_id_end) +ImGuiID ImGui::GetPageID(const char* str_id_begin, const char* str_id_end) { ImGuiWindow* window = GImGui->CurrentWindow; - return window->GetID(str_id_begin, str_id_end); + return window->GetPageID(str_id_begin, str_id_end); } -ImGuiID ImGui::GetID(const void* ptr_id) +ImGuiID ImGui::GetPageID(const void* ptr_id) { ImGuiWindow* window = GImGui->CurrentWindow; - return window->GetID(ptr_id); + return window->GetPageID(ptr_id); } bool ImGui::IsRectVisible(const ImVec2& size) @@ -8520,7 +8520,7 @@ bool ImGui::IsPopupOpen(ImGuiID id, ImGuiPopupFlags popup_flags) bool ImGui::IsPopupOpen(const char* str_id, ImGuiPopupFlags popup_flags) { ImGuiContext& g = *GImGui; - ImGuiID id = (popup_flags & ImGuiPopupFlags_AnyPopupId) ? 0 : g.CurrentWindow->GetID(str_id); + ImGuiID id = (popup_flags & ImGuiPopupFlags_AnyPopupId) ? 0 : g.CurrentWindow->GetPageID(str_id); if ((popup_flags & ImGuiPopupFlags_AnyPopupLevel) && id != 0) IM_ASSERT(0 && "Cannot use IsPopupOpen() with a string id and ImGuiPopupFlags_AnyPopupLevel."); // But non-string version is legal and used internally return IsPopupOpen(id, popup_flags); @@ -8549,7 +8549,7 @@ ImGuiWindow* ImGui::GetTopMostAndVisiblePopupModal() void ImGui::OpenPopup(const char* str_id, ImGuiPopupFlags popup_flags) { ImGuiContext& g = *GImGui; - OpenPopupEx(g.CurrentWindow->GetID(str_id), popup_flags); + OpenPopupEx(g.CurrentWindow->GetPageID(str_id), popup_flags); } void ImGui::OpenPopup(ImGuiID id, ImGuiPopupFlags popup_flags) @@ -8760,7 +8760,7 @@ bool ImGui::BeginPopup(const char* str_id, ImGuiWindowFlags flags) return false; } flags |= ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoSavedSettings; - return BeginPopupEx(g.CurrentWindow->GetID(str_id), flags); + return BeginPopupEx(g.CurrentWindow->GetPageID(str_id), flags); } // If 'p_open' is specified for a modal popup window, the popup will have a regular close button which will close the popup. @@ -8769,7 +8769,7 @@ bool ImGui::BeginPopupModal(const char* name, bool* p_open, ImGuiWindowFlags fla { ImGuiContext& g = *GImGui; ImGuiWindow* window = g.CurrentWindow; - const ImGuiID id = window->GetID(name); + const ImGuiID id = window->GetPageID(name); if (!IsPopupOpen(id, ImGuiPopupFlags_None)) { g.NextWindowData.ClearFlags(); // We behave like Begin() and need to consume those values @@ -8825,7 +8825,7 @@ void ImGui::OpenPopupOnItemClick(const char* str_id, ImGuiPopupFlags popup_flags int mouse_button = (popup_flags & ImGuiPopupFlags_MouseButtonMask_); if (IsMouseReleased(mouse_button) && IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup)) { - ImGuiID id = str_id ? window->GetID(str_id) : g.LastItemData.ID; // If user hasn't passed an ID, we can use the LastItemID. Using LastItemID as a Popup ID won't conflict! + ImGuiID id = str_id ? window->GetPageID(str_id) : g.LastItemData.ID; // If user hasn't passed an ID, we can use the LastItemID. Using LastItemID as a Popup ID won't conflict! IM_ASSERT(id != 0); // You cannot pass a NULL str_id if the last item has no identifier (e.g. a Text() item) OpenPopupEx(id, popup_flags); } @@ -8853,7 +8853,7 @@ bool ImGui::BeginPopupContextItem(const char* str_id, ImGuiPopupFlags popup_flag ImGuiWindow* window = g.CurrentWindow; if (window->SkipItems) return false; - ImGuiID id = str_id ? window->GetID(str_id) : g.LastItemData.ID; // If user hasn't passed an ID, we can use the LastItemID. Using LastItemID as a Popup ID won't conflict! + ImGuiID id = str_id ? window->GetPageID(str_id) : g.LastItemData.ID; // If user hasn't passed an ID, we can use the LastItemID. Using LastItemID as a Popup ID won't conflict! IM_ASSERT(id != 0); // You cannot pass a NULL str_id if the last item has no identifier (e.g. a Text() item) int mouse_button = (popup_flags & ImGuiPopupFlags_MouseButtonMask_); if (IsMouseReleased(mouse_button) && IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup)) @@ -8867,7 +8867,7 @@ bool ImGui::BeginPopupContextWindow(const char* str_id, ImGuiPopupFlags popup_fl ImGuiWindow* window = g.CurrentWindow; if (!str_id) str_id = "window_context"; - ImGuiID id = window->GetID(str_id); + ImGuiID id = window->GetPageID(str_id); int mouse_button = (popup_flags & ImGuiPopupFlags_MouseButtonMask_); if (IsMouseReleased(mouse_button) && IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup)) if (!(popup_flags & ImGuiPopupFlags_NoOpenOverItems) || !IsAnyItemHovered()) @@ -8881,7 +8881,7 @@ bool ImGui::BeginPopupContextVoid(const char* str_id, ImGuiPopupFlags popup_flag ImGuiWindow* window = g.CurrentWindow; if (!str_id) str_id = "void_context"; - ImGuiID id = window->GetID(str_id); + ImGuiID id = window->GetPageID(str_id); int mouse_button = (popup_flags & ImGuiPopupFlags_MouseButtonMask_); if (IsMouseReleased(mouse_button) && !IsWindowHovered(ImGuiHoveredFlags_AnyWindow)) if (GetTopMostPopupModal() == NULL) diff --git a/depend/imgui/imgui.h b/depend/imgui/imgui.h index e986e6c..430448c 100644 --- a/depend/imgui/imgui.h +++ b/depend/imgui/imgui.h @@ -477,9 +477,9 @@ namespace ImGui IMGUI_API void PushID(const void* ptr_id); // push pointer into the ID stack (will hash pointer). IMGUI_API void PushID(int int_id); // push integer into the ID stack (will hash integer). IMGUI_API void PopID(); // pop from the ID stack. - IMGUI_API ImGuiID GetID(const char* str_id); // calculate unique ID (hash of whole ID stack + given parameter). e.g. if you want to query into ImGuiStorage yourself - IMGUI_API ImGuiID GetID(const char* str_id_begin, const char* str_id_end); - IMGUI_API ImGuiID GetID(const void* ptr_id); + IMGUI_API ImGuiID GetPageID(const char* str_id); // calculate unique ID (hash of whole ID stack + given parameter). e.g. if you want to query into ImGuiStorage yourself + IMGUI_API ImGuiID GetPageID(const char* str_id_begin, const char* str_id_end); + IMGUI_API ImGuiID GetPageID(const void* ptr_id); // Widgets: Text IMGUI_API void TextUnformatted(const char* text, const char* text_end = NULL); // raw text without formatting. Roughly equivalent to Text("%s", text) but: A) doesn't require null terminated string if 'text_end' is specified, B) it's faster, no memory copy is done, no buffer size limits, recommended for long chunks of text. diff --git a/depend/imgui/imgui_demo.cpp b/depend/imgui/imgui_demo.cpp index 9cbc503..192e6a8 100644 --- a/depend/imgui/imgui_demo.cpp +++ b/depend/imgui/imgui_demo.cpp @@ -2942,7 +2942,7 @@ static void ShowDemoWindowLayout() ImGui::TextUnformatted(names[i]); const ImGuiWindowFlags child_flags = enable_extra_decorations ? ImGuiWindowFlags_MenuBar : 0; - const ImGuiID child_id = ImGui::GetID((void*)(intptr_t)i); + const ImGuiID child_id = ImGui::GetPageID((void*)(intptr_t)i); const bool child_is_visible = ImGui::BeginChild(child_id, ImVec2(child_w, 200.0f), true, child_flags); if (ImGui::BeginMenuBar()) { @@ -2989,7 +2989,7 @@ static void ShowDemoWindowLayout() { float child_height = ImGui::GetTextLineHeight() + style.ScrollbarSize + style.WindowPadding.y * 2.0f; ImGuiWindowFlags child_flags = ImGuiWindowFlags_HorizontalScrollbar | (enable_extra_decorations ? ImGuiWindowFlags_AlwaysVerticalScrollbar : 0); - ImGuiID child_id = ImGui::GetID((void*)(intptr_t)i); + ImGuiID child_id = ImGui::GetPageID((void*)(intptr_t)i); bool child_is_visible = ImGui::BeginChild(child_id, ImVec2(-100, child_height), true, child_flags); if (scroll_to_off) ImGui::SetScrollX(scroll_to_off_px); @@ -5854,7 +5854,7 @@ void ImGui::ShowAboutWindow(bool* p_open) bool copy_to_clipboard = ImGui::Button("Copy to clipboard"); ImVec2 child_size = ImVec2(0, ImGui::GetTextLineHeightWithSpacing() * 18); - ImGui::BeginChildFrame(ImGui::GetID("cfg_infos"), child_size, ImGuiWindowFlags_NoMove); + ImGui::BeginChildFrame(ImGui::GetPageID("cfg_infos"), child_size, ImGuiWindowFlags_NoMove); if (copy_to_clipboard) { ImGui::LogToClipboard(); @@ -7805,7 +7805,7 @@ void ShowExampleAppDocuments(bool* p_open) { ImGui::Text("Save change to the following items?"); float item_height = ImGui::GetTextLineHeightWithSpacing(); - if (ImGui::BeginChildFrame(ImGui::GetID("frame"), ImVec2(-FLT_MIN, 6.25f * item_height))) + if (ImGui::BeginChildFrame(ImGui::GetPageID("frame"), ImVec2(-FLT_MIN, 6.25f * item_height))) { for (int n = 0; n < close_queue.Size; n++) if (close_queue[n]->Dirty) diff --git a/depend/imgui/imgui_internal.h b/depend/imgui/imgui_internal.h index 73d58f6..49b68f5 100644 --- a/depend/imgui/imgui_internal.h +++ b/depend/imgui/imgui_internal.h @@ -2050,9 +2050,9 @@ public: ImGuiWindow(ImGuiContext* context, const char* name); ~ImGuiWindow(); - ImGuiID GetID(const char* str, const char* str_end = NULL); - ImGuiID GetID(const void* ptr); - ImGuiID GetID(int n); + ImGuiID GetPageID(const char* str, const char* str_end = NULL); + ImGuiID GetPageID(const void* ptr); + ImGuiID GetPageID(int n); ImGuiID GetIDNoKeepAlive(const char* str, const char* str_end = NULL); ImGuiID GetIDNoKeepAlive(const void* ptr); ImGuiID GetIDNoKeepAlive(int n); diff --git a/depend/imgui/imgui_tables.cpp b/depend/imgui/imgui_tables.cpp index 8a3fe93..5f12be7 100644 --- a/depend/imgui/imgui_tables.cpp +++ b/depend/imgui/imgui_tables.cpp @@ -303,7 +303,7 @@ ImGuiTable* ImGui::TableFindByID(ImGuiID id) // Read about "TABLE SIZING" at the top of this file. bool ImGui::BeginTable(const char* str_id, int columns_count, ImGuiTableFlags flags, const ImVec2& outer_size, float inner_width) { - ImGuiID id = GetID(str_id); + ImGuiID id = GetPageID(str_id); return BeginTableEx(str_id, id, columns_count, flags, outer_size, inner_width); } @@ -2898,7 +2898,7 @@ void ImGui::TableHeader(const char* label) // Keep header highlighted when context menu is open. const bool selected = (table->IsContextPopupOpen && table->ContextPopupColumn == column_n && table->InstanceInteracted == table->InstanceCurrent); - ImGuiID id = window->GetID(label); + ImGuiID id = window->GetPageID(label); ImRect bb(cell_r.Min.x, cell_r.Min.y, cell_r.Max.x, ImMax(cell_r.Max.y, cell_r.Min.y + label_height + g.Style.CellPadding.y * 2.0f)); ItemSize(ImVec2(0.0f, label_height)); // Don't declare unclipped width, it'll be fed ContentMaxPosHeadersIdeal if (!ItemAdd(bb, id)) @@ -3812,7 +3812,7 @@ ImGuiID ImGui::GetColumnsID(const char* str_id, int columns_count) // Differentiate column ID with an arbitrary prefix for cases where users name their columns set the same as another widget. // In addition, when an identifier isn't explicitly provided we include the number of columns in the hash to make it uniquer. PushID(0x11223347 + (str_id ? 0 : columns_count)); - ImGuiID id = window->GetID(str_id ? str_id : "columns"); + ImGuiID id = window->GetPageID(str_id ? str_id : "columns"); PopID(); return id; diff --git a/depend/imgui/imgui_widgets.cpp b/depend/imgui/imgui_widgets.cpp index f199ad4..d75b786 100644 --- a/depend/imgui/imgui_widgets.cpp +++ b/depend/imgui/imgui_widgets.cpp @@ -675,7 +675,7 @@ bool ImGui::ButtonEx(const char* label, const ImVec2& size_arg, ImGuiButtonFlags ImGuiContext& g = *GImGui; const ImGuiStyle& style = g.Style; - const ImGuiID id = window->GetID(label); + const ImGuiID id = window->GetPageID(label); const ImVec2 label_size = CalcTextSize(label, NULL, true); ImVec2 pos = window->DC.CursorPos; @@ -738,7 +738,7 @@ bool ImGui::InvisibleButton(const char* str_id, const ImVec2& size_arg, ImGuiBut // Cannot use zero-size for InvisibleButton(). Unlike Button() there is not way to fallback using the label size. IM_ASSERT(size_arg.x != 0.0f && size_arg.y != 0.0f); - const ImGuiID id = window->GetID(str_id); + const ImGuiID id = window->GetPageID(str_id); ImVec2 size = CalcItemSize(size_arg, 0.0f, 0.0f); const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + size); ItemSize(size); @@ -758,7 +758,7 @@ bool ImGui::ArrowButtonEx(const char* str_id, ImGuiDir dir, ImVec2 size, ImGuiBu return false; ImGuiContext& g = *GImGui; - const ImGuiID id = window->GetID(str_id); + const ImGuiID id = window->GetPageID(str_id); const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + size); const float default_size = GetFrameHeight(); ItemSize(size, (size.y >= default_size) ? g.Style.FramePadding.y : -1.0f); @@ -1062,7 +1062,7 @@ bool ImGui::ImageButton(ImTextureID user_texture_id, const ImVec2& size, const I // Default to using texture ID as ID. User can still push string/integer prefixes. PushID((void*)(intptr_t)user_texture_id); - const ImGuiID id = window->GetID("#image"); + const ImGuiID id = window->GetPageID("#image"); PopID(); const ImVec2 padding = (frame_padding >= 0) ? ImVec2((float)frame_padding, (float)frame_padding) : g.Style.FramePadding; @@ -1077,7 +1077,7 @@ bool ImGui::Checkbox(const char* label, bool* v) ImGuiContext& g = *GImGui; const ImGuiStyle& style = g.Style; - const ImGuiID id = window->GetID(label); + const ImGuiID id = window->GetPageID(label); const ImVec2 label_size = CalcTextSize(label, NULL, true); const float square_sz = GetFrameHeight(); @@ -1183,7 +1183,7 @@ bool ImGui::RadioButton(const char* label, bool active) ImGuiContext& g = *GImGui; const ImGuiStyle& style = g.Style; - const ImGuiID id = window->GetID(label); + const ImGuiID id = window->GetPageID(label); const ImVec2 label_size = CalcTextSize(label, NULL, true); const float square_sz = GetFrameHeight(); @@ -1579,7 +1579,7 @@ bool ImGui::BeginCombo(const char* label, const char* preview_value, ImGuiComboF return false; const ImGuiStyle& style = g.Style; - const ImGuiID id = window->GetID(label); + const ImGuiID id = window->GetPageID(label); IM_ASSERT((flags & (ImGuiComboFlags_NoArrowButton | ImGuiComboFlags_NoPreview)) != (ImGuiComboFlags_NoArrowButton | ImGuiComboFlags_NoPreview)); // Can't use both flags together const float arrow_size = (flags & ImGuiComboFlags_NoArrowButton) ? 0.0f : GetFrameHeight(); @@ -2395,7 +2395,7 @@ bool ImGui::DragScalar(const char* label, ImGuiDataType data_type, void* p_data, ImGuiContext& g = *GImGui; const ImGuiStyle& style = g.Style; - const ImGuiID id = window->GetID(label); + const ImGuiID id = window->GetPageID(label); const float w = CalcItemWidth(); const ImVec2 label_size = CalcTextSize(label, NULL, true); @@ -3013,7 +3013,7 @@ bool ImGui::SliderScalar(const char* label, ImGuiDataType data_type, void* p_dat ImGuiContext& g = *GImGui; const ImGuiStyle& style = g.Style; - const ImGuiID id = window->GetID(label); + const ImGuiID id = window->GetPageID(label); const float w = CalcItemWidth(); const ImVec2 label_size = CalcTextSize(label, NULL, true); @@ -3179,7 +3179,7 @@ bool ImGui::VSliderScalar(const char* label, const ImVec2& size, ImGuiDataType d ImGuiContext& g = *GImGui; const ImGuiStyle& style = g.Style; - const ImGuiID id = window->GetID(label); + const ImGuiID id = window->GetPageID(label); const ImVec2 label_size = CalcTextSize(label, NULL, true); const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + size); @@ -3979,7 +3979,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ if (is_multiline) // Open group before calling GetID() because groups tracks id created within their scope (including the scrollbar) BeginGroup(); - const ImGuiID id = window->GetID(label); + const ImGuiID id = window->GetPageID(label); const ImVec2 label_size = CalcTextSize(label, NULL, true); const ImVec2 frame_size = CalcItemSize(size_arg, CalcItemWidth(), (is_multiline ? g.FontSize * 8.0f : label_size.y) + style.FramePadding.y * 2.0f); // Arbitrary default of 8 lines high for multi-line const ImVec2 total_size = ImVec2(frame_size.x + (label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f), frame_size.y); @@ -5506,7 +5506,7 @@ bool ImGui::ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFl return false; ImGuiContext& g = *GImGui; - const ImGuiID id = window->GetID(desc_id); + const ImGuiID id = window->GetPageID(desc_id); float default_size = GetFrameHeight(); if (size.x == 0.0f) size.x = default_size; @@ -5763,7 +5763,7 @@ bool ImGui::TreeNode(const char* label) ImGuiWindow* window = GetCurrentWindow(); if (window->SkipItems) return false; - return TreeNodeBehavior(window->GetID(label), 0, label, NULL); + return TreeNodeBehavior(window->GetPageID(label), 0, label, NULL); } bool ImGui::TreeNodeV(const char* str_id, const char* fmt, va_list args) @@ -5782,7 +5782,7 @@ bool ImGui::TreeNodeEx(const char* label, ImGuiTreeNodeFlags flags) if (window->SkipItems) return false; - return TreeNodeBehavior(window->GetID(label), flags, label, NULL); + return TreeNodeBehavior(window->GetPageID(label), flags, label, NULL); } bool ImGui::TreeNodeEx(const char* str_id, ImGuiTreeNodeFlags flags, const char* fmt, ...) @@ -5811,7 +5811,7 @@ bool ImGui::TreeNodeExV(const char* str_id, ImGuiTreeNodeFlags flags, const char ImGuiContext& g = *GImGui; const char* label_end = g.TempBuffer + ImFormatStringV(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), fmt, args); - return TreeNodeBehavior(window->GetID(str_id), flags, g.TempBuffer, label_end); + return TreeNodeBehavior(window->GetPageID(str_id), flags, g.TempBuffer, label_end); } bool ImGui::TreeNodeExV(const void* ptr_id, ImGuiTreeNodeFlags flags, const char* fmt, va_list args) @@ -5822,7 +5822,7 @@ bool ImGui::TreeNodeExV(const void* ptr_id, ImGuiTreeNodeFlags flags, const char ImGuiContext& g = *GImGui; const char* label_end = g.TempBuffer + ImFormatStringV(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), fmt, args); - return TreeNodeBehavior(window->GetID(ptr_id), flags, g.TempBuffer, label_end); + return TreeNodeBehavior(window->GetPageID(ptr_id), flags, g.TempBuffer, label_end); } bool ImGui::TreeNodeBehaviorIsOpen(ImGuiID id, ImGuiTreeNodeFlags flags) @@ -6131,7 +6131,7 @@ bool ImGui::CollapsingHeader(const char* label, ImGuiTreeNodeFlags flags) if (window->SkipItems) return false; - return TreeNodeBehavior(window->GetID(label), flags | ImGuiTreeNodeFlags_CollapsingHeader, label); + return TreeNodeBehavior(window->GetPageID(label), flags | ImGuiTreeNodeFlags_CollapsingHeader, label); } // p_visible == NULL : regular collapsing header @@ -6147,7 +6147,7 @@ bool ImGui::CollapsingHeader(const char* label, bool* p_visible, ImGuiTreeNodeFl if (p_visible && !*p_visible) return false; - ImGuiID id = window->GetID(label); + ImGuiID id = window->GetPageID(label); flags |= ImGuiTreeNodeFlags_CollapsingHeader; if (p_visible) flags |= ImGuiTreeNodeFlags_AllowItemOverlap | ImGuiTreeNodeFlags_ClipLabelForTrailingButton; @@ -6191,7 +6191,7 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl const ImGuiStyle& style = g.Style; // Submit label or explicit size to ItemSize(), whereas ItemAdd() will submit a larger/spanning rectangle. - ImGuiID id = window->GetID(label); + ImGuiID id = window->GetPageID(label); ImVec2 label_size = CalcTextSize(label, NULL, true); ImVec2 size(size_arg.x != 0.0f ? size_arg.x : label_size.x, size_arg.y != 0.0f ? size_arg.y : label_size.y); ImVec2 pos = window->DC.CursorPos; @@ -6354,7 +6354,7 @@ bool ImGui::BeginListBox(const char* label, const ImVec2& size_arg) return false; const ImGuiStyle& style = g.Style; - const ImGuiID id = GetID(label); + const ImGuiID id = GetPageID(label); const ImVec2 label_size = CalcTextSize(label, NULL, true); // Size default to hold ~7.25 items. @@ -6483,7 +6483,7 @@ int ImGui::PlotEx(ImGuiPlotType plot_type, const char* label, float (*values_get return -1; const ImGuiStyle& style = g.Style; - const ImGuiID id = window->GetID(label); + const ImGuiID id = window->GetPageID(label); const ImVec2 label_size = CalcTextSize(label, NULL, true); if (frame_size.x == 0.0f) @@ -6893,7 +6893,7 @@ bool ImGui::BeginMenuEx(const char* label, const char* icon, bool enabled) ImGuiContext& g = *GImGui; const ImGuiStyle& style = g.Style; - const ImGuiID id = window->GetID(label); + const ImGuiID id = window->GetPageID(label); bool menu_is_open = IsPopupOpen(id, ImGuiPopupFlags_None); // Sub-menus are ChildWindow so that mouse can be hovering across them (otherwise top-most popup menu would steal focus and not allow hovering on parent menu) @@ -7261,7 +7261,7 @@ bool ImGui::BeginTabBar(const char* str_id, ImGuiTabBarFlags flags) if (window->SkipItems) return false; - ImGuiID id = window->GetID(str_id); + ImGuiID id = window->GetPageID(str_id); ImGuiTabBar* tab_bar = g.TabBars.GetOrAddByKey(id); ImRect tab_bar_bb = ImRect(window->DC.CursorPos.x, window->DC.CursorPos.y, window->WorkRect.Max.x, window->DC.CursorPos.y + g.FontSize + g.Style.FramePadding.y * 2); tab_bar->ID = id; @@ -7608,7 +7608,7 @@ static ImU32 ImGui::TabBarCalcTabID(ImGuiTabBar* tab_bar, const char* label) else { ImGuiWindow* window = GImGui->CurrentWindow; - return window->GetID(label); + return window->GetPageID(label); } } diff --git a/resource/common/locale/English.toml b/resource/common/locale/English.toml index d8bb28e..1d8208c 100644 --- a/resource/common/locale/English.toml +++ b/resource/common/locale/English.toml @@ -143,9 +143,8 @@ TranslatorName = "Grinch_" About = "About" Author = "Author" AutoCheckUpdate = "Check for updates" -BugDisclaimer = "If you find bugs or have suggestions, let me know on discord." +BugDisclaimer = "Be sure to inform me about bugs or suggestions & join the discord server for beta updates" Build = "Build" -CheatMenuNoDir = "Failed to find CheatMenu directory!" CheckUpdate = "Check update" Commands = "Commands" Config = "Config" diff --git a/resource/common/locale/chinese.toml b/resource/common/locale/chinese.toml index 9b0d9a5..f4d1461 100644 --- a/resource/common/locale/chinese.toml +++ b/resource/common/locale/chinese.toml @@ -139,7 +139,6 @@ Author = "作者" AutoCheckUpdate = "检查更新" BugDisclaimer = "如果您发现错误或有建议,请通知我告诉我有哪些问题。" Build = "生成" -CheatMenuNoDir = "未能找到 CheatMenu 目录!" CheckUpdate = "检查更新" Commands = "命令" Config = "配置" diff --git a/src/cheatmenu.cpp b/src/cheatmenu.cpp index 4ec85cd..4b0aeec 100644 --- a/src/cheatmenu.cpp +++ b/src/cheatmenu.cpp @@ -15,13 +15,14 @@ #include "pages/vehicle.h" #include "pages/visual.h" #include "pages/weapon.h" +#include "interface/ipage.h" static bool DrawTitleBar() { bool hovered, held; ImGuiWindow *window = ImGui::GetCurrentWindow(); ImGuiStyle& Style = ImGui::GetStyle(); - ImGuiID id = window->GetID("#CLOSE"); + ImGuiID id = window->GetPageID("#CLOSE"); ImGui::PushFont(FontMgr::Get("title")); Widget::TextCentered(MENU_TITLE); @@ -87,7 +88,7 @@ void CheatMenu::DrawWindow() ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(ImGui::GetWindowWidth() / 85, ImGui::GetWindowHeight() / 200)); - ProcessPages(); + PageHandler::DrawPages(); if (m_bSizeChangedExternal) m_bSizeChangedExternal = false; @@ -119,21 +120,18 @@ void CheatMenu::Init() } // Load menu settings - m_nMenuPage = (eMenuPages)gConfig.Get("Window.CurrentPage", (size_t)eMenuPages::WELCOME); + // m_nMenuPage = (eMenuPages)gConfig.Get("Window.CurrentPage", (size_t)eMenuPages::WELCOME); m_fMenuSize.x = gConfig.Get("Window.SizeX", screen::GetScreenWidth() / 4.0f); m_fMenuSize.y = gConfig.Get("Window.SizeY", screen::GetScreenHeight() / 1.2f); srand(CTimer::m_snTimeInMilliseconds); ApplyStyle(); Locale::Init(FILE_NAME "/locale/", "English", "English"); - GenHeaderList(); + // GenHeaderList(); // Init menu parts - Game::Init(); - Menu::Init(); Player::Init(); Ped::Init(); - Teleport::Init(); Vehicle::Init(); Visual::Init(); WeaponPage::Init(); @@ -164,7 +162,7 @@ void CheatMenu::Init() D3dHook::SetMouseState(m_bShowMenu); } - if (Teleport::IsQuickTeleportActive() && quickTeleport.PressedRealtime()) + if (teleportPage.IsQuickTeleportActive() && quickTeleport.PressedRealtime()) { D3dHook::SetMouseState(true); } diff --git a/src/cheatmenu.h b/src/cheatmenu.h index a445037..83ca8f1 100644 --- a/src/cheatmenu.h +++ b/src/cheatmenu.h @@ -3,7 +3,7 @@ /* * Main CheatMenu Class -* Handles rendering, resizing, page handling etc. +* Handles rendering, resizing, page drawing etc. */ class CheatMenu { diff --git a/src/custom/freecam_sa.cpp b/src/custom/freecam_sa.cpp index 18d55f6..3b9effe 100644 --- a/src/custom/freecam_sa.cpp +++ b/src/custom/freecam_sa.cpp @@ -35,7 +35,7 @@ void FreecamMgr::Enable() Command(true); } -void FreecamMgr::Process() +void FreecamMgr::DrawPages() { int delta = (CTimer::m_snTimeInMilliseconds - CTimer::m_snPreviousTimeInMilliseconds); int ratio = 1 / (1 + (delta * m_nMul)); @@ -183,7 +183,7 @@ FreecamMgr::FreecamMgr() { if (m_bEnabled) { - Process(); + DrawPages(); } }; } \ No newline at end of file diff --git a/src/custom/freecam_sa.h b/src/custom/freecam_sa.h index 240b362..09f7d8d 100644 --- a/src/custom/freecam_sa.h +++ b/src/custom/freecam_sa.h @@ -19,7 +19,7 @@ private: FreecamMgr(const FreecamMgr&); // Process freecam mode each frame - void Process(); + void DrawPages(); public: int m_nMul = 1; // speed multiplier diff --git a/src/custom/neon_sa.cpp b/src/custom/neon_sa.cpp index 3d96c88..a0e9005 100644 --- a/src/custom/neon_sa.cpp +++ b/src/custom/neon_sa.cpp @@ -231,11 +231,11 @@ NeonMgr::NeonMgr() NeonMgr::~NeonMgr() { - if (m_pNeonTexture) - { - RwTextureDestroy(m_pNeonTexture); - m_pNeonTexture = nullptr; - } + // if (m_pNeonTexture) + // { + // RwTextureDestroy(m_pNeonTexture); + // m_pNeonTexture = nullptr; + // } } bool NeonMgr::IsInstalled(CVehicle* pVeh) diff --git a/src/custom/randomcheats_sa.cpp b/src/custom/randomcheats_sa.cpp index 3f252be..1517fc9 100644 --- a/src/custom/randomcheats_sa.cpp +++ b/src/custom/randomcheats_sa.cpp @@ -3,7 +3,7 @@ RandomCheatsMgr& RandomCheats = RandomCheatsMgr::Get(); -void RandomCheatsMgr::Process() +void RandomCheatsMgr::DrawPages() { uint timer = CTimer::m_snTimeInMilliseconds; static uint m_nTimer = 0; @@ -72,7 +72,7 @@ RandomCheatsMgr::RandomCheatsMgr() { if (m_bEnabled) { - Process(); + DrawPages(); } }; } \ No newline at end of file diff --git a/src/custom/randomcheats_sa.h b/src/custom/randomcheats_sa.h index 661bbac..b133f92 100644 --- a/src/custom/randomcheats_sa.h +++ b/src/custom/randomcheats_sa.h @@ -17,7 +17,7 @@ private: RandomCheatsMgr(const RandomCheatsMgr&); // Process the RandomCheat each frame & draw progress bar - void Process(); + void DrawPages(); public: bool m_bProgressBar = true; diff --git a/src/custom/topdowncam_sa.cpp b/src/custom/topdowncam_sa.cpp index 574d7e1..d7654af 100644 --- a/src/custom/topdowncam_sa.cpp +++ b/src/custom/topdowncam_sa.cpp @@ -9,7 +9,7 @@ TopDownCamera::TopDownCamera() { if (m_bEnabled) { - Process(); + DrawPages(); } }; } @@ -18,7 +18,7 @@ TopDownCamera::TopDownCamera() Taken from gta chaos mod by Lordmau5 https://github.com/gta-chaos-mod/Trilogy-ASI-Script */ -void TopDownCamera::Process() +void TopDownCamera::DrawPages() { CPlayerPed *player = FindPlayerPed(); CVector pos = player->GetPosition (); diff --git a/src/custom/topdowncam_sa.h b/src/custom/topdowncam_sa.h index 5b4fb41..fc923ad 100644 --- a/src/custom/topdowncam_sa.h +++ b/src/custom/topdowncam_sa.h @@ -17,7 +17,7 @@ public: int m_nZoom = 40; // Process cheat each frame - void Process(); + void DrawPages(); }; extern TopDownCamera& TopDownCam; \ No newline at end of file diff --git a/src/defines.h b/src/defines.h index 99bcb12..4ec5e53 100644 --- a/src/defines.h +++ b/src/defines.h @@ -4,6 +4,7 @@ #define SPAWN_PED_LIMIT 20 #define DISCORD_INVITE "https://discord.gg/ZzW7kmf" #define GITHUB_LINK "https://github.com/user-grinch/Cheat-Menu" +#define PATREON_LINK "https://www.patreon.com/grinch_" #define IMGUI_DEFINE_MATH_OPERATORS #define MENU_NAME "Cheat Menu" diff --git a/src/dllmain.cpp b/src/dllmain.cpp index b6f5a0e..40e1205 100644 --- a/src/dllmain.cpp +++ b/src/dllmain.cpp @@ -100,7 +100,7 @@ void MenuThread(void* param) CheatMenu::Init(); // Checking for updates once a day - if (Menu::m_bAutoCheckUpdate && gConfig.Get("Menu.LastUpdateChecked", 0) != st.wDay) + if (menuPage.m_bAutoCheckUpdate && gConfig.Get("Menu.LastUpdateChecked", 0) != st.wDay) { Updater::CheckUpdate(); gConfig.Set("Menu.LastUpdateChecked", st.wDay); @@ -113,9 +113,9 @@ void MenuThread(void* param) while (true) { - FontMgr::Process(); - RPC::Process(); - Updater::Process(); + FontMgr::DrawPages(); + RPC::DrawPages(); + Updater::DrawPages(); Sleep(1000); } } diff --git a/src/interface/ipage.cpp b/src/interface/ipage.cpp index 595cd35..186876a 100644 --- a/src/interface/ipage.cpp +++ b/src/interface/ipage.cpp @@ -2,90 +2,21 @@ #include "ipage.h" #include "utils/updater.h" #include "utils/widget.h" +#include "imgui/imgui_internal.h" +#include "pages/welcome.h" -static void DrawAnniversaryPage() +void PageHandler::AddPage(PagePtr page) { - Widget::TextCentered("Happy Anniversary!"); - ImGui::NewLine(); - - ImGui::TextWrapped("On this day, in 2019, the first public version of menu was released in MixMods Forum." - " It's been a blast working on it and I've learned a lot in the process.\n\nThanks to you and everyone who used or" - " contributed to the modification in any form or shape."); - - ImGui::NewLine(); - ImGui::TextWrapped("Feel free to star the GitHub repo or join the discord server and provide feedback, ideas, or suggestions."); - ImGui::NewLine(); - - if (ImGui::Button(TEXT("Menu.DiscordServer"), ImVec2(Widget::CalcSize(3)))) - { - OPEN_LINK(DISCORD_INVITE); - } - ImGui::SameLine(); - if (ImGui::Button(TEXT("Menu.GitHubRepo"), ImVec2(Widget::CalcSize(3)))) - { - OPEN_LINK(GITHUB_LINK); - } -} - -static void DrawWelcomePage() -{ - ImGui::NewLine(); - - Widget::TextCentered(TEXT("Menu.WelcomeMSG")); - Widget::TextCentered(std::format("{}: Grinch_",TEXT("Menu.Author"))); - - ImGui::NewLine(); - ImGui::TextWrapped(TEXT("Menu.EnsureLatest")); - if (ImGui::Button(TEXT("Menu.DiscordServer"), ImVec2(Widget::CalcSize(2)))) - { - OPEN_LINK(DISCORD_INVITE); - } - ImGui::SameLine(); - if (ImGui::Button(TEXT("Menu.GitHubRepo"), ImVec2(Widget::CalcSize(2)))) - { - OPEN_LINK(GITHUB_LINK); - } - ImGui::NewLine(); - ImGui::TextWrapped(TEXT("Menu.BugDisclaimer")); - ImGui::Dummy(ImVec2(0, 20)); - Widget::TextCentered(TEXT("Menu.PatreonText")); - if (ImGui::Button(TEXT("Menu.Patreon"), ImVec2(Widget::CalcSize(1)))) - { - OPEN_LINK("https://www.patreon.com/grinch_"); - } - ImGui::Dummy(ImVec2(0, 30)); - Widget::TextCentered(TEXT("Menu.CopyrightDisclaimer")); + m_PageList.push_back(page); } -static void DrawUpdatePage() +void PageHandler::SetCurrentPage(PagePtr page) { - std::string ver = Updater::GetUpdateVersion(); - ImGui::Dummy(ImVec2(0, 20)); - Widget::TextCentered(TEXT("Menu.NewVersion")); - Widget::TextCentered(std::format("{}: {}", TEXT("Menu.CurrentVersion"), MENU_VERSION)); - Widget::TextCentered(TEXT("Menu.LatestVersion") + ver); - ImGui::Dummy(ImVec2(0, 10)); - ImGui::TextWrapped(TEXT("Menu.UpdaterInfo1")); - ImGui::Dummy(ImVec2(0, 10)); - ImGui::TextWrapped(TEXT("Menu.UpdaterInfo2")); - - ImGui::Dummy(ImVec2(0, 5)); - if (ImGui::Button(TEXT("Menu.DiscordServer"), ImVec2(Widget::CalcSize(2)))) - { - OPEN_LINK(DISCORD_INVITE); - } - - ImGui::SameLine(); - - if (ImGui::Button(TEXT("Menu.DownloadPage"), Widget::CalcSize(2))) - { - ShellExecute(NULL, "open", std::string("https://github.com/user-grinch/Cheat-Menu/releases/tag/" + - ver).c_str(), NULL, NULL, SW_SHOWNORMAL); - } + m_pCurrentPage = page; } -template -void IPage::Process() +using IPageStatic = IPage; // dummy class +void PageHandler::DrawPages() { ImVec2 size = Widget::CalcSize(3, false); ImGuiStyle &style = ImGui::GetStyle(); @@ -93,12 +24,20 @@ void IPage::Process() ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 0)); if (Updater::IsUpdateAvailable()) { - m_nCurrentPage = eMenuPage::Update; + for (PagePtr ptr : m_PageList) + { + IPageStatic* page = reinterpret_cast(ptr); + if (page->GetPageID() == ePageID::Update) + { + m_pCurrentPage = page; + break; + } + } } // Check once if it's anniversary day - static bool aniCheckDone; - if (!aniCheckDone) + static bool checked; + if (!checked) { SYSTEMTIME st; GetSystemTime(&st); @@ -114,48 +53,40 @@ void IPage::Process() if (!flag) { gConfig.Set("Window.AnniversaryShown", true); - m_nMenuPage = eMenuPages::ANNIVERSARY; + + for (void* ptr : m_PageList) + { + IPageStatic* page = reinterpret_cast(ptr); + if (page->GetPageID() == ePageID::Anniversary) + { + m_pCurrentPage = page; + break; + } + } } } - aniCheckDone = true; + checked = true; } + // Draw header buttons ImDrawList *pDrawList = ImGui::GetWindowDrawList(); - for (size_t i = 0; i < m_headerList.size(); ++i) - { - /* - * For welcome & update pages - * They don't need to add item in the header list - */ - if (m_headerList[i].skipHeader) + size_t count = 0; + for (PagePtr ptr : m_PageList) + { + IPageStatic* pg = reinterpret_cast(ptr); + if (!pg->HasHeaderButton()) { - if (m_nMenuPage == m_headerList[i].page) - { - pCallback = m_headerList[i].pFunc; - } - continue; } - const char* text = m_headerList[i].name.c_str(); + std::string text = TEXT_S(pg->GetPageKey()); + ImVec4 color = (pg == m_pCurrentPage) ? style.Colors[ImGuiCol_ButtonActive] : style.Colors[ImGuiCol_Button]; - ImVec4 color; - if (m_headerList[i].page == m_nMenuPage) + if (ImGui::InvisibleButton(text.c_str(), size)) { - color = style.Colors[ImGuiCol_ButtonActive]; - pCallback = m_headerList[i].pFunc; - } - else - { - color = style.Colors[ImGuiCol_Button]; - } - - if (ImGui::InvisibleButton(text, size)) - { - m_nMenuPage = m_headerList[i].page; - size_t curPage = static_cast(m_headerList[i].page); - gConfig.Set("Window.CurrentPage", curPage); - pCallback = m_headerList[i].pFunc; + m_pCurrentPage = pg; + size_t id = static_cast(pg->GetPageID()); + gConfig.Set("Window.CurrentPage", id); Updater::ResetUpdaterState(); } @@ -169,28 +100,30 @@ void IPage::Process() * TODO: hardcoded atm */ ImDrawFlags flags = ImDrawFlags_RoundCornersNone; - if (i == 0) flags = ImDrawFlags_RoundCornersTopLeft; - if (i == 2) flags = ImDrawFlags_RoundCornersTopRight; - if (i == 6) flags = ImDrawFlags_RoundCornersBottomLeft; - if (i == 8) flags = ImDrawFlags_RoundCornersBottomRight; + if (count == 0) flags = ImDrawFlags_RoundCornersTopLeft; + if (count == 2) flags = ImDrawFlags_RoundCornersTopRight; + if (count == 6) flags = ImDrawFlags_RoundCornersBottomLeft; + if (count == 8) flags = ImDrawFlags_RoundCornersBottomRight; ImVec2 min = ImGui::GetItemRectMin(); ImVec2 max = ImGui::GetItemRectMax(); - ImVec2 size = ImGui::CalcTextSize(text); + ImVec2 size = ImGui::CalcTextSize(text.c_str()); pDrawList->AddRectFilled(min, max, ImGui::GetColorU32(color), style.FrameRounding, flags); - ImGui::RenderTextClipped(min + style.FramePadding, max - style.FramePadding, text, NULL, &size, style.ButtonTextAlign); + ImGui::RenderTextClipped(min + style.FramePadding, max - style.FramePadding, text.c_str(), NULL, &size, style.ButtonTextAlign); - if (i % 3 != 2) + if (count % 3 != 2) { ImGui::SameLine(); } + ++count; } ImGui::PopStyleVar(); + ImGui::Spacing(); ImGui::Dummy(ImVec2(0, 10)); if (m_pCurrentPage != nullptr && ImGui::BeginChild("HEADERCONTENT")) { - m_pCurrentPage->Draw(); + reinterpret_cast(m_pCurrentPage)->Draw(); ImGui::EndChild(); } } \ No newline at end of file diff --git a/src/interface/ipage.h b/src/interface/ipage.h index f69062e..d154c70 100644 --- a/src/interface/ipage.h +++ b/src/interface/ipage.h @@ -1,7 +1,7 @@ #pragma once #include -enum class eMenuPage +enum class ePageID { Anniversary, Game, @@ -18,6 +18,30 @@ enum class eMenuPage Welcome }; +/* + Handles all pages + Draws the page code too +*/ +using PagePtr = void*; +class PageHandler +{ +private: + static inline std::vector m_PageList; // Contains list of the created pages + static inline PagePtr m_pCurrentPage = nullptr; // Currently visible menu page + +public: + + PageHandler() = delete; + PageHandler(const PageHandler&) = delete; + + // Process the menu pages & draw them + static void DrawPages(); + + // Add a new page + static void AddPage(PagePtr page); + static void SetCurrentPage(PagePtr page); +}; + /* Interface class for pages Every page must inherit this @@ -26,47 +50,41 @@ template class IPage { private: - eMenuPage m_ePage; // Menu page ID + ePageID m_eID; // Menu page ID bool m_bHasHeader; // Does the page has a header button std::string m_NameKey; // A key to the page name string public: - static inline std::vector m_nPageList; // Contains list of the created pages - static inline IPage* m_pCurrentPage = nullptr; // Currently visible menu page - - IPage(m_ePage page, std::string&& key, bool header = true) - : m_ePage(page), m_NameKey(key), m_bHasHeader(header) + IPage(ePageID page, const std::string& key, bool header) + : m_eID(page), m_NameKey(key), m_bHasHeader(header) { - m_nPageList.push_back(this); + PageHandler::AddPage(reinterpret_cast(this)); } // Page drawing code goes here virtual void Draw() = 0; - static T *Get() final + static T &Get() { static T _instance; - return &_instance; + return _instance; } // Returns the ID of the page - eMenuPage GetPageID() final + virtual ePageID GetPageID() final { - return m_ePage; + return m_eID; } // Returns true if the page has a visible header button - bool HasHeaderButton() final + virtual bool HasHeaderButton() final { return m_bHasHeader; } // Returns the page name key - std::string GetKey() final + virtual std::string GetPageKey() final { return m_NameKey; } - - // Process the menu pages & draw them - static void Process() final; }; \ No newline at end of file diff --git a/src/pages/anniversary.cpp b/src/pages/anniversary.cpp new file mode 100644 index 0000000..29245e4 --- /dev/null +++ b/src/pages/anniversary.cpp @@ -0,0 +1,34 @@ +#include "pch.h" +#include "anniversary.h" +#include "utils/widget.h" + +AnniversaryPage& anniversaryPage = AnniversaryPage::Get(); + +void AnniversaryPage::Draw() +{ + Widget::TextCentered("Happy Anniversary!"); + ImGui::NewLine(); + + ImGui::TextWrapped("On this day, in 2019, the first public version of menu was released." + " It's been a blast working on it and I've learned a lot in the process.\n\nThanks to you and everyone who used or" + " contributed to the modification in any shape or form."); + + ImGui::NewLine(); + ImGui::TextWrapped("Feel free to star the GitHub repo or join the discord server and provide feedback, ideas, or suggestions."); + ImGui::NewLine(); + + if (ImGui::Button(TEXT("Menu.DiscordServer"), ImVec2(Widget::CalcSize(3)))) + { + OPEN_LINK(DISCORD_INVITE); + } + ImGui::SameLine(); + if (ImGui::Button(TEXT("Menu.GitHubRepo"), ImVec2(Widget::CalcSize(3)))) + { + OPEN_LINK(GITHUB_LINK); + } + ImGui::SameLine(); + if (ImGui::Button(TEXT("Menu.Patreon"), ImVec2(Widget::CalcSize(3)))) + { + OPEN_LINK(PATREON_LINK); + } +} \ No newline at end of file diff --git a/src/pages/anniversary.h b/src/pages/anniversary.h new file mode 100644 index 0000000..489ef0d --- /dev/null +++ b/src/pages/anniversary.h @@ -0,0 +1,16 @@ +#pragma once +#include "interface/ipage.h" + +// The anniversary celebration page +class AnniversaryPage : public IPage +{ +private: + friend IPage; + AnniversaryPage() : IPage(ePageID::Anniversary, "Anniversary", false){} + AnniversaryPage(const AnniversaryPage&); + +public: + void Draw(); +}; + +extern AnniversaryPage& anniversaryPage; \ No newline at end of file diff --git a/src/pages/game.cpp b/src/pages/game.cpp index 9018c34..acc3cb9 100644 --- a/src/pages/game.cpp +++ b/src/pages/game.cpp @@ -38,7 +38,10 @@ static void RealTimeClock() CClock::ms_nGameClockSeconds = now->tm_sec; } -void Game::Init() +GamePage& gamePage = GamePage::Get(); + +GamePage::GamePage() + : IPage(ePageID::Game, "Window.GamePage", true) { #ifdef GTASA @@ -52,13 +55,13 @@ void Game::Init() }; #endif - Events::processScriptsEvent += [] + Events::processScriptsEvent += [this] { uint timer = CTimer::m_snTimeInMilliseconds; CPlayerPed* pPlayer = FindPlayerPed(); int hplayer = CPools::GetPedRef(pPlayer); - if (HardMode::m_bEnabled) + if (m_HardMode.m_bEnabled) { if (pPlayer->m_fHealth > 50.0f) { @@ -122,9 +125,9 @@ void Game::Init() if (Freecam.Toggle()) { // restore lock camera zoom here - if (Game::m_bLockCameraZoom) + if (m_bLockCameraZoom) { - TheCamera.LerpFOV(TheCamera.FindCamFOV(), Game::m_nCameraZoom, 250, true); + TheCamera.LerpFOV(TheCamera.FindCamFOV(), m_nCameraZoom, 250, true); } else { @@ -170,7 +173,7 @@ void SetPlayerMission(std::string& rootkey, std::string& name, std::string& id) } } -void Game::ShowPage() +void GamePage::Draw() { ImGui::Spacing(); CPlayerPed* pPlayer = FindPlayerPed(); @@ -269,32 +272,32 @@ void Game::ShowPage() { Command(m_bMissionTimer); } - if (Widget::Checkbox(TEXT("Game.HardMode"), &HardMode::m_bEnabled, TEXT("Game.HardModeText"))) + if (Widget::Checkbox(TEXT("Game.HardMode"), &m_HardMode.m_bEnabled, TEXT("Game.HardModeText"))) { CPlayerPed* player = FindPlayerPed(); - if (HardMode::m_bEnabled) + if (m_HardMode.m_bEnabled) { - HardMode::m_fBacArmour = player->m_fArmour; - HardMode::m_fBacHealth = player->m_fHealth; + m_HardMode.m_fBacArmour = player->m_fArmour; + m_HardMode.m_fBacHealth = player->m_fHealth; #ifdef GTASA - HardMode::m_fBacMaxHealth = CStats::GetStatValue(STAT_MAX_HEALTH); - HardMode::m_fBacStamina = CStats::GetStatValue(STAT_STAMINA); + m_HardMode.m_fBacMaxHealth = CStats::GetStatValue(STAT_MAX_HEALTH); + m_HardMode.m_fBacStamina = CStats::GetStatValue(STAT_STAMINA); #else - HardMode::m_fBacMaxHealth = 100.0f; + m_HardMode.m_fBacMaxHealth = 100.0f; #endif player->m_fHealth = 50.0f; } else { - player->m_fArmour = HardMode::m_fBacArmour; + player->m_fArmour = m_HardMode.m_fBacArmour; #ifdef GTASA - CStats::SetStatValue(STAT_STAMINA, HardMode::m_fBacStamina); - CStats::SetStatValue(STAT_MAX_HEALTH, HardMode::m_fBacMaxHealth); + CStats::SetStatValue(STAT_STAMINA, m_HardMode.m_fBacStamina); + CStats::SetStatValue(STAT_MAX_HEALTH, m_HardMode.m_fBacMaxHealth); #endif - player->m_fHealth = HardMode::m_fBacHealth; + player->m_fHealth = m_HardMode.m_fBacHealth; } } #ifdef GTASA @@ -611,9 +614,9 @@ void Game::ShowPage() if (Freecam.Toggle()) { // restore lock camera zoom here - if (Game::m_bLockCameraZoom) + if (m_bLockCameraZoom) { - TheCamera.LerpFOV(TheCamera.FindCamFOV(), Game::m_nCameraZoom, 250, true); + TheCamera.LerpFOV(TheCamera.FindCamFOV(), m_nCameraZoom, 250, true); } else { diff --git a/src/pages/game.h b/src/pages/game.h index 2b1bb9e..281c6f9 100644 --- a/src/pages/game.h +++ b/src/pages/game.h @@ -1,44 +1,47 @@ #pragma once #include "pch.h" +#include "interface/ipage.h" -class Game +class GamePage : public IPage { private: - static inline ResourceStore m_MissionData{ "missions", eResourceType::TYPE_TEXT }; - static inline bool m_bDisableCheats; - static inline bool m_bDisableReplay; - static inline bool m_bMissionTimer; - static inline bool m_bMobileRadio; + ResourceStore m_MissionData{ "missions", eResourceType::TYPE_TEXT }; + bool m_bDisableCheats; + bool m_bDisableReplay; + bool m_bMissionTimer; + bool m_bMobileRadio; - struct HardMode + struct { - static inline bool m_bEnabled; - static inline float m_fBacHealth = 0.0f; - static inline float m_fBacMaxHealth = 0.0f; - static inline float m_fBacArmour = 0.0f; - static inline float m_fBacStamina = 0.0f; - }; + bool m_bEnabled; + float m_fBacHealth; + float m_fBacMaxHealth; + float m_fBacArmour; + float m_fBacStamina; + } m_HardMode; #ifdef GTASA - static inline bool m_bForbiddenArea = true; // wanted level when going outside playable aea - static inline bool m_bSolidWater; // walk on water hack - static inline bool m_bNoWaterPhysics; - static inline bool m_bScreenShot; - static inline ResourceStore m_StatData{ "stats", eResourceType::TYPE_TEXT }; + bool m_bForbiddenArea = true; // Wanted level when going outside playable aea + bool m_bSolidWater; // Walk on water hack + bool m_bNoWaterPhysics; + bool m_bScreenShot; + ResourceStore m_StatData{ "stats", eResourceType::TYPE_TEXT }; #endif + friend IPage; + GamePage(); + GamePage(const GamePage&); + public: - static inline bool m_bFreezeTime; - static inline bool m_bSyncTime; + bool m_bFreezeTime; + bool m_bSyncTime; // Sync time with system #ifdef GTASA - static inline int m_nCameraZoom = 70.0f; - static inline bool m_bLockCameraZoom; + int m_nCameraZoom = 70.0f; + bool m_bLockCameraZoom; #endif - Game() = delete; - Game(const Game&) = delete; - - static void Init(); - static void ShowPage(); + void Draw(); }; + +extern GamePage& gamePage; \ No newline at end of file diff --git a/src/pages/menu.cpp b/src/pages/menu.cpp index b471182..58eab6d 100644 --- a/src/pages/menu.cpp +++ b/src/pages/menu.cpp @@ -7,7 +7,9 @@ #include "utils/rpc.h" #include "utils/overlay.h" -void Menu::Init() +MenuPage& menuPage = MenuPage::Get(); +MenuPage::MenuPage() +: IPage(ePageID::Menu, "Window.MenuPage", true) { m_bDiscordRPC = gConfig.Get("Menu.DiscordRPC", false); m_bAutoCheckUpdate = gConfig.Get("Menu.AutoCheckUpdate", true); @@ -19,7 +21,7 @@ void Menu::Init() } } -void Menu::ShowPage() +void MenuPage::Draw() { if (ImGui::BeginTabBar("Menu", ImGuiTabBarFlags_NoTooltip + ImGuiTabBarFlags_FittingPolicyScroll)) { @@ -49,7 +51,7 @@ void Menu::ShowPage() { Locale::SetDefaultLocale(); selected = Locale::GetCurrentLocaleIndex(); - CheatMenu::GenHeaderList(); + // CheatMenu::GenHeaderList(); } } @@ -72,7 +74,7 @@ void Menu::ShowPage() { if (Locale::SetLocale(selected) == Locale::eReturnCodes::SUCCESS) { - CheatMenu::GenHeaderList(); + // CheatMenu::GenHeaderList(); } else { @@ -306,7 +308,7 @@ void Menu::ShowPage() if (ImGui::Button(TEXT("Menu.Patreon"), ImVec2(Widget::CalcSize(2)))) { - OPEN_LINK("https://www.patreon.com/grinch_"); + OPEN_LINK(PATREON_LINK); } ImGui::Spacing(); diff --git a/src/pages/menu.h b/src/pages/menu.h index d7d8df9..1375186 100644 --- a/src/pages/menu.h +++ b/src/pages/menu.h @@ -1,23 +1,18 @@ #pragma once -#include "pch.h" +#include "interface/ipage.h" -/* - Menu Class - Handles code for the Menu page -*/ -class Menu +class MenuPage : public IPage { public: - static inline bool m_bAutoCheckUpdate; // Should updates be checked automatically - static inline bool m_bDiscordRPC; // Is the discord rich presence enabled - static inline bool m_bTextOnlyMode; // Hide all menu images mode - - Menu() = delete; - Menu(const Menu&) = delete; + bool m_bAutoCheckUpdate; // Should updates be checked automatically + bool m_bDiscordRPC; // Is the discord rich presence enabled + bool m_bTextOnlyMode; // Hide all menu images mode - // Inits the class - static void Init(); + friend IPage; + MenuPage(); + MenuPage(const MenuPage&); - // Displays the menu page - static void ShowPage(); + void Draw(); }; + +extern MenuPage& menuPage; diff --git a/src/pages/scene.cpp b/src/pages/scene.cpp index 5356a4f..5107399 100644 --- a/src/pages/scene.cpp +++ b/src/pages/scene.cpp @@ -10,6 +10,8 @@ #include "custom/particle_sa.h" #endif +ScenePage& scenePage = ScenePage::Get(); + void ScenePage::Draw() { if (ImGui::BeginTabBar("Animation", ImGuiTabBarFlags_NoTooltip + ImGuiTabBarFlags_FittingPolicyScroll)) diff --git a/src/pages/scene.h b/src/pages/scene.h index 9718ebe..a812483 100644 --- a/src/pages/scene.h +++ b/src/pages/scene.h @@ -1,14 +1,19 @@ #pragma once -#include "pch.h" +#include "interface/ipage.h" /* - Scene Player class + ScenePage Class + Contains animations, cutscenes, particles, tasks etc */ -class ScenePage +class ScenePage : public IPage { -public: - ScenePage() = delete; - ScenePage(const ScenePage&) = delete; +private: + friend IPage; + ScenePage() : IPage(ePageID::Scene, "Window.ScenePage", true){} + ScenePage(const ScenePage&); - static void Draw(); -}; \ No newline at end of file +public: + void Draw(); +}; + +extern ScenePage& scenePage; \ No newline at end of file diff --git a/src/pages/teleport.cpp b/src/pages/teleport.cpp index 9e27538..25ea20e 100644 --- a/src/pages/teleport.cpp +++ b/src/pages/teleport.cpp @@ -9,7 +9,7 @@ tRadarTrace* ms_RadarTrace = reinterpret_cast(patch::GetPointer(0x5838B0 + 2)); static int maxSprites = *(uint*)0x5D5870; -void Teleport::FetchRadarSpriteData() +void TeleportPage::FetchRadarSpriteData() { uint timer = CTimer::m_snTimeInMilliseconds; @@ -35,21 +35,22 @@ void Teleport::FetchRadarSpriteData() } #endif -bool Teleport::IsQuickTeleportActive() +bool TeleportPage::IsQuickTeleportActive() { return m_bQuickTeleport; } +TeleportPage& teleportPage = TeleportPage::Get(); - -void Teleport::Init() +TeleportPage::TeleportPage() +: IPage(ePageID::Teleport, "Window.TeleportPage", true) { m_bTeleportMarker = gConfig.Get("Features.TeleportMarker", false); m_bQuickTeleport = gConfig.Get("Features.QuickTeleport", false); m_fMapSize.x = gConfig.Get("Game.MapSizeX", 6000.0f); m_fMapSize.y = gConfig.Get("Game.MapSizeY", 6000.0f); - Events::drawingEvent += [] + Events::drawingEvent += [this] { if (m_bTeleportMarker && teleportMarker.Pressed()) { @@ -119,7 +120,7 @@ void Teleport::Init() #ifdef GTASA template -void Teleport::WarpPlayer(CVector pos, int interiorID) +void TeleportPage::WarpPlayer(CVector pos, int interiorID) { CPlayerPed* pPlayer = FindPlayerPed(); CVehicle* pVeh = pPlayer->m_pVehicle; @@ -192,7 +193,7 @@ void Teleport::WarpPlayer(CVector pos, int interiorID) } #else template -void Teleport::WarpPlayer(CVector pos, int interiorID) +void TeleportPage::WarpPlayer(CVector pos, int interiorID) { CPlayerPed* pPlayer = FindPlayerPed(); CVehicle* pVeh = pPlayer->m_pVehicle; @@ -224,9 +225,41 @@ void Teleport::WarpPlayer(CVector pos, int interiorID) } #endif -void Teleport::ShowPage() +void TeleportPage::LocationAddNew() +{ + ImGui::InputTextWithHint(TEXT("Teleport.Location"), TEXT("Teleport.LocationHint"), m_LocBuf, INPUT_BUFFER_SIZE); + ImGui::InputTextWithHint(TEXT("Teleport.Coordinates"), "x, y, z", m_InBuf, INPUT_BUFFER_SIZE); + ImGui::Spacing(); + if (ImGui::Button(TEXT("Window.AddEntry"), Widget::CalcSize())) + { + std::string key = std::string("Custom.") + m_LocBuf; + m_locData.m_pData->Set(key.c_str(), ("0, " + std::string(m_InBuf))); +#ifdef GTASA + // Clear the Radar coordinates + m_locData.m_pData->RemoveTable("Radar"); +#endif + + m_locData.m_pData->Save(); + Util::SetMessage(TEXT("Window.AddEntryMSG")); + } +} + +void TeleportPage::LocationClick(str& unk1, str& unk2, str& loc) +{ + int dim = 0; + CVector pos; + if (sscanf(loc.c_str(), "%d,%f,%f,%f", &dim, &pos.x, &pos.y, &pos.z) == 4) + { + WarpPlayer(pos, dim); + } + else + { + Util::SetMessage(TEXT("Teleport.InvalidLocation")); + } +} + +void TeleportPage::Draw() { - static char locBuf[INPUT_BUFFER_SIZE], inBuf[INPUT_BUFFER_SIZE]; if (ImGui::BeginTabBar("Teleport", ImGuiTabBarFlags_NoTooltip + ImGuiTabBarFlags_FittingPolicyScroll)) { ImGui::Spacing(); @@ -264,19 +297,19 @@ void Teleport::ShowPage() { CVector pos = FindPlayerPed()->GetPosition(); - strcpy(inBuf, + strcpy(m_InBuf, (std::to_string(static_cast(pos.x)) + ", " + std::to_string(static_cast(pos.y)) + ", " + std::to_string(static_cast(pos.z))).c_str()); } - ImGui::InputTextWithHint(TEXT("Teleport.Coordinates"), "x, y, z", inBuf, INPUT_BUFFER_SIZE); + ImGui::InputTextWithHint(TEXT("Teleport.Coordinates"), "x, y, z", m_InBuf, INPUT_BUFFER_SIZE); ImGui::Spacing(); if (ImGui::Button(TEXT("Teleport.TeleportToCoord"), Widget::CalcSize(2))) { CVector pos{0, 0, 10}; - if (sscanf(inBuf,"%f,%f,%f", &pos.x, &pos.y, &pos.z) == 3) + if (sscanf(m_InBuf,"%f,%f,%f", &pos.x, &pos.y, &pos.z) == 3) { pos.z += 1.0f; WarpPlayer(pos); @@ -336,36 +369,8 @@ void Teleport::ShowPage() FetchRadarSpriteData(); #endif ImGui::Spacing(); - Widget::DataList(m_locData, - [](std::string& unk1, std::string& unk2, std::string& loc){ - int dim = 0; - CVector pos; - if (sscanf(loc.c_str(), "%d,%f,%f,%f", &dim, &pos.x, &pos.y, &pos.z) == 4) - { - WarpPlayer(pos, dim); - } - else - { - Util::SetMessage(TEXT("Teleport.InvalidLocation")); - } - }, - [](){ - ImGui::InputTextWithHint(TEXT("Teleport.Location"), TEXT("Teleport.LocationHint"), locBuf, INPUT_BUFFER_SIZE); - ImGui::InputTextWithHint(TEXT("Teleport.Coordinates"), "x, y, z", inBuf, INPUT_BUFFER_SIZE); - ImGui::Spacing(); - if (ImGui::Button(TEXT("Window.AddEntry"), Widget::CalcSize())) - { - std::string key = std::string("Custom.") + locBuf; - m_locData.m_pData->Set(key.c_str(), ("0, " + std::string(inBuf))); -#ifdef GTASA - // Clear the Radar coordinates - m_locData.m_pData->RemoveTable("Radar"); -#endif - - m_locData.m_pData->Save(); - Util::SetMessage(TEXT("Window.AddEntryMSG")); - } - }); + Widget::DataList(m_locData, fArg3Wrapper(teleportPage.LocationClick), + fArgNoneWrapper(teleportPage.LocationAddNew)); ImGui::EndTabItem(); } ImGui::EndTabBar(); diff --git a/src/pages/teleport.h b/src/pages/teleport.h index dc2c6d2..8e49d44 100644 --- a/src/pages/teleport.h +++ b/src/pages/teleport.h @@ -1,5 +1,6 @@ #pragma once #include "pch.h" +#include "interface/ipage.h" enum class eTeleportType { @@ -8,43 +9,44 @@ enum class eTeleportType Coordinate, }; -/* - Teleport Class - Contains code for the Teleport menu page -*/ -class Teleport +class TeleportPage : public IPage { private: - static inline bool m_bInsertCoord; - static inline bool m_bTeleportMarker; - static inline bool m_bQuickTeleport; - static inline ImVec2 m_fMapSize; + char m_LocBuf[INPUT_BUFFER_SIZE], m_InBuf[INPUT_BUFFER_SIZE]; + bool m_bInsertCoord; + bool m_bTeleportMarker; + bool m_bQuickTeleport; + ImVec2 m_fMapSize; #ifdef GTASA - static inline DataStore m_SpriteData {"sprites"}; + + DataStore m_SpriteData {"sprites"}; /* Generates radar sprite coordinates on the fly. Shouldn't get saved in 'teleport.json', needs to be cleared at game shutdown. */ - static void FetchRadarSpriteData(); + void FetchRadarSpriteData(); #endif public: - static inline ResourceStore m_locData{"locations", eResourceType::TYPE_TEXT}; + ResourceStore m_locData{"locations", eResourceType::TYPE_TEXT}; - Teleport() = delete; - Teleport(const Teleport&) = delete; + friend IPage; + TeleportPage(); + TeleportPage(const TeleportPage&); - // Initialized the class, hooks etc. - static void Init(); + void Draw(); + + // Returns true if quick teleport feature is active + bool IsQuickTeleportActive(); + + // Callbacks + void LocationAddNew(); + void LocationClick(str&, str&, str&); // Warp player to position, marker, map etc template - static void WarpPlayer(CVector pos = CVector(0, 0, 0), int interiorID = 0); - - // Returns true if quick teleport feature is active - static bool IsQuickTeleportActive(); - - // Draws the teleport menu page - static void ShowPage(); + void WarpPlayer(CVector pos = CVector(0, 0, 0), int interiorID = 0); }; + +extern TeleportPage& teleportPage; diff --git a/src/pages/update.cpp b/src/pages/update.cpp new file mode 100644 index 0000000..2accddc --- /dev/null +++ b/src/pages/update.cpp @@ -0,0 +1,32 @@ +#include "pch.h" +#include "update.h" +#include "utils/widget.h" +#include "utils/updater.h" + +UpdatePage& updatePage = UpdatePage::Get(); + +void UpdatePage::Draw() +{ + std::string ver = Updater::GetUpdateVersion(); + ImGui::Dummy(ImVec2(0, 20)); + Widget::TextCentered(TEXT("Menu.NewVersion")); + Widget::TextCentered(std::format("{}: {}", TEXT("Menu.CurrentVersion"), MENU_VERSION)); + Widget::TextCentered(TEXT("Menu.LatestVersion") + ver); + ImGui::Dummy(ImVec2(0, 10)); + ImGui::TextWrapped(TEXT("Menu.UpdaterInfo1")); + ImGui::Dummy(ImVec2(0, 10)); + ImGui::TextWrapped(TEXT("Menu.UpdaterInfo2")); + + ImGui::Dummy(ImVec2(0, 5)); + if (ImGui::Button(TEXT("Menu.DiscordServer"), ImVec2(Widget::CalcSize(2)))) + { + OPEN_LINK(DISCORD_INVITE); + } + + ImGui::SameLine(); + + if (ImGui::Button(TEXT("Menu.DownloadPage"), Widget::CalcSize(2))) + { + OPEN_LINK(std::string("https://github.com/user-grinch/Cheat-Menu/releases/tag/" + ver).c_str()); + } +} \ No newline at end of file diff --git a/src/pages/update.h b/src/pages/update.h new file mode 100644 index 0000000..3126dd7 --- /dev/null +++ b/src/pages/update.h @@ -0,0 +1,16 @@ +#pragma once +#include "interface/ipage.h" + +// This page shows up when an update is found +class UpdatePage : public IPage +{ +private: + friend IPage; + UpdatePage() : IPage(ePageID::Update, "Update", false){} + UpdatePage(const UpdatePage&); + +public: + void Draw(); +}; + +extern UpdatePage& updatePage; \ No newline at end of file diff --git a/src/pages/vehicle.cpp b/src/pages/vehicle.cpp index 4a449ae..721160c 100644 --- a/src/pages/vehicle.cpp +++ b/src/pages/vehicle.cpp @@ -1238,7 +1238,7 @@ void Vehicle::ShowPage() if (ImGui::BeginTabItem(TEXT("Teleport.Location"))) { ImGui::Spacing(); - Widget::DataList(Teleport::m_locData, + Widget::DataList(teleportPage.m_locData, [](std::string& rootkey, std::string& bLocName, std::string& loc) { CVehicle* pVeh = BY_GAME(FindPlayerVehicle(-1, false), FindPlayerVehicle(), FindPlayerVehicle()); diff --git a/src/pages/visual.cpp b/src/pages/visual.cpp index aa0d540..22fca49 100644 --- a/src/pages/visual.cpp +++ b/src/pages/visual.cpp @@ -979,34 +979,34 @@ void Visual::ShowPage() int hour = CClock::ms_nGameClockHours; int minute = CClock::ms_nGameClockMinutes; - if (Game::m_bSyncTime) + if (gamePage.m_bSyncTime) { - ImGui::BeginDisabled(Game::m_bSyncTime); + ImGui::BeginDisabled(gamePage.m_bSyncTime); } - if (ImGui::InputInt(TEXT("Visual.Hour"), &hour) & !Game::m_bSyncTime) + if (ImGui::InputInt(TEXT("Visual.Hour"), &hour) & !gamePage.m_bSyncTime) { if (hour < 0) hour = 23; if (hour > 23) hour = 0; CClock::ms_nGameClockHours = hour; } - if (ImGui::InputInt(TEXT("Visual.Minute"), &minute) & !Game::m_bSyncTime) + if (ImGui::InputInt(TEXT("Visual.Minute"), &minute) & !gamePage.m_bSyncTime) { if (minute < 0) minute = 59; if (minute > 59) minute = 0; CClock::ms_nGameClockMinutes = minute; } - if (Game::m_bSyncTime) + if (gamePage.m_bSyncTime) { ImGui::EndDisabled(); Widget::Tooltip(TEXT("Visual.SyncTimeEnabled")); } - if (ImGui::Checkbox(TEXT("Visual.FreezeGameTime"), &Game::m_bFreezeTime)) + if (ImGui::Checkbox(TEXT("Visual.FreezeGameTime"), &gamePage.m_bFreezeTime)) { - if (Game::m_bFreezeTime) + if (gamePage.m_bFreezeTime) { patch::SetRaw(BY_GAME(0x52CF10, 0x487010, 0x473460), (char *)"\xEB\xEF", 2); } diff --git a/src/pages/welcome.cpp b/src/pages/welcome.cpp new file mode 100644 index 0000000..a46785a --- /dev/null +++ b/src/pages/welcome.cpp @@ -0,0 +1,35 @@ +#include "pch.h" +#include "welcome.h" +#include "utils/widget.h" + +WelcomePage& welcomePage = WelcomePage::Get(); + +void WelcomePage::Draw() +{ + ImGui::NewLine(); + + Widget::TextCentered(TEXT("Menu.WelcomeMSG")); + Widget::TextCentered(std::format("{}: Grinch_",TEXT("Menu.Author"))); + + ImGui::NewLine(); + ImGui::TextWrapped(TEXT("Menu.EnsureLatest")); + if (ImGui::Button(TEXT("Menu.DiscordServer"), ImVec2(Widget::CalcSize(3)))) + { + OPEN_LINK(DISCORD_INVITE); + } + ImGui::SameLine(); + if (ImGui::Button(TEXT("Menu.GitHubRepo"), ImVec2(Widget::CalcSize(3)))) + { + OPEN_LINK(GITHUB_LINK); + } + ImGui::SameLine(); + if (ImGui::Button(TEXT("Menu.Patreon"), ImVec2(Widget::CalcSize(3)))) + { + OPEN_LINK(PATREON_LINK); + } + ImGui::NewLine(); + ImGui::TextWrapped(TEXT("Menu.BugDisclaimer")); + ImGui::Dummy(ImVec2(0, 20)); + Widget::TextCentered(TEXT("Menu.PatreonText")); + Widget::TextCentered(TEXT("Menu.CopyrightDisclaimer")); +} \ No newline at end of file diff --git a/src/pages/welcome.h b/src/pages/welcome.h new file mode 100644 index 0000000..c7d61c0 --- /dev/null +++ b/src/pages/welcome.h @@ -0,0 +1,19 @@ +#pragma once +#include "interface/ipage.h" + +// The default page for new install +class WelcomePage : public IPage +{ +private: + friend IPage; + WelcomePage() : IPage(ePageID::Welcome, "Welcome", false) + { + PageHandler::SetCurrentPage(this); + } + WelcomePage(const WelcomePage&); + +public: + void Draw(); +}; + +extern WelcomePage& welcomePage; \ No newline at end of file diff --git a/src/utils/fontmgr.cpp b/src/utils/fontmgr.cpp index 6586d36..cd39eac 100644 --- a/src/utils/fontmgr.cpp +++ b/src/utils/fontmgr.cpp @@ -71,7 +71,7 @@ void FontMgr::ReloadAll() m_bFontReloadRequired = false; } -void FontMgr::Process() +void FontMgr::DrawPages() { if (curState == eStates::Idle) { diff --git a/src/utils/fontmgr.h b/src/utils/fontmgr.h index fd873c4..fa1fa64 100644 --- a/src/utils/fontmgr.h +++ b/src/utils/fontmgr.h @@ -45,7 +45,7 @@ public: static ImFont* Load(const char* fontID, const char* path = 0, float fontMul = 1.0f); // Handles font downloading - static void Process(); + static void DrawPages(); // Reloads all the fonts static void ReloadAll(); diff --git a/src/utils/overlay.cpp b/src/utils/overlay.cpp index bfcb3c0..5633e03 100644 --- a/src/utils/overlay.cpp +++ b/src/utils/overlay.cpp @@ -310,7 +310,7 @@ void Overlay::ProcessCommands(std::string&& str) ss >> temp; pos.z = std::stof(temp); - Teleport::WarpPlayer(pos); + teleportPage.WarpPlayer(pos); } catch (...) { diff --git a/src/utils/rpc.cpp b/src/utils/rpc.cpp index 24e3173..12e2bf7 100644 --- a/src/utils/rpc.cpp +++ b/src/utils/rpc.cpp @@ -66,9 +66,9 @@ void RPC::Init() } } -void RPC::Process() +void RPC::DrawPages() { - if (!(Menu::m_bDiscordRPC && bInit)) + if (!(menuPage.m_bDiscordRPC && bInit)) { return; } diff --git a/src/utils/rpc.h b/src/utils/rpc.h index d85ad75..ffb65fb 100644 --- a/src/utils/rpc.h +++ b/src/utils/rpc.h @@ -36,6 +36,6 @@ public: RPC(RPC&) = delete; static void Init(); - static void Process(); + static void DrawPages(); static void Shutdown(); }; \ No newline at end of file diff --git a/src/utils/updater.cpp b/src/utils/updater.cpp index ba7af7a..e307f76 100644 --- a/src/utils/updater.cpp +++ b/src/utils/updater.cpp @@ -24,7 +24,7 @@ void Updater::CheckUpdate() } } -void Updater::Process() +void Updater::DrawPages() { if (Updater::curState != States::CHECKING) { diff --git a/src/utils/updater.h b/src/utils/updater.h index 71e4514..1613534 100644 --- a/src/utils/updater.h +++ b/src/utils/updater.h @@ -32,7 +32,7 @@ public: static bool IsUpdateAvailable(); // Needs to run in it's own thread to prevent the game from freezing - static void Process(); + static void DrawPages(); // Resets updater state to IDLE static void ResetUpdaterState(); diff --git a/src/utils/widget.cpp b/src/utils/widget.cpp index deb1211..c21825c 100644 --- a/src/utils/widget.cpp +++ b/src/utils/widget.cpp @@ -323,7 +323,7 @@ void Widget::ImageList(ResourceStore &store, fArg1_t clickFunc, fRtnArg1_t getNa m_ImageSize.x = ImGui::GetWindowContentRegionWidth() - style.ItemSpacing.x * (imagesInRow-1); m_ImageSize.x /= imagesInRow; - bool showImages = !Menu::m_bTextOnlyMode; + bool showImages = !menuPage.m_bTextOnlyMode; if (gRenderer == Render_DirectX11) { showImages = false;