]> code.bitgloo.com Git - clyne/stmdspgui.git/commitdiff
swap status bar for log view
authorClyne Sullivan <clyne@bitgloo.com>
Mon, 9 Aug 2021 02:50:12 +0000 (22:50 -0400)
committerClyne Sullivan <clyne@bitgloo.com>
Mon, 9 Aug 2021 02:50:12 +0000 (22:50 -0400)
Makefile
source/code.cpp
source/device.cpp
source/file.cpp
source/logview.h [new file with mode: 0644]
source/main.cpp

index e00f59ee5defceaef54a09557146674a7251cc78..81f96f7e263eeaa942eb67e6f7b30eb472494689 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -31,5 +31,5 @@ clean:
 
 %.o: %.cc
        @echo "  CXX   " $<
-       g++ $(CXXFLAGS) -c $< -o $@
+       @g++ $(CXXFLAGS) -c $< -o $@
 
index ae0d2bf4c486e562de4e720b018efaacaf4ae819..e53165cfb6d690ec9fd9bea49bf734ef2ccd3c75 100644 (file)
 #include <string>
 
 extern std::string tempFileName;
-extern std::string statusMessage;
 extern stmdsp::device *m_device;
 
+extern void log(const std::string& str);
+
 TextEditor editor; // file.cpp
 static std::string editorCompiled;
-static std::string compileMessage;
 
 static std::string newTempFileName();
 static void compileEditorCode();
@@ -63,18 +63,13 @@ void codeRenderToolbar()
 
 void codeRenderWidgets()
 {
-    editor.Render("code", {WINDOW_WIDTH - 15, 635}, true);
-
-    if (ImGui::BeginPopup("compile", ImGuiWindowFlags_AlwaysHorizontalScrollbar)) {
-        ImGui::Text(compileMessage.c_str());
-        if (ImGui::Button("Close"))
-            ImGui::CloseCurrentPopup();
-        ImGui::EndPopup();
-    }
+    editor.Render("code", {WINDOW_WIDTH - 15, 450}, true);
 }
 
 void compileEditorCode()
 {
+    log("Compiling...");
+
     // Scrap cached build if there are changes
     if (editor.GetText().compare(editorCompiled) != 0) {
         std::filesystem::remove(tempFileName + ".o");
@@ -143,7 +138,7 @@ void compileEditorCode()
     std::ifstream result_file (makeOutput);
     std::ostringstream sstr;
     sstr << result_file.rdbuf();
-    compileMessage = sstr.str();
+    log(sstr.str().c_str());
 
     std::filesystem::remove(tempFileName);
     std::filesystem::remove(tempFileName + script_ext);
@@ -151,15 +146,16 @@ void compileEditorCode()
 
     if (result == 0) {
         editorCompiled = editor.GetText();
-        statusMessage = "Compilation succeeded.";
+        log("Compilation succeeded.");
     } else {
-        statusMessage = "Compilation failed.";
-        ImGui::OpenPopup("compile");
+        log("Compilation failed.");
     }
 }
 
 void disassembleCode()
 {
+    log("Disassembling...");
+
     if (tempFileName.size() == 0 || editor.GetText().compare(editorCompiled) != 0) {
         compileEditorCode();
     }
@@ -173,15 +169,15 @@ void disassembleCode()
             std::ifstream result_file (output);
             std::ostringstream sstr;
             sstr << result_file.rdbuf();
-            compileMessage = sstr.str();
+            log(sstr.str().c_str());
         }
 
         ImGui::OpenPopup("compile");
         std::filesystem::remove(output);
 
-        statusMessage = "Ready.";
+        log("Ready.");
     } else {
-        statusMessage = "Failed to load disassembly.";
+        log("Failed to load disassembly.");
     }
 }
 
index 1dcacf07b4204e22e9321976812d9fb4790120dc..cb4ee0a4b1cf369cb226f300b3a68bb3db225912 100644 (file)
@@ -14,7 +14,7 @@
 #include "imgui.h"
 
 extern stmdsp::device *m_device;
