Unfiy all sub projects back into 1 libpalladium
This commit is contained in:
65
source/ui7/container/button.cpp
Executable file
65
source/ui7/container/button.cpp
Executable file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
MIT License
|
||||
Copyright (c) 2024 - 2025 René Amthor (tobid7)
|
||||
|
||||
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 <pd/ui7/container/button.hpp>
|
||||
|
||||
namespace PD {
|
||||
namespace UI7 {
|
||||
PD_UI7_API void Button::HandleInput() {
|
||||
/// Ensure to only check input once
|
||||
if (inp_done) {
|
||||
return;
|
||||
}
|
||||
/// Ensure it gets sed to false and stays if not pressed
|
||||
pressed = false;
|
||||
color = UI7Color_Button;
|
||||
// Assert(screen.get(), "Screen is not set up!");
|
||||
// if (screen->ScreenType() == Screen::Bottom) {
|
||||
if (io->InputHandler->DragObject(this->GetID(), fvec4(FinalPos(), size))) {
|
||||
if (io->InputHandler->DragReleased) {
|
||||
color = UI7Color_ButtonActive;
|
||||
pressed = true;
|
||||
} else {
|
||||
color = UI7Color_ButtonHovered;
|
||||
}
|
||||
}
|
||||
//}
|
||||
inp_done = true;
|
||||
}
|
||||
PD_UI7_API void Button::Draw() {
|
||||
// Assert(io.get() && list.get(), "Did you run Container::Init correctly?");
|
||||
// io->Ren->OnScreen(screen);
|
||||
list->PathRect(FinalPos(), FinalPos() + size, io->FrameRounding);
|
||||
list->PathFill(io->Theme->Get(color));
|
||||
list->LayerUp();
|
||||
list->DrawText(FinalPos() + size * 0.5 - tdim * 0.5, label,
|
||||
io->Theme->Get(UI7Color_Text));
|
||||
list->LayerDown();
|
||||
}
|
||||
|
||||
PD_UI7_API void Button::Update() {
|
||||
// Assert(io.get(), "Did you run Container::Init correctly?");
|
||||
this->SetSize(tdim + io->FramePadding);
|
||||
}
|
||||
} // namespace UI7
|
||||
} // namespace PD
|
||||
68
source/ui7/container/checkbox.cpp
Executable file
68
source/ui7/container/checkbox.cpp
Executable file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
MIT License
|
||||
Copyright (c) 2024 - 2025 René Amthor (tobid7)
|
||||
|
||||
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 <pd/ui7/container/checkbox.hpp>
|
||||
|
||||
namespace PD {
|
||||
namespace UI7 {
|
||||
PD_UI7_API void Checkbox::HandleInput() {
|
||||
/// Ensure to only check input once
|
||||
if (inp_done) {
|
||||
return;
|
||||
}
|
||||
color = UI7Color_FrameBackground;
|
||||
/// Ensure it gets sed to false and stays if not pressed
|
||||
// Assert(screen.get(), "Screen is not set up!");
|
||||
// if (screen->ScreenType() == Screen::Bottom) {
|
||||
if (io->InputHandler->DragObject(this->GetID(), fvec4(FinalPos(), size))) {
|
||||
if (io->InputHandler->DragReleased) {
|
||||
color = UI7Color_FrameBackgroundHovered;
|
||||
usr_ref = !usr_ref;
|
||||
} else {
|
||||
color = UI7Color_FrameBackgroundHovered;
|
||||
}
|
||||
}
|
||||
//}
|
||||
inp_done = true;
|
||||
}
|
||||
PD_UI7_API void Checkbox::Draw() {
|
||||
// Assert(list.get() && io.get(), "Did you run Container::Init correctly?");
|
||||
// io->Ren->OnScreen(screen);
|
||||
list->PathRect(FinalPos(), FinalPos() + cbs, io->FrameRounding);
|
||||
list->PathFill(io->Theme->Get(color));
|
||||
if (usr_ref) {
|
||||
list->PathRect(FinalPos() + 2, FinalPos() + cbs - 2, io->FrameRounding);
|
||||
list->PathFill(io->Theme->Get(UI7Color_Checkmark));
|
||||
}
|
||||
list->DrawText(
|
||||
FinalPos() + fvec2(cbs.x + io->ItemSpace.x, cbs.y * 0.5 - tdim.y * 0.5),
|
||||
label, io->Theme->Get(UI7Color_Text));
|
||||
}
|
||||
|
||||
PD_UI7_API void Checkbox::Update() {
|
||||
// Assert(io.get(), "Did you run Container::Init correctly?");
|
||||
cbs = io->ItemRowHeight;
|
||||
this->SetSize(cbs + fvec2(tdim.x + io->ItemSpace.x, 0));
|
||||
}
|
||||
} // namespace UI7
|
||||
} // namespace PD
|
||||
99
source/ui7/container/coloredit.cpp
Executable file
99
source/ui7/container/coloredit.cpp
Executable file
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
MIT License
|
||||
Copyright (c) 2024 - 2025 René Amthor (tobid7)
|
||||
|
||||
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 <pd/ui7/container/coloredit.hpp>
|
||||
#include <pd/ui7/containers.hpp>
|
||||
|
||||
namespace PD {
|
||||
namespace UI7 {
|
||||
PD_UI7_API void ColorEdit::HandleInput() {
|
||||
/// Ensure to only check input once
|
||||
if (inp_done) {
|
||||
return;
|
||||
}
|
||||
// Assert(screen.get(), "Screen is not set up!");
|
||||
// if (screen->ScreenType() == Screen::Bottom) {
|
||||
if (io->InputHandler->DragObject(this->GetID() + 2,
|
||||
fvec4(FinalPos(), size))) {
|
||||
if (io->InputHandler->DragReleasedAW) {
|
||||
is_shown = !is_shown;
|
||||
}
|
||||
}
|
||||
//}
|
||||
inp_done = true;
|
||||
}
|
||||
PD_UI7_API void ColorEdit::Draw() {
|
||||
// Assert(io.get() && list.get(), "Did you run Container::Init correctly?");
|
||||
// io->Ren->OnScreen(screen);
|
||||
list->PathRect(FinalPos(), FinalPos() + io->ItemRowHeight, io->FrameRounding);
|
||||
list->PathFill(*color_ref);
|
||||
list->DrawText(FinalPos() + fvec2(io->ItemSpace.x + io->ItemRowHeight, 0),
|
||||
label, io->Theme->Get(UI7Color_Text));
|
||||
if (is_shown) {
|
||||
if (!layout) {
|
||||
layout = Layout::New(GetID(), io);
|
||||
}
|
||||
layout->SetPosition(FinalPos());
|
||||
layout->AddObjectEx(
|
||||
DynObj::New(
|
||||
[=, this](UI7::IO::Ref io, Li::DrawList::Ref l, Container* thiz) {
|
||||
thiz->SetSize(layout->GetSize());
|
||||
l->Layer(30);
|
||||
l->PathRect(thiz->GetPos(), thiz->GetPos() + thiz->GetSize(),
|
||||
io->FrameRounding);
|
||||
l->PathFill(io->Theme->Get(UI7Color_FrameBackground));
|
||||
}),
|
||||
UI7LytAdd_Front | UI7LytAdd_NoCursorUpdate | UI7LytAdd_NoScrollHandle);
|
||||
auto obj = DynObj::New(
|
||||
[=, this](UI7::IO::Ref io, Li::DrawList::Ref l, Container* thiz) {
|
||||
l->PathRect(thiz->FinalPos(), thiz->FinalPos() + io->ItemRowHeight,
|
||||
io->FrameRounding);
|
||||
l->PathFill(*color_ref);
|
||||
l->DrawText(
|
||||
thiz->FinalPos() + fvec2(io->ItemSpace.x + io->ItemRowHeight, 0),
|
||||
label, io->Theme->Get(UI7Color_Text));
|
||||
});
|
||||
obj->SetSize(PD::fvec2(200, io->ItemRowHeight));
|
||||
layout->AddObject(obj);
|
||||
layout->Label("RGBA: ({}, {}, {}, {})", *((u8*)color_ref),
|
||||
*(((u8*)color_ref) + 1), *(((u8*)color_ref) + 2),
|
||||
*(((u8*)color_ref) + 3));
|
||||
layout->Label("Hex: {}", PD::Color(*color_ref).Hex(true));
|
||||
|
||||
layout->Slider<u8>("R", ((u8*)color_ref));
|
||||
layout->Slider<u8>("G", ((u8*)color_ref) + 1);
|
||||
layout->Slider<u8>("B", ((u8*)color_ref) + 2);
|
||||
layout->Slider<u8>("A", ((u8*)color_ref) + 3);
|
||||
layout->Update();
|
||||
list->Merge(layout->GetDrawList());
|
||||
// io->RegisterDrawList(GetID(), layout->GetDrawList());
|
||||
}
|
||||
}
|
||||
|
||||
PD_UI7_API void ColorEdit::Update() {
|
||||
// Assert(io.get(), "Did you run Container::Init correctly?");
|
||||
this->SetSize(
|
||||
fvec2(tdim.x + io->ItemSpace.x + io->ItemRowHeight, io->ItemRowHeight));
|
||||
}
|
||||
} // namespace UI7
|
||||
} // namespace PD
|
||||
44
source/ui7/container/container.cpp
Executable file
44
source/ui7/container/container.cpp
Executable file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
MIT License
|
||||
Copyright (c) 2024 - 2025 René Amthor (tobid7)
|
||||
|
||||
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 <pd/ui7/container/container.hpp>
|
||||
|
||||
namespace PD {
|
||||
namespace UI7 {
|
||||
PD_UI7_API void Container::HandleScrolling(fvec2 scrolling, fvec4 viewport) {
|
||||
if (last_use != 0 && OS::GetTime() - last_use > 5000) {
|
||||
rem = true;
|
||||
}
|
||||
last_use = OS::GetTime();
|
||||
pos -= fvec2(0, scrolling.y);
|
||||
skippable = !Li::Renderer::InBox(
|
||||
pos, size,
|
||||
fvec4(viewport.x, viewport.y, viewport.x + viewport.z,
|
||||
viewport.y + viewport.w));
|
||||
}
|
||||
|
||||
PD_UI7_API void Container::HandleInternalInput() {
|
||||
/** Requires Handle Scrolling First */
|
||||
}
|
||||
} // namespace UI7
|
||||
} // namespace PD
|
||||
117
source/ui7/container/dragdata.cpp
Executable file
117
source/ui7/container/dragdata.cpp
Executable file
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
MIT License
|
||||
Copyright (c) 2024 - 2025 René Amthor (tobid7)
|
||||
|
||||
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 <pd/ui7/container/dragdata.hpp>
|
||||
#include <pd/ui7/container/label.hpp>
|
||||
#include <type_traits>
|
||||
|
||||
namespace PD {
|
||||
namespace UI7 {
|
||||
// Setup Supported Datatypes (Probably making this Object
|
||||
// header only to not care about datatype support)
|
||||
template class PD_UI7_API DragData<float>;
|
||||
template class PD_UI7_API DragData<int>;
|
||||
template class PD_UI7_API DragData<double>;
|
||||
template class PD_UI7_API DragData<u8>;
|
||||
template class PD_UI7_API DragData<u16>;
|
||||
template class PD_UI7_API DragData<u32>;
|
||||
template class PD_UI7_API DragData<u64>;
|
||||
template <typename T>
|
||||
PD_UI7_API void DragData<T>::HandleInput() {
|
||||
/// Ensure to only check input once
|
||||
if (inp_done) {
|
||||
return;
|
||||
}
|
||||
// Assert(screen.get(), "Screen is not set up!");
|
||||
// if (screen->ScreenType() == Screen::Bottom) {
|
||||
float off_x = 0;
|
||||
for (size_t i = 0; i < elm_count; i++) {
|
||||
std::string p;
|
||||
if constexpr (std::is_floating_point_v<T>) {
|
||||
p = std::format("{:.{}f}", data[i], precision);
|
||||
} else {
|
||||
p = std::format("{}", data[i]);
|
||||
}
|
||||
vec2 tdim = io->Font->GetTextBounds(p, io->FontScale);
|
||||
// Unsafe but is the fastest solution
|
||||
if (io->InputHandler->DragObject(
|
||||
this->GetID() + i + 1,
|
||||
fvec4(FinalPos() + fvec2(off_x, 0), tdim + io->FramePadding))) {
|
||||
data[i] = std::clamp(
|
||||
T(data[i] + (step * (io->InputHandler->DragPosition.x -
|
||||
io->InputHandler->DragLastPosition.x))),
|
||||
this->min, this->max);
|
||||
}
|
||||
off_x += tdim.x + io->ItemSpace.x + io->FramePadding.x;
|
||||
}
|
||||
//}
|
||||
inp_done = true;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
PD_UI7_API void DragData<T>::Draw() {
|
||||
// Assert(io.get() && list.get(), "Did you run Container::Init correctly?");
|
||||
// io->Ren->OnScreen(screen);
|
||||
float off_x = 0.f;
|
||||
for (size_t i = 0; i < elm_count; i++) {
|
||||
std::string p;
|
||||
if constexpr (std::is_floating_point_v<T>) {
|
||||
p = std::format("{:.{}f}", data[i], precision);
|
||||
} else {
|
||||
p = std::format("{}", data[i]);
|
||||
}
|
||||
vec2 td = io->Font->GetTextBounds(p, io->FontScale);
|
||||
list->PathRect(FinalPos() + fvec2(off_x, 0),
|
||||
FinalPos() + fvec2(off_x, 0) + td + io->FramePadding,
|
||||
io->FrameRounding);
|
||||
list->PathFill(io->Theme->Get(UI7Color_Button));
|
||||
list->LayerUp();
|
||||
list->DrawTextEx(FinalPos() + fvec2(off_x, 0), p,
|
||||
io->Theme->Get(UI7Color_Text), LiTextFlags_AlignMid,
|
||||
td + io->FramePadding);
|
||||
list->LayerDown();
|
||||
off_x += td.x + io->ItemSpace.x + io->FramePadding.x;
|
||||
}
|
||||
list->DrawText(FinalPos() + fvec2(off_x, io->FramePadding.y * 0.5), label,
|
||||
io->Theme->Get(UI7Color_Text));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
PD_UI7_API void DragData<T>::Update() {
|
||||
// Assert(io.get(), "Did you run Container::Init correctly?");
|
||||
// Probably need to find a faster solution (caching sizes calculated here)
|
||||
float off_x = 0;
|
||||
for (size_t i = 0; i < elm_count; i++) {
|
||||
std::string p;
|
||||
if constexpr (std::is_floating_point_v<T>) {
|
||||
p = std::format("{:.{}f}", data[i], precision);
|
||||
} else {
|
||||
p = std::format("{}", data[i]);
|
||||
}
|
||||
vec2 tdim = io->Font->GetTextBounds(p, io->FontScale);
|
||||
off_x += tdim.x + io->ItemSpace.x + io->FramePadding.x;
|
||||
}
|
||||
this->SetSize(vec2(tdim.x + off_x, tdim.y + io->FramePadding.y));
|
||||
}
|
||||
} // namespace UI7
|
||||
} // namespace PD
|
||||
39
source/ui7/container/dynobj.cpp
Executable file
39
source/ui7/container/dynobj.cpp
Executable file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2024 - 2025 tobid7
|
||||
|
||||
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 <pd/ui7/container/dynobj.hpp>
|
||||
|
||||
namespace PD {
|
||||
namespace UI7 {
|
||||
PD_UI7_API void DynObj::Draw() { pRenFun(io, list, this); }
|
||||
|
||||
PD_UI7_API void DynObj::HandleInput() {
|
||||
if (pInp) {
|
||||
pInp(io, this);
|
||||
}
|
||||
}
|
||||
|
||||
PD_UI7_API void DynObj::Update() {}
|
||||
} // namespace UI7
|
||||
} // namespace PD
|
||||
39
source/ui7/container/image.cpp
Executable file
39
source/ui7/container/image.cpp
Executable file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
MIT License
|
||||
Copyright (c) 2024 - 2025 René Amthor (tobid7)
|
||||
|
||||
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 <pd/ui7/container/image.hpp>
|
||||
|
||||
namespace PD {
|
||||
namespace UI7 {
|
||||
PD_UI7_API void Image::Draw() {
|
||||
// Assert(io.get() && list.get(), "Did you run Container::Init correctly?");
|
||||
// Assert(img.get(), "Image is nullptr!");
|
||||
// io->Ren->OnScreen(screen);
|
||||
list->LayerUp();
|
||||
list->DrawTexture(img);
|
||||
list->DrawRectFilled(FinalPos(), newsize, 0xffffffff);
|
||||
list->DrawSolid();
|
||||
list->LayerDown();
|
||||
}
|
||||
} // namespace UI7
|
||||
} // namespace PD
|
||||
57
source/ui7/container/label.cpp
Executable file
57
source/ui7/container/label.cpp
Executable file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
MIT License
|
||||
Copyright (c) 2024 - 2025 René Amthor (tobid7)
|
||||
|
||||
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 <pd/ui7/container/label.hpp>
|
||||
|
||||
namespace PD {
|
||||
namespace UI7 {
|
||||
PD_UI7_API void Label::Draw() {
|
||||
// Assert(io.get() && list.get(), "Did you run Container::Init correctly?");
|
||||
// io->Ren->OnScreen(screen);
|
||||
if (pCLipRectUsed) {
|
||||
list->PushClipRect(pClipRect);
|
||||
}
|
||||
list->DrawTextEx(FinalPos(), label, io->Theme->Get(UI7Color_Text),
|
||||
LiTextFlags_NoOOS, PD::fvec2(0, io->CurrentViewPort.w));
|
||||
if (pCLipRectUsed) {
|
||||
list->PopClipRect();
|
||||
}
|
||||
}
|
||||
|
||||
PD_UI7_API void Label::Update() {
|
||||
/**
|
||||
* Todo: This is a hacky workaround
|
||||
* Needs proper optimisation
|
||||
* Needs a max size (to support sligning dynaically by the window size)
|
||||
*/
|
||||
if (io->WrapLabels) {
|
||||
this->label =
|
||||
io->Font->pWrapText(this->label, io->FontScale,
|
||||
PD::fvec2(io->CurrentViewPort.z - FinalPos().x * 4,
|
||||
io->CurrentViewPort.w),
|
||||
this->tdim);
|
||||
SetSize(tdim);
|
||||
}
|
||||
}
|
||||
} // namespace UI7
|
||||
} // namespace PD
|
||||
107
source/ui7/container/slider.cpp
Normal file
107
source/ui7/container/slider.cpp
Normal file
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
MIT License
|
||||
Copyright (c) 2024 - 2025 René Amthor (tobid7)
|
||||
|
||||
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 <pd/ui7/container/label.hpp>
|
||||
#include <pd/ui7/container/slider.hpp>
|
||||
#include <type_traits>
|
||||
|
||||
namespace PD {
|
||||
namespace UI7 {
|
||||
// Setup Supported Datatypes (Probably making this Object
|
||||
// header only to not care about datatype support)
|
||||
template class PD_UI7_API Slider<float>;
|
||||
template class PD_UI7_API Slider<int>;
|
||||
template class PD_UI7_API Slider<double>;
|
||||
template class PD_UI7_API Slider<u8>;
|
||||
template class PD_UI7_API Slider<u16>;
|
||||
template class PD_UI7_API Slider<u32>;
|
||||
template class PD_UI7_API Slider<u64>;
|
||||
template <typename T>
|
||||
PD_UI7_API void Slider<T>::HandleInput() {
|
||||
/// Ensure to only check input once
|
||||
if (inp_done) {
|
||||
return;
|
||||
}
|
||||
// Assert(screen.get(), "Screen is not set up!");
|
||||
std::string p;
|
||||
if constexpr (std::is_floating_point_v<T>) {
|
||||
p = std::format("{:.{}f}", *data, precision);
|
||||
} else {
|
||||
p = std::format("{}", *data);
|
||||
}
|
||||
// Unsafe but is the fastest solution
|
||||
float xps = FinalPos().x;
|
||||
if (io->InputHandler->DragObject(
|
||||
this->GetID(),
|
||||
fvec4(FinalPos() + fvec2(2, 0), fvec2(width, GetSize().y)))) {
|
||||
if (!io->InputHandler->DragReleasedAW) {
|
||||
*data = std::clamp(
|
||||
T(max * (std::clamp(io->InputHandler->DragLastPosition.x - xps, 0.f,
|
||||
width) /
|
||||
width)),
|
||||
this->min, this->max);
|
||||
}
|
||||
}
|
||||
inp_done = true;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
PD_UI7_API void Slider<T>::Draw() {
|
||||
// Assert(io.get() && list.get(), "Did you run Container::Init correctly?");
|
||||
// io->Ren->OnScreen(screen);
|
||||
std::string p;
|
||||
if constexpr (std::is_floating_point_v<T>) {
|
||||
p = std::format("{:.{}f}", *data, precision);
|
||||
} else {
|
||||
p = std::format("{}", *data);
|
||||
}
|
||||
fvec2 td = io->Font->GetTextBounds(p, io->FontScale);
|
||||
list->PathRect(FinalPos(), FinalPos() + fvec2(width, td.y) + io->FramePadding,
|
||||
io->FrameRounding);
|
||||
list->PathFill(io->Theme->Get(UI7Color_Button));
|
||||
list->PathRect(FinalPos() + 2 + PD::fvec2(slp, 0),
|
||||
FinalPos() + fvec2(slp + slw - 2, td.y - 2) + io->FramePadding,
|
||||
io->FrameRounding);
|
||||
list->PathFill(io->Theme->Get(UI7Color_ButtonActive));
|
||||
list->LayerUp();
|
||||
list->DrawTextEx(FinalPos(), p, io->Theme->Get(UI7Color_Text),
|
||||
LiTextFlags_AlignMid, fvec2(width, td.y) + io->FramePadding);
|
||||
list->LayerDown();
|
||||
list->DrawText(FinalPos() + fvec2(width + io->FramePadding.x * 2.f,
|
||||
io->FramePadding.y * 0.5),
|
||||
label, io->Theme->Get(UI7Color_Text));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
PD_UI7_API void Slider<T>::Update() {
|
||||
// Assert(io.get(), "Did you run Container::Init correctly?");
|
||||
// Probably need to find a faster solution (caching sizes calculated here)
|
||||
slw = std::clamp(static_cast<float>(width / max), 3.f, width);
|
||||
slp = static_cast<float>((float)*data / (float)max) * (width - slw);
|
||||
fvec2 tdim = io->Font->GetTextBounds(label, io->FontScale);
|
||||
|
||||
this->SetSize(
|
||||
fvec2(width + tdim.x + io->ItemSpace.x * 2, tdim.y + io->FramePadding.y));
|
||||
}
|
||||
} // namespace UI7
|
||||
} // namespace PD
|
||||
44
source/ui7/io.cpp
Executable file
44
source/ui7/io.cpp
Executable file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
MIT License
|
||||
Copyright (c) 2024 - 2025 René Amthor (tobid7)
|
||||
|
||||
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 <pd/core/core.hpp>
|
||||
#include <pd/ui7/io.hpp>
|
||||
|
||||
namespace PD {
|
||||
PD_UI7_API void UI7::IO::Update() {
|
||||
/** Todo: find out if we even still use the Drawlist regestry */
|
||||
u64 current = OS::GetNanoTime();
|
||||
Delta = static_cast<float>(current - LastTime) / 1000000.f;
|
||||
LastTime = current;
|
||||
DeltaStats->Add(Delta * 1000);
|
||||
Time->Update();
|
||||
InputHandler->Update();
|
||||
Framerate = 1000.f / Delta;
|
||||
DrawListRegestry.clear();
|
||||
DrawListRegestry.push_front(std::make_pair("CtxBackList", Back));
|
||||
if (Font) ItemRowHeight = FontScale * Font->PixelHeight;
|
||||
// RegisterDrawList("CtxBackList", Back);
|
||||
NumIndices = FDL->pNumIndices;
|
||||
NumVertices = FDL->pNumVertices;
|
||||
}
|
||||
} // namespace PD
|
||||
185
source/ui7/layout.cpp
Executable file
185
source/ui7/layout.cpp
Executable file
@@ -0,0 +1,185 @@
|
||||
/*
|
||||
MIT License
|
||||
Copyright (c) 2024 - 2025 René Amthor (tobid7)
|
||||
|
||||
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 <pd/ui7/containers.hpp>
|
||||
#include <pd/ui7/layout.hpp>
|
||||
|
||||
namespace PD {
|
||||
namespace UI7 {
|
||||
PD_UI7_API void Layout::CursorInit() { Cursor = fvec2(WorkRect.x, WorkRect.y); }
|
||||
|
||||
PD_UI7_API void Layout::SameLine() {
|
||||
BackupCursor = LastObjSize;
|
||||
Cursor = SamelineCursor;
|
||||
}
|
||||
|
||||
PD_UI7_API void Layout::CursorMove(const fvec2& size) {
|
||||
LastObjSize = size;
|
||||
SamelineCursor = Cursor + fvec2(size.x + IO->ItemSpace.x, 0);
|
||||
if (BeforeSameLine.y) {
|
||||
Cursor =
|
||||
fvec2(IO->MenuPadding.x, Cursor.y + BeforeSameLine.y + IO->ItemSpace.y);
|
||||
BeforeSameLine = 0.f;
|
||||
} else {
|
||||
Cursor = fvec2(IO->MenuPadding.x + InitialCursorOffset.x,
|
||||
Cursor.y + size.y + IO->ItemSpace.y);
|
||||
}
|
||||
// Logical Issue here as x should use a max check
|
||||
MaxPosition = fvec2(std::max(MaxPosition.x, SamelineCursor.x), Cursor.y);
|
||||
}
|
||||
|
||||
PD_UI7_API bool Layout::ObjectWorkPos(fvec2& movpos) {
|
||||
if (Scrolling[1]) {
|
||||
movpos.y -= ScrollOffset.y;
|
||||
if (!Li::Renderer::InBox(
|
||||
movpos, LastObjSize,
|
||||
fvec4(WorkRect.x, WorkRect.y, WorkRect.x + WorkRect.z,
|
||||
WorkRect.y + WorkRect.w))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
PD_UI7_API void Layout::AddObject(Container::Ref obj) {
|
||||
obj->Init(IO, DrawList);
|
||||
obj->SetPos(AlignPosition(Cursor, obj->GetSize(), WorkRect, GetAlignment()));
|
||||
obj->Update();
|
||||
CursorMove(obj->GetSize());
|
||||
obj->HandleScrolling(ScrollOffset, WorkRect);
|
||||
Objects.push_back(obj);
|
||||
}
|
||||
|
||||
PD_UI7_API void Layout::AddObjectEx(Container::Ref obj, u32 flags) {
|
||||
obj->Init(IO, DrawList);
|
||||
if (!(flags & UI7LytAdd_NoCursorUpdate)) {
|
||||
obj->SetPos(
|
||||
AlignPosition(Cursor, obj->GetSize(), WorkRect, GetAlignment()));
|
||||
}
|
||||
obj->Update();
|
||||
if (!(flags & UI7LytAdd_NoCursorUpdate)) {
|
||||
CursorMove(obj->GetSize());
|
||||
}
|
||||
if (!(flags & UI7LytAdd_NoScrollHandle)) {
|
||||
obj->HandleScrolling(ScrollOffset, WorkRect);
|
||||
}
|
||||
if (flags & UI7LytAdd_Front) {
|
||||
Objects.push_front(obj);
|
||||
} else {
|
||||
Objects.push_back(obj);
|
||||
}
|
||||
}
|
||||
|
||||
PD_UI7_API Container::Ref Layout::FindObject(u32 id) {
|
||||
for (auto& it : IDObjects) {
|
||||
if (it->GetID() == id) {
|
||||
return it;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PD_UI7_API fvec2 Layout::AlignPosition(fvec2 pos, fvec2 size, fvec4 area,
|
||||
UI7Align alignment) {
|
||||
vec2 p = pos;
|
||||
if (alignment & UI7Align_Center) {
|
||||
p.x = (area.x + area.z) * 0.5 - (pos.x - area.x + size.x * 0.5);
|
||||
} else if (alignment & UI7Align_Right) {
|
||||
}
|
||||
if (alignment & UI7Align_Mid) {
|
||||
p.y = (area.y + area.w) * 0.5 - (pos.y - area.y + size.y * 0.5);
|
||||
} else if (alignment & UI7Align_Bottom) {
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
PD_UI7_API void Layout::Update() {
|
||||
if (Size == fvec2(0.f)) {
|
||||
Size = fvec2(MaxPosition) + IO->MenuPadding * 2;
|
||||
}
|
||||
for (auto& it : Objects) {
|
||||
if (it->GetID() != 0 && !FindObject(it->GetID())) {
|
||||
IDObjects.push_back(it);
|
||||
}
|
||||
if (!it->Skippable()) {
|
||||
it->SetPos(it->GetPos() + Pos);
|
||||
it->HandleInput();
|
||||
it->UnlockInput();
|
||||
it->Draw();
|
||||
}
|
||||
}
|
||||
|
||||
for (auto it = IDObjects.begin(); it != IDObjects.end();) {
|
||||
if ((*it)->Removable()) {
|
||||
it = IDObjects.erase(it);
|
||||
} else {
|
||||
it++;
|
||||
}
|
||||
}
|
||||
|
||||
Objects.clear();
|
||||
WorkRect = fvec4(fvec2(WorkRect.x, WorkRect.y), Size - IO->MenuPadding);
|
||||
CursorInit();
|
||||
}
|
||||
|
||||
/** SECTION CONTAINERS (STOLEN FROM FORMER MENU) */
|
||||
|
||||
PD_UI7_API void Layout::Label(const std::string& label) {
|
||||
// Layout API
|
||||
auto r = Label::New(label, IO);
|
||||
r->SetClipRect(fvec4(GetPosition(), GetPosition() + GetSize()));
|
||||
AddObject(r);
|
||||
}
|
||||
|
||||
PD_UI7_API bool Layout::Button(const std::string& label) {
|
||||
bool ret = false;
|
||||
u32 id = Strings::FastHash("btn" + label + std::to_string(Objects.size()));
|
||||
Container::Ref r = FindObject(id);
|
||||
if (!r) {
|
||||
r = Button::New(label, IO);
|
||||
r->SetID(id);
|
||||
}
|
||||
AddObject(r);
|
||||
if (!r->Skippable()) {
|
||||
ret = std::static_pointer_cast<UI7::Button>(r)->IsPressed();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
PD_UI7_API void Layout::Checkbox(const std::string& label, bool& v) {
|
||||
u32 id = Strings::FastHash("cbx" + label + std::to_string(Objects.size()));
|
||||
Container::Ref r = FindObject(id);
|
||||
if (!r) {
|
||||
r = Checkbox::New(label, v, IO);
|
||||
r->SetID(id);
|
||||
}
|
||||
AddObject(r);
|
||||
}
|
||||
|
||||
PD_UI7_API void Layout::Image(Li::Texture::Ref img, fvec2 size, Li::Rect uv) {
|
||||
Container::Ref r = Image::New(img, size, uv);
|
||||
AddObject(r);
|
||||
}
|
||||
|
||||
} // namespace UI7
|
||||
} // namespace PD
|
||||
429
source/ui7/menu.cpp
Executable file
429
source/ui7/menu.cpp
Executable file
@@ -0,0 +1,429 @@
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2024 - 2025 tobid7
|
||||
|
||||
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 <pd/ui7/containers.hpp>
|
||||
#include <pd/ui7/menu.hpp>
|
||||
|
||||
namespace PD {
|
||||
namespace UI7 {
|
||||
Menu::Menu(const ID& id, IO::Ref io) : pIO(io), pID(id) {
|
||||
pLayout = Layout::New(id, io);
|
||||
TitleBarHeight = pIO->FontScale * pIO->Font->PixelHeight + pIO->MenuPadding.y;
|
||||
pLayout->WorkRect.y += TitleBarHeight;
|
||||
pLayout->CursorInit();
|
||||
}
|
||||
|
||||
PD_UI7_API void Menu::Label(const std::string& label) {
|
||||
// Layout API
|
||||
auto r = Label::New(label, pIO);
|
||||
r->SetClipRect(fvec4(pLayout->GetPosition(),
|
||||
pLayout->GetPosition() + pLayout->GetSize()));
|
||||
pLayout->AddObject(r);
|
||||
}
|
||||
|
||||
PD_UI7_API bool Menu::Button(const std::string& label) {
|
||||
bool ret = false;
|
||||
u32 id = Strings::FastHash("btn" + label +
|
||||
std::to_string(pLayout->Objects.size()));
|
||||
Container::Ref r = pLayout->FindObject(id);
|
||||
if (!r) {
|
||||
r = Button::New(label, pIO);
|
||||
r->SetID(id);
|
||||
}
|
||||
pLayout->AddObject(r);
|
||||
if (!r->Skippable()) {
|
||||
ret = std::static_pointer_cast<UI7::Button>(r)->IsPressed();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
PD_UI7_API void Menu::Checkbox(const std::string& label, bool& v) {
|
||||
u32 id = Strings::FastHash("cbx" + label +
|
||||
std::to_string(pLayout->Objects.size()));
|
||||
Container::Ref r = pLayout->FindObject(id);
|
||||
if (!r) {
|
||||
r = Checkbox::New(label, v, pIO);
|
||||
r->SetID(id);
|
||||
}
|
||||
pLayout->AddObject(r);
|
||||
}
|
||||
|
||||
PD_UI7_API void Menu::Image(Li::Texture::Ref img, fvec2 size, Li::Rect uv) {
|
||||
Container::Ref r = Image::New(img, size, uv);
|
||||
pLayout->AddObject(r);
|
||||
}
|
||||
|
||||
PD_UI7_API void Menu::ColorEdit(const std::string& label, u32& clr) {
|
||||
u32 id = Strings::FastHash("drd" + label);
|
||||
Container::Ref r = pLayout->FindObject(id);
|
||||
if (!r) {
|
||||
r = UI7::ColorEdit::New(label, &clr, pIO);
|
||||
r->SetID(id);
|
||||
}
|
||||
pLayout->AddObject(r);
|
||||
}
|
||||
|
||||
PD_UI7_API void Menu::Separator() {
|
||||
// Dynamic Objects are very simple...
|
||||
Container::Ref r = DynObj::New(
|
||||
[=, this](UI7::IO::Ref io, Li::DrawList::Ref l, UI7::Container* self) {
|
||||
l->DrawRectFilled(self->FinalPos(), self->GetSize(),
|
||||
pIO->Theme->Get(UI7Color_TextDead));
|
||||
});
|
||||
// Set size before pushing (cause Cursor Move will require it)
|
||||
r->SetSize(fvec2(
|
||||
pLayout->Size.x - pIO->MenuPadding.x * 2 - pLayout->InitialCursorOffset.x,
|
||||
1));
|
||||
pLayout->AddObject(r);
|
||||
}
|
||||
|
||||
PD_UI7_API void Menu::SeparatorText(const std::string& label) {
|
||||
// Also note to use [=] instead of [&] to not undefined access label
|
||||
Container::Ref r = DynObj::New([=, this](UI7::IO::Ref io, Li::DrawList::Ref l,
|
||||
UI7::Container* self) {
|
||||
fvec2 size = self->GetSize();
|
||||
fvec2 tdim = io->Font->GetTextBounds(label, io->FontScale);
|
||||
fvec2 pos = self->FinalPos();
|
||||
auto align = pLayout->GetAlignment();
|
||||
vec2 rpos = pLayout->AlignPosition(
|
||||
pos, tdim, fvec4(pLayout->Pos, pLayout->Size), align);
|
||||
if (!(align & UI7Align_Left)) {
|
||||
l->DrawRectFilled(fvec2(rpos.x + io->FramePadding.x, tdim.y * 0.5),
|
||||
fvec2(pos.x - rpos.x - io->MenuPadding.x, 1),
|
||||
io->Theme->Get(UI7Color_TextDead));
|
||||
}
|
||||
if (!(align & UI7Align_Right)) {
|
||||
l->DrawRectFilled(pos + fvec2(tdim.x + io->FramePadding.x, tdim.y * 0.5),
|
||||
fvec2(size.x - tdim.x - io->MenuPadding.x, 1),
|
||||
io->Theme->Get(UI7Color_TextDead));
|
||||
}
|
||||
l->DrawTextEx(rpos, label, io->Theme->Get(UI7Color_Text), 0,
|
||||
fvec2(pLayout->Size.x, self->GetSize().y));
|
||||
});
|
||||
// Set size before pushing (cause Cursor Move will require it)
|
||||
r->SetSize(fvec2(
|
||||
pLayout->Size.x - pIO->MenuPadding.x * 2 - pLayout->InitialCursorOffset.x,
|
||||
pIO->Font->PixelHeight * pIO->FontScale));
|
||||
pLayout->AddObject(r);
|
||||
}
|
||||
PD_UI7_API void Menu::HandleFocus() {
|
||||
// Check if menu can be focused for Selective Menu Input API
|
||||
vec4 newarea = fvec4(pLayout->Pos, pLayout->Size);
|
||||
if (!pIsOpen) {
|
||||
newarea = fvec4(pLayout->Pos, fvec2(pLayout->Size.x, TitleBarHeight));
|
||||
}
|
||||
if ((Hid::IsDown(Hid::Key::Touch) ||
|
||||
Hid::IsEvent(Hid::Event::Event_Down, HidKb::Kb_MouseLeft)) &&
|
||||
Li::Renderer::InBox(Hid::MousePos(), newarea) &&
|
||||
!Li::Renderer::InBox(Hid::MousePos(),
|
||||
pIO->InputHandler->FocusedMenuRect)) {
|
||||
pIO->InputHandler->FocusedMenu = pID;
|
||||
}
|
||||
if (pIO->InputHandler->FocusedMenu == pID) {
|
||||
pIO->InputHandler->FocusedMenuRect = newarea;
|
||||
}
|
||||
}
|
||||
|
||||
/** Todo: (func name is self describing) */
|
||||
PD_UI7_API void Menu::HandleScrolling() {
|
||||
if (Flags & UI7MenuFlags_VtScrolling) {
|
||||
bool allowed =
|
||||
pLayout->MaxPosition.y > (pLayout->WorkRect.w - pLayout->WorkRect.y);
|
||||
if (allowed) {
|
||||
if (PD::Hid::IsDown(PD::Hid::Key::Touch)) {
|
||||
pLayout->ScrollStart = pLayout->ScrollOffset;
|
||||
}
|
||||
if (pIO->InputHandler->DragObject(
|
||||
"sbg" + pID.GetName(),
|
||||
fvec4(pLayout->Pos, fvec2(0.f)) + pLayout->WorkRect)) {
|
||||
if (pIO->InputHandler->DragReleasedAW) {
|
||||
} else {
|
||||
pLayout->ScrollOffset.y = std::clamp(
|
||||
pLayout->ScrollStart.y + pIO->InputHandler->DragSourcePos.y -
|
||||
pIO->InputHandler->DragPosition.y,
|
||||
-20.f, pLayout->MaxPosition.y - 220);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
pLayout->ScrollOffset.y = 0.f;
|
||||
}
|
||||
|
||||
if (pLayout->ScrollOffset.y > pLayout->MaxPosition.y - 240) {
|
||||
pLayout->ScrollOffset.y -= 1.5;
|
||||
if (pLayout->ScrollOffset.y < pLayout->MaxPosition.y - 240) {
|
||||
pLayout->ScrollOffset.y = pLayout->MaxPosition.y - 240;
|
||||
}
|
||||
}
|
||||
if (pLayout->ScrollOffset.y < 0) {
|
||||
pLayout->ScrollOffset.y += 1.5;
|
||||
if (pLayout->ScrollOffset.y > 0) {
|
||||
pLayout->ScrollOffset.y = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PD_UI7_API void Menu::HandleTitlebarActions() {
|
||||
// Collapse
|
||||
if (!(Flags & UI7MenuFlags_NoCollapse)) {
|
||||
vec2 cpos = pLayout->Pos + pIO->FramePadding;
|
||||
// clr_collapse_tri = UI7Color_FrameBackground;
|
||||
if (pIO->InputHandler->DragObject(UI7::ID(pID.GetName() + "clbse"),
|
||||
fvec4(cpos, fvec2(18, TitleBarHeight)))) {
|
||||
if (pIO->InputHandler->DragReleased) {
|
||||
pIsOpen = !pIsOpen;
|
||||
}
|
||||
// clr_collapse_tri = UI7Color_FrameBackgroundHovered;
|
||||
}
|
||||
}
|
||||
// Close Logic
|
||||
if (!(Flags & UI7MenuFlags_NoClose) && pIsShown != nullptr) {
|
||||
vec2 cpos =
|
||||
fvec2(pLayout->Pos.x + pLayout->Size.x - 12 - pIO->FramePadding.x,
|
||||
pLayout->Pos.y + pIO->FramePadding.y);
|
||||
|
||||
// clr_close_btn = UI7Color_FrameBackground;
|
||||
if (pIO->InputHandler->DragObject(UI7::ID(pID.GetName() + "clse"),
|
||||
fvec4(cpos, fvec2(12)))) {
|
||||
if (pIO->InputHandler->DragReleased) {
|
||||
*pIsShown = !(*pIsShown);
|
||||
}
|
||||
// clr_close_btn = UI7Color_FrameBackgroundHovered;
|
||||
}
|
||||
}
|
||||
// Resize logic
|
||||
if (!(Flags & UI7MenuFlags_NoResize)) {
|
||||
vec2 cpos = pLayout->Pos + pLayout->Size - fvec2(20);
|
||||
|
||||
// clr_close_btn = UI7Color_FrameBackground;
|
||||
if (pIO->InputHandler->DragObject(UI7::ID(pID.GetName() + "rszs"),
|
||||
fvec4(cpos, fvec2(20)))) {
|
||||
fvec2 szs = pLayout->Size + (pIO->InputHandler->DragPosition -
|
||||
pIO->InputHandler->DragLastPosition);
|
||||
if (szs.x < 30) szs.x = 30;
|
||||
if (szs.y < 30) szs.y = 30;
|
||||
pLayout->Size = szs;
|
||||
// clr_close_btn = UI7Color_FrameBackgroundHovered;
|
||||
}
|
||||
}
|
||||
// Menu Movement
|
||||
if (!(Flags & UI7MenuFlags_NoMove)) {
|
||||
if (pIO->InputHandler->DragObject(
|
||||
pID.GetName() + "tmv",
|
||||
fvec4(pLayout->Pos, fvec2(pLayout->Size.x, TitleBarHeight)))) {
|
||||
if (pIO->InputHandler->DragDoubleRelease) {
|
||||
pIsOpen = !pIsOpen;
|
||||
}
|
||||
pLayout->Pos = pLayout->Pos + (pIO->InputHandler->DragPosition -
|
||||
pIO->InputHandler->DragLastPosition);
|
||||
// Keep Window In Viewport
|
||||
// Maybe i need to add some operators to vec
|
||||
pLayout->Pos.x = std::clamp<float>(pLayout->Pos.x, -pLayout->Size.x + 10,
|
||||
pIO->CurrentViewPort.z - 10);
|
||||
pLayout->Pos.y = std::clamp<float>(pLayout->Pos.y, pIO->CurrentViewPort.y,
|
||||
pIO->CurrentViewPort.w - 10);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PD_UI7_API void Menu::DrawBaseLayout() {
|
||||
if (pIsOpen) {
|
||||
/** Resize Sym (Render on Top of Everything) */
|
||||
if (!(Flags & UI7MenuFlags_NoResize)) {
|
||||
Container::Ref r = DynObj::New(
|
||||
[](IO::Ref io, Li::DrawList::Ref l, UI7::Container* self) {
|
||||
l->Layer(1);
|
||||
l->PathAdd(self->FinalPos() + self->GetSize() - fvec2(0, 20));
|
||||
l->PathAdd(self->FinalPos() + self->GetSize());
|
||||
l->PathAdd(self->FinalPos() + self->GetSize() - fvec2(20, 0));
|
||||
l->PathFill(io->Theme->Get(UI7Color_Button));
|
||||
});
|
||||
r->SetSize(
|
||||
fvec2(pLayout->GetSize().x, pLayout->GetSize().y - TitleBarHeight));
|
||||
r->SetPos(fvec2(0, TitleBarHeight));
|
||||
pLayout->AddObjectEx(r,
|
||||
UI7LytAdd_NoCursorUpdate | UI7LytAdd_NoScrollHandle);
|
||||
}
|
||||
|
||||
/** Background */
|
||||
Container::Ref r = DynObj::New([](IO::Ref io, Li::DrawList::Ref l,
|
||||
UI7::Container* self) {
|
||||
l->Layer(0);
|
||||
l->PathRectEx(self->FinalPos(), self->FinalPos() + self->GetSize(), 10.f,
|
||||
LiPathRectFlags_KeepTop | LiPathRectFlags_KeepBot);
|
||||
l->PathFill(io->Theme->Get(UI7Color_Background));
|
||||
/*l->DrawRectFilled(self->FinalPos(), self->GetSize(),
|
||||
io->Theme->Get(UI7Color_Background));*/
|
||||
});
|
||||
// Set size before pushing (cause Cursor Move will require it)
|
||||
r->SetSize(
|
||||
fvec2(pLayout->GetSize().x, pLayout->GetSize().y - TitleBarHeight));
|
||||
r->SetPos(fvec2(0, TitleBarHeight));
|
||||
pLayout->AddObjectEx(r, UI7LytAdd_NoCursorUpdate |
|
||||
UI7LytAdd_NoScrollHandle | UI7LytAdd_Front);
|
||||
}
|
||||
if (!(Flags & UI7MenuFlags_NoTitlebar)) {
|
||||
Container::Ref r = DynObj::New(
|
||||
[=, this](UI7::IO::Ref io, Li::DrawList::Ref l, UI7::Container* self) {
|
||||
l->Layer(20);
|
||||
/** Header Bar */
|
||||
l->DrawRectFilled(self->FinalPos(), self->GetSize(),
|
||||
io->Theme->Get(UI7Color_Header));
|
||||
l->Layer(21);
|
||||
/** Inline if statement to shift the Text if collapse sym is shown */
|
||||
/** What the hell is this code btw (didn't found a better way) */
|
||||
l->DrawText(self->FinalPos() + fvec2((Flags & UI7MenuFlags_NoCollapse)
|
||||
? pIO->FramePadding.x
|
||||
: (TitleBarHeight -
|
||||
pIO->FramePadding.y * 2 +
|
||||
(io->FramePadding.x * 2)),
|
||||
2),
|
||||
pID.GetName(), io->Theme->Get(UI7Color_Text));
|
||||
});
|
||||
r->SetSize(fvec2(pLayout->GetSize().x, TitleBarHeight));
|
||||
r->SetPos(0);
|
||||
pLayout->AddObjectEx(r,
|
||||
UI7LytAdd_NoCursorUpdate | UI7LytAdd_NoScrollHandle);
|
||||
|
||||
/** Collapse Sym */
|
||||
if (!(Flags & UI7MenuFlags_NoCollapse)) {
|
||||
r = DynObj::New([=, this](UI7::IO::Ref io, Li::DrawList::Ref l,
|
||||
UI7::Container* self) {
|
||||
/** This sym actually requires layer 21 (i dont know why) */
|
||||
l->Layer(21);
|
||||
/**
|
||||
* Symbol (Position Swapping set by pIsOpen ? openpos : closepos;)
|
||||
*/
|
||||
l->DrawTriangleFilled(
|
||||
self->FinalPos(),
|
||||
self->FinalPos() +
|
||||
fvec2(self->GetSize().x, pIsOpen ? 0 : self->GetSize().y * 0.5),
|
||||
self->FinalPos() +
|
||||
fvec2(pIsOpen ? self->GetSize().x * 0.5 : 0, self->GetSize().y),
|
||||
io->Theme->Get(UI7Color_FrameBackground));
|
||||
});
|
||||
r->SetSize(TitleBarHeight - pIO->FramePadding.y * 2);
|
||||
r->SetPos(pIO->FramePadding);
|
||||
pLayout->AddObjectEx(r,
|
||||
UI7LytAdd_NoCursorUpdate | UI7LytAdd_NoScrollHandle);
|
||||
}
|
||||
/** Close Sym (only shown if pIsShown is not nullptr) */
|
||||
if (!(Flags & UI7MenuFlags_NoClose) && pIsShown) {
|
||||
fvec2 size = TitleBarHeight - pIO->FramePadding.y * 2; // Fixed quad size
|
||||
// Need to clamp this way as the math lib lacks a less and greater
|
||||
// operator in vec2 (don't checked if it would make sense yet)
|
||||
size.x = std::clamp(size.x, 5.f, std::numeric_limits<float>::max());
|
||||
size.y = std::clamp(size.y, 5.f, std::numeric_limits<float>::max());
|
||||
// Probably should fix the minsize to be locked on y
|
||||
fvec2 cpos =
|
||||
fvec2(pLayout->Pos.x + pLayout->Size.x - size.x - pIO->FramePadding.x,
|
||||
pLayout->Pos.y + pIO->FramePadding.y);
|
||||
pLayout->DrawList->DrawLine(cpos, cpos + size,
|
||||
pIO->Theme->Get(UI7Color_FrameBackground), 2);
|
||||
pLayout->DrawList->DrawLine(cpos + fvec2(0, size.y),
|
||||
cpos + fvec2(size.x, 0),
|
||||
pIO->Theme->Get(UI7Color_FrameBackground), 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PD_UI7_API void Menu::Update() {
|
||||
HandleFocus();
|
||||
if (pLayout->Size == fvec2(0.f) || Flags & UI7MenuFlags_AlwaysAutoSize) {
|
||||
pLayout->Size = fvec2(pLayout->MaxPosition) + pIO->MenuPadding * 2;
|
||||
}
|
||||
if (!(Flags & UI7MenuFlags_NoTitlebar)) {
|
||||
TitleBarHeight =
|
||||
pIO->FontScale * pIO->Font->PixelHeight + pIO->MenuPadding.y;
|
||||
pLayout->WorkRect.y = 5.f + TitleBarHeight;
|
||||
HandleTitlebarActions();
|
||||
} else {
|
||||
TitleBarHeight = 0.f;
|
||||
pLayout->WorkRect.y = 5.f;
|
||||
}
|
||||
DrawBaseLayout();
|
||||
pLayout->Update();
|
||||
if (Flags & UI7MenuFlags_VtScrolling || Flags & UI7MenuFlags_HzScrolling) {
|
||||
HandleScrolling();
|
||||
}
|
||||
}
|
||||
|
||||
PD_UI7_API bool Menu::BeginTreeNode(const ID& id) {
|
||||
// As of some notes this should work:
|
||||
auto n = pTreeNodes.find(id);
|
||||
if (n == pTreeNodes.end()) {
|
||||
pTreeNodes[id] = false;
|
||||
n = pTreeNodes.find(id);
|
||||
}
|
||||
fvec2 pos = pLayout->Cursor;
|
||||
fvec2 tdim = pIO->Font->GetTextBounds(id.GetName(), pIO->FontScale);
|
||||
fvec2 szs = tdim + fvec2(pIO->ItemSpace.x + 10, 0);
|
||||
|
||||
if (n->second) {
|
||||
pLayout->InitialCursorOffset += 10.f;
|
||||
}
|
||||
|
||||
// Object
|
||||
auto r =
|
||||
DynObj::New([=, this](IO::Ref io, Li::DrawList::Ref l, Container* self) {
|
||||
fvec2 ts = self->FinalPos() + fvec2(0, 7);
|
||||
fvec2 pl[2] = {fvec2(10, 5), fvec2(0, 10)};
|
||||
if (n->second) {
|
||||
float t = pl[0].y;
|
||||
pl[0].y = pl[1].x;
|
||||
pl[1].x = t;
|
||||
}
|
||||
l->DrawTriangleFilled(ts, ts + pl[0], ts + pl[1],
|
||||
io->Theme->Get(UI7Color_FrameBackground));
|
||||
|
||||
l->DrawText(self->FinalPos() + fvec2(10 + io->ItemSpace.x, 0),
|
||||
id.GetName(), io->Theme->Get(UI7Color_Text));
|
||||
});
|
||||
/** Yes this new function handler was created for tree nodes */
|
||||
r->AddInputHandler([=, this](IO::Ref io, Container* self) {
|
||||
if (io->InputHandler->DragObject(
|
||||
ID(pID.GetName() + id.GetName()),
|
||||
fvec4(self->FinalPos(), self->GetSize()))) {
|
||||
if (io->InputHandler->DragReleased) {
|
||||
n->second = !n->second;
|
||||
}
|
||||
}
|
||||
});
|
||||
r->SetPos(pos);
|
||||
r->SetSize(szs);
|
||||
/** Use Add Object as it is faster */
|
||||
pLayout->AddObject(r);
|
||||
|
||||
return n->second;
|
||||
}
|
||||
|
||||
PD_UI7_API void UI7::Menu::EndTreeNode() {
|
||||
pLayout->InitialCursorOffset.x -= 10.f;
|
||||
pLayout->Cursor.x -= 10.f;
|
||||
if (pLayout->InitialCursorOffset.x < 0.f) {
|
||||
pLayout->InitialCursorOffset.x = 0.f;
|
||||
}
|
||||
}
|
||||
} // namespace UI7
|
||||
} // namespace PD
|
||||
68
source/ui7/theme.cpp
Executable file
68
source/ui7/theme.cpp
Executable file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
MIT License
|
||||
Copyright (c) 2024 - 2025 René Amthor (tobid7)
|
||||
|
||||
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 <pd/ui7/theme.hpp>
|
||||
|
||||
namespace PD {
|
||||
namespace UI7 {
|
||||
PD_UI7_API void Theme::Default(Theme& theme) {
|
||||
theme.Set(UI7Color_Text, Color("#FFFFFFFF"));
|
||||
theme.Set(UI7Color_TextDead, Color("#AAAAAAFF"));
|
||||
theme.Set(UI7Color_Background, Color("#222222aa"));
|
||||
theme.Set(UI7Color_Border, Color("#999999ff"));
|
||||
theme.Set(UI7Color_Button, Color("#111111FF"));
|
||||
theme.Set(UI7Color_ButtonDead, Color("#080808FF"));
|
||||
theme.Set(UI7Color_ButtonActive, Color("#2A2A2AFF"));
|
||||
theme.Set(UI7Color_ButtonHovered, Color("#222222FF"));
|
||||
theme.Set(UI7Color_Header, Color("#111111cc"));
|
||||
theme.Set(UI7Color_HeaderDead, Color("#080808FF"));
|
||||
theme.Set(UI7Color_Selector, Color("#222222FF"));
|
||||
theme.Set(UI7Color_Checkmark, Color("#2A2A2AFF"));
|
||||
theme.Set(UI7Color_FrameBackground, Color("#555555FF"));
|
||||
theme.Set(UI7Color_FrameBackgroundHovered, Color("#777777FF"));
|
||||
theme.Set(UI7Color_Progressbar, Color("#00FF00FF"));
|
||||
theme.Set(UI7Color_ListEven, Color("#CCCCCCFF"));
|
||||
theme.Set(UI7Color_ListOdd, Color("#BBBBBBFF"));
|
||||
}
|
||||
|
||||
PD_UI7_API void Theme::Flashbang(Theme& theme) {
|
||||
theme.Set(UI7Color_Text, Color("#000000FF"));
|
||||
theme.Set(UI7Color_TextDead, Color("#333333FF"));
|
||||
theme.Set(UI7Color_Background, Color("#eeeeeeFF"));
|
||||
theme.Set(UI7Color_Border, Color("#777777ff"));
|
||||
theme.Set(UI7Color_Button, Color("#ccccccFF"));
|
||||
theme.Set(UI7Color_ButtonDead, Color("#bbbbbbFF"));
|
||||
theme.Set(UI7Color_ButtonActive, Color("#ccccccFF"));
|
||||
theme.Set(UI7Color_ButtonHovered, Color("#acacacFF"));
|
||||
theme.Set(UI7Color_Header, Color("#ddddddFF"));
|
||||
theme.Set(UI7Color_HeaderDead, Color("#cdcdcdFF"));
|
||||
theme.Set(UI7Color_Selector, Color("#222222FF"));
|
||||
theme.Set(UI7Color_Checkmark, Color("#ccccccFF"));
|
||||
theme.Set(UI7Color_FrameBackground, Color("#aaaaaaFF"));
|
||||
theme.Set(UI7Color_FrameBackgroundHovered, Color("#909090FF"));
|
||||
theme.Set(UI7Color_Progressbar, Color("#00FF00FF"));
|
||||
theme.Set(UI7Color_ListEven, Color("#CCCCCCFF"));
|
||||
theme.Set(UI7Color_ListOdd, Color("#BBBBBBFF"));
|
||||
}
|
||||
} // namespace UI7
|
||||
} // namespace PD
|
||||
351
source/ui7/ui7.cpp
Normal file
351
source/ui7/ui7.cpp
Normal file
@@ -0,0 +1,351 @@
|
||||
/*
|
||||
MIT License
|
||||
Copyright (c) 2024 - 2025 René Amthor (tobid7)
|
||||
|
||||
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 <pd/ui7/ui7.hpp>
|
||||
|
||||
#include "pd/ui7/flags.hpp"
|
||||
#include "pd/ui7/pd_p_api.hpp"
|
||||
|
||||
#define UI7DHX32(x) std::format("{}: {:#08x}", #x, x)
|
||||
#define UI7DTF(x) PD::Strings::FormatNanos(x)
|
||||
|
||||
namespace PD {
|
||||
namespace UI7 {
|
||||
PD_UI7_API std::string GetVersion(bool show_build) {
|
||||
std::stringstream s;
|
||||
s << ((UI7_VERSION >> 24) & 0xFF) << ".";
|
||||
s << ((UI7_VERSION >> 16) & 0xFF) << ".";
|
||||
s << ((UI7_VERSION >> 8) & 0xFF);
|
||||
if (show_build) s << "-" << ((UI7_VERSION) & 0xFF);
|
||||
return s.str();
|
||||
}
|
||||
|
||||
PD_UI7_API void Context::AddViewPort(const ID& id, const ivec4& vp) {
|
||||
pIO->AddViewPort(id, vp);
|
||||
}
|
||||
|
||||
PD_UI7_API void Context::UseViewPort(const ID& id) {
|
||||
if (!pIO->ViewPorts.count(id)) {
|
||||
return;
|
||||
}
|
||||
pIO->CurrentViewPort = pIO->ViewPorts[id]->GetSize();
|
||||
}
|
||||
|
||||
PD_UI7_API Menu::Ref Context::BeginMenu(const ID& id, UI7MenuFlags flags,
|
||||
bool* pShow) {
|
||||
if (pCurrent) {
|
||||
std::cout << "[UI7] Error: You are already in " << pCurrent->pID.GetName()
|
||||
<< " Menu" << std::endl;
|
||||
return nullptr;
|
||||
}
|
||||
if (std::find(pCurrentMenus.begin(), pCurrentMenus.end(), (u32)id) !=
|
||||
pCurrentMenus.end()) {
|
||||
std::cout << "[UI7] Error: Menu " << id.GetName() << " already exists!"
|
||||
<< std::endl;
|
||||
return nullptr;
|
||||
}
|
||||
pCurrent = pGetOrCreateMenu(id);
|
||||
this->pCurrent->pIsShown = pShow;
|
||||
if (pCurrent->pIsShown != nullptr) {
|
||||
if (!*pCurrent->pIsShown) {
|
||||
pCurrent = nullptr;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
/** Probably we dont even need Input Handling in this stage */
|
||||
// this->pIO->InputHandler->CurrentMenu = id;
|
||||
pCurrentMenus.push_back(id);
|
||||
pCurrent->Flags = flags;
|
||||
if (!pCurrent->pIsOpen) {
|
||||
pCurrent = nullptr;
|
||||
}
|
||||
return pCurrent;
|
||||
}
|
||||
|
||||
PD_UI7_API void Context::EndMenu() {
|
||||
/**
|
||||
* Currently it would be a better wy to handle menus as follows
|
||||
*
|
||||
* The folowing context will generate a new menu as normally but instead
|
||||
* of true or false we have m is false (nullptr) or true (some ptr returned)
|
||||
* and after that it should simply out of scope
|
||||
* (This would probably require some wrapper class to find out if m goes
|
||||
* out of scope)
|
||||
* ```cpp
|
||||
* if(auto m = ui7->BeginMenu("Test")) {
|
||||
* m->Label("Show some Text");
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
if (!pCurrent) {
|
||||
return;
|
||||
}
|
||||
pCurrent = nullptr;
|
||||
// pIO->InputHandler->CurrentMenu = 0;
|
||||
}
|
||||
|
||||
PD_UI7_API void Context::Update() {
|
||||
/**
|
||||
* Cause Commenting each line looks carbage...
|
||||
* This function simply clears the FinalDrawList, Searches for Menu ID's in
|
||||
* The sorted menu List from last frame to insert them as same order into
|
||||
* the final list. After that it adds new menus to the begin to 'add' new
|
||||
* menus on top. As final step the focused menu gets add to begin
|
||||
* Then the menus update their Input and DraeList Generation in List Order
|
||||
* and the DrawLists get Merged into the FDL in reverse Order. At end the List
|
||||
* gets cleanup and io gets updated
|
||||
*
|
||||
* Very simple ...
|
||||
*/
|
||||
pIO->FDL->Clear();
|
||||
if (std::find(pCurrentMenus.begin(), pCurrentMenus.end(),
|
||||
pIO->InputHandler->FocusedMenu) == pCurrentMenus.end()) {
|
||||
pIO->InputHandler->FocusedMenu = 0;
|
||||
pIO->InputHandler->FocusedMenuRect = fvec4(0);
|
||||
}
|
||||
std::vector<u32> FinalList;
|
||||
for (auto it : pDFO) {
|
||||
if (std::find(pCurrentMenus.begin(), pCurrentMenus.end(), it) !=
|
||||
pCurrentMenus.end() &&
|
||||
it != pIO->InputHandler->FocusedMenu) {
|
||||
FinalList.push_back(it);
|
||||
}
|
||||
}
|
||||
for (auto it : pCurrentMenus) {
|
||||
if (std::find(FinalList.begin(), FinalList.end(), it) == FinalList.end() &&
|
||||
it != pIO->InputHandler->FocusedMenu) {
|
||||
FinalList.push_back(it);
|
||||
}
|
||||
}
|
||||
if (pMenus.count(pIO->InputHandler->FocusedMenu)) {
|
||||
FinalList.insert(FinalList.begin(), pIO->InputHandler->FocusedMenu);
|
||||
}
|
||||
pDFO = FinalList;
|
||||
for (auto& it : FinalList) {
|
||||
this->pIO->InputHandler->CurrentMenu = it;
|
||||
pMenus[it]->Update(); /** Render */
|
||||
this->pIO->InputHandler->CurrentMenu = 0;
|
||||
}
|
||||
for (int i = (int)FinalList.size() - 1; i >= 0; i--) {
|
||||
pIO->FDL->Merge(pMenus[FinalList[i]]->pLayout->GetDrawList());
|
||||
}
|
||||
pCurrentMenus.clear();
|
||||
pIO->Update();
|
||||
pIO->FDL->pPool.Sort();
|
||||
}
|
||||
|
||||
PD_UI7_API void Context::AboutMenu(bool* show) {
|
||||
if (auto m = BeginMenu("About UI7", UI7MenuFlags_Scrolling, show)) {
|
||||
m->Label("Palladium UI7 " + GetVersion());
|
||||
m->Separator();
|
||||
m->Label("(c) 2023-2025 René Amthor");
|
||||
m->Label("UI7 is licensed under the MIT License.");
|
||||
m->Label("See LICENSE for more information.");
|
||||
static bool show_build;
|
||||
m->Checkbox("Show Build Info", show_build);
|
||||
if (show_build) {
|
||||
m->SeparatorText("Build Info");
|
||||
m->Label("Full Version -> " + GetVersion(true));
|
||||
m->Label("sizeof(size_t) -> " + std::to_string(sizeof(size_t)));
|
||||
m->Label("sizeof(LI::Vertex) -> " + std::to_string(sizeof(Li::Vertex)));
|
||||
m->Label("__cplusplus -> " + std::to_string(__cplusplus));
|
||||
m->Label("Compiler -> " +
|
||||
Strings::GetCompilerVersion()); // + LibInfo::CompiledWith());
|
||||
}
|
||||
EndMenu();
|
||||
}
|
||||
}
|
||||
|
||||
PD_UI7_API void Context::MetricsMenu(bool* show) {
|
||||
if (auto m = BeginMenu("UI7 Metrics", UI7MenuFlags_Scrolling, show)) {
|
||||
m->Label("Palladium - UI7 " + GetVersion());
|
||||
m->Separator();
|
||||
m->Label(
|
||||
std::format("Average {:.3f} ms/f ({:.1f} FPS)",
|
||||
((float)pIO->DeltaStats->GetAverage() / 1000.f),
|
||||
1000.f / ((float)pIO->DeltaStats->GetAverage() / 1000.f)));
|
||||
m->Label(std::format("NumVertices: {}", pIO->NumVertices));
|
||||
m->Label(std::format("NumIndices: {} -> {} Tris", pIO->NumIndices,
|
||||
pIO->NumIndices / 3));
|
||||
m->Label("Menus: " + std::to_string(pMenus.size()));
|
||||
/** Section TimeTrace */
|
||||
m->SeparatorText("TimeTrace");
|
||||
if (m->BeginTreeNode("Traces (" + std::to_string(OS::GetTraceMap().size()) +
|
||||
")")) {
|
||||
for (auto& it : OS::GetTraceMap()) {
|
||||
if (m->BeginTreeNode(it.second->GetID())) {
|
||||
m->Label("Diff: " + UI7DTF(it.second->GetLastDiff()));
|
||||
m->Label("Protocol Len: " +
|
||||
std::to_string(it.second->GetProtocol()->GetLen()));
|
||||
m->Label("Average: " +
|
||||
UI7DTF(it.second->GetProtocol()->GetAverage()));
|
||||
m->Label("Min: " + UI7DTF(it.second->GetProtocol()->GetMin()));
|
||||
m->Label("Max: " + UI7DTF(it.second->GetProtocol()->GetMax()));
|
||||
m->EndTreeNode();
|
||||
}
|
||||
}
|
||||
m->EndTreeNode();
|
||||
}
|
||||
m->SeparatorText("Palladium Info");
|
||||
m->Label("Renderer: " + PD::Gfx::pGfx->pName);
|
||||
if (m->BeginTreeNode(std::string("Input: " + PD::Hid::pHid->pName))) {
|
||||
if (PD::Hid::GetFlags() & PD::HidDriver::Flags_HasKeyboard) {
|
||||
m->Label("- Keyboard Supported");
|
||||
}
|
||||
if (PD::Hid::GetFlags() & PD::HidDriver::Flags_HasMouse) {
|
||||
m->Label("- Mouse Supported");
|
||||
}
|
||||
if (PD::Hid::GetFlags() & PD::HidDriver::Flags_HasTouch) {
|
||||
m->Label("- Touch Supported");
|
||||
}
|
||||
if (PD::Hid::GetFlags() & PD::HidDriver::FLags_HasGamepad) {
|
||||
m->Label("- Gamepad Supported");
|
||||
}
|
||||
m->EndTreeNode();
|
||||
}
|
||||
/** Section IO */
|
||||
m->SeparatorText("IO");
|
||||
if (m->BeginTreeNode("Menus (" + std::to_string(pMenus.size()) + ")")) {
|
||||
for (auto& it : pMenus) {
|
||||
if (m->BeginTreeNode(it.second->pID.GetName())) {
|
||||
m->Label("Name: " + it.second->pID.GetName());
|
||||
m->Label(std::format("Pos: {}", it.second->pLayout->GetPosition()));
|
||||
m->Label(std::format("Size: {}", it.second->pLayout->GetSize()));
|
||||
m->Label(std::format("WorkRect: {}", it.second->pLayout->WorkRect));
|
||||
m->Label(std::format("Cursor: {}", it.second->pLayout->Cursor));
|
||||
if (m->BeginTreeNode(
|
||||
"ID Objects (" +
|
||||
std::to_string(it.second->pLayout->IDObjects.size()) + ")")) {
|
||||
for (auto& jt : it.second->pLayout->IDObjects) {
|
||||
m->Label(std::format("{:08X}", jt->GetID()));
|
||||
}
|
||||
m->EndTreeNode();
|
||||
}
|
||||
m->EndTreeNode();
|
||||
}
|
||||
}
|
||||
m->EndTreeNode();
|
||||
}
|
||||
if (m->BeginTreeNode("Active Menus (" +
|
||||
std::to_string(pCurrentMenus.size()) + ")")) {
|
||||
for (auto& it : pCurrentMenus) {
|
||||
if (m->BeginTreeNode(pMenus[it]->pID.GetName())) {
|
||||
m->Label("Name: " + pMenus[it]->pID.GetName());
|
||||
m->Label(std::format("Pos: {}", pMenus[it]->pLayout->GetPosition()));
|
||||
m->Label(std::format("Size: {}", pMenus[it]->pLayout->GetSize()));
|
||||
m->Label(std::format("WorkRect: {}", pMenus[it]->pLayout->WorkRect));
|
||||
m->Label(std::format("Cursor: {}", pMenus[it]->pLayout->Cursor));
|
||||
if (m->BeginTreeNode(
|
||||
"ID Objects (" +
|
||||
std::to_string(pMenus[it]->pLayout->IDObjects.size()) +
|
||||
")")) {
|
||||
for (auto& jt : pMenus[it]->pLayout->IDObjects) {
|
||||
m->Label(std::format("{:08X}", jt->GetID()));
|
||||
}
|
||||
m->EndTreeNode();
|
||||
}
|
||||
m->EndTreeNode();
|
||||
}
|
||||
}
|
||||
m->EndTreeNode();
|
||||
}
|
||||
// Well this are Li Drawlists now and they do not count their stats (yet)
|
||||
/*if (m->BeginTreeNode("DrawLists (" +
|
||||
std::to_string(pIO->DrawListRegestry.size()) + ")")) {
|
||||
for (auto &it : pIO->DrawListRegestry) {
|
||||
if (m->BeginTreeNode(it.First.GetName())) {
|
||||
m->Label("Vertices: " + std::to_string(it.Second->NumVertices));
|
||||
m->Label("Indices: " + std::to_string(it.Second->NumIndices));
|
||||
m->Label("Base Layer: " + std::to_string(it.Second->Base));
|
||||
m->EndTreeNode();
|
||||
}
|
||||
}
|
||||
m->EndTreeNode();
|
||||
}*/
|
||||
m->Label("io->Time: " + Strings::FormatMillis(pIO->Time->Get()));
|
||||
m->Label(std::format("Delta: {:.3f}", pIO->Delta));
|
||||
m->Label(std::format("Framerate: {:.2f}", pIO->Framerate));
|
||||
m->Label(
|
||||
std::format("Focused Menu: {:08X}", pIO->InputHandler->FocusedMenu));
|
||||
m->Label(std::format("Dragged Object: {:08X}",
|
||||
pIO->InputHandler->DraggedObject));
|
||||
m->Label(std::format("DragTime: {:.2f}s",
|
||||
pIO->InputHandler->DragTime->GetSeconds()));
|
||||
m->Label(std::format("DragDestination: [{}]",
|
||||
pIO->InputHandler->DragDestination));
|
||||
m->Label(std::format("DragSource: [{}]", pIO->InputHandler->DragSourcePos));
|
||||
m->Label(std::format("DragPos: [{}]", pIO->InputHandler->DragPosition));
|
||||
m->Label(
|
||||
std::format("DragLastPos: [{}]", pIO->InputHandler->DragLastPosition));
|
||||
EndMenu();
|
||||
}
|
||||
}
|
||||
|
||||
PD_UI7_API void UI7::Context::StyleEditor(bool* show) {
|
||||
if (auto m = BeginMenu("UI7 Style Editor", UI7MenuFlags_Scrolling, show)) {
|
||||
m->Label("Palladium - UI7 " + GetVersion() + " Style Editor");
|
||||
m->Separator();
|
||||
m->DragData("MenuPadding", (float*)&pIO->MenuPadding, 2, 0.f, 100.f);
|
||||
m->DragData("FramePadding", (float*)&pIO->FramePadding, 2, 0.f, 100.f);
|
||||
m->DragData("ItemSpace", (float*)&pIO->ItemSpace, 2, 0.f, 100.f);
|
||||
m->DragData("MinSliderSize", (float*)&pIO->MinSliderDragSize, 2, 1.f,
|
||||
100.f);
|
||||
m->DragData("OverScroll Modifier", &pIO->OverScrollMod, 1, 0.01f,
|
||||
std::numeric_limits<float>::max(), 0.01f, 2);
|
||||
m->Checkbox("Menu Border", pIO->ShowMenuBorder);
|
||||
m->Checkbox("Frame Border", pIO->ShowFrameBorder);
|
||||
m->SeparatorText("Theme");
|
||||
if (m->Button("Dark")) {
|
||||
UI7::Theme::Default(*pIO->Theme.get());
|
||||
}
|
||||
m->SameLine();
|
||||
if (m->Button("Flashbang")) {
|
||||
UI7::Theme::Flashbang(*pIO->Theme.get());
|
||||
}
|
||||
/// Small trick to print without prefix
|
||||
#define ts(x) m->ColorEdit(std::string(#x).substr(9), pIO->Theme->GetRef(x));
|
||||
#define ts2(x) \
|
||||
m->DragData(std::string(#x).substr(9), (u8*)&pIO->Theme->GetRef(x), 4, \
|
||||
(u8)0, (u8)255);
|
||||
ts(UI7Color_Background);
|
||||
ts(UI7Color_Border);
|
||||
ts(UI7Color_Button);
|
||||
ts(UI7Color_ButtonDead);
|
||||
ts(UI7Color_ButtonActive);
|
||||
ts(UI7Color_ButtonHovered);
|
||||
ts(UI7Color_Text);
|
||||
ts(UI7Color_TextDead);
|
||||
ts(UI7Color_Header);
|
||||
ts(UI7Color_HeaderDead);
|
||||
ts(UI7Color_Selector);
|
||||
ts(UI7Color_Checkmark);
|
||||
ts(UI7Color_FrameBackground);
|
||||
ts(UI7Color_FrameBackgroundHovered);
|
||||
ts(UI7Color_Progressbar);
|
||||
ts(UI7Color_ListEven);
|
||||
ts(UI7Color_ListOdd);
|
||||
this->EndMenu();
|
||||
}
|
||||
}
|
||||
} // namespace UI7
|
||||
} // namespace PD
|
||||
Reference in New Issue
Block a user