Skip to content

Commit d34dc6d

Browse files
committed
tool: remove redundant code + improve a bit the UX
1 parent 5d866de commit d34dc6d

3 files changed

Lines changed: 98 additions & 85 deletions

File tree

include/screenshot_tool.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ enum ErrorFlag : size_t
7474
InvalidPath,
7575
InvalidModel,
7676
FailedToScanBarCode,
77+
FailedToCopyText,
7778
COUNT
7879
};
7980

@@ -220,6 +221,7 @@ class ScreenshotTool
220221
bool m_is_color_picking = false;
221222
bool m_is_text_placing = false;
222223

224+
void CreateCopyTextButton(const std::string& text);
223225
void RefreshOcrModels();
224226

225227
void HandleShortcutsInput();

src/screenshot_tool.cpp

Lines changed: 95 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
using namespace std::chrono_literals;
4444
using namespace spdlog;
4545

46+
static constexpr ImVec4 k_error_color(1.0f, 0.0f, 0.0f, 1.0f);
4647
static constexpr ImVec2 origin(0, 0);
4748
static void* logo_texture = nullptr;
4849

@@ -1111,35 +1112,41 @@ void ScreenshotTool::DrawOcrTools()
11111112

11121113
auto refresh_models = [&]() {
11131114
RefreshOcrModels();
1114-
const auto& it = std::find(m_ocr_models_list.begin(), m_ocr_models_list.end(), m_inputs.ocr_model);
1115+
const auto& it = std::find(m_ocr_models_list.begin(), m_ocr_models_list.end(), ocr_model);
11151116
item_selected_idx = (it != m_ocr_models_list.end()) ? std::distance(m_ocr_models_list.begin(), it) : 0;
11161117
};
11171118

1119+
auto push_error_style = [](bool cond) {
1120+
if (cond)
1121+
ImGui::PushStyleColor(ImGuiCol_Text, k_error_color);
1122+
};
1123+
auto pop_error_label = [](bool cond, const char* label) {
1124+
if (cond)
1125+
{
1126+
ImGui::PopStyleColor();
1127+
ImGui::SameLine();
1128+
ImGui::TextColored(k_error_color, "%s", label);
1129+
}
1130+
};
1131+
11181132
ImGui::PushID("OcrTools");
11191133
ImGui::SeparatorText("OCR");
11201134

1121-
// Snapshot of the error for not crashing the program
1122-
bool invalid_path = HasError(InvalidPath);
1123-
if (invalid_path)
1124-
ImGui::PushStyleColor(ImGuiCol_Text, IM_COL32(255, 0, 0, 255));
1135+
const bool invalid_path = HasError(InvalidPath);
1136+
const bool invalid_model = HasError(InvalidModel);
1137+
const bool has_errors = invalid_path || invalid_model;
11251138

1139+
// --- Path input ---
1140+
push_error_style(invalid_path);
11261141
draw_input_text_folder("Path", "##ocr_path", refresh_models, ocr_path);
1127-
1128-
if (invalid_path)
1129-
{
1130-
ImGui::SameLine();
1131-
ImGui::Text("Invalid!");
1132-
ImGui::PopStyleColor();
1133-
}
1142+
pop_error_label(invalid_path, "Invalid path!");
11341143
ImGui::SameLine();
1135-
HelpMarker("Full-Path to the OCR models (.traineddata). Supports drag-and-drop too");
1144+
HelpMarker("Full path to the OCR models (.traineddata). Supports drag-and-drop");
11361145

