Select screen with a centered preview and a portrait taskbar
This commit is contained in:
1 parent
e0e43d9285
commit
ee13be56d7
8 files changed
+168
-161
No files matched your search
+1
-1
@@ -32,7 +32,7 @@ There's two folders inside resources; "characters" and "font".
|
||||
|
||||
"font" holds the one font the whole game uses (Mali, under the SIL Open Font License; see its LICENSE.txt).
|
||||
|
||||
"common" holds files characters share (sounds, particles, the cursor and so on). Whenever a character names a file, the game looks in the character's folder first, then in "common", so a character can use anything there as is, or replace it by having its own file at the same path. This includes the taskbar's icons, `gfx/ui/icons.anm2`: one region per icon, named after its button (`talk`, `mood`, `spawn`, `autofeed`, `home`, `stats`, `catalog`, `settings`, `cheats`, `help`, plus whatever `icon`s the interaction types name). A character with its own `gfx/ui/icons.anm2` gets its own icons.
|
||||
"common" holds files characters share (sounds, particles, the cursor and so on). Whenever a character names a file, the game looks in the character's folder first, then in "common", so a character can use anything there as is, or replace it by having its own file at the same path. This includes the taskbar's icons, `gfx/ui/icons.anm2`: one region per icon, named after its button (`talk`, `mood`, `spawn`, `autofeed`, `home`, `stats`, `catalog`, `settings`, `cheats`, `help`, `credits`, plus whatever `icon`s the interaction types name). A character with its own `gfx/ui/icons.anm2` gets its own icons.
|
||||
|
||||
EVERYTHING ELSE is stored inside character folders in the "characters" folder; one folder per character, named however you like (the folder name is also the name of its save file). This has all data associated with characters. Think of characters more as tailored game experiences rather than literally being just the characters. Not only is there the character graphics, but backgrounds, items, parameters, etc. These are intensely customizable to suit whatever experience you'd like (within the confines of the engine, of course).
|
||||
|
||||
|
||||
@@ -18,7 +18,8 @@
|
||||
{"name": "settings", "crop": [195, 65], "size": [64, 64], "origin": "center"},
|
||||
{"name": "help", "crop": [260, 65], "size": [64, 64], "origin": "center"},
|
||||
{"name": "close", "crop": [325, 65], "size": [64, 64], "origin": "center"},
|
||||
{"name": "cheats", "crop": [390, 65], "size": [64, 64], "origin": "center"}
|
||||
{"name": "cheats", "crop": [390, 65], "size": [64, 64], "origin": "center"},
|
||||
{"name": "credits", "crop": [455, 65], "size": [64, 64], "origin": "center"}
|
||||
]
|
||||
}
|
||||
],
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 15 KiB |
@@ -3,10 +3,8 @@
|
||||
|
||||
constexpr const char* AREA_PATH = "gfx/areas/area.anm2";
|
||||
constexpr const char* BOUNDS_NULL = "Bounds";
|
||||
constexpr const char* COMMON_FOLDER = "common/";
|
||||
constexpr const char* CURSOR_PATH = "gfx/cursor/cursor.anm2";
|
||||
constexpr const char* DATA_FILE = "character.json";
|
||||
constexpr const char* ICONS_PATH = "gfx/ui/icons.anm2";
|
||||
constexpr const char* PORTRAIT_PATH = "gfx/preview/portrait.png";
|
||||
constexpr const char* RENDER_PATH = "gfx/preview/render.png";
|
||||
constexpr const char* SPAWN_NULL = "ItemSpawn";
|
||||
|
||||
@@ -63,6 +63,8 @@ enum Hook
|
||||
};
|
||||
|
||||
constexpr const char* ANM2_PATH = "gfx/character/character.anm2";
|
||||
constexpr const char* COMMON_FOLDER = "common/";
|
||||
constexpr const char* ICONS_PATH = "gfx/ui/icons.anm2";
|
||||
constexpr const char* CURSOR_ANIMATION_CLICK = "Click";
|
||||
constexpr const char* CURSOR_ANIMATION_DISPOSE = "Dispose";
|
||||
constexpr const char* CURSOR_ANIMATION_GRAB = "Grab";
|
||||
|
||||
@@ -136,6 +136,7 @@ static void init()
|
||||
app.ui.audio = &app.audio;
|
||||
app.ui.renderer = &app.renderer;
|
||||
app.ui.commands = &app.commands;
|
||||
app.ui.iconsDefault.load(ICONS_PATH, {path_get(COMMON_FOLDER)}, app.renderer, app.audio);
|
||||
app.console.renderer = &app.renderer;
|
||||
app.console.commands = &app.commands;
|
||||
app.characters = characters_load(app.renderer);
|
||||
|
||||
+154
-154
@@ -43,8 +43,12 @@ constexpr float TASKBAR_FIT = 0.8f;
|
||||
constexpr int BUTTONS_FIXED = 9;
|
||||
constexpr float INFO_GAP = 4;
|
||||
constexpr int COOLDOWN_SEGMENTS = 48;
|
||||
constexpr const char* PANEL_ICONS[] = {"", "stats", "catalog", "settings", "cheats"};
|
||||
constexpr const char* PANEL_NAMES[] = {"", "Stats", "Catalog", "Settings", "Cheats"};
|
||||
constexpr const char* PANEL_ICONS[] = {"", "stats", "catalog", "settings", "cheats", "credits"};
|
||||
constexpr const char* PANEL_NAMES[] = {"", "Stats", "Catalog", "Settings", "Cheats", "Credits"};
|
||||
constexpr float PREVIEW_FRACTION = 0.68f;
|
||||
constexpr float PREVIEW_WIDTH = 760;
|
||||
constexpr float SELECT_BUTTON_SIZE = 112;
|
||||
constexpr int SELECT_BUTTONS_FIXED = 2;
|
||||
constexpr float KG_TO_G = 1000;
|
||||
constexpr float KG_TO_LB = 2.20462f;
|
||||
constexpr float LB_TO_OZ = 16;
|
||||
@@ -394,7 +398,7 @@ void Ui::command_add(CommandType type, const std::string& key)
|
||||
// An icon from the character's icon sheet (see Character::icons), fit into a square and tinted.
|
||||
void Ui::icon_draw(const char* name, ImVec2 position, float size, ImU32 tint)
|
||||
{
|
||||
Anm2* icons = character ? character->icons : nullptr;
|
||||
Anm2* icons = character && character->icons ? character->icons : &iconsDefault;
|
||||
const Anm2Region* region = icons ? icons->region_get(0, name) : nullptr;
|
||||
Texture* sheet = region && !icons->sheets.empty() ? icons->sheets[0] : nullptr;
|
||||
if (!sheet)
|
||||
@@ -446,10 +450,10 @@ static void cooldown_draw(float progress)
|
||||
}
|
||||
}
|
||||
|
||||
void Ui::window_open(Play& play, Panel next)
|
||||
void Ui::sound_play(SoundId id)
|
||||
{
|
||||
panel = next;
|
||||
play.audio->play(play.character->sounds[SOUND_OPEN]);
|
||||
if (character)
|
||||
audio->play(character->sounds[id]);
|
||||
}
|
||||
|
||||
// The bar along the bottom: the character's name and body at a glance, then a button for everything. A thin bar above
|
||||
@@ -618,7 +622,7 @@ void Ui::taskbar_draw(Play& play, ImVec2 screen)
|
||||
continue;
|
||||
ImGui::SameLine();
|
||||
if (icon_button(PANEL_ICONS[each], PANEL_NAMES[each], BUTTON_NORMAL))
|
||||
window_open(play, each);
|
||||
panel = each;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (icon_button("help", "Help", state_get(dialogue.is_hook(HOOK_HELP))))
|
||||
@@ -946,49 +950,46 @@ void Ui::catalog_draw(Play& play)
|
||||
style_pop();
|
||||
}
|
||||
|
||||
// The open window (stats, catalog, settings or cheats): one at a time, fixed in size above the taskbar, closed by its
|
||||
// X, escape or a click off it, and holding the mouse while open.
|
||||
void Ui::window_draw(Play& play, Settings& settings, ImVec2 screen)
|
||||
// Starts the open window (one at a time, from the taskbar), fixed in size above the bottom inset. Its contents follow,
|
||||
// then window_end.
|
||||
bool Ui::window_begin(ImVec2 screen, float inset)
|
||||
{
|
||||
if (play.text.isScene)
|
||||
panel = PANEL_NONE;
|
||||
play.isBlocked = panel != PANEL_NONE;
|
||||
if (panel == PANEL_NONE)
|
||||
return;
|
||||
return false;
|
||||
const char* title = PANEL_NAMES[panel];
|
||||
float above = screen.y - play.inset - TOGGLE_HEIGHT;
|
||||
float above = screen.y - inset - TOGGLE_HEIGHT;
|
||||
ImVec2 size = {std::min(WINDOW_WIDTH, screen.x * WINDOW_FIT), std::min(WINDOW_HEIGHT, above * WINDOW_FIT)};
|
||||
ImGui::SetNextWindowSize(size);
|
||||
ImGui::SetNextWindowPos({screen.x / 2, above / 2}, ImGuiCond_Always, {0.5f, 0.5f});
|
||||
if (!ImGui::IsPopupOpen(title))
|
||||
ImGui::OpenPopup(title);
|
||||
bool isOpen = true;
|
||||
if (ImGui::BeginPopupModal(title, &isOpen, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove))
|
||||
{
|
||||
if (panel == PANEL_STATS)
|
||||
stats_draw(play);
|
||||
else if (panel == PANEL_CATALOG)
|
||||
catalog_draw(play);
|
||||
else if (panel == PANEL_CHEATS)
|
||||
cheats_draw(play);
|
||||
else
|
||||
settings_draw(settings);
|
||||
ImVec2 min = ImGui::GetWindowPos();
|
||||
ImVec2 max = {min.x + ImGui::GetWindowWidth(), min.y + ImGui::GetWindowHeight()};
|
||||
bool isFocused = ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows | ImGuiFocusedFlags_NoPopupHierarchy);
|
||||
bool isClickedOff =
|
||||
isFocused && ImGui::IsMouseClicked(ImGuiMouseButton_Left) && !ImGui::IsMouseHoveringRect(min, max, false);
|
||||
if (ImGui::IsKeyPressed(ImGuiKey_Escape) || isClickedOff)
|
||||
{
|
||||
isOpen = false;
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
ImGui::EndPopup();
|
||||
ImGui::OpenPopup(title);
|
||||
sound_play(SOUND_OPEN);
|
||||
}
|
||||
if (isOpen)
|
||||
return;
|
||||
isWindowOpen = true;
|
||||
if (ImGui::BeginPopupModal(title, &isWindowOpen, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove))
|
||||
return true;
|
||||
panel = PANEL_NONE;
|
||||
play.audio->play(play.character->sounds[SOUND_CLOSE]);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Ends the open window, closing it on its X, escape or a click off it.
|
||||
void Ui::window_end()
|
||||
{
|
||||
ImVec2 min = ImGui::GetWindowPos();
|
||||
ImVec2 max = {min.x + ImGui::GetWindowWidth(), min.y + ImGui::GetWindowHeight()};
|
||||
bool isFocused = ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows | ImGuiFocusedFlags_NoPopupHierarchy);
|
||||
bool isClickedOff =
|
||||
isFocused && ImGui::IsMouseClicked(ImGuiMouseButton_Left) && !ImGui::IsMouseHoveringRect(min, max, false);
|
||||
if (ImGui::IsKeyPressed(ImGuiKey_Escape) || isClickedOff)
|
||||
isWindowOpen = false;
|
||||
if (!isWindowOpen)
|
||||
{
|
||||
ImGui::CloseCurrentPopup();
|
||||
panel = PANEL_NONE;
|
||||
sound_play(SOUND_CLOSE);
|
||||
}
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
void Ui::play_update(Play& play, Settings& settings)
|
||||
@@ -1004,15 +1005,29 @@ void Ui::play_update(Play& play, Settings& settings)
|
||||
taskbar_draw(play, screen);
|
||||
toasts_draw(play);
|
||||
text_draw(play, screen);
|
||||
window_draw(play, settings, screen);
|
||||
if (play.text.isScene)
|
||||
panel = PANEL_NONE;
|
||||
play.isBlocked = panel != PANEL_NONE;
|
||||
if (!window_begin(screen, play.inset))
|
||||
return;
|
||||
if (panel == PANEL_STATS)
|
||||
stats_draw(play);
|
||||
else if (panel == PANEL_CATALOG)
|
||||
catalog_draw(play);
|
||||
else if (panel == PANEL_CHEATS)
|
||||
cheats_draw(play);
|
||||
else
|
||||
settings_draw(settings);
|
||||
window_end();
|
||||
}
|
||||
|
||||
void Ui::select_update(std::vector<Character>& characters, Settings& settings)
|
||||
{
|
||||
ImGuiStyle& style = ImGui::GetStyle();
|
||||
ImVec2 screen = ImGui::GetIO().DisplaySize;
|
||||
ImVec2 half = {screen.x / 2 - style.WindowPadding.x * 2, screen.y / 2 - style.WindowPadding.y * 2};
|
||||
character = nullptr;
|
||||
measurement = &settings.measurement;
|
||||
buttonSize = SELECT_BUTTON_SIZE;
|
||||
characterIndex = characters.empty() ? -1 : std::clamp(characterIndex, 0, (int)characters.size() - 1);
|
||||
Character* selected = characterIndex >= 0 ? &characters[characterIndex] : nullptr;
|
||||
if (selected && selectedIndex != characterIndex)
|
||||
@@ -1022,88 +1037,111 @@ void Ui::select_update(std::vector<Character>& characters, Settings& settings)
|
||||
selectedIndex = characterIndex;
|
||||
}
|
||||
|
||||
int count = (int)characters.size() + SELECT_BUTTONS_FIXED;
|
||||
float width = count * buttonSize + (count - 1) * style.ItemSpacing.x + style.ItemSpacing.x * INFO_GAP +
|
||||
style.WindowPadding.x * 2;
|
||||
float height = buttonSize + style.WindowPadding.y * 2;
|
||||
ImGui::SetNextWindowPos({(screen.x - width) / 2, screen.y - height});
|
||||
ImGui::SetNextWindowSize({width, height});
|
||||
if (ImGui::Begin("##Select Bar", nullptr, BAR_FLAGS))
|
||||
{
|
||||
for (int i = 0; i < (int)characters.size(); i++)
|
||||
{
|
||||
Character& entry = characters[i];
|
||||
ImGui::PushID(i);
|
||||
style_push(entry.color);
|
||||
bool isCurrent = i == characterIndex;
|
||||
if (isCurrent)
|
||||
ImGui::PushStyleColor(ImGuiCol_Button, ImGui::GetStyleColorVec4(ImGuiCol_ButtonHovered));
|
||||
ImVec2 size = {buttonSize, buttonSize};
|
||||
bool isPressed = entry.portrait
|
||||
? ImGui::ImageButton("##Portrait", texture_id_get(*entry.portrait),
|
||||
{size.x - style.FramePadding.x * 2, size.y - style.FramePadding.y * 2})
|
||||
: ImGui::Button(entry.name.c_str(), size);
|
||||
if (is_fx(isPressed))
|
||||
characterIndex = i;
|
||||
if (isCurrent)
|
||||
ImGui::PopStyleColor();
|
||||
ImGui::SetItemTooltip("%s", entry.name.c_str());
|
||||
style_pop();
|
||||
ImGui::PopID();
|
||||
ImGui::SameLine();
|
||||
}
|
||||
ImGui::SameLine(0, style.ItemSpacing.x * INFO_GAP / 2);
|
||||
ImVec2 cursor = ImGui::GetCursorScreenPos();
|
||||
ImGui::GetWindowDrawList()->AddLine({cursor.x, cursor.y}, {cursor.x, cursor.y + buttonSize},
|
||||
ImGui::GetColorU32(ImGuiCol_Separator));
|
||||
ImGui::SameLine(0, style.ItemSpacing.x * INFO_GAP / 2);
|
||||
ImGui::BeginDisabled(!selected);
|
||||
if (icon_button("credits", "Credits", BUTTON_NORMAL))
|
||||
panel = PANEL_CREDITS;
|
||||
ImGui::EndDisabled();
|
||||
ImGui::SameLine();
|
||||
if (icon_button("settings", "Settings", BUTTON_NORMAL))
|
||||
panel = PANEL_SETTINGS;
|
||||
}
|
||||
ImGui::End();
|
||||
|
||||
if (selected)
|
||||
{
|
||||
float above = screen.y - height;
|
||||
ImVec2 size = {std::min(PREVIEW_WIDTH, screen.x * WINDOW_FIT), above * WINDOW_FIT};
|
||||
style_push(selected->color);
|
||||
ImGui::SetNextWindowSize(half);
|
||||
ImGui::SetNextWindowPos({style.WindowPadding.x, style.WindowPadding.y});
|
||||
if (ImGui::Begin("##Preview", nullptr, PANEL_FLAGS) && ImGui::BeginTabBar("##Preview Tabs"))
|
||||
ImGui::SetNextWindowSize(size);
|
||||
ImGui::SetNextWindowPos({screen.x / 2, above / 2}, ImGuiCond_Always, {0.5f, 0.5f});
|
||||
if (ImGui::Begin("##Preview", nullptr, PANEL_FLAGS))
|
||||
{
|
||||
ImVec2 available = ImGui::GetContentRegionAvail();
|
||||
if (is_fx(ImGui::BeginTabItem("Render")))
|
||||
if (ImGui::BeginTabBar("##Preview Tabs"))
|
||||
{
|
||||
if (Texture* render = selected->render)
|
||||
if (is_fx(ImGui::BeginTabItem("In Game")))
|
||||
{
|
||||
float scale = std::min(available.x / render->width, available.y / render->height);
|
||||
ImVec2 size = {render->width * scale, render->height * scale};
|
||||
ImGui::SetCursorPos({ImGui::GetCursorPosX() + (available.x - size.x) / 2,
|
||||
ImGui::GetCursorPosY() + (available.y - size.y) / 2});
|
||||
ImGui::Image(texture_id_get(*render), size);
|
||||
isPreviewRender = false;
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
else
|
||||
ImGui::TextWrapped("%s\n%s", selected->name.c_str(), selected->description.c_str());
|
||||
ImGui::EndTabItem();
|
||||
if (is_fx(ImGui::BeginTabItem("Render")))
|
||||
{
|
||||
isPreviewRender = true;
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
ImGui::EndTabBar();
|
||||
}
|
||||
if (is_fx(ImGui::BeginTabItem("In Game")))
|
||||
ImVec2 available = {ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y * PREVIEW_FRACTION};
|
||||
ImVec2 shown = {};
|
||||
ImTextureID texture = {};
|
||||
if (isPreviewRender && selected->render)
|
||||
{
|
||||
Texture& render = *selected->render;
|
||||
float scale = std::min(available.x / render.width, available.y / render.height);
|
||||
shown = {render.width * scale, render.height * scale};
|
||||
texture = texture_id_get(render);
|
||||
}
|
||||
else
|
||||
{
|
||||
Anm2* anm2 = selected->anm2_get(ANM2_PATH, *renderer, *audio);
|
||||
if (previewActor.anm2 != anm2 || !anm2)
|
||||
previewActor = Actor(anm2);
|
||||
previewActor.update(*audio);
|
||||
ImVec2 size = canvas_draw(*renderer, previewCanvas, previewActor, available);
|
||||
ImGui::SetCursorPos({ImGui::GetCursorPosX() + (available.x - size.x) / 2,
|
||||
ImGui::GetCursorPosY() + (available.y - size.y) / 2});
|
||||
ImGui::Image(texture_id_get(previewCanvas.texture), size);
|
||||
ImGui::EndTabItem();
|
||||
shown = canvas_draw(*renderer, previewCanvas, previewActor, available);
|
||||
texture = texture_id_get(previewCanvas.texture);
|
||||
}
|
||||
ImGui::EndTabBar();
|
||||
}
|
||||
ImGui::End();
|
||||
ImVec2 start = ImGui::GetCursorPos();
|
||||
ImGui::SetCursorPos({start.x + (available.x - shown.x) / 2, start.y + (available.y - shown.y) / 2});
|
||||
if (shown.x > 0)
|
||||
ImGui::Image(texture, shown);
|
||||
ImGui::SetCursorPos({start.x, start.y + available.y});
|
||||
ImGui::Separator();
|
||||
|
||||
ImGui::SetNextWindowSize(half);
|
||||
ImGui::SetNextWindowPos({style.WindowPadding.x, screen.y / 2 + style.WindowPadding.y});
|
||||
if (ImGui::Begin("##Info", nullptr, PANEL_FLAGS))
|
||||
{
|
||||
float footer = ImGui::GetTextLineHeightWithSpacing() + style.WindowPadding.y + style.ItemSpacing.y;
|
||||
ImGui::PushFont(nullptr, FONT_HEADER_3);
|
||||
if (ImGui::BeginChild("##Info Child", {0, ImGui::GetContentRegionAvail().y - footer}))
|
||||
{
|
||||
ImGui::TextUnformatted(selected->name.c_str());
|
||||
ImGui::PushFont(nullptr, FONT_NORMAL);
|
||||
if (ImGui::BeginTabBar("##Info Tabs"))
|
||||
{
|
||||
ImGui::PushFont(nullptr, FONT_HEADER_2);
|
||||
if (ImGui::BeginTabItem("Overview"))
|
||||
{
|
||||
ImGui::Separator();
|
||||
if (!selected->description.empty())
|
||||
{
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, imvec4_get(GRAY));
|
||||
ImGui::TextWrapped("%s", selected->description.c_str());
|
||||
ImGui::PopStyleColor();
|
||||
ImGui::Separator();
|
||||
}
|
||||
float weight = isSelectedSaved ? selectedStats.weight : selected->traits.weight;
|
||||
ImGui::Text("Weight: %s", weight_format(weight, settings.measurement).c_str());
|
||||
ImGui::Text("Stages: %i", (int)selected->stages.size() + 1);
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
if (ImGui::BeginTabItem("Credits"))
|
||||
{
|
||||
ImGui::Separator();
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, imvec4_get(GRAY));
|
||||
ImGui::TextWrapped("%s", selected->credits.empty() ? "No credits listed."
|
||||
: selected->credits.c_str());
|
||||
ImGui::PopStyleColor();
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
ImGui::PopFont();
|
||||
ImGui::EndTabBar();
|
||||
}
|
||||
ImGui::PopFont();
|
||||
}
|
||||
ImGui::EndChild();
|
||||
ImGui::PushFont(nullptr, FONT_HEADER_2);
|
||||
ImGui::TextUnformatted(selected->name.c_str());
|
||||
ImGui::PopFont();
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, imvec4_get(GRAY));
|
||||
ImGui::TextWrapped("%s", selected->description.c_str());
|
||||
ImGui::PopStyleColor();
|
||||
float weight = isSelectedSaved ? selectedStats.weight : selected->traits.weight;
|
||||
ImGui::Text("Weight: %s Stages: %i", weight_format(weight, settings.measurement).c_str(),
|
||||
(int)selected->stages.size() + 1);
|
||||
|
||||
ImGui::SetCursorPosY(ImGui::GetWindowHeight() - style.WindowPadding.y - ImGui::GetFrameHeight());
|
||||
ImVec2 buttonSize = {row_width_get(isSelectedSaved ? 2 : 1), 0};
|
||||
if (isSelectedSaved)
|
||||
{
|
||||
@@ -1121,9 +1159,8 @@ void Ui::select_update(std::vector<Character>& characters, Settings& settings)
|
||||
isNewGameWarning = isSelectedSaved;
|
||||
}
|
||||
tooltip_set("Start a new game.\nThis will delete progress!");
|
||||
ImGui::PopFont();
|
||||
|
||||
ImGui::SetNextWindowSize({screen.x / 2, 0});
|
||||
ImGui::SetNextWindowSize({size.x, 0});
|
||||
ImGui::SetNextWindowPos({screen.x / 2, screen.y / 2}, ImGuiCond_Always, {0.5f, 0.5f});
|
||||
if (ImGui::BeginPopupModal("New Game Warning", &isNewGameWarning,
|
||||
ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize))
|
||||
@@ -1142,53 +1179,16 @@ void Ui::select_update(std::vector<Character>& characters, Settings& settings)
|
||||
style_pop();
|
||||
}
|
||||
|
||||
ImGui::SetNextWindowSize({screen.x / 2 - style.WindowPadding.x, screen.y - style.WindowPadding.y * 2});
|
||||
ImGui::SetNextWindowPos({screen.x / 2, style.WindowPadding.y});
|
||||
if (ImGui::Begin("##Main Menu", nullptr, PANEL_FLAGS) && ImGui::BeginTabBar("##Main Tabs"))
|
||||
if (window_begin(screen, height))
|
||||
{
|
||||
if (is_fx(ImGui::BeginTabItem("Characters")))
|
||||
if (panel == PANEL_CREDITS && selected)
|
||||
{
|
||||
if (ImGui::BeginPopupContextWindow("##Characters Context"))
|
||||
{
|
||||
if (ImGui::MenuItem("Refresh"))
|
||||
{
|
||||
command_add(COMMAND_RELOAD);
|
||||
selectedIndex = -1;
|
||||
}
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
float side = ImGui::GetContentRegionAvail().x / 4;
|
||||
float right = ImGui::GetCursorScreenPos().x + ImGui::GetContentRegionAvail().x;
|
||||
for (int i = 0; i < (int)characters.size(); i++)
|
||||
{
|
||||
Character& entry = characters[i];
|
||||
ImGui::PushID(i);
|
||||
style_push(entry.color);
|
||||
bool isCurrent = i == characterIndex;
|
||||
if (isCurrent)
|
||||
ImGui::PushStyleColor(ImGuiCol_FrameBg, ImGui::GetStyleColorVec4(ImGuiCol_FrameBgHovered));
|
||||
bool isPressed = entry.portrait ? ImGui::ImageButton(entry.name.c_str(),
|
||||
texture_id_get(*entry.portrait), {side, side})
|
||||
: ImGui::Button(entry.name.c_str(), {side, side});
|
||||
if (is_fx(isPressed))
|
||||
characterIndex = i;
|
||||
if (isCurrent)
|
||||
ImGui::PopStyleColor();
|
||||
ImGui::SetItemTooltip("%s", entry.name.c_str());
|
||||
style_pop();
|
||||
float next = ImGui::GetItemRectMax().x + style.ItemSpacing.x + side;
|
||||
if (i + 1 < (int)characters.size() && next < right)
|
||||
ImGui::SameLine();
|
||||
ImGui::PopID();
|
||||
}
|
||||
ImGui::EndTabItem();
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, imvec4_get(GRAY));
|
||||
ImGui::TextWrapped("%s", selected->credits.empty() ? "No credits listed." : selected->credits.c_str());
|
||||
ImGui::PopStyleColor();
|
||||
}
|
||||
if (is_fx(ImGui::BeginTabItem("Settings")))
|
||||
{
|
||||
else
|
||||
settings_draw(settings);
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
ImGui::EndTabBar();
|
||||
window_end();
|
||||
}
|
||||
ImGui::End();
|
||||
}
|
||||
@@ -23,7 +23,8 @@ enum Panel
|
||||
PANEL_STATS,
|
||||
PANEL_CATALOG,
|
||||
PANEL_SETTINGS,
|
||||
PANEL_CHEATS
|
||||
PANEL_CHEATS,
|
||||
PANEL_CREDITS
|
||||
};
|
||||
|
||||
enum ButtonState
|
||||
@@ -61,6 +62,7 @@ public:
|
||||
std::vector<Canvas> itemCanvases;
|
||||
std::vector<ImVec2> itemSizes;
|
||||
Actor previewActor;
|
||||
Anm2 iconsDefault;
|
||||
Canvas previewCanvas;
|
||||
Stats selectedStats;
|
||||
Audio* audio = nullptr;
|
||||
@@ -77,7 +79,9 @@ public:
|
||||
Panel panel = PANEL_NONE;
|
||||
bool isFullscreen = false;
|
||||
bool isNewGameWarning = false;
|
||||
bool isPreviewRender = false;
|
||||
bool isSelectedSaved = false;
|
||||
bool isWindowOpen = false;
|
||||
|
||||
void play_update(Play& play, Settings& settings);
|
||||
void select_update(std::vector<Character>& characters, Settings& settings);
|
||||
@@ -87,9 +91,10 @@ private:
|
||||
bool icon_button(const char* icon, const char* tooltip, ButtonState state);
|
||||
void icon_draw(const char* name, ImVec2 position, float size, ImU32 tint);
|
||||
void command_add(CommandType type, const std::string& key = "");
|
||||
void window_open(Play& play, Panel next);
|
||||
void sound_play(SoundId id);
|
||||
void taskbar_draw(Play& play, ImVec2 screen);
|
||||
void window_draw(Play& play, Settings& settings, ImVec2 screen);
|
||||
bool window_begin(ImVec2 screen, float inset);
|
||||
void window_end();
|
||||
void stats_draw(Play& play);
|
||||
void cheats_draw(Play& play);
|
||||
void catalog_draw(Play& play);
|
||||
|
||||
Reference in new issue
Block a user