diff --git a/libobs/obs-scene.c b/libobs/obs-scene.c index 2c90933a1..d663ac768 100644 --- a/libobs/obs-scene.c +++ b/libobs/obs-scene.c @@ -22,6 +22,10 @@ static const char *obs_scene_signals[] = { "void item_add(ptr scene, ptr item)", "void item_remove(ptr scene, ptr item)", + "void item_move_up(ptr scene, ptr item)", + "void item_move_down(ptr scene, ptr item)", + "void item_move_top(ptr scene, ptr item)", + "void item_move_bottom(ptr scene, ptr item)", NULL }; @@ -134,10 +138,11 @@ static inline void detach_sceneitem(struct obs_scene_item *item) item->parent = NULL; } -static inline void attach_sceneitem(struct obs_scene_item *item, - struct obs_scene_item *prev) +static inline void attach_sceneitem(struct obs_scene *parent, + struct obs_scene_item *item, struct obs_scene_item *prev) { - item->prev = prev; + item->prev = prev; + item->parent = parent; if (prev) { item->next = prev->next; @@ -145,8 +150,6 @@ static inline void attach_sceneitem(struct obs_scene_item *item, prev->next->prev = item; prev->next = item; } else { - assert(item->parent != NULL); - item->next = item->parent->first_item; item->parent->first_item = item; } @@ -516,38 +519,66 @@ void obs_sceneitem_setscale(obs_sceneitem_t item, const struct vec2 *scale) vec2_copy(&item->scale, scale); } +static inline void signal_move_dir(struct obs_scene_item *item, + enum order_movement movement) +{ + const char *command; + struct calldata params = {0}; + + switch (movement) { + case ORDER_MOVE_UP: command = "item_move_up"; break; + case ORDER_MOVE_DOWN: command = "item_move_down"; break; + case ORDER_MOVE_TOP: command = "item_move_top"; break; + case ORDER_MOVE_BOTTOM: command = "item_move_bottom"; break; + } + + calldata_setptr(¶ms, "scene", item->parent); + calldata_setptr(¶ms, "item", item); + + signal_handler_signal(item->parent->source->context.signals, + command, ¶ms); + + calldata_free(¶ms); +} + void obs_sceneitem_setorder(obs_sceneitem_t item, enum order_movement movement) { if (!item) return; + struct obs_scene_item *next, *prev; struct obs_scene *scene = item->parent; obs_scene_addref(scene); pthread_mutex_lock(&scene->mutex); + next = item->next; + prev = item->prev; + detach_sceneitem(item); - if (movement == ORDER_MOVE_UP) { - attach_sceneitem(item, item->prev); + if (movement == ORDER_MOVE_DOWN) { + attach_sceneitem(scene, item, prev ? prev->prev : NULL); - } else if (movement == ORDER_MOVE_DOWN) { - attach_sceneitem(item, item->next); + } else if (movement == ORDER_MOVE_UP) { + attach_sceneitem(scene, item, next ? next : prev); } else if (movement == ORDER_MOVE_TOP) { - struct obs_scene_item *last = item->next; + struct obs_scene_item *last = next; if (!last) { - last = item->prev; + last = prev; } else { while (last->next) last = last->next; } - attach_sceneitem(item, last); + attach_sceneitem(scene, item, last); } else if (movement == ORDER_MOVE_BOTTOM) { - attach_sceneitem(item, NULL); + attach_sceneitem(scene, item, NULL); } + signal_move_dir(item, movement); + pthread_mutex_unlock(&scene->mutex); obs_scene_release(scene); } diff --git a/libobs/obs.h b/libobs/obs.h index 2f983a395..6c1c97b72 100644 --- a/libobs/obs.h +++ b/libobs/obs.h @@ -89,7 +89,7 @@ extern "C" { * * Reset to zero each major or minor version */ -#define LIBOBS_API_PATCH_VER 0 +#define LIBOBS_API_PATCH_VER 1 #define LIBOBS_API_VER ((LIBOBS_API_MAJOR_VER << 24) | \ (LIBOBS_API_MINOR_VER << 16) | \ diff --git a/obs/window-basic-main.cpp b/obs/window-basic-main.cpp index 01a007c15..3f8b77fdb 100644 --- a/obs/window-basic-main.cpp +++ b/obs/window-basic-main.cpp @@ -46,6 +46,7 @@ using namespace std; Q_DECLARE_METATYPE(OBSScene); Q_DECLARE_METATYPE(OBSSceneItem); +Q_DECLARE_METATYPE(order_movement); OBSBasic::OBSBasic(QWidget *parent) : OBSMainWindow (parent), @@ -536,6 +537,14 @@ void OBSBasic::AddScene(OBSSource source) OBSBasic::SceneItemAdded, this); signal_handler_connect(handler, "item_remove", OBSBasic::SceneItemRemoved, this); + signal_handler_connect(handler, "item_move_up", + OBSBasic::SceneItemMoveUp, this); + signal_handler_connect(handler, "item_move_down", + OBSBasic::SceneItemMoveDown, this); + signal_handler_connect(handler, "item_move_top", + OBSBasic::SceneItemMoveTop, this); + signal_handler_connect(handler, "item_move_bottom", + OBSBasic::SceneItemMoveBottom, this); } void OBSBasic::RemoveScene(OBSSource source) @@ -616,6 +625,42 @@ void OBSBasic::UpdateSceneSelection(OBSSource source) } } +void OBSBasic::MoveSceneItem(OBSSceneItem item, order_movement movement) +{ + OBSScene scene = obs_sceneitem_getscene(item); + if (scene != GetCurrentScene()) + return; + + int curRow = ui->sources->currentRow(); + if (curRow == -1) + return; + + QListWidgetItem *listItem = ui->sources->takeItem(curRow); + + switch (movement) { + case ORDER_MOVE_UP: + if (curRow > 0) + curRow--; + break; + + case ORDER_MOVE_DOWN: + if (curRow < ui->sources->count()) + curRow++; + break; + + case ORDER_MOVE_TOP: + curRow = 0; + break; + + case ORDER_MOVE_BOTTOM: + curRow = ui->sources->count(); + break; + } + + ui->sources->insertItem(curRow, listItem); + ui->sources->setCurrentRow(curRow); +} + void OBSBasic::ActivateAudioSource(OBSSource source) { VolControl *vol = new VolControl(source); @@ -739,6 +784,42 @@ void OBSBasic::RenderMain(void *data, uint32_t cx, uint32_t cy) UNUSED_PARAMETER(cy); } +void OBSBasic::SceneItemMoveUp(void *data, calldata_t params) +{ + OBSSceneItem item = (obs_sceneitem_t)calldata_ptr(params, "item"); + QMetaObject::invokeMethod(static_cast(data), + "MoveSceneItem", + Q_ARG(OBSSceneItem, OBSSceneItem(item)), + Q_ARG(order_movement, ORDER_MOVE_UP)); +} + +void OBSBasic::SceneItemMoveDown(void *data, calldata_t params) +{ + OBSSceneItem item = (obs_sceneitem_t)calldata_ptr(params, "item"); + QMetaObject::invokeMethod(static_cast(data), + "MoveSceneItem", + Q_ARG(OBSSceneItem, OBSSceneItem(item)), + Q_ARG(order_movement, ORDER_MOVE_DOWN)); +} + +void OBSBasic::SceneItemMoveTop(void *data, calldata_t params) +{ + OBSSceneItem item = (obs_sceneitem_t)calldata_ptr(params, "item"); + QMetaObject::invokeMethod(static_cast(data), + "MoveSceneItem", + Q_ARG(OBSSceneItem, OBSSceneItem(item)), + Q_ARG(order_movement, ORDER_MOVE_TOP)); +} + +void OBSBasic::SceneItemMoveBottom(void *data, calldata_t params) +{ + OBSSceneItem item = (obs_sceneitem_t)calldata_ptr(params, "item"); + QMetaObject::invokeMethod(static_cast(data), + "MoveSceneItem", + Q_ARG(OBSSceneItem, OBSSceneItem(item)), + Q_ARG(order_movement, ORDER_MOVE_BOTTOM)); +} + /* Main class functions */ obs_service_t OBSBasic::GetService() @@ -1125,10 +1206,14 @@ void OBSBasic::on_actionSourceProperties_triggered() void OBSBasic::on_actionSourceUp_triggered() { + OBSSceneItem item = GetCurrentSceneItem(); + obs_sceneitem_setorder(item, ORDER_MOVE_UP); } void OBSBasic::on_actionSourceDown_triggered() { + OBSSceneItem item = GetCurrentSceneItem(); + obs_sceneitem_setorder(item, ORDER_MOVE_DOWN); } void OBSBasic::StreamingStart() diff --git a/obs/window-basic-main.hpp b/obs/window-basic-main.hpp index cc5c88337..c71bc259f 100644 --- a/obs/window-basic-main.hpp +++ b/obs/window-basic-main.hpp @@ -108,6 +108,8 @@ private slots: void RemoveScene(OBSSource source); void UpdateSceneSelection(OBSSource source); + void MoveSceneItem(OBSSceneItem item, order_movement movement); + void ActivateAudioSource(OBSSource source); void DeactivateAudioSource(OBSSource source); @@ -122,6 +124,11 @@ private: static void ChannelChanged(void *data, calldata_t params); static void RenderMain(void *data, uint32_t cx, uint32_t cy); + static void SceneItemMoveUp(void *data, calldata_t params); + static void SceneItemMoveDown(void *data, calldata_t params); + static void SceneItemMoveTop(void *data, calldata_t params); + static void SceneItemMoveBottom(void *data, calldata_t params); + void ResizePreview(uint32_t cx, uint32_t cy); void AddSource(const char *id); diff --git a/obs/window-basic-settings.cpp b/obs/window-basic-settings.cpp index 4877581ce..e55976f08 100644 --- a/obs/window-basic-settings.cpp +++ b/obs/window-basic-settings.cpp @@ -588,11 +588,7 @@ void OBSBasicSettings::SaveAudioSettings() QString auxDevice2 = GetComboData(ui->auxAudioDevice2); QString auxDevice3 = GetComboData(ui->auxAudioDevice3); - const char *channelSetup; - if (channelSetupIdx == 0) - channelSetup = "Mono"; - else - channelSetup = "Stereo"; + const char *channelSetup = (channelSetupIdx == 0) ? "Mono" : "Stereo"; int sampleRate = 44100; if (sampleRateStr == "22.05khz")