Background color change, better keybinds
Some checks failed
Run Build / run-build-debian (push) Failing after 56s
Run Build / run-build-arch (push) Failing after 1m1s
Run Build / run-build-ubuntu (push) Failing after 1m6s

This commit is contained in:
2025-07-06 12:01:09 -04:00
parent fd3437d65b
commit c918665f6a
3 changed files with 213 additions and 164 deletions

View File

@ -58,6 +58,7 @@ struct Context
float DefaultPanelHeight = 600; // Height of panel in pixels
float DefaultInitialPanelWidth = 600; // Only applies when window first appears
int MaxAnnotations = 1000; // Limit number of texel annotations for performance
float InitialZoom = 1.0f;
};
Context *GContext = nullptr;
@ -191,7 +192,7 @@ bool BeginInspectorPanel(const char *title, ImTextureID texture, ImVec2 textureS
}
else if (justCreated)
{
newScale = 1;
newScale = GContext->InitialZoom;
}
if (newScale != -1)
@ -684,6 +685,11 @@ void SetZoomRate(float rate)
GContext->ZoomRate = rate;
}
void SetInitialZoom(float zoom)
{
GContext->InitialZoom = zoom;
}
//-------------------------------------------------------------------------
// [SECTION] Life Cycle
//-------------------------------------------------------------------------

View File

