Initial import
@@ -0,0 +1,3 @@
|
|||||||
|
.idea
|
||||||
|
cmake-build-*
|
||||||
|
build/
|
||||||
@@ -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
|
||||||
@@ -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)
|
||||||
@@ -0,0 +1,110 @@
|
|||||||
|
#include "grbl.h"
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
|
#include <fstream>
|
||||||
|
#include <regex>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <utility>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
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<instruction> instructions{};
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
#include "grbl.h"
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
After Width: | Height: | Size: 101 KiB |
|
After Width: | Height: | Size: 101 KiB |
|
After Width: | Height: | Size: 107 KiB |
|
After Width: | Height: | Size: 110 KiB |
|
After Width: | Height: | Size: 116 KiB |
|
After Width: | Height: | Size: 4.2 KiB |
|
After Width: | Height: | Size: 108 KiB |
|
After Width: | Height: | Size: 96 KiB |
|
After Width: | Height: | Size: 103 KiB |
@@ -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 <wenzel.jakob@epfl.ch>.
|
||||||
|
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 <nanogui/opengl.h>
|
||||||
|
#include <nanogui/screen.h>
|
||||||
|
#include <nanogui/window.h>
|
||||||
|
#include <nanogui/layout.h>
|
||||||
|
#include <nanogui/label.h>
|
||||||
|
#include <nanogui/checkbox.h>
|
||||||
|
#include <nanogui/button.h>
|
||||||
|
#include <nanogui/toolbutton.h>
|
||||||
|
#include <nanogui/popupbutton.h>
|
||||||
|
#include <nanogui/combobox.h>
|
||||||
|
#include <nanogui/progressbar.h>
|
||||||
|
#include <nanogui/icons.h>
|
||||||
|
#include <nanogui/messagedialog.h>
|
||||||
|
#include <nanogui/textbox.h>
|
||||||
|
#include <nanogui/slider.h>
|
||||||
|
#include <nanogui/imagepanel.h>
|
||||||
|
#include <nanogui/imageview.h>
|
||||||
|
#include <nanogui/vscrollpanel.h>
|
||||||
|
#include <nanogui/colorwheel.h>
|
||||||
|
#include <nanogui/colorpicker.h>
|
||||||
|
#include <nanogui/graph.h>
|
||||||
|
#include <nanogui/tabwidget.h>
|
||||||
|
#include <nanogui/texture.h>
|
||||||
|
#include <nanogui/shader.h>
|
||||||
|
#include <nanogui/renderpass.h>
|
||||||
|
#include <iostream>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#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 <stb_image.h>
|
||||||
|
#include "grbl.h"
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
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<Button>("Styled", FA_ROCKET);
|
||||||
|
b->set_background_color(Color(0, 0, 255, 25));
|
||||||
|
b->set_callback([] { std::cout << "pushed!" << std::endl; });
|
||||||
|
b->set_tooltip("This button has a fairly long tooltip. It is so long, in "
|
||||||
|
"fact, that the shown text will span several lines.");
|
||||||
|
|
||||||
|
new Label(left_window, "Toggle buttons", "sans-bold");
|
||||||
|
b = new Button(left_window, "Toggle me");
|
||||||
|
b->set_flags(Button::ToggleButton);
|
||||||
|
b->set_change_callback([](bool state) { std::cout << "Toggle button state: " << state << std::endl; });
|
||||||
|
|
||||||
|
new Label(left_window, "Radio buttons", "sans-bold");
|
||||||
|
b = new Button(left_window, "Radio button 1");
|
||||||
|
b->set_flags(Button::RadioButton);
|
||||||
|
b = new Button(left_window, "Radio button 2");
|
||||||
|
b->set_flags(Button::RadioButton);
|
||||||
|
|
||||||
|
new Label(left_window, "A tool palette", "sans-bold");
|
||||||
|
Widget *tools = new Widget(left_window);
|
||||||
|
tools->set_layout(new BoxLayout(Orientation::Horizontal,
|
||||||
|
Alignment::Middle, 0, 6));
|
||||||
|
|
||||||
|
b = new ToolButton(tools, FA_CLOUD);
|
||||||
|
b = new ToolButton(tools, FA_FAST_FORWARD);
|
||||||
|
b = new ToolButton(tools, FA_COMPASS);
|
||||||
|
b = new ToolButton(tools, FA_UTENSILS);
|
||||||
|
|
||||||
|
new Label(left_window, "Popup buttons", "sans-bold");
|
||||||
|
PopupButton *popup_btn = new PopupButton(left_window, "Popup", FA_FLASK);
|
||||||
|
Popup *popup = popup_btn->popup();
|
||||||
|
popup->set_layout(new GroupLayout());
|
||||||
|
new Label(popup, "Arbitrary widgets can be placed here");
|
||||||
|
new CheckBox(popup, "A check box");
|
||||||
|
// popup right
|
||||||
|
popup_btn = new PopupButton(popup, "Recursive popup", FA_CHART_PIE);
|
||||||
|
Popup *popup_right = popup_btn->popup();
|
||||||
|
popup_right->set_layout(new GroupLayout());
|
||||||
|
new CheckBox(popup_right, "Another check box");
|
||||||
|
// popup left
|
||||||
|
popup_btn = new PopupButton(popup, "Recursive popup", FA_DNA);
|
||||||
|
popup_btn->set_side(Popup::Side::Left);
|
||||||
|
Popup *popup_left = popup_btn->popup();
|
||||||
|
popup_left->set_layout(new GroupLayout());
|
||||||
|
new CheckBox(popup_left, "Another check box");
|
||||||
|
|
||||||
|
/*
|
||||||
|
window = new Window(this, "Basic widgets");
|
||||||
|
window->set_position(Vector2i(200, 15));
|
||||||
|
window->set_layout(new GroupLayout());
|
||||||
|
|
||||||
|
new Label(window, "Message dialog", "sans-bold");
|
||||||
|
tools = new Widget(window);
|
||||||
|
tools->set_layout(new BoxLayout(Orientation::Horizontal,
|
||||||
|
Alignment::Middle, 0, 6));
|
||||||
|
b = new Button(tools, "Info");
|
||||||
|
b->set_callback([&] {
|
||||||
|
auto dlg = new MessageDialog(this, MessageDialog::Type::Information, "Title", "This is an information message");
|
||||||
|
dlg->set_callback([](int result) { std::cout << "Dialog result: " << result << std::endl; });
|
||||||
|
});
|
||||||
|
b = new Button(tools, "Warn");
|
||||||
|
b->set_callback([&] {
|
||||||
|
auto dlg = new MessageDialog(this, MessageDialog::Type::Warning, "Title", "This is a warning message");
|
||||||
|
dlg->set_callback([](int result) { std::cout << "Dialog result: " << result << std::endl; });
|
||||||
|
});
|
||||||
|
b = new Button(tools, "Ask");
|
||||||
|
b->set_callback([&] {
|
||||||
|
auto dlg = new MessageDialog(this, MessageDialog::Type::Question, "Title", "This is a question message", "Yes", "No", true);
|
||||||
|
dlg->set_callback([](int result) { std::cout << "Dialog result: " << result << std::endl; });
|
||||||
|
});
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
/// Executable is in the Debug/Release/.. subdirectory
|
||||||
|
std::string resources_folder_path("../icons");
|
||||||
|
#else
|
||||||
|
std::string resources_folder_path("./icons");
|
||||||
|
#endif
|
||||||
|
std::vector<std::pair<int, std::string>> icons;
|
||||||
|
|
||||||
|
#if !defined(EMSCRIPTEN)
|
||||||
|
try {
|
||||||
|
icons = load_image_directory(m_nvg_context, resources_folder_path);
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
std::cerr << "Warning: " << e.what() << std::endl;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
new Label(window, "Image panel & scroll panel", "sans-bold");
|
||||||
|
PopupButton *image_panel_btn = new PopupButton(window, "Image Panel");
|
||||||
|
image_panel_btn->set_icon(FA_IMAGES);
|
||||||
|
popup = image_panel_btn->popup();
|
||||||
|
VScrollPanel *vscroll = new VScrollPanel(popup);
|
||||||
|
ImagePanel *img_panel = new ImagePanel(vscroll);
|
||||||
|
img_panel->set_images(icons);
|
||||||
|
popup->set_fixed_size(Vector2i(245, 150));
|
||||||
|
|
||||||
|
auto image_window = new Window(this, "Selected image");
|
||||||
|
image_window->set_position(Vector2i(710, 15));
|
||||||
|
image_window->set_layout(new GroupLayout(3));
|
||||||
|
|
||||||
|
// Create a Texture instance for each object
|
||||||
|
for (auto& icon: icons) {
|
||||||
|
Vector2i size;
|
||||||
|
int n = 0;
|
||||||
|
ImageHolder texture_data(
|
||||||
|
stbi_load((icon.second + ".png").c_str(), &size.x(), &size.y(), &n, 0),
|
||||||
|
stbi_image_free);
|
||||||
|
assert(n == 4);
|
||||||
|
|
||||||
|
Texture *tex = new Texture(
|
||||||
|
Texture::PixelFormat::RGBA,
|
||||||
|
Texture::ComponentFormat::UInt8,
|
||||||
|
size,
|
||||||
|
Texture::InterpolationMode::Trilinear,
|
||||||
|
Texture::InterpolationMode::Nearest);
|
||||||
|
|
||||||
|
tex->upload(texture_data.get());
|
||||||
|
|
||||||
|
m_images.emplace_back(tex, std::move(texture_data));
|
||||||
|
}
|
||||||
|
|
||||||
|
ImageView *image_view = new ImageView(image_window);
|
||||||
|
if (!m_images.empty())
|
||||||
|
image_view->set_image(m_images[0].first);
|
||||||
|
image_view->center();
|
||||||
|
m_current_image = 0;
|
||||||
|
|
||||||
|
img_panel->set_callback([this, image_view](int i) {
|
||||||
|
std::cout << "Selected item " << i << std::endl;
|
||||||
|
image_view->set_image(m_images[i].first);
|
||||||
|
m_current_image = i;
|
||||||
|
});
|
||||||
|
|
||||||
|
image_view->set_pixel_callback(
|
||||||
|
[this](const Vector2i& index, char **out, size_t size) {
|
||||||
|
const Texture *texture = m_images[m_current_image].first.get();
|
||||||
|
uint8_t *data = m_images[m_current_image].second.get();
|
||||||
|
for (int ch = 0; ch < 4; ++ch) {
|
||||||
|
uint8_t value = data[(index.x() + index.y() * texture->size().x()) * 4 + ch];
|
||||||
|
snprintf(out[ch], size, "%i", (int) value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
new Label(window, "File dialog", "sans-bold");
|
||||||
|
tools = new Widget(window);
|
||||||
|
tools->set_layout(new BoxLayout(Orientation::Horizontal,
|
||||||
|
Alignment::Middle, 0, 6));
|
||||||
|
b = new Button(tools, "Open");
|
||||||
|
b->set_callback([&] {
|
||||||
|
std::cout << "File dialog result: " << file_dialog(
|
||||||
|
{{"png", "Portable Network Graphics"},
|
||||||
|
{"txt", "Text file"}}, false) << std::endl;
|
||||||
|
});
|
||||||
|
b = new Button(tools, "Save");
|
||||||
|
b->set_callback([&] {
|
||||||
|
std::cout << "File dialog result: " << file_dialog(
|
||||||
|
{{"png", "Portable Network Graphics"},
|
||||||
|
{"txt", "Text file"}}, true) << std::endl;
|
||||||
|
});
|
||||||
|
|
||||||
|
new Label(window, "Combo box", "sans-bold");
|
||||||
|
new ComboBox(window, {"Combo box item 1", "Combo box item 2", "Combo box item 3"});
|
||||||
|
new Label(window, "Check box", "sans-bold");
|
||||||
|
CheckBox *cb = new CheckBox(window, "Flag 1",
|
||||||
|
[](bool state) { std::cout << "Check box 1 state: " << state << std::endl; }
|
||||||
|
);
|
||||||
|
cb->set_checked(true);
|
||||||
|
cb = new CheckBox(window, "Flag 2",
|
||||||
|
[](bool state) { std::cout << "Check box 2 state: " << state << std::endl; }
|
||||||
|
);
|
||||||
|
new Label(window, "Progress bar", "sans-bold");
|
||||||
|
m_progress = new ProgressBar(window);
|
||||||
|
|
||||||
|
new Label(window, "Slider and text box", "sans-bold");
|
||||||
|
|
||||||
|
Widget *panel = new Widget(window);
|
||||||
|
panel->set_layout(new BoxLayout(Orientation::Horizontal,
|
||||||
|
Alignment::Middle, 0, 20));
|
||||||
|
|
||||||
|
Slider *slider = new Slider(panel);
|
||||||
|
slider->set_value(0.5f);
|
||||||
|
slider->set_fixed_width(80);
|
||||||
|
|
||||||
|
TextBox *text_box = new TextBox(panel);
|
||||||
|
text_box->set_fixed_size(Vector2i(60, 25));
|
||||||
|
text_box->set_value("50");
|
||||||
|
text_box->set_units("%");
|
||||||
|
slider->set_callback([text_box](float value) {
|
||||||
|
text_box->set_value(std::to_string((int) (value * 100)));
|
||||||
|
});
|
||||||
|
slider->set_final_callback([&](float value) {
|
||||||
|
std::cout << "Final slider value: " << (int) (value * 100) << std::endl;
|
||||||
|
});
|
||||||
|
text_box->set_fixed_size(Vector2i(60, 25));
|
||||||
|
text_box->set_font_size(20);
|
||||||
|
text_box->set_alignment(TextBox::Alignment::Right);
|
||||||
|
|
||||||
|
window = new Window(this, "Misc. widgets");
|
||||||
|
window->set_position(Vector2i(425, 15));
|
||||||
|
window->set_layout(new GroupLayout());
|
||||||
|
|
||||||
|
TabWidget *tab_widget = window->add<TabWidget>();
|
||||||
|
|
||||||
|
Widget *layer = new Widget(tab_widget);
|
||||||
|
layer->set_layout(new GroupLayout());
|
||||||
|
tab_widget->append_tab("Color Wheel", layer);
|
||||||
|
|
||||||
|
// Use overloaded variadic add to fill the tab widget with Different tabs.
|
||||||
|
layer->add<Label>("Color wheel widget", "sans-bold");
|
||||||
|
layer->add<ColorWheel>();
|
||||||
|
|
||||||
|
layer = new Widget(tab_widget);
|
||||||
|
layer->set_layout(new GroupLayout());
|
||||||
|
tab_widget->append_tab("Function Graph", layer);
|
||||||
|
|
||||||
|
layer->add<Label>("Function graph widget", "sans-bold");
|
||||||
|
|
||||||
|
Graph *graph = layer->add<Graph>("Some Function");
|
||||||
|
|
||||||
|
graph->set_header("E = 2.35e-3");
|
||||||
|
graph->set_footer("Iteration 89");
|
||||||
|
std::vector<float>& func = graph->values();
|
||||||
|
func.resize(100);
|
||||||
|
for (int i = 0; i < 100; ++i)
|
||||||
|
func[i] = 0.5f * (0.5f * std::sin(i / 10.f) +
|
||||||
|
0.5f * std::cos(i / 23.f) + 1);
|
||||||
|
|
||||||
|
// Dummy tab used to represent the last tab button.
|
||||||
|
int plus_id = tab_widget->append_tab("+", new Widget(tab_widget));
|
||||||
|
|
||||||
|
// A simple counter.
|
||||||
|
int counter = 1;
|
||||||
|
tab_widget->set_callback([tab_widget, this, counter, plus_id](int id) mutable {
|
||||||
|
if (id == plus_id) {
|
||||||
|
// When the "+" tab has been clicked, simply add a new tab.
|
||||||
|
std::string tab_name = "Dynamic " + std::to_string(counter);
|
||||||
|
Widget *layer_dyn = new Widget(tab_widget);
|
||||||
|
int new_id = tab_widget->insert_tab(tab_widget->tab_count() - 1,
|
||||||
|
tab_name, layer_dyn);
|
||||||
|
layer_dyn->set_layout(new GroupLayout());
|
||||||
|
layer_dyn->add<Label>("Function graph widget", "sans-bold");
|
||||||
|
Graph *graph_dyn = layer_dyn->add<Graph>("Dynamic function");
|
||||||
|
|
||||||
|
graph_dyn->set_header("E = 2.35e-3");
|
||||||
|
graph_dyn->set_footer("Iteration " + std::to_string(new_id * counter));
|
||||||
|
std::vector<float>& func_dyn = graph_dyn->values();
|
||||||
|
func_dyn.resize(100);
|
||||||
|
for (int i = 0; i < 100; ++i)
|
||||||
|
func_dyn[i] = 0.5f *
|
||||||
|
std::abs((0.5f * std::sin(i / 10.f + counter) +
|
||||||
|
0.5f * std::cos(i / 23.f + 1 + counter)));
|
||||||
|
++counter;
|
||||||
|
tab_widget->set_selected_id(new_id);
|
||||||
|
|
||||||
|
// We must invoke the layout manager after adding tabs dynamically
|
||||||
|
perform_layout();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// A button to go back to the first tab and scroll the window.
|
||||||
|
panel = window->add<Widget>();
|
||||||
|
panel->add<Label>("Jump to tab: ");
|
||||||
|
panel->set_layout(new BoxLayout(Orientation::Horizontal,
|
||||||
|
Alignment::Middle, 0, 6));
|
||||||
|
|
||||||
|
auto ib = panel->add<IntBox<int>>();
|
||||||
|
ib->set_editable(true);
|
||||||
|
|
||||||
|
b = panel->add<Button>("", FA_FORWARD);
|
||||||
|
b->set_fixed_size(Vector2i(22, 22));
|
||||||
|
ib->set_fixed_height(22);
|
||||||
|
b->set_callback([tab_widget, ib] {
|
||||||
|
int value = ib->value();
|
||||||
|
if (value >= 0 && value < tab_widget->tab_count())
|
||||||
|
tab_widget->set_selected_index(value);
|
||||||
|
});
|
||||||
|
|
||||||
|
window = new Window(this, "Grid of small widgets");
|
||||||
|
window->set_position(Vector2i(425, 300));
|
||||||
|
GridLayout *layout =
|
||||||
|
new GridLayout(Orientation::Horizontal, 2,
|
||||||
|
Alignment::Middle, 15, 5);
|
||||||
|
layout->set_col_alignment(
|
||||||
|
{Alignment::Maximum, Alignment::Fill});
|
||||||
|
layout->set_spacing(0, 10);
|
||||||
|
window->set_layout(layout);
|
||||||
|
|
||||||
|
// FP widget
|
||||||
|
{
|
||||||
|
new Label(window, "Floating point :", "sans-bold");
|
||||||
|
text_box = new TextBox(window);
|
||||||
|
text_box->set_editable(true);
|
||||||
|
text_box->set_fixed_size(Vector2i(100, 20));
|
||||||
|
text_box->set_value("50");
|
||||||
|
text_box->set_units("GiB");
|
||||||
|
text_box->set_default_value("0.0");
|
||||||
|
text_box->set_font_size(16);
|
||||||
|
text_box->set_format("[-]?[0-9]*\\.?[0-9]+");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Positive integer widget
|
||||||
|
{
|
||||||
|
new Label(window, "Positive integer :", "sans-bold");
|
||||||
|
auto int_box = new IntBox<int>(window);
|
||||||
|
int_box->set_editable(true);
|
||||||
|
int_box->set_fixed_size(Vector2i(100, 20));
|
||||||
|
int_box->set_value(50);
|
||||||
|
int_box->set_units("Mhz");
|
||||||
|
int_box->set_default_value("0");
|
||||||
|
int_box->set_font_size(16);
|
||||||
|
int_box->set_format("[1-9][0-9]*");
|
||||||
|
int_box->set_spinnable(true);
|
||||||
|
int_box->set_min_value(1);
|
||||||
|
int_box->set_value_increment(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Checkbox widget
|
||||||
|
{
|
||||||
|
new Label(window, "Checkbox :", "sans-bold");
|
||||||
|
|
||||||
|
cb = new CheckBox(window, "Check me");
|
||||||
|
cb->set_font_size(16);
|
||||||
|
cb->set_checked(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
new Label(window, "Combo box :", "sans-bold");
|
||||||
|
ComboBox *cobo =
|
||||||
|
new ComboBox(window, {"Item 1", "Item 2", "Item 3"});
|
||||||
|
cobo->set_font_size(16);
|
||||||
|
cobo->set_fixed_size(Vector2i(100, 20));
|
||||||
|
|
||||||
|
new Label(window, "Color picker :", "sans-bold");
|
||||||
|
auto cp = new ColorPicker(window, {255, 120, 0, 255});
|
||||||
|
cp->set_fixed_size({100, 20});
|
||||||
|
cp->set_final_callback([](const Color& c) {
|
||||||
|
std::cout << "ColorPicker final callback: ["
|
||||||
|
<< c.r() << ", "
|
||||||
|
<< c.g() << ", "
|
||||||
|
<< c.b() << ", "
|
||||||
|
<< c.w() << "]" << std::endl;
|
||||||
|
});
|
||||||
|
// setup a fast callback for the color picker widget on a new window
|
||||||
|
// for demonstrative purposes
|
||||||
|
window = new Window(this, "Color Picker Fast Callback");
|
||||||
|
layout = new GridLayout(Orientation::Horizontal, 2,
|
||||||
|
Alignment::Middle, 15, 5);
|
||||||
|
layout->set_col_alignment(
|
||||||
|
{Alignment::Maximum, Alignment::Fill});
|
||||||
|
layout->set_spacing(0, 10);
|
||||||
|
window->set_layout(layout);
|
||||||
|
window->set_position(Vector2i(425, 500));
|
||||||
|
new Label(window, "Combined: ");
|
||||||
|
b = new Button(window, "ColorWheel", FA_INFINITY);
|
||||||
|
new Label(window, "Red: ");
|
||||||
|
auto red_int_box = new IntBox<int>(window);
|
||||||
|
red_int_box->set_editable(false);
|
||||||
|
new Label(window, "Green: ");
|
||||||
|
auto green_int_box = new IntBox<int>(window);
|
||||||
|
green_int_box->set_editable(false);
|
||||||
|
new Label(window, "Blue: ");
|
||||||
|
auto blue_int_box = new IntBox<int>(window);
|
||||||
|
blue_int_box->set_editable(false);
|
||||||
|
new Label(window, "Alpha: ");
|
||||||
|
auto alpha_int_box = new IntBox<int>(window);
|
||||||
|
|
||||||
|
cp->set_callback([b, red_int_box, blue_int_box, green_int_box, alpha_int_box](const Color& c) {
|
||||||
|
b->set_background_color(c);
|
||||||
|
b->set_text_color(c.contrasting_color());
|
||||||
|
int red = (int) (c.r() * 255.0f);
|
||||||
|
red_int_box->set_value(red);
|
||||||
|
int green = (int) (c.g() * 255.0f);
|
||||||
|
green_int_box->set_value(green);
|
||||||
|
int blue = (int) (c.b() * 255.0f);
|
||||||
|
blue_int_box->set_value(blue);
|
||||||
|
int alpha = (int) (c.w() * 255.0f);
|
||||||
|
alpha_int_box->set_value(alpha);
|
||||||
|
});
|
||||||
|
*/
|
||||||
|
|
||||||
|
perform_layout();
|
||||||
|
|
||||||
|
// All NanoGUI widgets are initialized at this point. Now
|
||||||
|
// create shaders to draw the main window contents.
|
||||||
|
//
|
||||||
|
// NanoGUI comes with a simple wrapper around OpenGL 3, which
|
||||||
|
// eliminates most of the tedious and error-prone shader and buffer
|
||||||
|
// object management.
|
||||||
|
|
||||||
|
m_render_pass = new RenderPass({this});
|
||||||
|
m_render_pass->set_clear_color(0, Color(0.3f, 0.3f, 0.32f, 1.f));
|
||||||
|
|
||||||
|
m_shader = new Shader(
|
||||||
|
m_render_pass,
|
||||||
|
|
||||||
|
/* An identifying name */
|
||||||
|
"a_simple_shader",
|
||||||
|
|
||||||
|
#if defined(NANOGUI_USE_OPENGL)
|
||||||
|
R"(/* Vertex shader */
|
||||||
|
#version 330
|
||||||
|
uniform mat4 mvp;
|
||||||
|
in vec3 position;
|
||||||
|
void main() {
|
||||||
|
gl_Position = mvp * vec4(position, 1.0);
|
||||||
|
})",
|
||||||
|
|
||||||
|
/* Fragment shader */
|
||||||
|
R"(#version 330
|
||||||
|
out vec4 color;
|
||||||
|
uniform float intensity;
|
||||||
|
void main() {
|
||||||
|
color = vec4(vec3(intensity), 1.0);
|
||||||
|
})"
|
||||||
|
#elif defined(NANOGUI_USE_GLES)
|
||||||
|
R"(/* Vertex shader */
|
||||||
|
precision highp float;
|
||||||
|
uniform mat4 mvp;
|
||||||
|
attribute vec3 position;
|
||||||
|
void main() {
|
||||||
|
gl_Position = mvp * vec4(position, 1.0);
|
||||||
|
})",
|
||||||
|
|
||||||
|
/* Fragment shader */
|
||||||
|
R"(precision highp float;
|
||||||
|
uniform float intensity;
|
||||||
|
void main() {
|
||||||
|
gl_FragColor = vec4(vec3(intensity), 1.0);
|
||||||
|
})"
|
||||||
|
#elif defined(NANOGUI_USE_METAL)
|
||||||
|
R"(using namespace metal;
|
||||||
|
struct VertexOut {
|
||||||
|
float4 position [[position]];
|
||||||
|
};
|
||||||
|
|
||||||
|
vertex VertexOut vertex_main(const device packed_float3 *position,
|
||||||
|
constant float4x4 &mvp,
|
||||||
|
uint id [[vertex_id]]) {
|
||||||
|
VertexOut vert;
|
||||||
|
vert.position = mvp * float4(position[id], 1.f);
|
||||||
|
return vert;
|
||||||
|
})",
|
||||||
|
|
||||||
|
/* Fragment shader */
|
||||||
|
R"(using namespace metal;
|
||||||
|
fragment float4 fragment_main(const constant float &intensity) {
|
||||||
|
return float4(intensity);
|
||||||
|
})"
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
|
||||||
|
uint32_t indices[3 * 2] = {
|
||||||
|
0, 1, 2,
|
||||||
|
2, 3, 0
|
||||||
|
};
|
||||||
|
|
||||||
|
float positions[3 * 4] = {
|
||||||
|
-1.f, -1.f, 0.f,
|
||||||
|
1.f, -1.f, 0.f,
|
||||||
|
1.f, 1.f, 0.f,
|
||||||
|
-1.f, 1.f, 0.f
|
||||||
|
};
|
||||||
|
|
||||||
|
m_shader->set_buffer("indices", VariableType::UInt32, {3 * 2}, indices);
|
||||||
|
m_shader->set_buffer("position", VariableType::Float32, {4, 3}, positions);
|
||||||
|
m_shader->set_uniform("intensity", 0.5f);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool resize_event(const Vector2i& size) override {
|
||||||
|
window->set_size(size);
|
||||||
|
Screen::resize_event(size);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool keyboard_event(int key, int scancode, int action, int modifiers) {
|
||||||
|
if (Screen::keyboard_event(key, scancode, action, modifiers))
|
||||||
|
return true;
|
||||||
|
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) {
|
||||||
|
set_visible(false);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key == GLFW_KEY_UP) {
|
||||||
|
if (action == GLFW_PRESS) {
|
||||||
|
set_caption("Jogging");
|
||||||
|
} else if (action == GLFW_RELEASE) {
|
||||||
|
set_caption("Idle");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void draw(NVGcontext *ctx) {
|
||||||
|
// Animate the scrollbar
|
||||||
|
// m_progress->set_value(std::fmod((float) glfwGetTime() / 10, 1.0f));
|
||||||
|
|
||||||
|
// Draw the user interface
|
||||||
|
Screen::draw(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void draw_contents() {
|
||||||
|
Matrix4f mvp = Matrix4f::scale(Vector3f(
|
||||||
|
(float) m_size.y() / (float) m_size.x() * 0.25f, 0.25f, 0.25f)) *
|
||||||
|
Matrix4f::rotate(Vector3f(0, 0, 1), (float) glfwGetTime());
|
||||||
|
|
||||||
|
m_shader->set_uniform("mvp", mvp);
|
||||||
|
|
||||||
|
m_render_pass->resize(framebuffer_size());
|
||||||
|
m_render_pass->begin();
|
||||||
|
|
||||||
|
m_shader->begin();
|
||||||
|
m_shader->draw_array(Shader::PrimitiveType::Triangle, 0, 6, true);
|
||||||
|
m_shader->end();
|
||||||
|
|
||||||
|
m_render_pass->end();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
ProgressBar *m_progress;
|
||||||
|
ref<Shader> m_shader;
|
||||||
|
ref<RenderPass> m_render_pass;
|
||||||
|
|
||||||
|
using ImageHolder = std::unique_ptr<uint8_t[], void (*)(void *)>;
|
||||||
|
std::vector<std::pair<ref<Texture>, ImageHolder>> m_images;
|
||||||
|
int m_current_image;
|
||||||
|
};
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
|
||||||
|
testing::InitGoogleTest(&argc, argv);
|
||||||
|
auto result = RUN_ALL_TESTS();
|
||||||
|
if (result) {
|
||||||
|
exit(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
grbl::program pgm;
|
||||||
|
pgm.load("./program.nc");
|
||||||
|
pgm.dump(std::cout);
|
||||||
|
|
||||||
|
nanogui::init();
|
||||||
|
|
||||||
|
// scoped variables
|
||||||
|
{
|
||||||
|
ref<SenderApp> app = new SenderApp();
|
||||||
|
app->dec_ref();
|
||||||
|
app->draw_all();
|
||||||
|
app->set_visible(true);
|
||||||
|
nanogui::mainloop(1 / 60.f * 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
nanogui::shutdown();
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
std::string error_msg = std::string("Caught a fatal error: ") + std::string(e.what());
|
||||||
|
std::cerr << error_msg << std::endl;
|
||||||
|
return -1;
|
||||||
|
} catch (...) {
|
||||||
|
std::cerr << "Caught an unknown error!" << std::endl;
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
cmake_minimum_required (VERSION 2.8.12)
|
||||||
|
|
||||||
|
# Create header for C file
|
||||||
|
file(WRITE ${OUTPUT_C} "/* Autogenerated by bin2c */\n\n")
|
||||||
|
file(APPEND ${OUTPUT_C} "#include <stdint.h>\n\n")
|
||||||
|
|
||||||
|
# Create header of H file
|
||||||
|
file(WRITE ${OUTPUT_H} "/* Autogenerated by bin2c */\n\n")
|
||||||
|
file(APPEND ${OUTPUT_H} "#pragma once\n")
|
||||||
|
file(APPEND ${OUTPUT_H} "#include <stdint.h>\n\n")
|
||||||
|
|
||||||
|
string(REPLACE "," ";" INPUT_LIST ${INPUT_FILES})
|
||||||
|
|
||||||
|
|
||||||
|
# Iterate through binary files files
|
||||||
|
foreach(bin ${INPUT_LIST})
|
||||||
|
# Get short filename
|
||||||
|
string(REGEX MATCH "([^/]+)$" filename ${bin})
|
||||||
|
# Replace filename spaces & extension separator for C compatibility
|
||||||
|
string(REGEX REPLACE "\\.| |-" "_" filename ${filename})
|
||||||
|
# Convert to lower case
|
||||||
|
string(TOLOWER ${filename} filename)
|
||||||
|
# Read hex data from file
|
||||||
|
file(READ ${bin} filedata HEX)
|
||||||
|
# Convert hex data for C compatibility
|
||||||
|
string(REGEX REPLACE "([0-9a-f][0-9a-f])" "0x\\1," filedata "${filedata}")
|
||||||
|
# Append data to c file
|
||||||
|
file(APPEND ${OUTPUT_C} "extern const uint8_t ${filename}[] = {${filedata}0x00};\n\nuint32_t ${filename}_size = sizeof(${filename}) - 1;\n\n")
|
||||||
|
# Append extern definitions to h file
|
||||||
|
file(APPEND ${OUTPUT_H} "extern const uint8_t ${filename}[];\n\nextern uint32_t ${filename}_size;\n\n")
|
||||||
|
endforeach()
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# Script to check include/test code for common pybind11 code style errors.
|
||||||
|
#
|
||||||
|
# This script currently checks for
|
||||||
|
#
|
||||||
|
# 1. use of tabs instead of spaces
|
||||||
|
# 2. MSDOS-style CRLF endings
|
||||||
|
# 3. trailing spaces
|
||||||
|
# 4. missing space between keyword and parenthesis, e.g.: for(, if(, while(
|
||||||
|
# 5. Missing space between right parenthesis and brace, e.g. 'for (...){'
|
||||||
|
# 6. opening brace on its own line. It should always be on the same line as the
|
||||||
|
# if/while/for/do statment.
|
||||||
|
#
|
||||||
|
# Invoke as: tools/check-style.sh
|
||||||
|
#
|
||||||
|
|
||||||
|
errors=0
|
||||||
|
IFS=$'\n'
|
||||||
|
found=
|
||||||
|
# The mt=41 sets a red background for matched tabs:
|
||||||
|
exec 3< <(GREP_COLORS='mt=41' grep $'\t' include/ src/ python/*.{h,cpp} docs/*.rst -rn --color=always)
|
||||||
|
while read -u 3 f; do
|
||||||
|
if [ -z "$found" ]; then
|
||||||
|
echo -e '\e[31m\e[01mError: found tabs instead of spaces in the following files:\e[0m'
|
||||||
|
found=1
|
||||||
|
errors=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo " $f"
|
||||||
|
done
|
||||||
|
|
||||||
|
found=
|
||||||
|
# The mt=41 sets a red background for matched MS-DOS CRLF characters
|
||||||
|
exec 3< <(GREP_COLORS='mt=41' grep -IUlr $'\r' include/ src/ python/*.{h,cpp} docs/*.rst --color=always)
|
||||||
|
while read -u 3 f; do
|
||||||
|
if [ -z "$found" ]; then
|
||||||
|
echo -e '\e[31m\e[01mError: found CRLF characters in the following files:\e[0m'
|
||||||
|
found=1
|
||||||
|
errors=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo " $f"
|
||||||
|
done
|
||||||
|
|
||||||
|
found=
|
||||||
|
# The mt=41 sets a red background for matched trailing spaces
|
||||||
|
exec 3< <(GREP_COLORS='mt=41' grep '\s\+$' include/ src/ python/*.{h,cpp} docs/*.rst -rn --color=always)
|
||||||
|
while read -u 3 f; do
|
||||||
|
if [ -z "$found" ]; then
|
||||||
|
echo -e '\e[31m\e[01mError: found trailing spaces in the following files:\e[0m'
|
||||||
|
found=1
|
||||||
|
errors=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo " $f"
|
||||||
|
done
|
||||||
|
|
||||||
|
found=
|
||||||
|
exec 3< <(grep '\<\(if\|for\|while\|catch\)(\|){' include/ src/ python/*.{h,cpp} -rn --color=always)
|
||||||
|
while read -u 3 line; do
|
||||||
|
if [ -z "$found" ]; then
|
||||||
|
echo -e '\e[31m\e[01mError: found the following coding style problems:\e[0m'
|
||||||
|
found=1
|
||||||
|
errors=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo " $line"
|
||||||
|
done
|
||||||
|
|
||||||
|
found=
|
||||||
|
exec 3< <(GREP_COLORS='mt=41' grep '^\s*{\s*$' include/ src/ -rn --color=always)
|
||||||
|
while read -u 3 f; do
|
||||||
|
if [ -z "$found" ]; then
|
||||||
|
echo -e '\e[31m\e[01mError: braces should occur on the same line as the if/while/.. statement. Found issues in the following files: \e[0m'
|
||||||
|
found=1
|
||||||
|
errors=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo " $f"
|
||||||
|
done
|
||||||
|
|
||||||
|
exit $errors
|
||||||
@@ -0,0 +1,132 @@
|
|||||||
|
# Imports FontAwesome's 'all.css' and creates the 'icons.h' header file
|
||||||
|
|
||||||
|
import yaml
|
||||||
|
|
||||||
|
with open("icons.yml", 'r') as stream:
|
||||||
|
try:
|
||||||
|
data = yaml.safe_load(stream)
|
||||||
|
except yaml.YAMLError as exc:
|
||||||
|
print(exc)
|
||||||
|
|
||||||
|
icons = []
|
||||||
|
for key, value in data.items():
|
||||||
|
if 'solid' in value['styles']:
|
||||||
|
key = 'fa-' + key
|
||||||
|
name = key.replace('-', '_').upper()
|
||||||
|
spacer = " " * (40-len(name))
|
||||||
|
icons.append((key, name, spacer, value['unicode']))
|
||||||
|
|
||||||
|
|
||||||
|
with open("icons.h", 'w') as f:
|
||||||
|
f.write('''/*
|
||||||
|
NanoGUI was developed by Wenzel Jakob <wenzel.jakob@epfl.ch>.
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Developer note: need to make a change to this file?
|
||||||
|
* Please raise an Issue on GitHub describing what needs to change. This file
|
||||||
|
* was generated, so the scripts that generated it needs to update as well.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \\file nanogui/icons.h
|
||||||
|
*
|
||||||
|
* \\brief This is a list of icon codes for the free variant of the
|
||||||
|
* FontAwesome 5.10.1 font.
|
||||||
|
*
|
||||||
|
* \\rst
|
||||||
|
*
|
||||||
|
* This file defines the full listing of
|
||||||
|
* `FontAwesome <https://raw.githubusercontent.com/FortAwesome/Font-Awesome>`_
|
||||||
|
* icons available in NanoGUI. Please note that if viewing the documentation
|
||||||
|
* on the web, your browser may display the icons differently than what they
|
||||||
|
* look like in NanoGUI. Run the one of the :ref:`nanogui_example_icons`
|
||||||
|
* executables to see what they all look like in NanoGUI.
|
||||||
|
*
|
||||||
|
* .. tip::
|
||||||
|
*
|
||||||
|
* In C++, ``#include <nanogui/icons.h>`` to gain access to the ``#define``
|
||||||
|
* shown in these docs and simply reference the names as listed in the
|
||||||
|
* documentation. To use the icons from Python, declare
|
||||||
|
* ``from nanogui import icons`` and reference the icons as follows:
|
||||||
|
* ``icons.FA_ASTERISK``.
|
||||||
|
*
|
||||||
|
* The following icons are available:
|
||||||
|
*
|
||||||
|
* .. raw:: html
|
||||||
|
*
|
||||||
|
* <center>
|
||||||
|
* <div class="wy-table-responsive">
|
||||||
|
* <table class="docutils" border=1>
|
||||||
|
* <colgroup>
|
||||||
|
* <col width="90%" align="center"/>
|
||||||
|
* <col width="10%" align="center" />
|
||||||
|
* </colgroup>
|
||||||
|
* <thead valign="bottom">
|
||||||
|
* <tr class="row-odd">
|
||||||
|
* <th class="head" align="center">Definition</th>
|
||||||
|
* <th class="head" align="center">Icon</th>
|
||||||
|
* </tr>
|
||||||
|
* </thead>
|
||||||
|
* <tbody valign="top">
|
||||||
|
''')
|
||||||
|
|
||||||
|
for i, icon in enumerate(icons):
|
||||||
|
evenodd = 'even' if i % 2 == 0 else 'odd'
|
||||||
|
name_orig = icon[0]
|
||||||
|
name_new = icon[1]
|
||||||
|
f.write(f''' * <tr class="row-{evenodd}">
|
||||||
|
* <td align="right"><code>{name_new}</code></td>
|
||||||
|
* <td align="center"><span class="{name_orig}"></span></td>
|
||||||
|
* </tr>
|
||||||
|
''')
|
||||||
|
f.write(''' * </tbody>
|
||||||
|
* </table>
|
||||||
|
* </div><!-- wy-table-responsive -->
|
||||||
|
* </center>
|
||||||
|
*
|
||||||
|
* \endrst
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
// prevent individual pages from being generated for all of these
|
||||||
|
#if !defined(DOXYGEN_SHOULD_SKIP_THIS)
|
||||||
|
|
||||||
|
''')
|
||||||
|
for name_orig, name_new, spacer, hexcode in icons:
|
||||||
|
f.write(f'#define {name_new}{spacer}0x{hexcode}\n')
|
||||||
|
f.write('\n#endif // DOXYGEN_SHOULD_SKIP_THIS\n')
|
||||||
|
|
||||||
|
|
||||||
|
with open('icons.cpp', 'w') as f:
|
||||||
|
f.write('''#ifdef NANOGUI_PYTHON
|
||||||
|
|
||||||
|
#include "python.h"
|
||||||
|
|
||||||
|
/* Developer note: need to make a change to this file?
|
||||||
|
* Please raise an Issue on GitHub describing what needs to change. This file
|
||||||
|
* was generated, so the scripts that generated it needs to update as well.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void register_entypo(py::module &m) {
|
||||||
|
/* Entypo constants */
|
||||||
|
{
|
||||||
|
#define C(name) g.attr(#name) = py::int_(name);
|
||||||
|
py::module g = m.def_submodule("icons");
|
||||||
|
''')
|
||||||
|
for name_orig, name_new, spacer, hexcode in icons:
|
||||||
|
f.write(f' C({name_new});\n')
|
||||||
|
f.write(''' #undef C
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
''')
|
||||||
|
with open('example_icons.cpp', 'w') as f:
|
||||||
|
for name_orig, name_new, spacer, hexcode in icons:
|
||||||
|
f.write(f' ADD_BUTTON({name_new});\n')
|
||||||
|
After Width: | Height: | Size: 101 KiB |
|
After Width: | Height: | Size: 101 KiB |
|
After Width: | Height: | Size: 107 KiB |
|
After Width: | Height: | Size: 110 KiB |
|
After Width: | Height: | Size: 116 KiB |
|
After Width: | Height: | Size: 4.2 KiB |
|
After Width: | Height: | Size: 108 KiB |
|
After Width: | Height: | Size: 96 KiB |
|
After Width: | Height: | Size: 103 KiB |
@@ -0,0 +1,18 @@
|
|||||||
|
#version 330
|
||||||
|
|
||||||
|
in vec2 uv;
|
||||||
|
in vec2 position_background;
|
||||||
|
out vec4 frag_color;
|
||||||
|
uniform sampler2D image;
|
||||||
|
uniform vec4 background_color;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec2 frac = position_background - floor(position_background);
|
||||||
|
float checkerboard = ((frac.x > .5) == (frac.y > .5)) ? 0.4 : 0.5;
|
||||||
|
|
||||||
|
vec4 background = (1.0 - background_color.a) * vec4(vec3(checkerboard), 1.0) +
|
||||||
|
background_color.a * vec4(background_color.rgb, 1.0);
|
||||||
|
|
||||||
|
vec4 value = texture(image, uv);
|
||||||
|
frag_color = (1.0 - value.a) * background + value.a * vec4(value.rgb, 1.0);
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
precision highp float;
|
||||||
|
|
||||||
|
varying vec2 uv;
|
||||||
|
varying vec2 position_background;
|
||||||
|
uniform sampler2D image;
|
||||||
|
uniform vec4 background_color;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec2 frac = position_background - floor(position_background);
|
||||||
|
float checkerboard = ((frac.x > .5) == (frac.y > .5)) ? 0.4 : 0.5;
|
||||||
|
|
||||||
|
vec4 background = (1.0 - background_color.a) * vec4(vec3(checkerboard), 1.0) +
|
||||||
|
background_color.a * vec4(background_color.rgb, 1.0);
|
||||||
|
|
||||||
|
vec4 value = texture2D(image, uv);
|
||||||
|
gl_FragColor = (1.0 - value.a) * background + value.a * vec4(value.rgb, 1.0);
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
#include <metal_stdlib>
|
||||||
|
|
||||||
|
using namespace metal;
|
||||||
|
|
||||||
|
struct VertexOut {
|
||||||
|
float4 position_image [[position]];
|
||||||
|
float2 position_background;
|
||||||
|
float2 uv;
|
||||||
|
};
|
||||||
|
|
||||||
|
fragment float4 fragment_main(VertexOut vert [[stage_in]],
|
||||||
|
texture2d<float, access::sample> image,
|
||||||
|
constant float4 &background_color,
|
||||||
|
sampler image_sampler) {
|
||||||
|
float2 frac = vert.position_background - floor(vert.position_background);
|
||||||
|
float checkerboard = ((frac.x > .5f) == (frac.y > .5f)) ? .4f : .5f;
|
||||||
|
|
||||||
|
float4 background = (1.f - background_color.a) * float4(float3(checkerboard), 1.f) +
|
||||||
|
background_color.a * float4(background_color.rgb, 1.f);
|
||||||
|
|
||||||
|
float4 value = image.sample(image_sampler, vert.uv);
|
||||||
|
return (1.f - value.a) * background + value.a * float4(value.rgb, 1.f);
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
#version 330
|
||||||
|
|
||||||
|
uniform mat4 matrix_image;
|
||||||
|
uniform mat4 matrix_background;
|
||||||
|
in vec2 position;
|
||||||
|
out vec2 position_background;
|
||||||
|
out vec2 uv;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec4 p = vec4(position, 0.0, 1.0);
|
||||||
|
gl_Position = matrix_image * p;
|
||||||
|
position_background = (matrix_background * p).xy;
|
||||||
|
uv = position;
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
precision highp float;
|
||||||
|
|
||||||
|
uniform mat4 matrix_image;
|
||||||
|
uniform mat4 matrix_background;
|
||||||
|
attribute vec2 position;
|
||||||
|
varying vec2 position_background;
|
||||||
|
varying vec2 uv;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec4 p = vec4(position, 0.0, 1.0);
|
||||||
|
gl_Position = matrix_image * p;
|
||||||
|
position_background = (matrix_background * p).xy;
|
||||||
|
uv = position;
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
#include <metal_stdlib>
|
||||||
|
|
||||||
|
using namespace metal;
|
||||||
|
|
||||||
|
struct VertexOut {
|
||||||
|
float4 position_image [[position]];
|
||||||
|
float2 position_background;
|
||||||
|
float2 uv;
|
||||||
|
};
|
||||||
|
|
||||||
|
vertex VertexOut vertex_main(const device float2 *position,
|
||||||
|
constant float4x4 &matrix_image,
|
||||||
|
constant float4x4 &matrix_background,
|
||||||
|
uint id [[vertex_id]]) {
|
||||||
|
float4 p = float4(position[id], 0.f, 1.f);
|
||||||
|
VertexOut vert;
|
||||||
|
vert.position_image = matrix_image * p;
|
||||||
|
vert.position_background = (matrix_background * p).xy;
|
||||||
|
vert.uv = p.xy;
|
||||||
|
return vert;
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
@PACKAGE_INIT@
|
||||||
|
|
||||||
|
set(nanogui_INCLUDE_DIR "${PACKAGE_PREFIX_DIR}/@CMAKE_INSTALL_INCLUDEDIR@")
|
||||||
|
set(nanogui_VERSION_TYPE "@ENOKI_VERSION_TYPE@")
|
||||||
|
set(nanogui_LIBRARY "")
|
||||||
|
|
||||||
|
check_required_components(nanogui)
|
||||||
|
|
||||||
|
include("${CMAKE_CURRENT_LIST_DIR}/nanoguiTargets.cmake")
|
||||||
|
|
||||||
|
if(NOT nanogui_FIND_QUIETLY)
|
||||||
|
message(STATUS "Found nanogui: ${nanogui_INCLUDE_DIR} (found version \"${nanogui_VERSION}\" ${nanogui_VERSION_TYPE})")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
After Width: | Height: | Size: 1.1 MiB |
|
After Width: | Height: | Size: 47 KiB |