// MIT License // // Copyright (C) 2018-2023, Tellusim Technologies Inc. https://tellusim.com/ // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #include #include #include #include #include /* */ using namespace Tellusim; /* */ class ExternControl : public ControlBase { public: explicit ExternControl(Control *parent) : ControlBase(parent) { create(); } void setAngle(float32_t a) { angle = a; } void setRadius(float32_t r) { radius = r; } private: // create control void create() { Canvas canvas = getCanvas(); canvas_rect = CanvasRect(canvas); canvas_rect.setColor(Color::black); ControlBase::create(); } // update control virtual void update_enabled(bool enabled) { enabled &= isEnabled(); canvas_rect.setEnabled(enabled); ControlBase::update_enabled(enabled); } virtual void update_rectangle(ControlRoot &root, int32_t &order, uint32_t scale) { canvas_rect.setOrder(order++); Rect rect(0.0f); rect.right = getWidth() + radius * 2.0f; rect.top = getHeight() + radius * 2.0f; rect += getMargin(); set_rect(rect); } virtual bool update(ControlRoot &root, const Rect ®ion, const Rect &view, uint32_t scale) { update_expand(root, region); Rect rect = getRect() - getMargin(); Vector3f position = get_position(region, scale); canvas_rect.setRadius(radius); canvas_rect.setSize(rect.getWidth(), rect.getHeight()); canvas_rect.setStrokeStyle(StrokeStyle(radius * 0.5f, Color::white)); canvas_rect.setTransform(Matrix4x4f::translate(rect.getCenterX() + position.x, rect.getCenterY() + position.y, position.z) * Matrix4x4f::rotateZ(angle)); return false; } float32_t angle = 0.0f; float32_t radius = 64.0f; CanvasRect canvas_rect; }; /* */ int32_t main(int32_t argc, char **argv) { DECLARE_WINDOW if(!window) return 1; // create window String title = String::format("%s Tellusim::ExternControl", window.getPlatformName()); if(!window.create(title) || !window.setHidden(false)) return 1; // create device Device device(window); if(!device) return 1; // create canvas Canvas canvas; // create root control ControlRoot root(canvas, true); root.setFontSize(18); // create extern control ExternControl extern_control(&root); extern_control.setSize(128.0f, 128.0f); extern_control.setAlign(Control::AlignCenter); // create window ControlDialog dialog(&root, 1, 0.0f, 8.0f); dialog.setAlign(Control::AlignRight | Control::AlignTop); dialog.setSize(192.0f, 0.0f); dialog.setMargin(16.0f); // create sliders ControlSlider size_x_slider(&dialog, "SizeX", 2, 0.25f); ControlSlider size_y_slider(&dialog, "SizeY", 2, 0.25f); ControlSlider radius_slider(&dialog, "Radius", 2, 0.25f); ControlSlider angle_slider(&dialog, "Angle", 2, 0.0f); size_x_slider.setAlign(Control::AlignExpandX); size_y_slider.setAlign(Control::AlignExpandX); radius_slider.setAlign(Control::AlignExpandX); angle_slider.setAlign(Control::AlignExpandX); ControlCheck enabled_slider(&dialog, "Enabled", true); enabled_slider.setClickedCallback([&](ControlCheck check) { extern_control.setEnabled(check.isChecked()); }); // create target Target target = device.createTarget(window); // main loop DECLARE_GLOBAL window.run([&]() -> bool { DECLARE_COMMON Window::update(); if(!window.render()) return false; // window size float32_t height = 720.0f; float32_t width = Tellusim::floor(height * (float32_t)window.getWidth() / (float32_t)window.getHeight()); float32_t mouse_x = width * (float32_t)window.getMouseX() / (float32_t)window.getWidth(); float32_t mouse_y = height * (float32_t)window.getMouseY() / (float32_t)window.getHeight(); // update element extern_control.setSize(size_x_slider.getValuef32() * 512.0f, size_y_slider.getValuef32() * 512.0f); extern_control.setRadius(radius_slider.getValuef32() * 256.0f + 16.0f); extern_control.setAngle(angle_slider.getValuef32() * 360.0f); // update controls root.setViewport(width, height); if(!pause) root.setMouse(mouse_x, mouse_y, translate_button(window.getMouseButtons())); while(root.update(canvas.getScale(target))) { } // create canvas canvas.create(device, target); // window target target.begin(); { // create command list Command command = device.createCommand(target); // draw canvas canvas.draw(command, target); } target.end(); if(!window.present()) return false; if(!device.check()) return false; return true; }); // finish context window.finish(); return 0; }