Changes related to text input on Android, general bug fixes, license change to GPLv3

This commit is contained in:
Yousef Khadadeh 2026-05-11 23:06:39 +03:00
parent 8b3e321ab5
commit fc8f414b67
308 changed files with 8707 additions and 440 deletions

View file

@ -1,3 +1,21 @@
/*
* InfiniPaint
* Copyright (C) 2025-2026 Yousef Khadadeh
*
* 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 <https://www.gnu.org/licenses/>.
*/
#include "ButtonHelpers.hpp"
#include "../Elements/SVGIcon.hpp"
#include "../Elements/LayoutElement.hpp"

View file

@ -1,3 +1,21 @@
/*
* InfiniPaint
* Copyright (C) 2025-2026 Yousef Khadadeh
*
* 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 <https://www.gnu.org/licenses/>.
*/
#pragma once
#include "../GUIManager.hpp"
#include "../Elements/SelectableButton.hpp"

View file

@ -1,3 +1,21 @@
/*
* InfiniPaint
* Copyright (C) 2025-2026 Yousef Khadadeh
*
* 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 <https://www.gnu.org/licenses/>.
*/
#include "CheckBoxHelpers.hpp"
#include "LayoutHelpers.hpp"
#include "TextLabelHelpers.hpp"

View file

@ -1,3 +1,21 @@
/*
* InfiniPaint
* Copyright (C) 2025-2026 Yousef Khadadeh
*
* 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 <https://www.gnu.org/licenses/>.
*/
#pragma once
#include "../GUIManager.hpp"

View file

@ -1,3 +1,21 @@
/*
* InfiniPaint
* Copyright (C) 2025-2026 Yousef Khadadeh
*
* 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 <https://www.gnu.org/licenses/>.
*/
#pragma once
#include "ColorPickerItemsHelpers.hpp"
#include "../Elements/ColorPickerButton.hpp"

View file

@ -1,3 +1,21 @@
/*
* InfiniPaint
* Copyright (C) 2025-2026 Yousef Khadadeh
*
* 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 <https://www.gnu.org/licenses/>.
*/
#pragma once
#include "../GUIManager.hpp"
#include "TextBoxHelpers.hpp"

View file

@ -0,0 +1,53 @@
/*
* InfiniPaint
* Copyright (C) 2025-2026 Yousef Khadadeh
*
* 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 <https://www.gnu.org/licenses/>.
*/
#pragma once
#include "../GUIManager.hpp"
#include "../Elements/DropDown.hpp"
namespace GUIStuff { namespace ElementHelpers {
template <typename T> void number_dropdown(GUIManager& gui, const char* id, T* data, int32_t minData, int32_t maxData, int32_t step, const std::function<void()>& onChange = nullptr) {
std::vector<std::string> dropdownStrings;
size_t closestSelectionDistance = std::numeric_limits<size_t>::max();
std::shared_ptr<size_t> currentSelection = std::make_shared<size_t>(0);
{
size_t i = 0;
for(int32_t newSelection = minData; newSelection <= maxData; newSelection += step) {
size_t newDistance = std::abs(static_cast<int32_t>(*data) - newSelection);
if(newDistance < closestSelectionDistance) {
closestSelectionDistance = newDistance;
*currentSelection = i;
}
dropdownStrings.emplace_back(std::to_string(newSelection));
i++;
}
}
gui.element<DropDown<size_t>>(id, currentSelection.get(), dropdownStrings, DropdownOptions{
.onClick = [minData, step, data, onChange, currentSelection] {
int32_t newVal = minData;
for(size_t i = 0; i < *currentSelection; i++)
newVal += step;
*data = static_cast<T>(newVal);
if(onChange) onChange();
}
});
}
}}

View file