-extern std::string statusMessage;
+extern void log(const std::string& str);
 
 static const char *sampleRateList[6] = {
     "8 kHz",
@@ -91,35 +91,35 @@ void deviceConnect()
             m_device = new stmdsp::device(devices.front());
             if (m_device->connected()) {
                 sampleRatePreview = sampleRateList[m_device->get_sample_rate()];
-                statusMessage = "Connected!";
+                log("Connected!");
             } else {
                 delete m_device;
                 m_device = nullptr;
-                statusMessage = "Failed to connect.";
+                log("Failed to connect.");
             }
         } else {
-            statusMessage = "No devices found.";
+            log("No devices found.");
         }
     } else {
         delete m_device;
         m_device = nullptr;
-        statusMessage = "Disconnected.";
+        log("Disconnected.");
     }
 }
 
 void deviceStart()
 {
     if (m_device == nullptr) {
-        statusMessage = "No device connected.";
+        log("No device connected.");
         return;
     }
 
     if (m_device->is_running()) {
         m_device->continuous_stop();
-        statusMessage = "Ready.";
+        log("Ready.");
     } else {
         m_device->continuous_start();
-        statusMessage = "Running.";
+        log("Running.");
     }
 }
 
index 355ab7b844a0fa9ba49d01b17ee91f101c6829ee..3e5284e7e42612c53ea8a2e1db0ba20440bebdd0 100644 (file)
@@ -26,7 +26,7 @@
 #include <vector>
 
 extern TextEditor editor;
-extern std::string statusMessage;
+extern void log(const std::string& str);
 
 enum class FileAction {
     None,
@@ -43,7 +43,7 @@ static void saveCurrentFile()
     if (std::ofstream ofs (fileCurrentPath, std::ios::binary); ofs.good()) {
         const auto& text = editor.GetText();
         ofs.write(text.data(), text.size());
-        statusMessage = "Saved.";
+        log("Saved.");
     }
 }
 
@@ -70,7 +70,7 @@ void fileRenderMenu()
             // TODO modified?
             fileCurrentPath.clear();
             editor.SetText(stmdsp::file_content);
-            statusMessage = "Ready.";
+            log("Ready.");
         }
 
         if (ImGui::MenuItem("Open")) {
@@ -87,7 +87,7 @@ void fileRenderMenu()
 
                     // Treat like new file.
                     fileCurrentPath.clear();
-                    statusMessage = "Ready.";
+                    log("Ready.");
                 }
             }
 
@@ -110,6 +110,7 @@ void fileRenderMenu()
                 "ChooseFileDlgKey", "Choose File", ".cpp", ".");
         }
 