1146+
// --- Model combo (only shown when path is valid) ---
11371147
if (!invalid_path)
11381148
{
1139-
bool invalid_model = HasError(InvalidModel);
1140-
if (invalid_model)
1141-
ImGui::PushStyleColor(ImGuiCol_Text, IM_COL32(255, 0, 0, 255));
1142-
1149+
push_error_style(invalid_model);
11431150
if (ImGui::BeginCombo("Model", ocr_model.c_str(), ImGuiComboFlags_HeightLarge))
11441151
{
11451152
static ImGuiTextFilter filter;
@@ -1154,9 +1161,9 @@ void ScreenshotTool::DrawOcrTools()
11541161

11551162
for (size_t i = 0; i < m_ocr_models_list.size(); ++i)
11561163
{
1157-
bool is_selected = (item_selected_idx == i);
11581164
if (filter.PassFilter(m_ocr_models_list[i].c_str()))
11591165
{
1166+
const bool is_selected = (item_selected_idx == i);
11601167
if (ImGui::Selectable(m_ocr_models_list[i].c_str(), is_selected))
11611168
{
11621169
item_selected_idx = i;
@@ -1167,50 +1174,45 @@ void ScreenshotTool::DrawOcrTools()
11671174
}
11681175
ImGui::EndCombo();
11691176
}
1177+
pop_error_label(invalid_model, "Invalid model!");
1178+
}
11701179

1171-
if (invalid_model)
1180+
// --- Extract button + result details ---
1181+
if (!has_errors)
1182+
{
1183+
if (ImGui::Button("Extract Text"))
11721184
{
1173-
ImGui::PopStyleColor();
1174-
ImGui::SameLine();
1175-
ImGui::TextColored(ImVec4(1, 0, 0, 1), "Invalid!");
1185+
const Result<>& res = m_ocr_api.Configure(ocr_path.c_str(), ocr_model.c_str());
1186+
if (!res.ok())
1187+
SetError(FailedToScanOcr, res.error_v());
1188+
else
1189+
{
1190+
ClearError(FailedToScanOcr);
1191+
Result<ocr_result_t> result = m_ocr_api.ExtractTextCapture(GetFinalImage(true));
1192+
if (result.ok())
1193+
m_inputs.ocr_results = std::move(result.get());
1194+
}
11761195
}
1177-
}
11781196

1179-
if (!HasError(InvalidModel) && !HasError(InvalidPath) && ImGui::Button("Extract Text"))
1180-
{
1181-
const Result<>& res = m_ocr_api.Configure(ocr_path.c_str(), ocr_model.c_str());
1182-
if (!res.ok())
1197+
if (HasError(FailedToScanOcr))
11831198
{
1184-
SetError(FailedToScanOcr, res.error_v());
1199+
ImGui::SameLine();
1200+
ImGui::TextColored(k_error_color, "Failed to scan: %s", GetError(FailedToScanOcr).c_str());
11851201
}
11861202
else
11871203
{
1188-
ClearError(FailedToScanOcr);
1189-
Result<ocr_result_t> result = m_ocr_api.ExtractTextCapture(GetFinalImage(true));
1190-
if (result.ok())
1191-
m_inputs.ocr_results = std::move(result.get());
1204+
ImGui::SameLine();
1205+
HelpMarker("If results seem off, try Edit > Optimize OCR for...");
11921206
}
1193-
}
1194-
1195-
HelpMarker("If the result seems off, you could try selecting an option in Edit > Optimize OCR for...");
11961207

1197-
if (HasError(FailedToScanOcr))
1198-
{
1199-
ImGui::SameLine();
1200-
ImGui::TextColored(ImVec4(1.0f, 0.0f, 0.0f, 1.0f), "Failed to scan image: %s", GetError(FailedToScanOcr).c_str());
1201-
}
1202-
1203-
if (!HasError(InvalidModel) && !HasError(InvalidPath))
1204-
{
1205-
ImGui::SameLine();
1206-
if (m_inputs.ocr_results.confidence && ImGui::TreeNode("Details"))
1208+
const auto& results = m_inputs.ocr_results;
1209+
if (results.confidence > 0 && ImGui::TreeNode("Details"))
12071210
{
1208-
ImGui::Text("Confidence score:");
1211+
ImGui::Text("Confidence:");
12091212
ImGui::SameLine();
1210-
ImGui::TextColored(
1211-
get_confidence_color(m_inputs.ocr_results.confidence), "%d%%", m_inputs.ocr_results.confidence);
1212-
1213-
ImGui::Text("Using PSM for: %s", m_inputs.ocr_results.psm_str.c_str());
1213+
ImGui::TextColored(get_confidence_color(results.confidence), "%d%%", results.confidence);
1214+
ImGui::SameLine();
1215+
ImGui::Text(" PSM: %s", results.psm_str.c_str());
12141216
ImGui::TreePop();
12151217
}
12161218
}
@@ -1220,20 +1222,8 @@ void ScreenshotTool::DrawOcrTools()
12201222
ImVec2(-1, ImGui::GetTextLineHeight() * 10),
12211223
g_config->File.allow_out_edit ? 0 : ImGuiInputTextFlags_ReadOnly);
12221224

1223-
if (m_inputs.ocr_results.data.empty())
1224-
{
1225-
ImGui::PopID();
1226-
return;
1227-
}
1228-
1229-
if (ImGui::Button("Copy Text"))
1230-
{
1231-
if (m_inputs.ocr_results.data.back() == '\n')
1232-
m_inputs.ocr_results.data.pop_back();
1233-
const Result<>& res = g_clipboard->CopyText(m_inputs.ocr_results.data);
1234-
if (!res.ok())
1235-
error("Failed to copy text: {}", res.error_v());
1236-
}
1225+
if (!m_inputs.ocr_results.data.empty())
1226+
CreateCopyTextButton(m_inputs.ocr_results.data);
12371227

12381228
ImGui::PopID();
12391229
}
@@ -1252,45 +1242,34 @@ void ScreenshotTool::DrawBarDecodeTools()
12521242
}
12531243
else
12541244
{
1245+
ClearError(FailedToScanBarCode);
12551246
m_inputs.zbar_scan_result = std::move(scan.get());
1247+
m_inputs.barcode_text.clear();
12561248
for (const auto& data : m_inputs.zbar_scan_result.datas)
12571249
m_inputs.barcode_text += data + "\n\n";
1258-
ClearError(FailedToScanBarCode);
12591250
}
12601251
}
12611252

