mirror of
https://github.com/obsproject/obs-studio.git
synced 2024-07-05 11:03:31 +00:00
Compare commits
2 commits
5364855d0b
...
8bc31dc453
Author | SHA1 | Date | |
---|---|---|---|
|
8bc31dc453 | ||
|
d790d5d51e |
|
@ -774,6 +774,24 @@ struct OBSStudioAPI : obs_frontend_callbacks {
|
||||||
undo_data, redo_data, repeatable);
|
undo_data, redo_data, repeatable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void obs_frontend_copy_sceneitem(obs_sceneitem_t *item) override
|
||||||
|
{
|
||||||
|
main->clipboard.clear();
|
||||||
|
main->CopySceneItem(item);
|
||||||
|
main->UpdateEditMenu();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool obs_frontend_can_paste_sceneitem(bool duplicate) override
|
||||||
|
{
|
||||||
|
return main->CanPasteSceneItem(duplicate);
|
||||||
|
}
|
||||||
|
|
||||||
|
void obs_frontend_paste_sceneitem(obs_scene_t *scene,
|
||||||
|
bool duplicate) override
|
||||||
|
{
|
||||||
|
main->PasteSceneItem(scene, duplicate);
|
||||||
|
}
|
||||||
|
|
||||||
void on_load(obs_data_t *settings) override
|
void on_load(obs_data_t *settings) override
|
||||||
{
|
{
|
||||||
for (size_t i = saveCallbacks.size(); i > 0; i--) {
|
for (size_t i = saveCallbacks.size(); i > 0; i--) {
|
||||||
|
|
|
@ -637,3 +637,22 @@ void obs_frontend_add_undo_redo_action(const char *name,
|
||||||
c->obs_frontend_add_undo_redo_action(
|
c->obs_frontend_add_undo_redo_action(
|
||||||
name, undo, redo, undo_data, redo_data, repeatable);
|
name, undo, redo, undo_data, redo_data, repeatable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void obs_frontend_copy_sceneitem(obs_sceneitem_t *item)
|
||||||
|
{
|
||||||
|
if (callbacks_valid())
|
||||||
|
return c->obs_frontend_copy_sceneitem(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool obs_frontend_can_paste_sceneitem(bool duplicate)
|
||||||
|
{
|
||||||
|
if (!callbacks_valid())
|
||||||
|
return false;
|
||||||
|
return c->obs_frontend_can_paste_sceneitem(duplicate);
|
||||||
|
}
|
||||||
|
|
||||||
|
void obs_frontend_paste_sceneitem(obs_scene_t *scene, bool duplicate)
|
||||||
|
{
|
||||||
|
if (callbacks_valid())
|
||||||
|
return c->obs_frontend_paste_sceneitem(scene, duplicate);
|
||||||
|
}
|
||||||
|
|
|
@ -253,6 +253,10 @@ EXPORT void obs_frontend_add_undo_redo_action(
|
||||||
const char *name, const undo_redo_cb undo, const undo_redo_cb redo,
|
const char *name, const undo_redo_cb undo, const undo_redo_cb redo,
|
||||||
const char *undo_data, const char *redo_data, bool repeatable);
|
const char *undo_data, const char *redo_data, bool repeatable);
|
||||||
|
|
||||||
|
EXPORT void obs_frontend_copy_sceneitem(obs_sceneitem_t *item);
|
||||||
|
EXPORT bool obs_frontend_can_paste_sceneitem(bool duplicate);
|
||||||
|
EXPORT void obs_frontend_paste_sceneitem(obs_scene_t *scene, bool duplicate);
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
@ -168,6 +168,11 @@ struct obs_frontend_callbacks {
|
||||||
const char *undo_data,
|
const char *undo_data,
|
||||||
const char *redo_data,
|
const char *redo_data,
|
||||||
bool repeatable) = 0;
|
bool repeatable) = 0;
|
||||||
|
|
||||||
|
virtual void obs_frontend_copy_sceneitem(obs_sceneitem_t *item) = 0;
|
||||||
|
virtual bool obs_frontend_can_paste_sceneitem(bool duplicate) = 0;
|
||||||
|
virtual void obs_frontend_paste_sceneitem(obs_scene_t *scene,
|
||||||
|
bool duplicate) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
EXPORT void
|
EXPORT void
|
||||||
|
|
|
@ -8599,22 +8599,6 @@ void OBSBasic::UpdateEditMenu()
|
||||||
filter_count = obs_source_filter_count(source);
|
filter_count = obs_source_filter_count(source);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool allowPastingDuplicate = !!clipboard.size();
|
|
||||||
for (size_t i = clipboard.size(); i > 0; i--) {
|
|
||||||
const size_t idx = i - 1;
|
|
||||||
OBSWeakSource &weak = clipboard[idx].weak_source;
|
|
||||||
if (obs_weak_source_expired(weak)) {
|
|
||||||
clipboard.erase(clipboard.begin() + idx);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
OBSSourceAutoRelease strong =
|
|
||||||
obs_weak_source_get_source(weak.Get());
|
|
||||||
if (allowPastingDuplicate &&
|
|
||||||
obs_source_get_output_flags(strong) &
|
|
||||||
OBS_SOURCE_DO_NOT_DUPLICATE)
|
|
||||||
allowPastingDuplicate = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
int videoCount = 0;
|
int videoCount = 0;
|
||||||
bool canTransformMultiple = false;
|
bool canTransformMultiple = false;
|
||||||
for (int i = 0; i < totalCount; i++) {
|
for (int i = 0; i < totalCount; i++) {
|
||||||
|
@ -8641,8 +8625,8 @@ void OBSBasic::UpdateEditMenu()
|
||||||
ui->actionCopyFilters->setEnabled(filter_count > 0);
|
ui->actionCopyFilters->setEnabled(filter_count > 0);
|
||||||
ui->actionPasteFilters->setEnabled(
|
ui->actionPasteFilters->setEnabled(
|
||||||
!obs_weak_source_expired(copyFiltersSource) && totalCount > 0);
|
!obs_weak_source_expired(copyFiltersSource) && totalCount > 0);
|
||||||
ui->actionPasteRef->setEnabled(!!clipboard.size());
|
ui->actionPasteRef->setEnabled(CanPasteSceneItem(false));
|
||||||
ui->actionPasteDup->setEnabled(allowPastingDuplicate);
|
ui->actionPasteDup->setEnabled(CanPasteSceneItem(true));
|
||||||
|
|
||||||
ui->actionMoveUp->setEnabled(totalCount > 0);
|
ui->actionMoveUp->setEnabled(totalCount > 0);
|
||||||
ui->actionMoveDown->setEnabled(totalCount > 0);
|
ui->actionMoveDown->setEnabled(totalCount > 0);
|
||||||
|
@ -8662,6 +8646,29 @@ void OBSBasic::UpdateEditMenu()
|
||||||
ui->actionHorizontalCenter->setEnabled(canTransformMultiple);
|
ui->actionHorizontalCenter->setEnabled(canTransformMultiple);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool OBSBasic::CanPasteSceneItem(bool duplicate)
|
||||||
|
{
|
||||||
|
if (!duplicate)
|
||||||
|
return !!clipboard.size();
|
||||||
|
|
||||||
|
bool allowPastingDuplicate = !!clipboard.size();
|
||||||
|
for (size_t i = clipboard.size(); i > 0; i--) {
|
||||||
|
const size_t idx = i - 1;
|
||||||
|
OBSWeakSource &weak = clipboard[idx].weak_source;
|
||||||
|
if (obs_weak_source_expired(weak)) {
|
||||||
|
clipboard.erase(clipboard.begin() + idx);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
OBSSourceAutoRelease strong =
|
||||||
|
obs_weak_source_get_source(weak.Get());
|
||||||
|
if (allowPastingDuplicate &&
|
||||||
|
obs_source_get_output_flags(strong) &
|
||||||
|
OBS_SOURCE_DO_NOT_DUPLICATE)
|
||||||
|
allowPastingDuplicate = false;
|
||||||
|
}
|
||||||
|
return allowPastingDuplicate;
|
||||||
|
}
|
||||||
|
|
||||||
void OBSBasic::on_actionEditTransform_triggered()
|
void OBSBasic::on_actionEditTransform_triggered()
|
||||||
{
|
{
|
||||||
const auto item = GetCurrentSceneItem();
|
const auto item = GetCurrentSceneItem();
|
||||||
|
@ -10037,31 +10044,39 @@ void OBSBasic::on_actionCopySource_triggered()
|
||||||
clipboard.clear();
|
clipboard.clear();
|
||||||
|
|
||||||
for (auto &selectedSource : GetAllSelectedSourceItems()) {
|
for (auto &selectedSource : GetAllSelectedSourceItems()) {
|
||||||
OBSSceneItem item = ui->sources->Get(selectedSource.row());
|
CopySceneItem(ui->sources->Get(selectedSource.row()));
|
||||||
if (!item)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
OBSSource source = obs_sceneitem_get_source(item);
|
|
||||||
|
|
||||||
SourceCopyInfo copyInfo;
|
|
||||||
copyInfo.weak_source = OBSGetWeakRef(source);
|
|
||||||
obs_sceneitem_get_info2(item, ©Info.transform);
|
|
||||||
obs_sceneitem_get_crop(item, ©Info.crop);
|
|
||||||
copyInfo.blend_method = obs_sceneitem_get_blending_method(item);
|
|
||||||
copyInfo.blend_mode = obs_sceneitem_get_blending_mode(item);
|
|
||||||
copyInfo.visible = obs_sceneitem_visible(item);
|
|
||||||
|
|
||||||
clipboard.push_back(copyInfo);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateEditMenu();
|
UpdateEditMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OBSBasic::CopySceneItem(OBSSceneItem item)
|
||||||
|
{
|
||||||
|
if (!item)
|
||||||
|
return;
|
||||||
|
OBSSource source = obs_sceneitem_get_source(item);
|
||||||
|
|
||||||
|
SourceCopyInfo copyInfo;
|
||||||
|
copyInfo.weak_source = OBSGetWeakRef(source);
|
||||||
|
obs_sceneitem_get_info2(item, ©Info.transform);
|
||||||
|
obs_sceneitem_get_crop(item, ©Info.crop);
|
||||||
|
copyInfo.blend_method = obs_sceneitem_get_blending_method(item);
|
||||||
|
copyInfo.blend_mode = obs_sceneitem_get_blending_mode(item);
|
||||||
|
copyInfo.visible = obs_sceneitem_visible(item);
|
||||||
|
|
||||||
|
clipboard.push_back(copyInfo);
|
||||||
|
}
|
||||||
|
|
||||||
void OBSBasic::on_actionPasteRef_triggered()
|
void OBSBasic::on_actionPasteRef_triggered()
|
||||||
{
|
{
|
||||||
OBSSource scene_source = GetCurrentSceneSource();
|
PasteSceneItem(GetCurrentScene(), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OBSBasic::PasteSceneItem(OBSScene scene, bool duplicate)
|
||||||
|
{
|
||||||
|
if (!scene || !clipboard.size())
|
||||||
|
return;
|
||||||
|
OBSSource scene_source = obs_scene_get_source(scene);
|
||||||
OBSData undo_data = BackupScene(scene_source);
|
OBSData undo_data = BackupScene(scene_source);
|
||||||
OBSScene scene = GetCurrentScene();
|
|
||||||
|
|
||||||
undo_s.push_disabled();
|
undo_s.push_disabled();
|
||||||
|
|
||||||
|
@ -10076,16 +10091,17 @@ void OBSBasic::on_actionPasteRef_triggered()
|
||||||
|
|
||||||
/* do not allow duplicate refs of the same group in the same
|
/* do not allow duplicate refs of the same group in the same
|
||||||
* scene */
|
* scene */
|
||||||
if (!!obs_scene_get_group(scene, name)) {
|
if (!duplicate && !!obs_scene_get_group(scene, name)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
OBSBasicSourceSelect::SourcePaste(copyInfo, false);
|
OBSBasicSourceSelect::SourcePaste(copyInfo, duplicate);
|
||||||
}
|
}
|
||||||
|
|
||||||
undo_s.pop_disabled();
|
undo_s.pop_disabled();
|
||||||
|
|
||||||
QString action_name = QTStr("Undo.PasteSourceRef");
|
QString action_name =
|
||||||
|
QTStr(duplicate ? "Undo.PasteSource" : "Undo.PasteSourceRef");
|
||||||
const char *scene_name = obs_source_get_name(scene_source);
|
const char *scene_name = obs_source_get_name(scene_source);
|
||||||
|
|
||||||
OBSData redo_data = BackupScene(scene_source);
|
OBSData redo_data = BackupScene(scene_source);
|
||||||
|
@ -10095,24 +10111,7 @@ void OBSBasic::on_actionPasteRef_triggered()
|
||||||
|
|
||||||
void OBSBasic::on_actionPasteDup_triggered()
|
void OBSBasic::on_actionPasteDup_triggered()
|
||||||
{
|
{
|
||||||
OBSSource scene_source = GetCurrentSceneSource();
|
PasteSceneItem(GetCurrentScene(), true);
|
||||||
OBSData undo_data = BackupScene(scene_source);
|
|
||||||
|
|
||||||
undo_s.push_disabled();
|
|
||||||
|
|
||||||
for (size_t i = clipboard.size(); i > 0; i--) {
|
|
||||||
SourceCopyInfo ©Info = clipboard[i - 1];
|
|
||||||
OBSBasicSourceSelect::SourcePaste(copyInfo, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
undo_s.pop_disabled();
|
|
||||||
|
|
||||||
QString action_name = QTStr("Undo.PasteSource");
|
|
||||||
const char *scene_name = obs_source_get_name(scene_source);
|
|
||||||
|
|
||||||
OBSData redo_data = BackupScene(scene_source);
|
|
||||||
CreateSceneUndoRedoAction(action_name.arg(scene_name), undo_data,
|
|
||||||
redo_data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OBSBasic::SourcePasteFilters(OBSSource source, OBSSource dstSource)
|
void OBSBasic::SourcePasteFilters(OBSSource source, OBSSource dstSource)
|
||||||
|
|
|
@ -1039,6 +1039,9 @@ public:
|
||||||
obs_data_array_t *redo_array);
|
obs_data_array_t *redo_array);
|
||||||
|
|
||||||
void UpdateEditMenu();
|
void UpdateEditMenu();
|
||||||
|
void CopySceneItem(OBSSceneItem item);
|
||||||
|
bool CanPasteSceneItem(bool duplicate);
|
||||||
|
void PasteSceneItem(OBSScene scene, bool duplicate);
|
||||||
|
|
||||||
void SetDisplayAffinity(QWindow *window);
|
void SetDisplayAffinity(QWindow *window);
|
||||||
|
|
||||||
|
|
|
@ -949,3 +949,29 @@ Functions
|
||||||
This uses the undo action from the first and the redo action from the last action.
|
This uses the undo action from the first and the redo action from the last action.
|
||||||
|
|
||||||
.. versionadded:: 29.1
|
.. versionadded:: 29.1
|
||||||
|
|
||||||
|
---------------------------------------
|
||||||
|
|
||||||
|
.. function:: void obs_frontend_copy_sceneitem(obs_sceneitem_t *item)
|
||||||
|
|
||||||
|
:param item: The scene item to copy
|
||||||
|
|
||||||
|
.. versionadded:: 31.0
|
||||||
|
|
||||||
|
---------------------------------------
|
||||||
|
|
||||||
|
.. function:: bool obs_frontend_can_paste_sceneitem(bool duplicate)
|
||||||
|
|
||||||
|
:param duplicate: Check if the copied source allows duplication.
|
||||||
|
:return: Whether there is a scene item copied and can be pasted
|
||||||
|
|
||||||
|
.. versionadded:: 31.0
|
||||||
|
|
||||||
|
---------------------------------------
|
||||||
|
|
||||||
|
.. function:: void obs_frontend_paste_sceneitem(obs_scene_t *scene, bool duplicate)
|
||||||
|
|
||||||
|
:param scene: The scene to paste on
|
||||||
|
:param duplicate: *true* for paste duplicate, *false* for paste reference
|
||||||
|
|
||||||
|
.. versionadded:: 31.0
|
||||||
|
|
Loading…
Reference in a new issue