@ -1,6 +1,25 @@
/*
* InfiniPaint
* Copyright (C) 2025-2026 Yousef Khadadeh
*
* 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 <https://www.gnu.org/licenses/>.
*/
#include "LayoutHelpers.hpp"
#include "../Elements/LayoutElement.hpp"
#include "Helpers/ConvertVec.hpp"
#include "../Elements/ManyElementScrollArea.hpp"
namespace GUIStuff { namespace ElementHelpers {
@ -213,4 +232,130 @@ void window_gap_side_bar(GUIManager& gui, const WindowFillSideBarConfig::Directi
}
}
void bottom_offset_setup(GUIManager& gui, float dropdownHeight, Clay_FloatingElementConfig& floatConfig, float& maxHeight, const DropDownPopupLayout& d) {
auto& bb = d.button->get_bb().value();
float xOffset = bb.center().x() - d.entrySize.x() * 0.5f;
if(xOffset < 0.0f)
xOffset = 0.0f;
else if(xOffset + d.entrySize.x() > gui.io.safeWindowRect.max.x())
xOffset = gui.io.safeWindowRect.max.x() - d.entrySize.x();
floatConfig = {
.offset = {
.x = xOffset,
.y = bb.max.y() + d.dropdownOffset
},
.zIndex = gui.get_z_index(),
.attachPoints = {
.element = CLAY_ATTACH_POINT_LEFT_TOP,
.parent = CLAY_ATTACH_POINT_LEFT_TOP
},
.attachTo = CLAY_ATTACH_TO_ROOT
};
maxHeight = std::max(gui.io.safeWindowRect.max.y() - bb.max.y() - d.dropdownOffset, 0.0f);
}
void top_offset_setup(GUIManager& gui, float dropdownHeight, Clay_FloatingElementConfig& floatConfig, float& maxHeight, const DropDownPopupLayout& d) {
auto& bb = d.button->get_bb().value();
float xOffset = bb.center().x() - d.entrySize.x() * 0.5f;
if(xOffset < 0.0f)
xOffset = 0.0f;
else if(xOffset + d.entrySize.x() > gui.io.safeWindowRect.max.x())
xOffset = gui.io.safeWindowRect.max.x() - d.entrySize.x();
floatConfig = {
.offset = {
.x = xOffset,
.y = bb.min.y() - d.dropdownOffset
},
.zIndex = gui.get_z_index(),
.attachPoints = {
.element = CLAY_ATTACH_POINT_LEFT_BOTTOM,
.parent = CLAY_ATTACH_POINT_LEFT_TOP
},
.attachTo = CLAY_ATTACH_TO_ROOT
};
maxHeight = std::max(bb.min.y() - gui.io.safeWindowRect.min.y() - d.dropdownOffset, 0.0f);
}
void left_right_offset_setup(GUIManager& gui, float dropdownHeight, Clay_FloatingElementConfig& floatConfig, float& maxHeight, bool isRightSide, const DropDownPopupLayout& d) {
auto& bb = d.button->get_bb().value();
float offsetY = bb.center().y() - dropdownHeight * 0.5f;
if(dropdownHeight >= gui.io.safeWindowRect.height() || offsetY < gui.io.safeWindowRect.min.y())
offsetY = gui.io.safeWindowRect.min.y();
else if(offsetY + dropdownHeight > gui.io.safeWindowRect.max.y())
offsetY -= (offsetY + dropdownHeight) - gui.io.safeWindowRect.max.y();
floatConfig = {
.offset = {
.x = isRightSide ? bb.max.x() + d.dropdownOffset : bb.min.x() - bb.width() - d.dropdownOffset,
.y = offsetY
},
.zIndex = gui.get_z_index(),
.attachPoints = {
.element = CLAY_ATTACH_POINT_LEFT_TOP,
.parent = CLAY_ATTACH_POINT_LEFT_TOP
},
.attachTo = CLAY_ATTACH_TO_ROOT
};
maxHeight = gui.io.safeWindowRect.height();
}
void dropdown_many_element_popup_layout(GUIManager& gui, const char* id, const DropDownPopupLayout& d) {
if(!d.button->get_bb().has_value())
return;
gui.element<LayoutElement>(id, [&](LayoutElement* l, const Clay_ElementId& lId) {
float dropdownHeight = d.entrySize.y() * d.entryCount + d.dropdownOffset;
Clay_FloatingElementConfig floatConfig;
float maxHeight = gui.io.safeWindowRect.height();
auto& buttonBB = d.button->get_bb().value();
if(buttonBB.max.y() + dropdownHeight > gui.io.safeWindowRect.max.y()) {
float rightSideWidth = gui.io.safeWindowRect.max.x() - buttonBB.max.x();
float leftSideWidth = buttonBB.min.x() - gui.io.safeWindowRect.min.x();
if(rightSideWidth > d.entrySize.x() || leftSideWidth > d.entrySize.x())
left_right_offset_setup(gui, dropdownHeight, floatConfig, maxHeight, rightSideWidth >= leftSideWidth, d);
else {
if(gui.io.safeWindowRect.max.y() - buttonBB.max.y() >= buttonBB.min.y() - gui.io.safeWindowRect.min.y())
bottom_offset_setup(gui, dropdownHeight, floatConfig, maxHeight, d);
else
top_offset_setup(gui, dropdownHeight, floatConfig, maxHeight, d);
}
}
else
bottom_offset_setup(gui, dropdownHeight, floatConfig, maxHeight, d);
CLAY(lId, {
.layout = {
.sizing = {.width = CLAY_SIZING_FIXED(d.entrySize.x()), .height = CLAY_SIZING_FIT(0, maxHeight)},
.childGap = 0
},
.backgroundColor = convert_vec4<Clay_Color>(gui.io.theme->backColor1),
.cornerRadius = CLAY_CORNER_RADIUS(4),
.floating = floatConfig,
.border = {
.color = convert_vec4<Clay_Color>(gui.io.theme->fillColor2),
.width = CLAY_BORDER_OUTSIDE(1)
}
}) {
gui.element<ManyElementScrollArea>("dropdown scroll area", ManyElementScrollArea::Options{
.entryHeight = d.entrySize.y(),
.entryCount = d.entryCount,
.clipHorizontal = true,
.elementContent = d.entryLayout
});
}
}, LayoutElement::Callbacks {
.onClick = [&, d](LayoutElement* l, const InputManager::MouseButtonCallbackArgs& m) {
if(!l->mouseHovering && !l->childMouseHovering && m.down && !d.button->mouseHovering && d.isOpen) {
*d.isOpen = false;
gui.set_to_layout();
}
}
});
}
}}

