feat: Make color picker tool much more useful
This commit is contained in:
parent
7405219fb8
commit
5a4f31bfa5
@ -124,9 +124,169 @@ namespace hex::plugin::builtin {
|
||||
|
||||
void drawColorPicker() {
|
||||
static std::array<float, 4> pickedColor = { 0 };
|
||||
static std::string rgba8;
|
||||
|
||||
ImGui::SetNextItemWidth(300_scaled);
|
||||
ImGui::ColorPicker4("hex.builtin.tools.color"_lang, pickedColor.data(), ImGuiColorEditFlags_Uint8 | ImGuiColorEditFlags_AlphaBar | ImGuiColorEditFlags_AlphaPreviewHalf | ImGuiColorEditFlags_DisplayRGB | ImGuiColorEditFlags_DisplayHSV | ImGuiColorEditFlags_DisplayHex);
|
||||
struct BitValue {
|
||||
int bits;
|
||||
float color;
|
||||
float saturationMultiplier;
|
||||
char name;
|
||||
u8 index;
|
||||
};
|
||||
|
||||
static std::array bitValues = {
|
||||
BitValue{ 8, 0.00F, 1.0F, 'R', 0 },
|
||||
BitValue{ 8, 0.33F, 1.0F, 'G', 1 },
|
||||
BitValue{ 8, 0.66F, 1.0F, 'B', 2 },
|
||||
BitValue{ 8, 0.00F, 0.0F, 'A', 3 }
|
||||
};
|
||||
|
||||
if (ImGui::BeginTable("##color_picker_table", 3)) {
|
||||
ImGui::TableSetupColumn("##picker", ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_NoResize, 300_scaled);
|
||||
ImGui::TableSetupColumn("##sliders", ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_NoResize, 80_scaled);
|
||||
ImGui::TableSetupColumn("##output", ImGuiTableColumnFlags_WidthStretch | ImGuiTableColumnFlags_NoResize);
|
||||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
// Draw main color picker widget
|
||||
ImVec2 startCursor, endCursor;
|
||||
{
|
||||
ImGui::PushItemWidth(-1);
|
||||
startCursor = ImGui::GetCursorPos();
|
||||
ImGui::ColorPicker4("hex.builtin.tools.color"_lang, pickedColor.data(), ImGuiColorEditFlags_Uint8 | ImGuiColorEditFlags_AlphaBar | ImGuiColorEditFlags_DisplayRGB | ImGuiColorEditFlags_DisplayHSV | ImGuiColorEditFlags_DisplayHex);
|
||||
endCursor = ImGui::GetCursorPos();
|
||||
ImGui::ColorButton("##color_button", ImColor(pickedColor[0], pickedColor[1], pickedColor[2], pickedColor[3]), ImGuiColorEditFlags_NoPicker | ImGuiColorEditFlags_NoDragDrop | ImGuiColorEditFlags_AlphaPreviewHalf, ImVec2(300_scaled, 0));
|
||||
ImGui::PopItemWidth();
|
||||
}
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
const auto colorName = hex::format("{}{}{}{}", bitValues[0].name, bitValues[1].name, bitValues[2].name, bitValues[3].name);
|
||||
|
||||
// Draw color bit count sliders
|
||||
{
|
||||
static auto drawBitsSlider = [&](BitValue *bitValue) {
|
||||
// Change slider color
|
||||
ImGui::PushStyleColor(ImGuiCol_FrameBg, ImColor::HSV(bitValue->color, 0.5f * bitValue->saturationMultiplier, 0.5f).Value);
|
||||
ImGui::PushStyleColor(ImGuiCol_FrameBgHovered, ImColor::HSV(bitValue->color, 0.6f * bitValue->saturationMultiplier, 0.5f).Value);
|
||||
ImGui::PushStyleColor(ImGuiCol_FrameBgActive, ImColor::HSV(bitValue->color, 0.7f * bitValue->saturationMultiplier, 0.5f).Value);
|
||||
ImGui::PushStyleColor(ImGuiCol_SliderGrab, ImColor::HSV(bitValue->color, 0.9f * bitValue->saturationMultiplier, 0.9f).Value);
|
||||
|
||||
// Draw slider
|
||||
ImGui::PushID(&bitValue->bits);
|
||||
auto format = hex::format("%d\n{}", bitValue->name);
|
||||
ImGui::VSliderInt("##slider", ImVec2(18_scaled, (endCursor - startCursor).y - 3_scaled), &bitValue->bits, 0, 16, format.c_str(), ImGuiSliderFlags_AlwaysClamp);
|
||||
ImGui::PopID();
|
||||
|
||||
ImGui::PopStyleColor(4);
|
||||
};
|
||||
|
||||
// Force sliders closer together
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(4, 4));
|
||||
|
||||
// Draw a slider for each color component
|
||||
for (u32 index = 0; auto &bitValue : bitValues) {
|
||||
// Draw slider
|
||||
drawBitsSlider(&bitValue);
|
||||
|
||||
// Configure drag and drop source and target
|
||||
if (ImGui::BeginDragDropSource(ImGuiDragDropFlags_None)) {
|
||||
// Set the current slider index as the payload
|
||||
ImGui::SetDragDropPayload("BIT_VALUE", &index, sizeof(u32));
|
||||
|
||||
// Draw a color button to show the color being dragged
|
||||
ImGui::ColorButton("##color_button", ImColor::HSV(bitValue.color, 0.5f * bitValue.saturationMultiplier, 0.5f).Value);
|
||||
|
||||
ImGui::EndDragDropSource();
|
||||
}
|
||||
if (ImGui::BeginDragDropTarget()) {
|
||||
if (const ImGuiPayload *payload = ImGui::AcceptDragDropPayload("BIT_VALUE"); payload != nullptr) {
|
||||
auto otherIndex = *static_cast<const u32 *>(payload->Data);
|
||||
|
||||
// Swap the currently hovered slider with the one being dragged
|
||||
std::swap(bitValues[index], bitValues[otherIndex]);
|
||||
}
|
||||
ImGui::EndDragDropTarget();
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
index += 1;
|
||||
}
|
||||
|
||||
ImGui::NewLine();
|
||||
|
||||
// Draw color name below sliders
|
||||
ImGui::TextFormatted("{}", colorName);
|
||||
|
||||
ImGui::PopStyleVar();
|
||||
}
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
// Draw encoded color values
|
||||
{
|
||||
// Calculate int and float representations of the selected color
|
||||
std::array<u32, 4> intColor = {};
|
||||
std::array<float, 4> floatColor = {};
|
||||
for (u32 index = 0; auto &bitValue : bitValues) {
|
||||
intColor[index] = u64(std::round(static_cast<long double>(pickedColor[bitValue.index]) * std::numeric_limits<u32>::max())) >> (32 - bitValue.bits);
|
||||
floatColor[index] = pickedColor[bitValue.index];
|
||||
|
||||
index += 1;
|
||||
}
|
||||
|
||||
// Draw a table with the color values
|
||||
if (ImGui::BeginTable("##value_table", 2, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg, ImVec2(0, 0))) {
|
||||
const static auto drawValue = [](const char *name, auto formatter) {
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
// Draw name of the formatting
|
||||
ImGui::TextUnformatted(name);
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
// Draw value
|
||||
ImGui::PushID(name);
|
||||
ImGui::TextFormattedSelectable("{}", formatter());
|
||||
ImGui::PopID();
|
||||
};
|
||||
|
||||
const u32 bitCount = bitValues[0].bits + bitValues[1].bits + bitValues[2].bits + bitValues[3].bits;
|
||||
|
||||
// Draw the different representations
|
||||
|
||||
drawValue("HEX", [&] {
|
||||
u64 hexValue = 0;
|
||||
for (u32 index = 0; auto &bitValue : bitValues) {
|
||||
hexValue <<= bitValue.bits;
|
||||
hexValue |= u64(intColor[index]) & hex::bitmask(bitValue.bits);
|
||||
index += 1;
|
||||
}
|
||||
|
||||
return hex::format("#{0:0{1}X}", hexValue, bitCount / 4);
|
||||
});
|
||||
|
||||
drawValue(colorName.c_str(), [&] {
|
||||
return hex::format("{}({}, {}, {}, {})", colorName, intColor[0], intColor[1], intColor[2], intColor[3]);
|
||||
});
|
||||
|
||||
drawValue("Vector4f", [&] {
|
||||
return hex::format("{{ {:.2}F, {:.2}F, {:.2}F, {:.2}F }}", floatColor[0], floatColor[1], floatColor[2], floatColor[3]);
|
||||
});
|
||||
|
||||
drawValue("Percentage", [&] {
|
||||
return hex::format("{{ {}%, {}%, {}%, {}% }}", u32(floatColor[0] * 100), u32(floatColor[1] * 100), u32(floatColor[2] * 100), u32(floatColor[3] * 100));
|
||||
});
|
||||
|
||||
ImGui::EndTable();
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::EndTable();
|
||||
}
|
||||
}
|
||||
|
||||
void drawMathEvaluator() {
|
||||
|
Loading…
Reference in New Issue
Block a user