12621253
if (HasError(FailedToScanBarCode))
12631254
{
1264-
ImGui::PushStyleColor(ImGuiCol_Text, IM_COL32(255, 0, 0, 255));
12651255
ImGui::SameLine();
1266-
ImGui::TextColored(
1267-
ImVec4(1.0f, 0.0f, 0.0f, 1.0f), "Failed to decode scan: %s", GetError(FailedToScanBarCode).c_str());
1268-
ImGui::PopStyleColor();
1256+
ImGui::TextColored(k_error_color, "Failed to decode: %s", GetError(FailedToScanBarCode).c_str());
12691257
}
1270-
else
1258+
else if (!m_inputs.zbar_scan_result.datas.empty() && ImGui::TreeNode("Details"))
12711259
{
1272-
if (!m_inputs.zbar_scan_result.datas.empty() && ImGui::TreeNode("Details"))
1273-
{
1274-
ImGui::Text("Detected barcodes:");
1275-
for (const auto& [sym, count] : m_inputs.zbar_scan_result.symbologies)
1276-
ImGui::BulletText("%s (x%d)", sym.c_str(), count);
1277-
ImGui::TreePop();
1278-
}
1260+
ImGui::Text("Detected barcodes:");
1261+
for (const auto& [sym, count] : m_inputs.zbar_scan_result.symbologies)
1262+
ImGui::BulletText("%s (x%d)", sym.c_str(), count);
1263+
ImGui::TreePop();
12791264
}
12801265

12811266
ImGui::InputTextMultiline("##barcode",
12821267
&m_inputs.barcode_text,
12831268
ImVec2(-1, ImGui::GetTextLineHeight() * 10),
12841269
g_config->File.allow_out_edit ? 0 : ImGuiInputTextFlags_ReadOnly);
12851270

1286-
if (!m_inputs.barcode_text.empty() && ImGui::Button("Copy Text"))
1287-
{
1288-
if (m_inputs.barcode_text.back() == '\n')
1289-
m_inputs.barcode_text.pop_back();
1290-
const Result<>& res = g_clipboard->CopyText(m_inputs.barcode_text);
1291-
if (!res.ok())
1292-
error("Failed to copy text: {}", res.error_v());
1293-
}
1271+
if (!m_inputs.barcode_text.empty())
1272+
CreateCopyTextButton(m_inputs.barcode_text);
12941273

12951274
ImGui::PopID();
12961275
}
@@ -1961,6 +1940,37 @@ ImFont* ScreenshotTool::CacheAndGetFont(const std::string& font_path, const floa
19611940
return font;
19621941
}
19631942

1943+
void ScreenshotTool::CreateCopyTextButton(const std::string& text_copy)
1944+
{
1945+
static bool just_copied = false;
1946+
static double copy_time = 0.0;
1947+
1948+
const double now = ImGui::GetTime();
1949+
if (just_copied && now - copy_time > 1.5)
1950+
just_copied = false;
1951+
1952+
if (ImGui::Button(just_copied ? "Copied!" : "Copy Text"))
1953+
{
1954+
const Result<>& res = g_clipboard->CopyText(text_copy);
1955+
if (!res.ok())
1956+
{
1957+
SetError(FailedToCopyText, res.error_v());
1958+
}
1959+
else
1960+
{
1961+
ClearError(FailedToCopyText);
1962+
just_copied = true;
1963+
copy_time = now;
1964+
}
1965+
}
1966+
1967+
if (HasError(FailedToCopyText))
1968+
{
1969+
ImGui::SameLine();
1970+
ImGui::TextColored(k_error_color, "Failed to copy text: %s", GetError(FailedToCopyText).c_str());
1971+
}
1972+
}
1973+
19641974
void ScreenshotTool::RefreshOcrModels()
19651975
{
19661976
m_ocr_models_list = get_training_data_list(m_inputs.ocr_path);

src/text_extraction.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ static std::string psm_to_str(tesseract::PageSegMode psm)
3030
case PSM_SINGLE_BLOCK_VERT_TEXT: return "Vertical block";
3131
case PSM_SPARSE_TEXT: return "Sparsed text - big region";
3232
case PSM_SINGLE_BLOCK: return "Mid-size block";
33+
case PSM_AUTO_OSD: return "Auto detection";
3334
default: return "Unknown";
3435
}
3536
}

0 commit comments

Comments
 (0)