Skip to content

Commit

Permalink
add clone style button
Browse files Browse the repository at this point in the history
  • Loading branch information
tope99 committed Dec 7, 2023
1 parent 1ee82b4 commit 660e9fd
Show file tree
Hide file tree
Showing 4 changed files with 268 additions and 36 deletions.
145 changes: 121 additions & 24 deletions src/imrad.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include "ui_binding.h"
#include "ui_combo_dlg.h"
#include "ui_horiz_layout.h"
#include "ui_clone_style.h"

//must come last
#define STB_IMAGE_IMPLEMENTATION
Expand Down Expand Up @@ -630,6 +631,42 @@ void GetStyles()
}
}

const std::array<ImU32, UIContext::Color::COUNT>&
GetCtxColors(const std::string& styleName)
{
static const std::array<ImU32, UIContext::Color::COUNT> classic{
IM_COL32(255, 255, 0, 128),
IM_COL32(255, 0, 0, 255),
IM_COL32(128, 128, 255, 255),
IM_COL32(255, 0, 255, 255),
IM_COL32(0, 255, 255, 255),
IM_COL32(0, 255, 0, 255),
};
static const std::array<ImU32, UIContext::Color::COUNT> light {
IM_COL32(255, 0, 0, 255),
IM_COL32(255, 0, 0, 255),
IM_COL32(128, 128, 255, 255),
IM_COL32(255, 0, 255, 255),
IM_COL32(0, 128, 128, 255),
IM_COL32(0, 255, 0, 255),
};
static const std::array<ImU32, UIContext::Color::COUNT> dark{
IM_COL32(255, 255, 0, 128),
IM_COL32(255, 0, 0, 255),
IM_COL32(128, 128, 255, 255),
IM_COL32(255, 0, 255, 255),
IM_COL32(0, 255, 255, 255),
IM_COL32(0, 255, 0, 255),
};

if (styleName == "Light")
return light;
else if (styleName == "Dark")
return dark;
else
return classic;
}

void LoadStyle()
{
if (!reloadStyle)
Expand Down Expand Up @@ -664,40 +701,19 @@ void LoadStyle()
{
ImGui::StyleColorsClassic(&ctx.style);
ctx.fontNames = { "" };
ctx.colors = {
IM_COL32(255, 255, 0, 128),
IM_COL32(255, 0, 0, 255),
IM_COL32(128, 128, 255, 255),
IM_COL32(255, 0, 255, 255),
IM_COL32(0, 255, 255, 255),
IM_COL32(0, 255, 0, 255),
};
ctx.colors = GetCtxColors(styleName);
}
else if (styleName == "Light")
{
ImGui::StyleColorsLight(&ctx.style);
ctx.fontNames = { "" };
ctx.colors = {
IM_COL32(255, 0, 0, 255),
IM_COL32(255, 0, 0, 255),
IM_COL32(128, 128, 255, 255),
IM_COL32(255, 0, 255, 255),
IM_COL32(0, 128, 128, 255),
IM_COL32(0, 255, 0, 255),
};
ctx.colors = GetCtxColors(styleName);
}
else if (styleName == "Dark")
{
ImGui::StyleColorsDark(&ctx.style);
ctx.fontNames = { "" };
ctx.colors = {
IM_COL32(255, 255, 0, 128),
IM_COL32(255, 0, 0, 255),
IM_COL32(128, 128, 255, 255),
IM_COL32(255, 0, 255, 255),
IM_COL32(0, 255, 255, 255),
IM_COL32(0, 255, 0, 255),
};
ctx.colors = GetCtxColors(styleName);
}
else
{
Expand Down Expand Up @@ -744,6 +760,80 @@ void LoadStyle()
ImGui_ImplOpenGL3_CreateFontsTexture();
}

void DoCloneStyle(const std::string& name)
{
auto FormatClr = [](ImU32 c) {
std::ostringstream os;
os << (c & 0xff) << " " <<
((c >> 8) & 0xff) << " " <<
((c >> 16) & 0xff) << " " <<
((c >> 24) & 0xff);
return os.str();
};

std::string from = fileTabs[activeTab].styleName;
std::string path = "style/" + name + ".ini";
try
{
if (from == "Classic" || from == "Dark" || from == "Light")
{
ImGuiStyle style;
if (from == "Dark")
ImGui::StyleColorsDark(&style);
else if (from == "Light")
ImGui::StyleColorsLight(&style);
else
ImGui::StyleColorsClassic(&style);

std::map<std::string, std::string> extra;
const auto& colors = GetCtxColors(from);
#define SET_CLR(a) extra[std::string("imrad.colors.") + #a] = FormatClr(colors[UIContext::Color::a]);
SET_CLR(Selected);
SET_CLR(Hovered);
SET_CLR(Snap1);
SET_CLR(Snap2);
SET_CLR(Snap3);
SET_CLR(Snap4);
SET_CLR(Snap5);
#undef SET_CLR
ImRad::SaveStyle(path, &style, extra);
}
else
{
fs::copy_file("style/" + from + ".ini", path, fs::copy_options::overwrite_existing);
}

fileTabs[activeTab].styleName = name;
if (!stx::count_if(styleNames, [&](const auto& s) { return s.first == name; }))
styleNames.push_back({ name, path });
}
catch (std::exception& e) {
messageBox.title = "error";
messageBox.message = e.what();
messageBox.buttons = ImRad::Ok;
messageBox.OpenPopup();
}
}

void CloneStyle()
{
cloneStyle.OpenPopup([](ImRad::ModalResult mr)
{
std::string path = "style/" + cloneStyle.styleName + ".ini";
if (fs::exists(path)) {
messageBox.title = "Confirmation";
messageBox.message = "Overwrite existing style?";
messageBox.buttons = ImRad::Yes | ImRad::No;
messageBox.OpenPopup([=](ImRad::ModalResult mr) {
if (mr == ImRad::Yes)
DoCloneStyle(cloneStyle.styleName);
});
}
else
DoCloneStyle(cloneStyle.styleName);
});
}

void DockspaceUI()
{
// We are using the ImGuiWindowFlags_NoDocking flag to make the parent window not dockable into,
Expand Down Expand Up @@ -904,6 +994,11 @@ void ToolbarUI()
ImGui::EndCombo();
}
ImGui::SameLine();
if (ImGui::Button(ICON_FA_CLONE))
CloneStyle();
if (ImGui::IsItemHovered(ImGuiHoveredFlags_DelayNormal))
ImGui::SetTooltip("Clone Style");
ImGui::SameLine();
ImGui::Text("Units");
ImGui::SameLine();
ImGui::SetNextItemWidth(100);
Expand Down Expand Up @@ -1289,6 +1384,8 @@ void PopupUI()
bindingDlg.Draw();

horizLayout.Draw();

cloneStyle.Draw();
}

