commit 708215a2ee86de769af94c55e9ebd8be777ee1e0 Author: Adrian Scripca Date: Thu Apr 27 14:31:06 2023 +0300 Initial import diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4a3be58 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.idea +cmake-build-* +build/ diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..bed7096 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,6 @@ +[submodule "libs/nanogui"] + path = libs/nanogui + url = https://github.com/mitsuba-renderer/nanogui.git +[submodule "libs/gtest"] + path = libs/gtest + url = https://github.com/google/googletest.git diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..67a7184 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,27 @@ +cmake_minimum_required(VERSION 3.13..3.18) +project(grbl_sender + DESCRIPTION "GRBLSender" + LANGUAGES CXX C + VERSION "1.0" + ) + +# Disable building extras we won't need (pure C++ project) +set(NANOGUI_BUILD_EXAMPLE OFF CACHE BOOL " " FORCE) +set(NANOGUI_BUILD_PYTHON OFF CACHE BOOL " " FORCE) +set(NANOGUI_INSTALL OFF CACHE BOOL " " FORCE) + +# Add the configurations from nanogui +add_subdirectory(libs/nanogui) +add_subdirectory(libs/gtest) +include_directories(libs/gtest/googletest/include) + +# For reliability of parallel build, make the NanoGUI targets dependencies +set_property(TARGET glfw glfw_objects nanogui PROPERTY FOLDER "dependencies") + +# Use C++17, visibility=hidden by default, interprocedural optimization +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_VISIBILITY_PRESET hidden) + + +add_executable(sender main.cpp grbl.h grbl.cpp grbl_test.cpp) +target_link_libraries(sender nanogui gtest gtest_main) \ No newline at end of file diff --git a/grbl.cpp b/grbl.cpp new file mode 100644 index 0000000..4340e0e --- /dev/null +++ b/grbl.cpp @@ -0,0 +1,110 @@ +#include "grbl.h" + +#include +#include +#include +#include + +grbl::instruction grbl::instruction::new_gcode(size_t line, std::string cmd, std::string comment) { + return instruction{ + .line = line, + .type = instruction_type::gcode, + .command = std::move(cmd), + .comment = std::move(comment), + }; +} + +grbl::instruction grbl::instruction::new_user_message(size_t line, std::string comment) { + return instruction{ + .line = line, + .type = instruction_type::user_message, + .comment = std::move(comment), + }; +} + +grbl::instruction grbl::instruction::new_comment(size_t line, std::string comment) { + return grbl::instruction{ + .line = line, + .type = instruction_type::comment, + .comment = std::move(comment), + }; +} + +grbl::program::program(std::string filename) { + load(std::move(filename)); +} + +static auto comment_re = std::regex(R"(\(([^)]*)\))"); +static auto gcode_re = std::regex(R"(([a-zA-Z0-9\s.]+).*(\(([^)]*)\))?)"); + +bool grbl::program::load(std::istream& in) { + is_loaded = true; + size_t line_number = 0; + for (std::string line; std::getline(in, line);) { + line_number++; + if (!line.empty()) { + + std::smatch sm{}; + if (std::regex_match(line, sm, comment_re)) { + auto comment = sm.str(1); + instructions.emplace_back(instruction::new_comment(line_number, comment)); + } else if (std::regex_match(line, sm, gcode_re)) { + auto command = sm.str(1); + auto comment = sm.str(3); + instructions.emplace_back(instruction::new_gcode(line_number, command, comment)); + } else { + std::cerr << "Failed to parse line " << line << std::endl; + is_loaded = false; + } + } + } + + return is_loaded; +} + +bool grbl::program::load_from_string(const std::string& content) { + std::stringstream in_stream; + in_stream << content; + + filename = ""; + is_loaded = load(in_stream); + return is_loaded; +} + +bool grbl::program::load(std::string path) { + filename = std::move(path); + is_loaded = false; + + std::ifstream in_file(filename); + if (!in_file) { + return false; + } + is_loaded = load(in_file); + return is_loaded; +} + +std::ostream& operator<<(std::ostream& out, const grbl::instruction_type& t) { + switch (t) { + case grbl::instruction_type::gcode: + out << "gcode"; + break; + case grbl::instruction_type::comment: + out << "comment"; + break; + case grbl::instruction_type::user_message: + out << "user_message"; + break; + } + return out; +} + +std::ostream& operator<<(std::ostream& out, const grbl::instruction& i) { + out << "{.line: " << i.line << ", .type: " << i.type << ", .cmd: " << i.command << ", .comment: " << i.comment << " }"; + return out; +} + +void grbl::program::dump(std::ostream& out) { + for (auto& i: instructions) { + out << i << std::endl; + } +} diff --git a/grbl.h b/grbl.h new file mode 100644 index 0000000..7b05822 --- /dev/null +++ b/grbl.h @@ -0,0 +1,51 @@ +#pragma once + +#include +#include +#include + +namespace grbl { + +enum class instruction_type { + gcode, + comment, + user_message +}; + +struct instruction { + static instruction new_gcode(size_t line, std::string cmd, std::string comment = ""); + static instruction new_user_message(size_t line, std::string comment = ""); + static instruction new_comment(size_t line, std::string comment = ""); + + size_t line = 0; + instruction_type type = instruction_type::comment; + std::string command; + std::string comment; +}; + + + +struct program { + program() = default; + explicit program(std::string filename); + + bool load(std::string filename); + bool load(std::istream& in); + bool load_from_string(const std::string& content); + + void dump(std::ostream& out); + + size_t number_of_instructions() const { + return instructions.size(); + } + + instruction instruction_at(size_t index) { + return instructions.at(index); + } + + bool is_loaded = false; + std::string filename; + std::vector instructions{}; +}; + +} diff --git a/grbl_test.cpp b/grbl_test.cpp new file mode 100644 index 0000000..aeb04ad --- /dev/null +++ b/grbl_test.cpp @@ -0,0 +1,28 @@ +#include "grbl.h" +#include + +TEST(grbl_program, default_state) { + grbl::program pgm; + + EXPECT_EQ("", pgm.filename); + EXPECT_EQ(0, pgm.number_of_instructions()); + EXPECT_EQ(false, pgm.is_loaded); +} + +TEST(grbl_program, load_from_string) { + grbl::program pgm; + + std::string content = R"(( pcb2gcode 1.2.2 ) +( Software-independent Gcode ) + +G94 ( Millimeters per minute feed rate. ) +G21 ( Units == Millimeters. ) +F600.00000 +X3.87739 Y78.52820 +)"; + pgm.load_from_string(content); + + EXPECT_EQ("", pgm.filename); + EXPECT_EQ(6, pgm.number_of_instructions()); + EXPECT_EQ(true, pgm.is_loaded); +} \ No newline at end of file diff --git a/icons/icon1.png b/icons/icon1.png new file mode 100644 index 0000000..b6db2e1 Binary files /dev/null and b/icons/icon1.png differ diff --git a/icons/icon2.png b/icons/icon2.png new file mode 100644 index 0000000..25ff5b9 Binary files /dev/null and b/icons/icon2.png differ diff --git a/icons/icon3.png b/icons/icon3.png new file mode 100644 index 0000000..825b420 Binary files /dev/null and b/icons/icon3.png differ diff --git a/icons/icon4.png b/icons/icon4.png new file mode 100644 index 0000000..42c12ac Binary files /dev/null and b/icons/icon4.png differ diff --git a/icons/icon5.png b/icons/icon5.png new file mode 100644 index 0000000..e1cf1ca Binary files /dev/null and b/icons/icon5.png differ diff --git a/icons/icon6.ico b/icons/icon6.ico new file mode 100644 index 0000000..06f75ed Binary files /dev/null and b/icons/icon6.ico differ diff --git a/icons/icon6.png b/icons/icon6.png new file mode 100644 index 0000000..98f3073 Binary files /dev/null and b/icons/icon6.png differ diff --git a/icons/icon7.png b/icons/icon7.png new file mode 100644 index 0000000..ca05f06 Binary files /dev/null and b/icons/icon7.png differ diff --git a/icons/icon8.png b/icons/icon8.png new file mode 100644 index 0000000..5c36b49 Binary files /dev/null and b/icons/icon8.png differ diff --git a/libs/gtest b/libs/gtest new file mode 160000 index 0000000..dea0484 --- /dev/null +++ b/libs/gtest @@ -0,0 +1 @@ +Subproject commit dea0484e4d3b6a2c50055c24c5617cd662a50c5f diff --git a/libs/nanogui b/libs/nanogui new file mode 160000 index 0000000..2ee903c --- /dev/null +++ b/libs/nanogui @@ -0,0 +1 @@ +Subproject commit 2ee903c96480d4aee54542ea3c340c13cc06dc32 diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..a508f25 --- /dev/null +++ b/main.cpp @@ -0,0 +1,650 @@ +/* + src/example1.cpp -- C++ version of an example application that shows + how to use the various widget classes. For a Python implementation, see + '../python/example1.py'. + + NanoGUI was developed by Wenzel Jakob . + The widget drawing code is based on the NanoVG demo application + by Mikko Mononen. + + All rights reserved. Use of this source code is governed by a + BSD-style license that can be found in the LICENSE.txt file. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define STB_IMAGE_STATIC +#define STB_IMAGE_IMPLEMENTATION +#if defined(_MSC_VER) +# pragma warning (disable: 4505) // don't warn about dead code in stb_image.h +#elif defined(__GNUC__) +# pragma GCC diagnostic ignored "-Wunused-function" +#endif + +#include +#include "grbl.h" +#include + +using namespace nanogui; + +class SenderApp : public Screen { +public: + + Window *window; + Window *left_window; + Window *right_window; + + SenderApp() : Screen(Vector2i(1024, 768), "GRBL Sender") { + inc_ref(); + window = new Window(this, "Button demo"); +// window->set_fixed_height(Screen::size().y()); + window->set_position(Vector2i(0, 0)); + window->set_layout(new GridLayout(nanogui::Orientation::Horizontal, 2, Alignment::Fill, 0, 0)); + window->set_size(Screen::size()); + + left_window = new Window(window, "Left sidebar"); + left_window->set_modal(true); + + right_window = new Window(window, "Right sidebar"); + right_window->set_modal(true); + + left_window->set_layout(new GroupLayout()); + + // No need to store a pointer, the data structure will be automatically + // freed when the parent window is deleted + new Label(left_window, "Push buttons", "sans-bold"); + + Button *b = new Button(left_window, "Plain button"); + b->set_callback([] { std::cout << "pushed!" << std::endl; }); + b->set_tooltip("short tooltip"); + + /* Alternative construction notation using variadic template */ + b = left_window->add