Files
crosspoint-reader-mod/src/activities/util/NumericStepperActivity.cpp
cottongin dfbc931c14 mod: Phase 1 - bring forward mod-exclusive files with ActivityManager migration
Brings ~55 mod-exclusive files to the upstream-based mod/master-resync branch:

Activities (migrated to new ActivityManager pattern):
- Clock/Time: SetTimeActivity, SetTimezoneOffsetActivity, NtpSyncActivity
- Dictionary: DictionaryDefinitionActivity, DictionarySuggestionsActivity,
  DictionaryWordSelectActivity, LookedUpWordsActivity
- Bookmark: EpubReaderBookmarkSelectionActivity
- Book management: BookManageMenuActivity, EndOfBookMenuActivity
- OPDS: OpdsServerListActivity, OpdsSettingsActivity
- Utility: DirectoryPickerActivity, NumericStepperActivity

Utilities (unchanged):
- BookManager, BookSettings, BookmarkStore, BootNtpSync
- Dictionary, LookupHistory, TimeSync, OpdsServerStore

Libraries: PlaceholderCover, TableData, ChapterXPathIndexer
Scripts: inject_mod_version, generate_book_icon, preview_placeholder_cover
Docs: KOReader sync XPath mapping

Migration changes:
- ActivityWithSubactivity -> Activity base class
- Callback constructors -> finish()/setResult() pattern
- enterNewActivity() -> startActivityForResult()
- Activity::RenderLock&& -> RenderLock&&

These files won't compile yet - they reference mod settings and I18n
strings that will be added in subsequent phases.

Made-with: Cursor
2026-03-07 15:10:00 -05:00

105 lines
3.0 KiB
C++

#include "NumericStepperActivity.h"
#include <GfxRenderer.h>
#include <I18n.h>
#include <algorithm>
#include <cstdio>
#include "ActivityResult.h"
#include "MappedInputManager.h"
#include "components/UITheme.h"
#include "fontIds.h"
void NumericStepperActivity::onEnter() {
Activity::onEnter();
requestUpdate();
}
void NumericStepperActivity::onExit() { Activity::onExit(); }
void NumericStepperActivity::loop() {
if (mappedInput.wasPressed(MappedInputManager::Button::Back)) {
ActivityResult r;
r.isCancelled = true;
setResult(std::move(r));
finish();
return;
}
if (mappedInput.wasPressed(MappedInputManager::Button::Confirm)) {
setResult(PageResult{.page = static_cast<uint32_t>(value)});
finish();
return;
}
// Side buttons: ±1
if (mappedInput.wasPressed(MappedInputManager::Button::Up)) {
if (value < maxValue) {
value++;
requestUpdate();
}
return;
}
if (mappedInput.wasPressed(MappedInputManager::Button::Down)) {
if (value > minValue) {
value--;
requestUpdate();
}
return;
}
// Front face buttons: ±10
if (mappedInput.wasPressed(MappedInputManager::Button::Right)) {
value = std::min(value + 10, maxValue);
requestUpdate();
return;
}
if (mappedInput.wasPressed(MappedInputManager::Button::Left)) {
value = std::max(value - 10, minValue);
requestUpdate();
return;
}
}
void NumericStepperActivity::render(RenderLock&&) {
renderer.clearScreen();
const auto pageWidth = renderer.getScreenWidth();
const int lineHeight12 = renderer.getLineHeight(UI_12_FONT_ID);
const auto& metrics = UITheme::getInstance().getMetrics();
GUI.drawHeader(renderer, Rect{0, metrics.topPadding, pageWidth, metrics.headerHeight}, title.c_str());
char valueStr[16];
snprintf(valueStr, sizeof(valueStr), "%d", value);
const int textWidth = renderer.getTextWidth(UI_12_FONT_ID, valueStr);
const int startX = (pageWidth - textWidth) / 2;
const int valueY = metrics.topPadding + metrics.headerHeight + 60;
constexpr int highlightPad = 10;
renderer.fillRoundedRect(startX - highlightPad, valueY - 4, textWidth + highlightPad * 2, lineHeight12 + 8, 6,
Color::LightGray);
renderer.drawText(UI_12_FONT_ID, startX, valueY, valueStr, true);
const int arrowX = pageWidth / 2;
const int arrowUpY = valueY - 20;
const int arrowDownY = valueY + lineHeight12 + 12;
constexpr int arrowSize = 6;
for (int row = 0; row < arrowSize; row++) {
renderer.drawLine(arrowX - row, arrowUpY + row, arrowX + row, arrowUpY + row);
}
for (int row = 0; row < arrowSize; row++) {
renderer.drawLine(arrowX - row, arrowDownY + arrowSize - 1 - row, arrowX + row, arrowDownY + arrowSize - 1 - row);
}
const auto labels = mappedInput.mapLabels(tr(STR_BACK), tr(STR_SAVE), "-10", "+10");
GUI.drawButtonHints(renderer, labels.btn1, labels.btn2, labels.btn3, labels.btn4);
GUI.drawSideButtonHints(renderer, "+1", "-1");
renderer.displayBuffer();
}