39#include <imgui_internal.h>
121 ImGuiWindowFlags win_flags = ImGuiWindowFlags_NoCollapse;
122 ImGui::SetNextWindowPosCenter(ImGuiCond_FirstUseEver);
123 ImGui::SetNextWindowSize(ImVec2((ImGui::GetIO().DisplaySize.x / 1.4), (ImGui::GetIO().DisplaySize.y / 1.2)), ImGuiCond_FirstUseEver);
124 bool keep_open =
true;
125 if (!ImGui::Begin(
_LC(
"MainSelector",
"Loader"), &keep_open, win_flags))
136 if (ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_RightArrow)))
144 else if (ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_LeftArrow)))
165 ImGui::PopItemWidth();
169 const ImVec2 searchbox_cursor = ImGui::GetCursorPos();
170 const float searchbox_width = ImGui::GetWindowWidth() -
171 (
LEFT_PANE_WIDTH * ImGui::GetFontSize() + 2 * (ImGui::GetStyle().WindowPadding.x) + ImGui::GetStyle().ItemSpacing.x);
175 ImGui::SetKeyboardFocusHere();
179 if (!
m_searchbox_was_active && (ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_Tab)) || ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_Slash))))
181 ImGui::SetKeyboardFocusHere();
183 ImGui::PushItemWidth(searchbox_width);
195 ImGui::PopItemWidth();
197 const ImVec2 separator_cursor = ImGui::GetCursorPos()
198 + ImVec2(0, ImGui::GetStyle().WindowPadding.y - ImGui::GetStyle().ItemSpacing.y);
212 ImGui::SetItemAllowOverlap();
213 ImVec2 p_min = ImGui::GetItemRectMin();
214 ImVec2 p_max = ImGui::GetItemRectMax();
215 ImGui::SetCursorScreenPos(ImVec2(
216 p_max.x - ImGui::GetFontSize() - ImGui::GetStyle().FramePadding.x,
217 p_min.y + ImGui::GetStyle().FramePadding.y - 3.0f));
220 if (ImGui::ImageButton(
reinterpret_cast<ImTextureID
>(
m_settings_icon->getHandle()), ImVec2(ImGui::GetFontSize(), ImGui::GetFontSize())))
222 ImGui::OpenPopup(
"##SelectorSearchSettings");
226 ImGui::SetNextWindowPos(ImGui::GetItemRectMin(), ImGuiCond_Always);
227 if (ImGui::BeginPopup(
"##SelectorSearchSettings", ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoMove))
229 ImGui::TextDisabled(
"Search settings:");
232 ImGui::TextDisabled(
"Fulltext search:");
233 ImGui::Text(
"~ partial name, filename, description, author name or e-mail");
234 ImGui::TextDisabled(
"Advanced search:");
235 ImGui::Text(
"guid: ~ partial GUID");
236 ImGui::Text(
"author: ~ partial author name or e-mail");
237 ImGui::Text(
"wheels: ~ wheel configuration (i.e. 4x4)");
238 ImGui::Text(
"file: ~ partial file name");
242 ImGui::SetCursorPos(separator_cursor);
246 ImGui::BeginChild(
"left pane", ImVec2(
LEFT_PANE_WIDTH * ImGui::GetFontSize(), 0),
true);
248 bool scroll_to_selected =
false;
252 if (ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_DownArrow)))
256 scroll_to_selected =
true;
258 else if (ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_UpArrow)))
262 scroll_to_selected =
true;
266 ImDrawList* drawlist = ImGui::GetWindowDrawList();
267 drawlist->ChannelsSplit(2);
268 bool do_apply =
false;
269 for (
int i = 0; i < num_entries; ++i)
275 drawlist->ChannelsSetCurrent(1);
277 ImGui::GetStyle().Colors[ImGuiCol_Text],
282 drawlist->ChannelsSetCurrent(0);
284 if (ImGui::Selectable(
"##dummy", &is_selected, 0, mouse_area))
290 if (ImGui::IsItemHovered() && ImGui::IsMouseDoubleClicked(0))
297 if (is_selected && scroll_to_selected)
299 ImGui::SetScrollHere();
308 drawlist->ChannelsMerge();
315 ImGui::BeginChild(
"item view", ImVec2(0, -ImGui::GetItemsLineHeightWithSpacing()));
324 ImVec2 cursor_pos = ImGui::GetCursorPos();
327 Ogre::TexturePtr preview_tex =
328 Ogre::TextureManager::getSingleton().load(
334 ImVec2 size(preview_tex->getWidth(), preview_tex->getHeight());
337 size *= max_size.x / size.x;
338 if (size.y > max_size.y)
340 size *= max_size.y / size.y;
344 ImGui::SetCursorPos((cursor_pos + ImGui::GetWindowSize()) - size);
345 ImGui::Image(
reinterpret_cast<ImTextureID
>(preview_tex->getHandle()), size);
346 ImGui::SetCursorPos(cursor_pos);
363 ImGui::TextDisabled(
"%s",
_LC(
"MainSelector",
"Author(s): "));
365 ImGui::TextColored(theme.
value_blue_text_color,
"%s [%s]", author.name.c_str(), author.type.c_str());
370 ImGui::Text(
"%s",
_LC(
"MainSelector",
"Wheels: "));
376 ImGui::Text(
"%s",
_LC(
"MainSelector",
"Mass: "));
385 ImGui::Text(
"%s",
_LC(
"MainSelector",
"Load Mass: "));
403 ImGui::Text(
"%s",
_LC(
"MainSelector",
"Using Submeshs: "));
409 ImGui::Text(
"%s",
_LC(
"MainSelector",
"Default skin: "));
417 ImGui::Text(
"%s",
_LC(
"MainSelector",
"Engine RPM: "));
443 ImGui::Text(
"%s",
_LC(
"MainSelector",
"Source: "));
450 ImGui::Text(
"%s",
_LC(
"MainSelector",
"Filename: "));
460 ImGui::BeginChild(
"buttons");
466 ImGui::PushItemWidth(ImGui::GetWindowWidth() / 2);
472 ImGui::SameLine(ImGui::GetWindowWidth() - ImGui::GetFontSize() * 17.5f);
473 if (ImGui::Button(
_LC(
"MainSelector",
"OK"), ImVec2(ImGui::GetFontSize() * 7.5f, 0.0f)) ||
474 ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_Enter)))
479 ImGui::SameLine(ImGui::GetWindowWidth() - ImGui::GetFontSize() * 9.375f);
480 if (ImGui::Button(
_LC(
"MainSelector",
"Cancel"), ImVec2(ImGui::GetFontSize() * 7.5f, 0.0f)) || ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_Escape)))
488 m_is_hovered = ImGui::IsWindowHovered(ImGuiHoveredFlags_RootAndChildWindows);
497template <
typename T1,
typename T2>
500 bool operator ()(std::pair<int, Ogre::String>
const& a, std::pair<int, Ogre::String>
const& b)
const
510 return a.second < b.second;
552 std::vector<std::pair<int, Ogre::String>> sorted_cats(cats.begin(), cats.end());
556 for (
auto itor: sorted_cats)
570 if (input.find(
":") == std::string::npos)
577 Ogre::StringVector v = Ogre::StringUtil::split(input,
":");
583 else if (v[0] ==
"guid")
588 else if (v[0] ==
"author")
593 else if (v[0] ==
"wheels")
598 else if (v[0] ==
"file")
624 ImGui::Text(
"%s", title);
626 ImGui::TextColored(
App::GetGuiManager()->GetTheme().value_blue_text_color,
"%d", val);
634 ImGui::Text(
"%s", title);
636 ImGui::TextColored(
App::GetGuiManager()->GetTheme().value_blue_text_color,
"%f", val);
644 ImGui::TextColored(
App::GetGuiManager()->GetTheme().value_red_text_color,
"%s", label);
652 ImGui::Text(
"%s", desc);
654 ImGui::TextColored(
App::GetGuiManager()->GetTheme().value_blue_text_color,
"%s", str.c_str());
717 LOG(fmt::format(
"[RoR|GameSettings] INTERNAL ERROR - Unrecognized dashboard type being selected ({})!",
727 std::string sectionconfig;
743 *out_text = dc_vec->at(idx).sdc_title.ToCStr();
764 : sdc_category_id(id)
766 sdc_title <<
"(" << usage <<
") " <<
_LC(
"ModCategory", name.c_str());
Central state/object manager and communications hub.
#define ROR_ASSERT(_EXPR)
void LOG(const char *msg)
Legacy alias - formerly a macro.
A database of user-installed content alias 'mods' (vehicles, terrains...)
Game state manager and message-queue provider.
void setStr(std::string const &str)
std::vector< Ogre::String > sectionconfigs
Ogre::String fname
filename
int version
file's version
Ogre::String dname
name parsed from the file
std::vector< AuthorInfo > authors
authors
std::time_t addtimestamp
timestamp when this file was added to the cache
int usagecounter
how much it was used already
std::string resource_bundle_type
Archive type recognized by OGRE resource system: 'FileSystem' or 'Zip'.
std::string resource_bundle_path
Path of ZIP or directory which contains the media. Shared between CacheEntries, loaded only once.
Ogre::String filecachename
preview image filename
std::time_t filetime
filetime
Ogre::String uniqueid
file's unique id
Ogre::String guid
global unique id; Type "addonpart" leaves this empty and uses addonpart_guids; Always lowercase.
const CategoryIdNameMap & GetCategories() const
std::string ActorTypeToName(ActorType driveable)
size_t Query(CacheQuery &query)
std::map< int, Ogre::String > CategoryIdNameMap
void AddResourcePack(ResourcePack const &resource_pack, std::string const &override_rgn="")
Loads resources if not already loaded.
CacheCategoryId default_dash_being_selected
std::map< LoaderType, int > m_last_selected_category
Last category-combobox position for each loader type.
std::string m_filter_guid
Used for skins.
int m_selected_sectionconfig
std::map< LoaderType, std::string > m_kept_searchstring
Stays empty if 'ui_keep_search' is false.
const float PREVIEW_SIZE_RATIO
std::map< LoaderType, int > m_last_selected_entry
Stores the last manually selected entry index for each loader type.
static bool CatComboItemGetter(void *data, int idx, const char **out_text)
CacheEntryPtr m_advertised_entry
Always shown on top, even if not existing in modcache (i.e. dummy default skin)
const float LEFT_PANE_WIDTH
Relative to font size.
void UpdateDisplayLists()
DisplayEntryVec m_display_entries
CacheSearchMethod m_search_method
int m_selected_cid
Category ID.
bool m_searchbox_was_active
DisplayCategoryVec m_display_categories
void DrawAttrInt(const char *desc, int val) const
void DrawAttrStr(const char *desc, std::string const &str) const
void DrawAttrFloat(const char *desc, float val) const
std::map< LoaderType, int > m_last_selected_cid
Last selected category-ID for each loader type.
Str< 500 > m_search_input
static bool ScComboItemGetter(void *data, int idx, const char **out_text)
void UpdateSearchParams()
void DrawAttrSpecial(bool val, const char *label) const
void Show(LoaderType type, std::string const &filter_guid="", CacheEntryPtr advertised_entry=nullptr)
int m_selected_category
Combobox position (uses display list)
Ogre::TexturePtr m_settings_icon
std::string m_search_string
std::vector< DisplayCategory > DisplayCategoryVec
GUI::GameSettings GameSettings
void RequestGuiCaptureKeyboard(bool val)
Pass true during frame to prevent input passing to application.
GUI::GameMainMenu GameMainMenu
void OnLoaderGuiApply(RoR::LoaderType type, CacheEntryPtr entry, std::string sectionconfig)
GUI callback.
void PushMessage(Message m)
Doesn't guarantee order! Use ChainMessage() if order matters.
void OnLoaderGuiCancel()
GUI callback.
const char * ToCStr() const
size_t GetCapacity() const
@ MSG_NET_DISCONNECT_REQUESTED
@ MSG_APP_LOAD_SCRIPT_REQUESTED
Payload = RoR::LoadScriptRequest* (owner)
@ MSG_SIM_LOAD_TERRN_REQUESTED
@ GADGET
Associated with a .gadget mod file, launched via UI or any method given below for CUSTOM scripts (use...
ContentManager * GetContentManager()
GUIManager * GetGuiManager()
GameContext * GetGameContext()
CVar * ui_default_boat_dash
string; name of the '.dashboard' file in modcache.
CVar * ui_default_truck_dash
string; name of the '.dashboard' file in modcache.
CacheSystem * GetCacheSystem()
LoaderType
< Search mode for ModCache::Query() & Operation mode for GUI::MainSelector
ImVec2 DrawColorMarkedText(ImDrawList *drawlist, ImVec2 text_cursor, ImVec4 default_color, float override_alpha, float wrap_width, std::string const &line)
Draw multiline text with '#rrggbb' color markers. Returns total text size.
@ AUTHORS
Partial match in: author name/email.
@ FILENAME
Partial match in file name.
@ WHEELS
Wheel configuration, i.e. 4x4.
@ GUID
Partial match in: guid.
@ NONE
Ignore the search string and find all.
@ FULLTEXT
Partial match in: name, filename, description, author name/mail.
void ImTextWrappedColorMarked(std::string const &text)
Prints multiline text with '#rrggbb' color markers. Behaves like ImGui::Text* functions.
bool DrawGCheckbox(CVar *cvar, const char *label)
Ogre::Real Round(Ogre::Real value, unsigned short ndigits=0)
int cqy_filter_category_id
std::string cqy_filter_guid
Exact match (case-insensitive); leave empty to disable.
std::map< int, size_t > cqy_res_category_usage
Total usage (ignores search params + category filter)
std::string cqy_search_string
CacheSearchMethod cqy_search_method
std::vector< CacheQueryResult > cqy_results
RoR::LoaderType cqy_filter_type
static const ResourcePack FAMICONS
DisplayCategory(int id, std::string const &name, size_t usage)
Str< 50 > sde_addtime_str
Str< 50 > sde_filetime_str
DisplayEntry(CacheEntryPtr entry)
Str< 50 > sde_driveable_str
ImVec4 value_blue_text_color
Unified game event system - all requests and state changes are reported using a message.