SDRPlusPlus/core/src/gui/widgets/frequency_select.cpp

228 wiersze
7.2 KiB
C++
Czysty Zwykły widok Historia

#include <gui/widgets/frequency_select.h>
#include <config.h>
2020-11-30 20:17:36 +00:00
#include <gui/style.h>
2021-06-23 19:45:38 +00:00
#include <gui/gui.h>
2022-01-29 19:35:08 +00:00
#include <backend.h>
#include <keybinds.h>
2020-07-19 13:59:44 +00:00
#ifndef IMGUI_DEFINE_MATH_OPERATORS
#define IMGUI_DEFINE_MATH_OPERATORS
#endif
#include <imgui/imgui_internal.h>
2020-07-19 13:59:44 +00:00
bool isInArea(ImVec2 val, ImVec2 min, ImVec2 max) {
return val.x >= min.x && val.x < max.x && val.y >= min.y && val.y < max.y;
}
FrequencySelect::FrequencySelect() {
}
void FrequencySelect::init() {
for (int i = 0; i < 12; i++) {
digits[i] = 0;
}
}
void FrequencySelect::onPosChange() {
ImVec2 digitSz = ImGui::CalcTextSize("0");
ImVec2 commaSz = ImGui::CalcTextSize(".");
int digitHeight = digitSz.y;
int digitWidth = digitSz.x;
2020-07-19 13:59:44 +00:00
int commaOffset = 0;
for (int i = 0; i < 12; i++) {
digitTopMins[i] = ImVec2(widgetPos.x + (i * digitWidth) + commaOffset, widgetPos.y);
digitBottomMins[i] = ImVec2(widgetPos.x + (i * digitWidth) + commaOffset, widgetPos.y + (digitHeight / 2));
2020-07-19 13:59:44 +00:00
digitTopMaxs[i] = ImVec2(widgetPos.x + (i * digitWidth) + commaOffset + digitWidth, widgetPos.y + (digitHeight / 2));
digitBottomMaxs[i] = ImVec2(widgetPos.x + (i * digitWidth) + commaOffset + digitWidth, widgetPos.y + digitHeight);
2020-07-19 13:59:44 +00:00
if ((i + 1) % 3 == 0 && i < 11) {
commaOffset += commaSz.x;
2020-07-19 13:59:44 +00:00
}
}
}
void FrequencySelect::incrementDigit(int i) {
if (i < 0) {
return;
}
if (digits[i] < 9) {
digits[i]++;
}
else {
digits[i] = 0;
incrementDigit(i - 1);
}
frequencyChanged = true;
}
void FrequencySelect::decrementDigit(int i) {
if (i < 0) {
return;
}
if (digits[i] > 0) {
digits[i]--;
}
else {
if (i == 0) { return; }
// Check if there are non zero digits afterwards
bool otherNoneZero = false;
for (int j = i - 1; j >= 0; j--) {
if (digits[j] > 0) {
otherNoneZero = true;
break;
}
}
if (!otherNoneZero) { return; }
2020-07-19 13:59:44 +00:00
digits[i] = 9;
decrementDigit(i - 1);
}
frequencyChanged = true;
}
void FrequencySelect::moveCursorToDigit(int i) {
double xpos, ypos;
2022-01-29 19:35:08 +00:00
backend::getMouseScreenPos(xpos, ypos);
double nxpos = (digitTopMaxs[i].x + digitTopMins[i].x) / 2.0;
backend::setMouseScreenPos(nxpos, ypos);
}
2020-07-19 13:59:44 +00:00
void FrequencySelect::draw() {
auto window = ImGui::GetCurrentWindow();
2020-07-19 13:59:44 +00:00
widgetPos = ImGui::GetWindowContentRegionMin();
2020-08-21 13:34:50 +00:00
ImVec2 cursorPos = ImGui::GetCursorPos();
widgetPos.x += window->Pos.x + cursorPos.x;
2020-11-30 20:17:36 +00:00
ImGui::PushFont(style::bigFont);
ImVec2 digitSz = ImGui::CalcTextSize("0");
ImVec2 commaSz = ImGui::CalcTextSize(".");
widgetPos.y = cursorPos.y - ((digitSz.y / 2.0f) - ceilf(15 * style::uiScale) - 5);
2020-07-19 13:59:44 +00:00
if (widgetPos.x != lastWidgetPos.x || widgetPos.y != lastWidgetPos.y) {
lastWidgetPos = widgetPos;
onPosChange();
}
2020-08-17 00:39:56 +00:00
ImU32 disabledColor = ImGui::GetColorU32(ImGuiCol_Text, 0.3f);
ImU32 textColor = ImGui::GetColorU32(ImGuiCol_Text);
int digitWidth = digitSz.x;
2020-07-19 13:59:44 +00:00
int commaOffset = 0;
float textOffset = 11.0f * style::uiScale;
2020-07-19 13:59:44 +00:00
bool zeros = true;
ImGui::ItemSize(ImRect(digitTopMins[0], ImVec2(digitBottomMaxs[11].x + 15, digitBottomMaxs[11].y)));
2020-07-19 13:59:44 +00:00
for (int i = 0; i < 12; i++) {
if (digits[i] != 0) {
zeros = false;
}
sprintf(buf, "%d", digits[i]);
window->DrawList->AddText(ImVec2(widgetPos.x + (i * digitWidth) + commaOffset, widgetPos.y),
zeros ? disabledColor : textColor, buf);
2020-07-19 13:59:44 +00:00
if ((i + 1) % 3 == 0 && i < 11) {
commaOffset += commaSz.x;
window->DrawList->AddText(ImVec2(widgetPos.x + (i * digitWidth) + commaOffset + textOffset, widgetPos.y),
zeros ? disabledColor : textColor, ".");
2020-07-19 13:59:44 +00:00
}
}
2021-06-23 19:45:38 +00:00
if (!gui::mainWindow.lockWaterfallControls) {
ImVec2 mousePos = ImGui::GetMousePos();
bool leftClick = ImGui::IsMouseClicked(ImGuiMouseButton_Left);
bool rightClick = ImGui::IsMouseClicked(ImGuiMouseButton_Right);
int mw = ImGui::GetIO().MouseWheel;
bool onDigit = false;
bool hovered = false;
for (int i = 0; i < 12; i++) {
onDigit = false;
if (isInArea(mousePos, digitTopMins[i], digitTopMaxs[i])) {
window->DrawList->AddRectFilled(digitTopMins[i], digitTopMaxs[i], IM_COL32(255, 0, 0, 75));
if (leftClick) {
incrementDigit(i);
2020-07-19 13:59:44 +00:00
}
2021-06-23 19:45:38 +00:00
onDigit = true;
2021-04-23 15:53:25 +00:00
}
2021-06-23 19:45:38 +00:00
if (isInArea(mousePos, digitBottomMins[i], digitBottomMaxs[i])) {
window->DrawList->AddRectFilled(digitBottomMins[i], digitBottomMaxs[i], IM_COL32(0, 0, 255, 75));
if (leftClick) {
decrementDigit(i);
}
onDigit = true;
2021-04-23 17:12:24 +00:00
}
2021-06-23 19:45:38 +00:00
if (onDigit) {
hovered = true;
2022-01-29 19:35:08 +00:00
if (rightClick || (ImGui::IsKeyPressed(KB_KEY_DEL) || ImGui::IsKeyPressed(KB_KEY_ENTER) || ImGui::IsKeyPressed(KB_KEY_KP_ENTER))) {
2021-06-23 19:45:38 +00:00
for (int j = i; j < 12; j++) {
digits[j] = 0;
}
2021-06-23 19:45:38 +00:00
frequencyChanged = true;
}
2022-01-29 19:35:08 +00:00
if (ImGui::IsKeyPressed(KB_KEY_UP)) {
2021-06-23 19:45:38 +00:00
incrementDigit(i);
}
2022-01-29 19:35:08 +00:00
if (ImGui::IsKeyPressed(KB_KEY_DOWN)) {
2021-06-23 19:45:38 +00:00
decrementDigit(i);
}
2022-01-29 19:35:08 +00:00
if ((ImGui::IsKeyPressed(KB_KEY_LEFT) || ImGui::IsKeyPressed(KB_KEY_BACKSPACE)) && i > 0) {
moveCursorToDigit(i - 1);
2021-06-23 19:45:38 +00:00
}
2022-01-29 19:35:08 +00:00
if (ImGui::IsKeyPressed(KB_KEY_RIGHT) && i < 11) {
2021-06-23 19:45:38 +00:00
moveCursorToDigit(i + 1);
}
2021-06-23 19:45:38 +00:00
auto chars = ImGui::GetIO().InputQueueCharacters;
2021-06-23 19:45:38 +00:00
// For each keyboard characters, type it
for (int j = 0; j < chars.Size; j++) {
if (chars[j] >= '0' && chars[j] <= '9') {
digits[i + j] = chars[j] - '0';
if ((i + j) < 11) { moveCursorToDigit(i + j + 1); }
frequencyChanged = true;
}
}
2021-06-23 19:45:38 +00:00
if (mw != 0) {
int count = abs(mw);
for (int j = 0; j < count; j++) {
mw > 0 ? incrementDigit(i) : decrementDigit(i);
}
2020-07-19 13:59:44 +00:00
}
}
}
2021-06-23 19:45:38 +00:00
digitHovered = hovered;
2020-07-19 13:59:44 +00:00
}
2020-08-20 16:29:23 +00:00
uint64_t freq = 0;
2020-07-19 13:59:44 +00:00
for (int i = 0; i < 12; i++) {
freq += digits[i] * pow(10, 11 - i);
}
uint64_t orig = freq;
freq = std::clamp<uint64_t>(freq, minFreq, maxFreq);
if (freq != orig && limitFreq) {
setFrequency(freq);
}
else {
frequency = orig;
}
2020-07-19 13:59:44 +00:00
ImGui::PopFont();
2020-12-08 15:27:52 +00:00
ImGui::SetCursorPosX(digitBottomMaxs[11].x + (17.0f * style::uiScale));
2020-07-19 13:59:44 +00:00
}
2021-07-29 18:22:16 +00:00
void FrequencySelect::setFrequency(int64_t freq) {
freq = std::max<int64_t>(0, freq);
2020-07-19 13:59:44 +00:00
int i = 11;
2020-08-20 16:29:23 +00:00
for (uint64_t f = freq; i >= 0; i--) {
2020-07-19 13:59:44 +00:00
digits[i] = f % 10;
f -= digits[i];
f /= 10;
}
frequency = freq;
}