void Draw()
Expand Down
35 changes: 23 additions & 12 deletions src/imrad.h
Original file line number Diff line number Diff line change
Expand Up @@ -322,22 +322,25 @@ Texture LoadTextureFromFile(std::string_view filename);
#endif

//For debugging pruposes
inline void SaveStyle(std::string_view fname)
inline void SaveStyle(std::string_view fname_, const ImGuiStyle* src = nullptr, const std::map<std::string, std::string>& extra = {})
{
std::ofstream fout(std::string(fname.begin(), fname.end()));
const auto& s = ImGui::GetStyle();

const ImGuiStyle* style = src ? src : &ImGui::GetStyle();
std::string fname(fname_.begin(), fname_.end());
std::ofstream fout(fname);
if (!fout)
throw std::runtime_error("can't write '" + fname + "'");

fout << "[colors]\n";
for (int i = 0; i < ImGuiCol_COUNT; ++i) {
fout << ImGui::GetStyleColorName(i) << " = ";
const auto& clr = s.Colors[i];
const auto& clr = style->Colors[i];
fout << int(clr.x * 255) << " " << int(clr.y * 255) << " "
<< int(clr.z * 255) << " " << int(clr.w * 255) << "\n";
}

fout << "\n[variables]\n";
#define WRITE_FLT(a) fout << #a " = " << s.a << "\n"
#define WRITE_VEC(a) fout << #a " = " << s.a.x << " " << s.a.y << "\n"
#define WRITE_FLT(a) fout << #a " = " << style->a << "\n"
#define WRITE_VEC(a) fout << #a " = " << style->a.x << " " << style->a.y << "\n"

WRITE_FLT(Alpha);
WRITE_FLT(DisabledAlpha);
Expand Down Expand Up @@ -365,12 +368,20 @@ inline void SaveStyle(std::string_view fname)
#undef WRITE_VEC

fout << "\n[fonts]\n";
fout << "# Default = \"Roboto-Medium.ttf\" size 20\n";
fout << "Default = \"Roboto-Medium.ttf\" size 20\n";

fout << "\n[imrad.colors]\n";
fout << "# Hovered 255 255 0 255\n";
fout << "# Selected 255 0 0 255\n";
fout << "# Snap1 ...\n";
std::string lastSection;
for (const auto& kv : extra)
{
size_t i = kv.first.find_last_of('.');
if (i == std::string::npos)
continue;
if (kv.first.substr(0, i) != lastSection) {
lastSection = kv.first.substr(0, i);
fout << "\n[" << lastSection << "]\n";
}
fout << kv.first.substr(i + 1) << " = " << kv.second << "\n";
}
}

