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:
parent
14ed043bf5
commit
089acbfff1
@ -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
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user