Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions data/locale/en-GB.ini
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ PTZ.Action.Preset.Save="Save Camera Preset"
PTZ.Action.Preset.Clear="Clear Camera Preset"
PTZ.Action.Preset.RecallNum="Camera Recall #%1"
PTZ.Action.Preset.SaveNum="Camera Save #%1"
PTZ.Action.Preset.Prev="Previous Preset"
PTZ.Action.Preset.Next="Next Preset"
PTZ.Action.Preset.RecallSelected="Recall Selected Preset"
PTZ.Action.Preset.Add.Tooltip="Add Preset"
PTZ.Action.Preset.MoveUp.Tooltip="Move Preset Up"
PTZ.Action.Preset.MoveDown.Tooltip="Move Preset Down"
Expand Down
54 changes: 54 additions & 0 deletions src/ptz-controls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,28 @@ PTZControls::PTZControls(QWidget *parent) : QFrame(parent), ui(new Ui::PTZContro
hotkey = registerHotkey(QT_TO_UTF8(name), QT_TO_UTF8(description), preset_set_cb, this);
preset_hotkey_map[hotkey] = i;
}

registerHotkey(
"PTZ.PresetPrev", obs_module_text("PTZ.Action.Preset.Prev"),
[](void *ptz_data, obs_hotkey_id, obs_hotkey_t *, bool pressed) {
if (pressed)
static_cast<PTZControls *>(ptz_data)->presetStep(-1);

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All the move logic is already implemented in CircularListView. You can drop the presetStep() helper and call static_cast<PTZControls *>(ptz_data)->ui->presetListView->cursorUp() directly.

},
this);
registerHotkey(
"PTZ.PresetNext", obs_module_text("PTZ.Action.Preset.Next"),
[](void *ptz_data, obs_hotkey_id, obs_hotkey_t *, bool pressed) {
if (pressed)
static_cast<PTZControls *>(ptz_data)->presetStep(1);
},

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto using cursorDown()

this);
registerHotkey(
"PTZ.PresetRecallSelected", obs_module_text("PTZ.Action.Preset.RecallSelected"),
[](void *ptz_data, obs_hotkey_id, obs_hotkey_t *, bool pressed) {
if (pressed)
static_cast<PTZControls *>(ptz_data)->presetRecallSelected();

@glikely glikely Aug 8, 2026

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There isn't a similar single helper for activating the item, but you could do this:

if (pressed) {
        auto ctrls = static_cast<PTZControls *>(ptz_data);
        ctrls->on_presetListView_activated(ctrls->ui->presetListView->currentIndex());
}

},
this);
}

#if defined(ENABLE_JOYSTICK)
Expand Down Expand Up @@ -979,6 +1001,38 @@ void PTZControls::presetReset(long long preset_id)
callCurrentDevice("ptz_preset_clear", "preset_id", preset_id);
}

/* Move the preset selection without recalling anything, so that a controller
* can browse the preset list and then trigger it with a separate button. Wraps
* around at both ends; with nothing selected yet, step forwards from the top
* and backwards from the bottom. */
void PTZControls::presetStep(int step)
{
auto model = ui->presetListView->model();
if (!model)
return;
const int count = model->rowCount();
if (count < 1)
return;
const int current = ui->presetListView->currentIndex().row();
int next;
if (current < 0)
next = step > 0 ? 0 : count - 1;
else
next = ((current + step) % count + count) % count;
ui->presetListView->setCurrentIndex(model->index(next, 0));
}

/* Recall whatever preset is currently highlighted in the list. The numbered
* PTZ.Recall<n> hotkeys address a fixed preset; this one follows the
* selection, which is what makes browse-then-activate possible from a
* joystick or a keyboard. */
void PTZControls::presetRecallSelected()
{
auto id = presetIndexToId(ui->presetListView->currentIndex());
if (id >= 0)
presetRecall(id);
}

int PTZControls::presetIndexToId(QModelIndex index)
{
if (index.isValid())
Expand Down
2 changes: 2 additions & 0 deletions src/ptz-controls.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ class PTZControls : public QFrame {
void presetSet(long long id);
void presetRecall(long long id);
void presetReset(long long id);
void presetStep(int step);
void presetRecallSelected();
void setAutofocusEnabled(bool autofocus_on);

bool callCurrentDevice(const char *method, calldata_t *cd = nullptr) const;
Expand Down
Loading