/* * Libpdw: Primitives Done Well! * Copyright (C) 2022 Rebekah Rowe * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include #include "gui/canvas.hpp" #include "gui/widgets/basebutton.hpp" #include "gui/widgets/checkbox.hpp" #include "gui/widgets/textinput.hpp" #include "gui/widgets/textlabel.hpp" //#include "splitcontainer.h" #include "gui/widgets/basecontainer.hpp" #include "gui/widgets/dropdown.hpp" #include "gui/widgets/slider.hpp" #include "tooltip.hpp" //#include "menucontainer.h" //#include "cvarcontainer.h" //#include "menuwindow.h" #include "var.hpp" #include "gui/widgets/titlebar.hpp" ui::Var gui_draw_bounds({ "Gui", "Debug" }, "Draw Bounds", false); ui::Var gui_visible({ "Gui" }, "Visible", true); Canvas::Canvas() : CBaseWindow(nullptr, "root") { } // Crashes associated with no set root in globals void Canvas::Setup() { gui_visible.Callback = [this](bool v) { this->visible = v; }; this->gui_color = glez::rgba(255, 105, 180); this->always_visible = true; this->hover = true; // this->font = new glez::font("../res/opensans.ttf", 10); // this->font->load(); this->font = glez::font::loadFromFile("../res/opensans.ttf", 10); if (!this->font.isLoaded()) throw std::runtime_error("Font loading failed"); this->tooltip = new menu::ncc::Tooltip(); AddChild(this->tooltip); auto bounds = input::GetBounds(); SetMaxSize(bounds.first, bounds.second); /*CBaseWindow* ws = new CBaseWindow("splitwindow"); ws->SetPositionMode(ABSOLUTE); CTitleBar* wst = new CTitleBar(ws, "Window Layout Test"); ws->AddChild(wst); ws->SetMaxSize(500, 0);*/ // CMenuWindow* win = new CMenuWindow("menu_window", this); // win->SetMaxSize(912, 410); // auto ms = GetMaxSize(); // win->AddElements(); // win->SetOffset((draw::width - 912) / 2, (draw::height - 410) / 2); // AddChild(win); } void Canvas::Update() { auto curtime = std::chrono::steady_clock::now(); m_bPressedState[CatKey::CATKEY_M_WHEEL_DOWN] = false; m_bPressedState[CatKey::CATKEY_M_WHEEL_UP] = false; // last_scroll_value = new_scroll; for (int i = 0; i < CatKey::CATKEY_COUNT; i++) { bool down = false, changed = false; ; if ((CatKey)i != CatKey::CATKEY_M_WHEEL_DOWN && (CatKey)i != CatKey::CATKEY_M_WHEEL_UP) { down = input::GetKey((CatKey)i); changed = m_bPressedState[i] != down; } else { down = m_bPressedState[i]; changed = down; } if (changed && down) m_iPressedFrame[i] = curtime; m_bPressedState[i] = down; if (m_bKeysInit) { if (changed) { // printf("Key %i changed! Now %i.\n", i, down); if (i == CatKey::CATKEY_MOUSE_1) { if (down && input::GetKey(CatKey::CATKEY_LCONTROL)) { this->OnKeyPress(CatKey::CATKEY_M_WHEEL_UP, false); // this->OnKeyRelease(CatKey::CATKEY_M_WHEEL_UP); } else if (down && input::GetKey(CatKey::CATKEY_LSHIFT)) { this->OnKeyPress(CatKey::CATKEY_M_WHEEL_DOWN, false); } else if (this->IsVisible()) { if (down) this->OnMousePress(); else this->OnMouseRelease(); } } else { if ((i == CatKey::CATKEY_INSERT || i == CatKey::CATKEY_F11) && down) { this->visible = !this->visible; } if (this->IsVisible()) { if (down) this->OnKeyPress((CatKey)i, false); else this->OnKeyRelease((CatKey)i); m_iSentFrame[i] = curtime; } } } else { if (down) { auto pressed_time = curtime - m_iPressedFrame[i]; bool shouldrepeat = false; if (pressed_time > std::chrono::seconds(1)) { auto time_since_keysend = curtime - m_iSentFrame[i]; if (pressed_time > std::chrono::seconds(4)) { if (time_since_keysend > std::chrono::milliseconds(250)) ; shouldrepeat = true; } else if (time_since_keysend > std::chrono::milliseconds(400)) ; shouldrepeat = true; } if (this->IsVisible() && shouldrepeat) this->OnKeyPress((CatKey)i, true); } } } } auto nmouse = input::GetMouse(); { auto mouse_delta = std::make_pair(nmouse.first - m_iMouseX, nmouse.second - m_iMouseY); mouse_dx = mouse_delta.first, mouse_dy = mouse_delta.second; if (mouse_delta.first || mouse_delta.second) this->OnMouseMove(mouse_delta); } m_iMouseX = nmouse.first; m_iMouseY = nmouse.second; if (!m_bKeysInit) m_bKeysInit = 1; // if (!this->IsVisible()) // this->Show(); tooltip->Hide(); CBaseWindow::Update(); this->Draw((ICanvas*)this); // Draw Mouse glez::draw::rect(m_iMouseX - 5, m_iMouseY - 5, 10, 10, Transparent(glez::color::black)); glez::draw::rect_outline(m_iMouseX - 5, m_iMouseY - 5, 10, 10, GetColor(), 2); if (gui_draw_bounds) this->DrawBounds(0, 0); } void Canvas::Draw(ICanvas* canvas) { if (tooltip->IsVisible()) { tooltip->SetOffset(this->m_iMouseX + 24, this->m_iMouseY + 8); } CBaseContainer::Draw(canvas); } static auto start_time = std::chrono::steady_clock::now(); static glez::rgba RainbowCurrent() { auto FromHSL = [](float h, float s, float v) { auto ToRGBA8 = [](float r, float g, float b, float a = 1.0f) { return glez::rgba(static_cast(r * 255), static_cast(g * 255), static_cast(b * 255), static_cast(a * 255)); }; if (s <= 0.0f) return ToRGBA8(v, v, v); if (h >= 360.0f) h = 0.0f; h /= 60.0f; long i = long(h); float ff = h - i; float p = v * (1.0f - s); float q = v * (1.0f - (s * ff)); float t = v * (1.0f - (s * (1.0f - ff))); switch (i) { case 0: return ToRGBA8(v, t, p); case 1: return ToRGBA8(q, v, p); case 2: return ToRGBA8(p, v, t); case 3: return ToRGBA8(p, q, v); case 4: return ToRGBA8(t, p, v); } return ToRGBA8(v, p, q); }; std::chrono::duration ctime = std::chrono::steady_clock::now() - start_time; return FromHSL(fabs(sin(ctime.count())) * 360.0f, 0.85f, 0.9f); } glez::rgba Canvas::GetColor() const { return gui_rainbow ? RainbowCurrent() : gui_color; } const glez::font& Canvas::GetFont() const { return this->font; } void Canvas::OnKeyPress(CatKey key, bool repeat) { if (GetHoveredChild()) GetHoveredChild()->OnKeyPress(key, repeat); } void Canvas::ShowTooltip(const std::string& text) { tooltip->Show(); tooltip->SetText(text); }