//This function can be used in your code to load style and fonts from the INI file
Expand Down
94 changes: 94 additions & 0 deletions src/ui_clone_style.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
// Generated with ImRAD 0.7
// visit https://github.com/tpecholt/imrad

#include "ui_clone_style.h"
#include "ui_message_box.h"

CloneStyle cloneStyle;


void CloneStyle::OpenPopup(std::function<void(ImRad::ModalResult)> clb)
{
callback = clb;
modalResult = ImRad::None;
animator.Start(ImRad::Animator::OpenPopup);
ImGui::OpenPopup(ID);
Init();
}

void CloneStyle::ClosePopup(ImRad::ModalResult mr)
{
modalResult = mr;
animator.Start(ImRad::Animator::ClosePopup);
}

void CloneStyle::Init()
{
// TODO: Add your code here
styleName = "";
}

void CloneStyle::Draw()
{
/// @style Dark
/// @unit px
/// @begin TopWindow
auto* ioUserData = (ImRad::IOUserData*)ImGui::GetIO().UserData;
ID = ImGui::GetID("###CloneStyle");
ImGui::SetNextWindowPos(ImGui::GetMainViewport()->GetCenter(), 0, { 0.5f, 0.5f }); //Center
ImGui::SetNextWindowSize({ 250, 120 });
bool tmpOpen = true;
if (ImGui::BeginPopupModal("Clone Style###CloneStyle", &tmpOpen, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse))
{
if (modalResult != ImRad::None)
{
ImGui::CloseCurrentPopup();
if (modalResult != ImRad::Cancel) callback(modalResult);
}
/// @separator

// TODO: Add Draw calls of dependent popup windows here
messageBox.Draw();

/// @begin Input
if (ImGui::IsWindowAppearing())
ImGui::SetKeyboardFocusHere();
ImGui::SetNextItemWidth(-1);
ImGui::InputTextWithHint("##styleName", "New style name", &styleName, ImGuiInputTextFlags_CharsNoBlank);
if (ImGui::IsItemActive())
ioUserData->imeType = ImRad::ImeText;
/// @end Input

/// @begin Table
ImRad::Spacing(3);
if (ImGui::BeginTable("table1", 3, ImGuiTableFlags_NoPadOuterX | ImGuiTableFlags_NoPadInnerX, { 0, 0 }))
{
ImGui::TableSetupColumn("left-stretch", ImGuiTableColumnFlags_WidthStretch, 0);
ImGui::TableSetupColumn("content", ImGuiTableColumnFlags_WidthFixed, 0);
ImGui::TableSetupColumn("right-stretch", ImGuiTableColumnFlags_WidthStretch, 0);
ImGui::TableNextRow(0, 0);
ImGui::TableSetColumnIndex(0);
/// @separator

/// @begin Button
ImRad::TableNextColumn(1);
ImGui::BeginDisabled(styleName==""||styleName=="Classic"||styleName=="Dark"||styleName=="Light");
if (ImGui::Button("OK", { 90, 30 }) ||
(!ImRad::IsItemDisabled() && ImGui::IsKeyPressed(ImGuiKey_Enter, false)))
{
ClosePopup(ImRad::Ok);
}
ImGui::EndDisabled();
/// @end Button


/// @separator
ImGui::EndTable();
}
/// @end Table

/// @separator
ImGui::EndPopup();
}
/// @end TopWindow
}
30 changes: 30 additions & 0 deletions src/ui_clone_style.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Generated with ImRAD 0.7
// visit https://github.com/tpecholt/imrad

#pragma once
#include "imrad.h"

class CloneStyle
{
public:
/// @begin interface
void OpenPopup(std::function<void(ImRad::ModalResult)> clb = [](ImRad::ModalResult){});
void ClosePopup(ImRad::ModalResult mr);
void Draw();

std::string styleName;
/// @end interface

private:
/// @begin impl
void Init();

ImGuiID ID = 0;
ImRad::ModalResult modalResult;
ImRad::Animator animator;
std::function<void(ImRad::ModalResult)> callback;

/// @end impl
};

extern CloneStyle cloneStyle;

0 comments on commit 660e9fd

Please sign in to comment.