View file

@ -1,3 +1,21 @@
/*
* InfiniPaint
* Copyright (C) 2025-2026 Yousef Khadadeh
*
* 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 <https://www.gnu.org/licenses/>.
*/
#pragma once
#include "../GUIManager.hpp"
#include "../Elements/LayoutElement.hpp"
@ -23,4 +41,15 @@ struct WindowFillSideBarConfig {
void window_fill_side_bar(GUIManager& gui, const WindowFillSideBarConfig& config, const std::function<void()>& innerContent);
void window_gap_side_bar(GUIManager& gui, const WindowFillSideBarConfig::Direction& dir);
struct DropDownPopupLayout {
float dropdownOffset = 4.0f;
Element* button = nullptr;
bool* isOpen;
Vector2f entrySize;
size_t entryCount;
std::function<void(size_t i)> entryLayout;
};
void dropdown_many_element_popup_layout(GUIManager& gui, const char* id, const DropDownPopupLayout& d);
}}

View file

@ -1,3 +1,21 @@
/*
* InfiniPaint
* Copyright (C) 2025-2026 Yousef Khadadeh
*
* 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 <https://www.gnu.org/licenses/>.
*/
#pragma once
#include "../GUIManager.hpp"
#include "TextBoxHelpers.hpp"

View file

@ -1,3 +1,21 @@
/*
* InfiniPaint
* Copyright (C) 2025-2026 Yousef Khadadeh
*
* 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 <https://www.gnu.org/licenses/>.
*/
#include "PopupHelpers.hpp"
namespace GUIStuff { namespace ElementHelpers {

View file

@ -1,3 +1,21 @@
/*
* InfiniPaint
* Copyright (C) 2025-2026 Yousef Khadadeh
*
* 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 <https://www.gnu.org/licenses/>.
*/
#pragma once
#include "../GUIManager.hpp"
#include "../Elements/PaintCircleMenu.hpp"

View file

@ -1,3 +1,21 @@
/*
* InfiniPaint
* Copyright (C) 2025-2026 Yousef Khadadeh
*
* 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 <https://www.gnu.org/licenses/>.
*/
#include "RadioButtonHelpers.hpp"
#include "../Elements/RadioButton.hpp"
#include "LayoutHelpers.hpp"

View file

@ -1,3 +1,21 @@
/*
* InfiniPaint
* Copyright (C) 2025-2026 Yousef Khadadeh
*
* 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 <https://www.gnu.org/licenses/>.
*/
#pragma once
#include "../GUIManager.hpp"

View file

@ -1,3 +1,21 @@
/*
* InfiniPaint
* Copyright (C) 2025-2026 Yousef Khadadeh
*
* 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 <https://www.gnu.org/licenses/>.
*/
#include "TextBoxHelpers.hpp"
#include "LayoutHelpers.hpp"

View file

@ -1,3 +1,21 @@
/*
* InfiniPaint
* Copyright (C) 2025-2026 Yousef Khadadeh
*
* 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 <https://www.gnu.org/licenses/>.
*/
#pragma once
#include "../GUIManager.hpp"
#include "../Elements/TextBox.hpp"

View file

@ -1,3 +1,21 @@
/*
* InfiniPaint
* Copyright (C) 2025-2026 Yousef Khadadeh
*
* 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 <https://www.gnu.org/licenses/>.
*/
#include "TextLabelHelpers.hpp"
#include "../Elements/MutableTextLabel.hpp"
#include "Helpers/ConvertVec.hpp"

View file

@ -1,3 +1,21 @@
/*
* InfiniPaint
* Copyright (C) 2025-2026 Yousef Khadadeh
*
* 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 <https://www.gnu.org/licenses/>.
*/
#pragma once
#include "../GUIManager.hpp"