fix: Normalize line endings in TranslationUI.cpp

Convert Windows CRLF to Unix LF line endings for consistency across platforms and version control.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
StillHammer 2025-11-21 18:11:57 +08:00
parent 14ed043bf5
commit 089acbfff1

View File

@ -1,250 +1,250 @@
#include <glad/glad.h> // MUST be FIRST! Provides OpenGL functions #include <glad/glad.h> // MUST be FIRST! Provides OpenGL functions
#define GLFW_INCLUDE_NONE // Tell GLFW not to include OpenGL headers (GLAD does it) #define GLFW_INCLUDE_NONE // Tell GLFW not to include OpenGL headers (GLAD does it)
#include "TranslationUI.h" #include "TranslationUI.h"
#include <imgui.h> #include <imgui.h>
#include <imgui_impl_glfw.h> #include <imgui_impl_glfw.h>
#include <imgui_impl_opengl3.h> #include <imgui_impl_opengl3.h>
#include <iostream> #include <iostream>
#include <thread> #include <thread>
namespace secondvoice { namespace secondvoice {
TranslationUI::TranslationUI(int width, int height) TranslationUI::TranslationUI(int width, int height)
: width_(width) : width_(width)
, height_(height) { , height_(height) {
} }
TranslationUI::~TranslationUI() { TranslationUI::~TranslationUI() {
if (window_) { if (window_) {
ImGui_ImplOpenGL3_Shutdown(); ImGui_ImplOpenGL3_Shutdown();
ImGui_ImplGlfw_Shutdown(); ImGui_ImplGlfw_Shutdown();
ImGui::DestroyContext(); ImGui::DestroyContext();
glfwDestroyWindow(window_); glfwDestroyWindow(window_);
glfwTerminate(); glfwTerminate();
} }
} }
bool TranslationUI::initialize() { bool TranslationUI::initialize() {
// Initialize GLFW // Initialize GLFW
std::cout << "[UI] Initializing GLFW..." << std::endl; std::cout << "[UI] Initializing GLFW..." << std::endl;
glfwSetErrorCallback([](int error, const char* description) { glfwSetErrorCallback([](int error, const char* description) {
std::cerr << "[GLFW Error " << error << "] " << description << std::endl; std::cerr << "[GLFW Error " << error << "] " << description << std::endl;
}); });
if (!glfwInit()) { if (!glfwInit()) {
std::cerr << "[UI] Failed to initialize GLFW" << std::endl; std::cerr << "[UI] Failed to initialize GLFW" << std::endl;
return false; return false;
} }
std::cout << "[UI] GLFW initialized successfully" << std::endl; std::cout << "[UI] GLFW initialized successfully" << std::endl;
// FORCE high-performance GPU (NVIDIA/AMD dedicated) // FORCE high-performance GPU (NVIDIA/AMD dedicated)
std::cout << "[UI] Requesting high-performance GPU..." << std::endl; std::cout << "[UI] Requesting high-performance GPU..." << std::endl;
// OpenGL 3.3 - core profile // OpenGL 3.3 - core profile
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
// Create window // Create window
std::cout << "[UI] Creating GLFW window (" << width_ << "x" << height_ << ")..." << std::endl; std::cout << "[UI] Creating GLFW window (" << width_ << "x" << height_ << ")..." << std::endl;
window_ = glfwCreateWindow(width_, height_, "SecondVoice - Live Translation", nullptr, nullptr); window_ = glfwCreateWindow(width_, height_, "SecondVoice - Live Translation", nullptr, nullptr);
if (!window_) { if (!window_) {
std::cerr << "[UI] Failed to create GLFW window" << std::endl; std::cerr << "[UI] Failed to create GLFW window" << std::endl;
glfwTerminate(); glfwTerminate();
return false; return false;
} }
std::cout << "[UI] GLFW window created successfully" << std::endl; std::cout << "[UI] GLFW window created successfully" << std::endl;
glfwMakeContextCurrent(window_); glfwMakeContextCurrent(window_);
glfwSwapInterval(1); // Enable vsync glfwSwapInterval(1); // Enable vsync
// Initialize GLAD - MUST happen after glfwMakeContextCurrent! // Initialize GLAD - MUST happen after glfwMakeContextCurrent!
std::cout << "[UI] Initializing GLAD OpenGL loader..." << std::endl; std::cout << "[UI] Initializing GLAD OpenGL loader..." << std::endl;
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) { if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
std::cerr << "[UI] Failed to initialize GLAD!" << std::endl; std::cerr << "[UI] Failed to initialize GLAD!" << std::endl;
glfwDestroyWindow(window_); glfwDestroyWindow(window_);
glfwTerminate(); glfwTerminate();
return false; return false;
} }
std::cout << "[UI] GLAD initialized successfully" << std::endl; std::cout << "[UI] GLAD initialized successfully" << std::endl;
// Query OpenGL context to see which GPU we got // Query OpenGL context to see which GPU we got
const GLubyte* vendor = glGetString(GL_VENDOR); const GLubyte* vendor = glGetString(GL_VENDOR);
const GLubyte* renderer = glGetString(GL_RENDERER); const GLubyte* renderer = glGetString(GL_RENDERER);
const GLubyte* version = glGetString(GL_VERSION); const GLubyte* version = glGetString(GL_VERSION);
std::cout << "[UI] ========================================" << std::endl; std::cout << "[UI] ========================================" << std::endl;
std::cout << "[UI] OpenGL Context Info:" << std::endl; std::cout << "[UI] OpenGL Context Info:" << std::endl;
std::cout << "[UI] Vendor: " << (vendor ? (const char*)vendor : "Unknown") << std::endl; std::cout << "[UI] Vendor: " << (vendor ? (const char*)vendor : "Unknown") << std::endl;
std::cout << "[UI] Renderer: " << (renderer ? (const char*)renderer : "Unknown") << std::endl; std::cout << "[UI] Renderer: " << (renderer ? (const char*)renderer : "Unknown") << std::endl;
std::cout << "[UI] Version: " << (version ? (const char*)version : "Unknown") << std::endl; std::cout << "[UI] Version: " << (version ? (const char*)version : "Unknown") << std::endl;
std::cout << "[UI] ========================================" << std::endl; std::cout << "[UI] ========================================" << std::endl;
// Initialize ImGui // Initialize ImGui
IMGUI_CHECKVERSION(); IMGUI_CHECKVERSION();
ImGui::CreateContext(); ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
ImGui::StyleColorsDark(); ImGui::StyleColorsDark();
ImGui_ImplGlfw_InitForOpenGL(window_, true); ImGui_ImplGlfw_InitForOpenGL(window_, true);
// TEST: Compile a simple shader to see REAL error messages // TEST: Compile a simple shader to see REAL error messages
std::cout << "[UI] Testing shader compilation..." << std::endl; std::cout << "[UI] Testing shader compilation..." << std::endl;
const char* vertexShaderSource = R"( const char* vertexShaderSource = R"(
#version 130 #version 130
in vec2 Position; in vec2 Position;
in vec2 UV; in vec2 UV;
in vec4 Color; in vec4 Color;
varying vec2 Frag_UV; varying vec2 Frag_UV;
varying vec4 Frag_Color; varying vec4 Frag_Color;
void main() { void main() {
Frag_UV = UV; Frag_UV = UV;
Frag_Color = Color; Frag_Color = Color;
gl_Position = vec4(Position, 0, 1); gl_Position = vec4(Position, 0, 1);
} }
)"; )";
GLuint testShader = glCreateShader(GL_VERTEX_SHADER); GLuint testShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(testShader, 1, &vertexShaderSource, NULL); glShaderSource(testShader, 1, &vertexShaderSource, NULL);
glCompileShader(testShader); glCompileShader(testShader);
GLint success; GLint success;
glGetShaderiv(testShader, GL_COMPILE_STATUS, &success); glGetShaderiv(testShader, GL_COMPILE_STATUS, &success);
if (!success) { if (!success) {
char infoLog[1024]; char infoLog[1024];
glGetShaderInfoLog(testShader, 1024, NULL, infoLog); glGetShaderInfoLog(testShader, 1024, NULL, infoLog);
std::cerr << "[UI] ==================== SHADER COMPILATION ERROR ====================" << std::endl; std::cerr << "[UI] ==================== SHADER COMPILATION ERROR ====================" << std::endl;
std::cerr << infoLog << std::endl; std::cerr << infoLog << std::endl;
std::cerr << "[UI] ====================================================================" << std::endl; std::cerr << "[UI] ====================================================================" << std::endl;
} else { } else {
std::cout << "[UI] Test shader compiled successfully!" << std::endl; std::cout << "[UI] Test shader compiled successfully!" << std::endl;
} }
glDeleteShader(testShader); glDeleteShader(testShader);
// DEBUG: Check if GLAD loaded glCreateShader // DEBUG: Check if GLAD loaded glCreateShader
std::cout << "[UI] DEBUG: glCreateShader function pointer = " << (void*)glCreateShader << std::endl; std::cout << "[UI] DEBUG: glCreateShader function pointer = " << (void*)glCreateShader << std::endl;
if (glCreateShader == nullptr) { if (glCreateShader == nullptr) {
std::cerr << "[UI] ERROR: glCreateShader is NULL!" << std::endl; std::cerr << "[UI] ERROR: glCreateShader is NULL!" << std::endl;
return false; return false;
} }
// Let ImGui auto-detect the GLSL version // Let ImGui auto-detect the GLSL version
ImGui_ImplOpenGL3_Init(nullptr); ImGui_ImplOpenGL3_Init(nullptr);
// CRITICAL: Release the OpenGL context from this thread // CRITICAL: Release the OpenGL context from this thread
// The UI rendering will happen in a separate thread which will call makeContextCurrent() // The UI rendering will happen in a separate thread which will call makeContextCurrent()
std::cout << "[UI] Releasing OpenGL context from initialization thread" << std::endl; std::cout << "[UI] Releasing OpenGL context from initialization thread" << std::endl;
glfwMakeContextCurrent(nullptr); glfwMakeContextCurrent(nullptr);
return true; return true;
} }
void TranslationUI::makeContextCurrent() { void TranslationUI::makeContextCurrent() {
if (window_) { if (window_) {
std::cout << "[UI] Making OpenGL context current in thread: " << std::this_thread::get_id() << std::endl; std::cout << "[UI] Making OpenGL context current in thread: " << std::this_thread::get_id() << std::endl;
glfwMakeContextCurrent(window_); glfwMakeContextCurrent(window_);
} }
} }
void TranslationUI::render() { void TranslationUI::render() {
glfwPollEvents(); glfwPollEvents();
// Start ImGui frame // Start ImGui frame
ImGui_ImplOpenGL3_NewFrame(); ImGui_ImplOpenGL3_NewFrame();
ImGui_ImplGlfw_NewFrame(); ImGui_ImplGlfw_NewFrame();
ImGui::NewFrame(); ImGui::NewFrame();
// Main window (full viewport) // Main window (full viewport)
ImGui::SetNextWindowPos(ImVec2(0, 0)); ImGui::SetNextWindowPos(ImVec2(0, 0));
ImGui::SetNextWindowSize(ImGui::GetIO().DisplaySize); ImGui::SetNextWindowSize(ImGui::GetIO().DisplaySize);
ImGui::Begin("SecondVoice", nullptr, ImGui::Begin("SecondVoice", nullptr,
ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoTitleBar |
ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoResize |
ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoMove |
ImGuiWindowFlags_NoCollapse); ImGuiWindowFlags_NoCollapse);
renderTranslations(); renderTranslations();
renderControls(); renderControls();
renderStatus(); renderStatus();
ImGui::End(); ImGui::End();
// Rendering // Rendering
ImGui::Render(); ImGui::Render();
int display_w, display_h; int display_w, display_h;
glfwGetFramebufferSize(window_, &display_w, &display_h); glfwGetFramebufferSize(window_, &display_w, &display_h);
glViewport(0, 0, display_w, display_h); glViewport(0, 0, display_w, display_h);
glClearColor(0.1f, 0.1f, 0.1f, 1.0f); glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
glfwSwapBuffers(window_); glfwSwapBuffers(window_);
} }
bool TranslationUI::shouldClose() const { bool TranslationUI::shouldClose() const {
return glfwWindowShouldClose(window_); return glfwWindowShouldClose(window_);
} }
void TranslationUI::addTranslation(const std::string& chinese, const std::string& french) { void TranslationUI::addTranslation(const std::string& chinese, const std::string& french) {
messages_.push_back({chinese, french}); messages_.push_back({chinese, french});
} }
void TranslationUI::renderTranslations() { void TranslationUI::renderTranslations() {
ImGui::Text("SecondVoice - Live Translation"); ImGui::Text("SecondVoice - Live Translation");
ImGui::Separator(); ImGui::Separator();
ImGui::BeginChild("Translations", ImVec2(0, -120), true); ImGui::BeginChild("Translations", ImVec2(0, -120), true);
for (const auto& msg : messages_) { for (const auto& msg : messages_) {
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.5f, 0.8f, 1.0f, 1.0f)); ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.5f, 0.8f, 1.0f, 1.0f));
ImGui::TextWrapped("中文: %s", msg.chinese.c_str()); ImGui::TextWrapped("中文: %s", msg.chinese.c_str());
ImGui::PopStyleColor(); ImGui::PopStyleColor();
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.5f, 1.0f, 0.5f, 1.0f)); ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.5f, 1.0f, 0.5f, 1.0f));
ImGui::TextWrapped("FR: %s", msg.french.c_str()); ImGui::TextWrapped("FR: %s", msg.french.c_str());
ImGui::PopStyleColor(); ImGui::PopStyleColor();
ImGui::Spacing(); ImGui::Spacing();
ImGui::Separator(); ImGui::Separator();
ImGui::Spacing(); ImGui::Spacing();
} }
if (auto_scroll_ && ImGui::GetScrollY() >= ImGui::GetScrollMaxY()) { if (auto_scroll_ && ImGui::GetScrollY() >= ImGui::GetScrollMaxY()) {
ImGui::SetScrollHereY(1.0f); ImGui::SetScrollHereY(1.0f);
} }
ImGui::EndChild(); ImGui::EndChild();
} }
void TranslationUI::renderControls() { void TranslationUI::renderControls() {
ImGui::Spacing(); ImGui::Spacing();
// Center the stop button // Center the stop button
float button_width = 200.0f; float button_width = 200.0f;
float window_width = ImGui::GetWindowWidth(); float window_width = ImGui::GetWindowWidth();
ImGui::SetCursorPosX((window_width - button_width) * 0.5f); ImGui::SetCursorPosX((window_width - button_width) * 0.5f);
if (ImGui::Button("STOP RECORDING", ImVec2(button_width, 40))) { if (ImGui::Button("STOP RECORDING", ImVec2(button_width, 40))) {
stop_requested_ = true; stop_requested_ = true;
} }
ImGui::Spacing(); ImGui::Spacing();
} }
void TranslationUI::renderStatus() { void TranslationUI::renderStatus() {
ImGui::Separator(); ImGui::Separator();
// Format duration as MM:SS // Format duration as MM:SS
int minutes = recording_duration_ / 60; int minutes = recording_duration_ / 60;
int seconds = recording_duration_ % 60; int seconds = recording_duration_ % 60;
ImGui::Text("Recording... Duration: %02d:%02d", minutes, seconds); ImGui::Text("Recording... Duration: %02d:%02d", minutes, seconds);
if (!processing_status_.empty()) { if (!processing_status_.empty()) {
ImGui::SameLine(); ImGui::SameLine();
ImGui::Text(" | Status: %s", processing_status_.c_str()); ImGui::Text(" | Status: %s", processing_status_.c_str());
} }
} }
} // namespace secondvoice } // namespace secondvoice