@ -32,7 +32,7 @@ enum InspectorAlphaMode
typedef ImU64 InspectorFlags;
enum InspectorFlags_
{
InspectorFlags_ShowWrap = 1 << 0, // Draw beyong the [0,1] uv range. What you see will depend on API
InspectorFlags_ShowWrap = 1 << 0, // Draw beyond the [0,1] uv range. What you see will depend on API
InspectorFlags_NoForceFilterNearest = 1 << 1, // Normally we force nearest neighbour sampling when zoomed in. Set to disable this.
InspectorFlags_NoGrid = 1 << 2, // By default a grid is shown at high zoom levels
InspectorFlags_NoTooltip = 1 << 3, // Disable tooltip on hover
@ -132,6 +132,7 @@ void DrawAlphaModeSelector(); // A combo box for selecting the alpha mode
* scroll will increase zoom level by 50%. The factor used for zooming out is
* 1/factor. */
void SetZoomRate(float factor);
void SetInitialZoom(float zoom);
//-------------------------------------------------------------------------
// [SECTION] ANNOTATION TOOLS

366
main.cpp
View File

@ -516,13 +516,25 @@ int main(int argc, char* argv[]) {
(SDL_WindowFlags)(SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE |
SDL_WINDOW_ALLOW_HIGHDPI);
int wh = 800;
int ww = 1280;
if (t.size.y > t.size.x) {
ww = 500;
wh = 1280;
float image_w = t.size.x;
float image_h = t.size.y;
if (t.exif.ImageOrientation == "6" || t.exif.ImageOrientation == "8") {
std::swap(image_w, image_h);
}
float aspect_ratio = image_w / image_h;
int viewer_h = image_h;
int viewer_w = image_w;
const int max_h = 1200;
if (viewer_h > max_h) {
viewer_h = max_h;
viewer_w = max_h * aspect_ratio;
}
int ww = viewer_w * 1.25;
int wh = viewer_h * 1.25;
SDL_Window *window =
SDL_CreateWindow("tview", SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED, ww, wh, window_flags);
@ -554,10 +566,20 @@ int main(int argc, char* argv[]) {
ImGui_ImplSDL2_InitForOpenGL(window, gl_context);
ImGui_ImplOpenGL3_Init(glsl_version);
ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);
ImVec4 clear_color = ImVec4(0.18f, 0.18f, 0.18f, 1.00f);
std::vector<ImVec4> background_colors = {
ImVec4(0.0f, 0.0f, 0.0f, 1.00f),
ImVec4(0.18f, 0.18f, 0.18f, 1.00f),
ImVec4(0.5f, 0.5f, 0.5f, 1.00f),
ImVec4(255.0f, 255.0f, 255.0f, 255.00f),
ImVec4(0.75f, 0.75f, 0.75f, 1.00f)
};
int background_color_index = 1;
auto flags = ImGuiTexInspect::InspectorFlags_FillVertical | ImGuiTexInspect::InspectorFlags_FillHorizontal;
t = LoadTexture(t);
ImGuiTexInspect::SetInitialZoom(0.80f);
Histogram histogram = Histogram(t.size.x, t.size.y, t.channels);
auto histogram_future = std::async(std::launch::async, [&]() {
histogram.Load(image);
@ -609,7 +631,7 @@ int main(int argc, char* argv[]) {
case SDL_SCANCODE_A:
AA_ENABLED = !AA_ENABLED;
break;
case SDL_SCANCODE_H:
case SDL_SCANCODE_SLASH:
SHOW_HELP = !SHOW_HELP;
break;
case SDL_SCANCODE_D:
@ -625,9 +647,13 @@ int main(int argc, char* argv[]) {
case SDL_SCANCODE_E:
SHOW_EXIF = !SHOW_EXIF;
break;
case SDL_SCANCODE_C:
case SDL_SCANCODE_H:
SHOW_HISTOGRAM = !SHOW_HISTOGRAM;
break;
case SDL_SCANCODE_B:
background_color_index = (background_color_index + 1) % background_colors.size();
clear_color = background_colors[background_color_index];
break;
case SDL_SCANCODE_LEFT:
if (current_image_index > 0) {
current_image_index--;
@ -696,6 +722,11 @@ int main(int argc, char* argv[]) {
ImGuiTexInspect::SizeExcludingBorder(wSize)
);
CurrentInspector_SetAlphaMode(
ImGuiTexInspect::InspectorAlphaMode_CustomColor
);
ImGuiTexInspect::CurrentInspector_SetCustomBackgroundColor(clear_color);
if (GRID_ENABLED) {
CurrentInspector_ClearFlags(ImGuiTexInspect::InspectorFlags_NoGrid);
}else {
@ -746,6 +777,7 @@ int main(int argc, char* argv[]) {
if (ImGui::BeginPopup("HelpPopup")) {
ImGui::Text("tview Help");
ImGui::Separator();
ImGui::Text("b - cycle background color");
ImGui::Text("r - rotate 90 deg clockwise");
ImGui::Text("g - toggle grid");
ImGui::Text("a - toggle filtering");
@ -753,14 +785,14 @@ int main(int argc, char* argv[]) {
ImGui::Text("d - cycle pixel detail mode");
ImGui::Separator();
ImGui::Text("modes:");
ImGui::Text("\tOff");
ImGui::Text("\tGradient Arrow");
ImGui::Text("\tHex Code");
ImGui::Text("\tRGB Values");
ImGui::Text("\tFloat Values");
ImGui::Text(" Off");
ImGui::Text(" Gradient Arrow");
ImGui::Text(" Hex Code");
ImGui::Text(" RGB Values");
ImGui::Text(" Float Values");
ImGui::Separator();
ImGui::Text("h - show help popup");
ImGui::Text("c - toggle color histogram");
ImGui::Text("? - show help popup");
ImGui::Text("h - toggle color histogram");
ImGui::Text("e - toggle EXIF info");
ImGui::Separator();
ImGui::Text("q - quit");
@ -768,155 +800,166 @@ int main(int argc, char* argv[]) {
ImGui::Text("click anywhere to continue");
ImGui::EndPopup();
}
if (SHOW_EXIF && t.exif.CameraMake != "NULL") {
ImGuiWindowClass topmost;
topmost.ClassId = ImHashStr("TopMost");
topmost.ViewportFlagsOverrideSet = ImGuiViewportFlags_TopMost;
ImGui::SetNextWindowClass(&topmost);
ImGui::SetNextWindowSize(ImVec2(600, 600), ImGuiCond_FirstUseEver);
ImGui::Begin("EXIF", NULL, ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoFocusOnAppearing);
if(ImGui::BeginTable("Hardware", 2, ImGuiTableFlags_Resizable)) {
ImGui::TableSetupColumn("Field", ImGuiTableColumnFlags_WidthFixed, ImGuiTableColumnFlags_NoHide, 150.0f);
ImGui::TableSetupColumn("Value", ImGuiTableColumnFlags_WidthStretch);
ImGui::TableNextRow();
ImGui::TableSetColumnIndex(0);
ImGui::TextWrapped("Make");
ImGui::TableSetColumnIndex(1);
ImGui::TextWrapped("%s", t.exif.CameraMake.c_str());
ImGui::TableNextRow();
ImGui::TableSetColumnIndex(0);
ImGui::TextWrapped("Model");
ImGui::TableSetColumnIndex(1);
ImGui::TextWrapped("%s", t.exif.CameraModel.c_str());
ImGui::TableNextRow();
ImGui::TableSetColumnIndex(0);
ImGui::TextWrapped("Lens");
ImGui::TableSetColumnIndex(1);
ImGui::TextWrapped("%s", t.exif.LensModel.c_str());
ImGui::EndTable();
}
ImGui::Separator();
if(ImGui::BeginTable("Photo", 2, ImGuiTableFlags_Resizable)) {
ImGui::TableSetupColumn("Field", ImGuiTableColumnFlags_WidthFixed, ImGuiTableColumnFlags_NoHide, 150.0f);
ImGui::TableSetupColumn("Value", ImGuiTableColumnFlags_WidthStretch);
ImGui::TableNextRow();
ImGui::TableSetColumnIndex(0);
ImGui::TextWrapped("Shutter Speed");
ImGui::TableSetColumnIndex(1);
ImGui::TextWrapped("%s", t.exif.ShutterSpeed.c_str());
ImGui::TableNextRow();
ImGui::TableSetColumnIndex(0);
ImGui::TextWrapped("F-Stop");
ImGui::TableSetColumnIndex(1);
ImGui::TextWrapped("%s", t.exif.FNumber.c_str());
ImGui::TableNextRow();
ImGui::TableSetColumnIndex(0);
ImGui::TextWrapped("ISO");
ImGui::TableSetColumnIndex(1);
ImGui::TextWrapped("%s", t.exif.ISO.c_str());
ImGui::TableNextRow();
ImGui::TableSetColumnIndex(0);
ImGui::TextWrapped("Focal Length");
ImGui::TableSetColumnIndex(1);
ImGui::TextWrapped("%s", t.exif.FocalLength.c_str());
ImGui::TableNextRow();
ImGui::TableSetColumnIndex(0);
ImGui::TextWrapped("Exposure Comp");
ImGui::TableSetColumnIndex(1);
ImGui::TextWrapped("%s", t.exif.ExposureBias.c_str());
ImGui::TableNextRow();
ImGui::TableSetColumnIndex(0);
ImGui::TextWrapped("Metering Mode");
ImGui::TableSetColumnIndex(1);
ImGui::TextWrapped("%s", t.exif.MeteringMode.c_str());
ImGui::TableNextRow();
ImGui::TableSetColumnIndex(0);
ImGui::TextWrapped("Flash");
ImGui::TableSetColumnIndex(1);
ImGui::TextWrapped("%s", t.exif.Flash.c_str());
ImGui::EndTable();
}
ImGui::Separator();
if(ImGui::BeginTable("Meta", 2, ImGuiTableFlags_Resizable)) {
ImGui::TableSetupColumn("Field", ImGuiTableColumnFlags_WidthFixed, ImGuiTableColumnFlags_NoHide, 150.0f);
ImGui::TableSetupColumn("Value", ImGuiTableColumnFlags_WidthStretch);
ImGui::TableNextRow();
ImGui::TableSetColumnIndex(0);
ImGui::TextWrapped("Date");
ImGui::TableSetColumnIndex(1);
ImGui::TextWrapped("%s %s", t.exif.TimeTaken.c_str(), t.exif.TimeTakenOffset.c_str());
ImGui::TableNextRow();
ImGui::TableSetColumnIndex(0);
ImGui::TextWrapped("Dimensions");
ImGui::TableSetColumnIndex(1);
ImGui::TextWrapped("%sx%s", t.exif.ImageDimensionX.c_str(), t.exif.ImageDimensiony.c_str());
ImGui::TableNextRow();
ImGui::TableSetColumnIndex(0);
ImGui::TextWrapped("Orientation");
ImGui::TableSetColumnIndex(1);
ImGui::TextWrapped("%s", t.exif.ImageOrientation.c_str());
ImGui::EndTable();
}
ImGui::Separator();
if(ImGui::BeginTable("Location", 2, ImGuiTableFlags_Resizable)) {
ImGui::TableSetupColumn("Field", ImGuiTableColumnFlags_WidthFixed, ImGuiTableColumnFlags_NoHide, 150.0f);
ImGui::TableSetupColumn("Value", ImGuiTableColumnFlags_WidthStretch);
ImGui::TableNextRow();
ImGui::TableSetColumnIndex(0);
ImGui::TextWrapped("Latitude");
ImGui::TableSetColumnIndex(1);
ImGui::TextWrapped("%s %s", t.exif.GPSLat.c_str(), t.exif.GPSLatref.c_str());
ImGui::TableNextRow();
ImGui::TableSetColumnIndex(0);
ImGui::TextWrapped("Longitude");
ImGui::TableSetColumnIndex(1);
ImGui::TextWrapped("%s %s", t.exif.GPSLon.c_str(), t.exif.GPSLonref.c_str());
ImGui::EndTable();
}
ImGui::Separator();
if(ImGui::BeginTable("All EXIF", 2, ImGuiTableFlags_Resizable)) {
ImGui::TableSetupColumn("Field", ImGuiTableColumnFlags_WidthFixed, ImGuiTableColumnFlags_NoHide, 150.0f);
ImGui::TableSetupColumn("Value", ImGuiTableColumnFlags_WidthStretch);
for (auto const& [key, val] : t.exif.all_fields)
{
if (SHOW_EXIF) {
if (t.exif.CameraMake != "NULL") {
ImGuiWindowClass topmost;
topmost.ClassId = ImHashStr("TopMost");
topmost.ViewportFlagsOverrideSet = ImGuiViewportFlags_TopMost;
ImGui::SetNextWindowClass(&topmost);
ImGui::SetNextWindowSize(ImVec2(600, 600), ImGuiCond_FirstUseEver);
ImGui::Begin("EXIF", &SHOW_EXIF, ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoFocusOnAppearing);
if(ImGui::BeginTable("Hardware", 2, ImGuiTableFlags_Resizable)) {
ImGui::TableSetupColumn("Field", ImGuiTableColumnFlags_WidthFixed, ImGuiTableColumnFlags_NoHide, 150.0f);
ImGui::TableSetupColumn("Value", ImGuiTableColumnFlags_WidthStretch);
ImGui::TableNextRow();
ImGui::TableSetColumnIndex(0);
ImGui::TextWrapped("%s", key.c_str());
ImGui::TextWrapped("Make");
ImGui::TableSetColumnIndex(1);
ImGui::TextWrapped("%s", val.c_str());
ImGui::TextWrapped("%s", t.exif.CameraMake.c_str());
ImGui::TableNextRow();
ImGui::TableSetColumnIndex(0);
ImGui::TextWrapped("Model");
ImGui::TableSetColumnIndex(1);
ImGui::TextWrapped("%s", t.exif.CameraModel.c_str());
ImGui::TableNextRow();
ImGui::TableSetColumnIndex(0);
ImGui::TextWrapped("Lens");
ImGui::TableSetColumnIndex(1);
ImGui::TextWrapped("%s", t.exif.LensModel.c_str());
ImGui::EndTable();
}
ImGui::EndTable();
ImGui::Separator();
if(ImGui::BeginTable("Photo", 2, ImGuiTableFlags_Resizable)) {
ImGui::TableSetupColumn("Field", ImGuiTableColumnFlags_WidthFixed, ImGuiTableColumnFlags_NoHide, 150.0f);
ImGui::TableSetupColumn("Value", ImGuiTableColumnFlags_WidthStretch);
ImGui::TableNextRow();
ImGui::TableSetColumnIndex(0);
ImGui::TextWrapped("Shutter Speed");
ImGui::TableSetColumnIndex(1);
ImGui::TextWrapped("%s", t.exif.ShutterSpeed.c_str());
ImGui::TableNextRow();
ImGui::TableSetColumnIndex(0);
ImGui::TextWrapped("F-Stop");
ImGui::TableSetColumnIndex(1);
ImGui::TextWrapped("%s", t.exif.FNumber.c_str());
ImGui::TableNextRow();
ImGui::TableSetColumnIndex(0);
ImGui::TextWrapped("ISO");
ImGui::TableSetColumnIndex(1);
ImGui::TextWrapped("%s", t.exif.ISO.c_str());
ImGui::TableNextRow();
ImGui::TableSetColumnIndex(0);
ImGui::TextWrapped("Focal Length");
ImGui::TableSetColumnIndex(1);
ImGui::TextWrapped("%s", t.exif.FocalLength.c_str());
ImGui::TableNextRow();
ImGui::TableSetColumnIndex(0);
ImGui::TextWrapped("Exposure Comp");
ImGui::TableSetColumnIndex(1);
ImGui::TextWrapped("%s", t.exif.ExposureBias.c_str());
ImGui::TableNextRow();
ImGui::TableSetColumnIndex(0);
ImGui::TextWrapped("Metering Mode");
ImGui::TableSetColumnIndex(1);
ImGui::TextWrapped("%s", t.exif.MeteringMode.c_str());
ImGui::TableNextRow();
ImGui::TableSetColumnIndex(0);
ImGui::TextWrapped("Flash");
ImGui::TableSetColumnIndex(1);
ImGui::TextWrapped("%s", t.exif.Flash.c_str());
ImGui::EndTable();
}
ImGui::Separator();
if(ImGui::BeginTable("Meta", 2, ImGuiTableFlags_Resizable)) {
ImGui::TableSetupColumn("Field", ImGuiTableColumnFlags_WidthFixed, ImGuiTableColumnFlags_NoHide, 150.0f);
ImGui::TableSetupColumn("Value", ImGuiTableColumnFlags_WidthStretch);
ImGui::TableNextRow();
ImGui::TableSetColumnIndex(0);
ImGui::TextWrapped("Date");
ImGui::TableSetColumnIndex(1);
ImGui::TextWrapped("%s %s", t.exif.TimeTaken.c_str(), t.exif.TimeTakenOffset.c_str());
ImGui::TableNextRow();
ImGui::TableSetColumnIndex(0);
ImGui::TextWrapped("Dimensions");
ImGui::TableSetColumnIndex(1);
ImGui::TextWrapped("%sx%s", t.exif.ImageDimensionX.c_str(), t.exif.ImageDimensiony.c_str());
ImGui::TableNextRow();
ImGui::TableSetColumnIndex(0);
ImGui::TextWrapped("Orientation");
ImGui::TableSetColumnIndex(1);
ImGui::TextWrapped("%s", t.exif.ImageOrientation.c_str());
ImGui::EndTable();
}
ImGui::Separator();
if(ImGui::BeginTable("Location", 2, ImGuiTableFlags_Resizable)) {
ImGui::TableSetupColumn("Field", ImGuiTableColumnFlags_WidthFixed, ImGuiTableColumnFlags_NoHide, 150.0f);
ImGui::TableSetupColumn("Value", ImGuiTableColumnFlags_WidthStretch);
ImGui::TableNextRow();
ImGui::TableSetColumnIndex(0);
ImGui::TextWrapped("Latitude");
ImGui::TableSetColumnIndex(1);
ImGui::TextWrapped("%s %s", t.exif.GPSLat.c_str(), t.exif.GPSLatref.c_str());
ImGui::TableNextRow();
ImGui::TableSetColumnIndex(0);
ImGui::TextWrapped("Longitude");
ImGui::TableSetColumnIndex(1);
ImGui::TextWrapped("%s %s", t.exif.GPSLon.c_str(), t.exif.GPSLonref.c_str());
ImGui::EndTable();
}
ImGui::Separator();
if(ImGui::BeginTable("All EXIF", 2, ImGuiTableFlags_Resizable)) {
ImGui::TableSetupColumn("Field", ImGuiTableColumnFlags_WidthFixed, ImGuiTableColumnFlags_NoHide, 150.0f);
ImGui::TableSetupColumn("Value", ImGuiTableColumnFlags_WidthStretch);
for (auto const& [key, val] : t.exif.all_fields)
{
ImGui::TableNextRow();
ImGui::TableSetColumnIndex(0);
ImGui::TextWrapped("%s", key.c_str());
ImGui::TableSetColumnIndex(1);
ImGui::TextWrapped("%s", val.c_str());
}
ImGui::EndTable();
}
ImGui::Separator();
ImGui::Text("Press e to hide");
ImGui::End();
} else {
ImGuiWindowClass topmost;
topmost.ClassId = ImHashStr("TopMost");
topmost.ViewportFlagsOverrideSet = ImGuiViewportFlags_TopMost;
ImGui::SetNextWindowClass(&topmost);
ImGui::SetNextWindowSize(ImVec2(200, 50), ImGuiCond_FirstUseEver);
ImGui::Begin("EXIF", &SHOW_EXIF, ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_AlwaysAutoResize);
ImGui::Text("No EXIF data available.");
ImGui::End();
}
ImGui::Separator();
ImGui::Text("Press e to hide");
ImGui::End();
}
}
if (SHOW_HISTOGRAM) {
@ -941,8 +984,7 @@ int main(int argc, char* argv[]) {
// Rendering
ImGui::Render();
glViewport(0, 0, (int)io.DisplaySize.x, (int)io.DisplaySize.y);
glClearColor(clear_color.x * clear_color.w, clear_color.y * clear_color.w,
clear_color.z * clear_color.w, clear_color.w);
glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w);
glClear(GL_COLOR_BUFFER_BIT);
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
SDL_GL_SwapWindow(window);