+        ImGui::Separator();
         if (ImGui::MenuItem("Quit")) {
             extern bool done;
             done = true;
@@ -131,7 +132,7 @@ void fileRenderDialog()
             case FileAction::Open:
                 fileCurrentPath = filePathName;
                 openCurrentFile();
-                statusMessage = "Ready.";
+                log("Ready.");
                 break;
             case FileAction::SaveAs:
                 fileCurrentPath = filePathName;
diff --git a/source/logview.h b/source/logview.h
new file mode 100644 (file)
index 0000000..cfe5011
--- /dev/null
@@ -0,0 +1,88 @@
+#ifndef LOGVIEW_H
+#define LOGVIEW_H
+
+#include <string>
+
+// Adapted from ExampleAppLog from imgui_demo.cpp
+class LogView
+{
+public:
+    LogView()
+    {
+        Clear();
+    }
+
+    void Clear()
+    {
+        Buf.clear();
+        LineOffsets.clear();
+        LineOffsets.push_back(0);
+    }
+
+    void AddLog(const std::string& str)
+    {
+        AddLog(str.c_str());
+    }
+
+    void AddLog(const char* fmt, ...) IM_FMTARGS(2)
+    {
+        int old_size = Buf.size();
+        va_list args;
+        va_start(args, fmt);
+        Buf.appendfv(fmt, args);
+        Buf.appendfv("\n", args);
+        va_end(args);
+        for (int new_size = Buf.size(); old_size < new_size; old_size++)
+            if (Buf[old_size] == '\n')
+                LineOffsets.push_back(old_size + 1);
+    }
+
+    void Draw(const char* title, bool* p_open = NULL, ImGuiWindowFlags flags = 0)
+    {
+        if (!ImGui::Begin(title, p_open, flags))
+        {
+            ImGui::End();
+            return;
+        }
+
+        if (ImGui::Button("Clear"))
+            Clear();
+        ImGui::SameLine();
+        if (ImGui::Button("Copy"))
+            ImGui::LogToClipboard();
+        ImGui::Separator();
+        ImGui::BeginChild("scrolling", ImVec2(0, 0), false, ImGuiWindowFlags_HorizontalScrollbar);
+
+
+        ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 0));
+        const char* buf = Buf.begin();
+        const char* buf_end = Buf.end();
+        ImGuiListClipper clipper;
+        clipper.Begin(LineOffsets.Size);
+        while (clipper.Step())
+        {
+            for (int line_no = clipper.DisplayStart; line_no < clipper.DisplayEnd; line_no++)
+            {
+                const char* line_start = buf + LineOffsets[line_no];
+                const char* line_end = (line_no + 1 < LineOffsets.Size) ? (buf + LineOffsets[line_no + 1] - 1) : buf_end;
+                ImGui::TextUnformatted(line_start, line_end);
+            }
+        }
+        clipper.End();
+
+        ImGui::PopStyleVar();
+
+        if (ImGui::GetScrollY() >= ImGui::GetScrollMaxY())
+            ImGui::SetScrollHereY(1.0f);
+
+        ImGui::EndChild();
+        ImGui::End();
+    }
+
+private:
+    ImGuiTextBuffer Buf;
+    ImVector<int> LineOffsets; // Index to lines offset. We maintain this with AddLog() calls.
+};
+
+#endif // LOGVIEW_H
+
index ca8471303acf53b805643edb22e0b425aeb003e1..dc5f789b00380132b89bc38b79276ffbc99aac58 100644 (file)
@@ -14,6 +14,7 @@
 #include "backends/imgui_impl_opengl2.h"
 
 #include "config.h"
+#include "logview.h"
 #include "stmdsp.hpp"
 
 #include <string>
@@ -40,10 +41,16 @@ extern void deviceRenderToolbar();
 
 // Globals that live here
 std::string tempFileName;
-std::string statusMessage ("Ready.");
 bool done = false;
 stmdsp::device *m_device = nullptr;
 
+static LogView logView;
+
+void log(const std::string& str)
+{
+    logView.AddLog(str);
+}
+
 int main(int, char **)
 {
     if (!guiInitialize())
@@ -69,7 +76,7 @@ int main(int, char **)
 
         // Begin the main view which the controls will be drawn onto.
         ImGui::SetNextWindowPos({0, 22});
-        ImGui::SetNextWindowSize({WINDOW_WIDTH, WINDOW_HEIGHT - 22});
+        ImGui::SetNextWindowSize({WINDOW_WIDTH, WINDOW_HEIGHT - 22 - 200});
         ImGui::Begin("main", nullptr,
                      ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoDecoration);
         ImGui::PushFont(font);
@@ -80,9 +87,12 @@ int main(int, char **)
         fileRenderDialog();
         codeRenderWidgets();
 
+        ImGui::SetNextWindowPos({0, WINDOW_HEIGHT - 200});
+        ImGui::SetNextWindowSize({WINDOW_WIDTH, 200});
+        logView.Draw("log", nullptr, ImGuiWindowFlags_NoDecoration);
+
         // Finish main view rendering.
         ImGui::PopFont();
-        ImGui::Text(statusMessage.c_str());
         ImGui::End();
 
         // Draw everything to the screen.