/* 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 #include "grbl_communication.h" #include "machine.h" using namespace nanogui; grbl::machine cnc{}; class SenderApp : public Screen, public grbl::machine_listener { public: Window *window; grbl::jog_state jog; Label *m_pos_x, *m_pos_y, *m_pos_z; TextBox *lblStatus, *lblSubstatus; nanogui::Color red = nanogui::Color(255, 0, 0, 255); int last_alarm = 0; SenderApp() : Screen(Vector2i(1024, 768), "GRBL Sender") { inc_ref(); window = new Window(this, "Machine status"); // window->set_fixed_height(Screen::size().y()); window->set_position(Vector2i(0, 0)); window->set_layout(new GroupLayout()); // window->set_size(Screen::size()); new Label(window, "Status", "sans-bold"); Widget *status_holder = new Widget(window); status_holder->set_layout(new GridLayout()); lblStatus = new TextBox(window, grbl::status_to_string(cnc.get_status().status)); lblSubstatus = new TextBox(window, cnc.get_status().sub_status); // Machine pos new Label(window, "Machine pos", "sans-bold"); Widget *mpos = new Widget(window); mpos->set_layout(new GridLayout()); new Label(mpos, "X"); m_pos_x = new Label(mpos, std::to_string(cnc.get_status().machine_pos[0])); new Label(mpos, "Y"); m_pos_y = new Label(mpos, std::to_string(cnc.get_status().machine_pos[1])); new Label(mpos, "Z"); m_pos_z = new Label(mpos, std::to_string(cnc.get_status().machine_pos[2])); // buttons to change state new Label(window, "Actions", "sans-bold"); Widget *actions = new Widget(window); actions->set_layout(new BoxLayout(Orientation::Horizontal)); Button *btnUnlock = new Button(actions, "Unlock"); btnUnlock->set_callback([&] { cnc.request_unlock(); }); Button *btnHome = new Button(actions, "Home"); btnHome->set_callback([&] { cnc.request_home(); }); Button *btnReset = new Button(actions, "Reset"); btnReset->set_background_color(red); btnReset->set_callback([&] { cnc.request_reset(); }); Button *btnCycleStart = new Button(actions, "Cycle Start"); btnCycleStart->set_callback([&] { cnc.request_cycle_start(); }); Button *btnFeedHold = new Button(actions, "Feed Hold"); btnFeedHold->set_callback([&] { cnc.request_feed_hold(); }); // No need to store a pointer, the data structure will be automatically // freed when the parent window is deleted new Label(window, "Program", "sans-bold"); Button *btnLoadProgram = new Button(window, "Load"); btnLoadProgram->set_callback([&] { auto path = file_dialog( {{"nc", "G-Code files"}, {"ngc", "G-Code files"}}, false); grbl::program pgm{path}; if (pgm.is_loaded) { cnc.run_program(pgm); } }); btnLoadProgram->set_tooltip("short tooltip"); // Alternative construction notation using variadic template btnLoadProgram = window->add