void OBSBasicTransform::OnControlChanged()
{
	if (ignoreItemChange)
		return;

	obs_source_t *source = obs_sceneitem_get_source(item);
	double width  = double(obs_source_get_width(source));
	double height = double(obs_source_get_height(source));

	obs_transform_info oti;
	oti.pos.x            = float(ui->positionX->value());
	oti.pos.y            = float(ui->positionY->value());
	oti.rot              = float(ui->rotation->value());
	oti.scale.x          = float(ui->sizeX->value() / width);
	oti.scale.y          = float(ui->sizeY->value() / height);
	oti.alignment        = listToAlign[ui->align->currentIndex()];

	oti.bounds_type      = (obs_bounds_type)ui->boundsType->currentIndex();
	oti.bounds_alignment = listToAlign[ui->boundsAlign->currentIndex()];
	oti.bounds.x         = float(ui->boundsWidth->value());
	oti.bounds.y         = float(ui->boundsHeight->value());

	ignoreTransformSignal = true;
	obs_sceneitem_set_info(item, &oti);
	ignoreTransformSignal = false;
}
void OBSBasicTransform::RefreshControls()
{
	if (!item)
		return;

	obs_transform_info osi;
	obs_sceneitem_get_info(item, &osi);

	obs_source_t *source = obs_sceneitem_get_source(item);
	float width  = float(obs_source_get_width(source));
	float height = float(obs_source_get_height(source));

	int alignIndex       = AlignToList(osi.alignment);
	int boundsAlignIndex = AlignToList(osi.bounds_alignment);

	ignoreItemChange = true;
	ui->positionX->setValue(osi.pos.x);
	ui->positionY->setValue(osi.pos.y);
	ui->rotation->setValue(osi.rot);
	ui->sizeX->setValue(osi.scale.x * width);
	ui->sizeY->setValue(osi.scale.y * height);
	ui->align->setCurrentIndex(alignIndex);

	ui->boundsType->setCurrentIndex(int(osi.bounds_type));
	ui->boundsAlign->setCurrentIndex(boundsAlignIndex);
	ui->boundsWidth->setValue(osi.bounds.x);
	ui->boundsHeight->setValue(osi.bounds.y);
	ignoreItemChange = false;
}
void OBSBasicTransform::OnBoundsType(int index)
{
	if (index == -1)
		return;

	obs_bounds_type type   = (obs_bounds_type)index;
	bool            enable = (type != OBS_BOUNDS_NONE);

	ui->boundsAlign->setEnabled(enable);
	ui->boundsWidth->setEnabled(enable);
	ui->boundsHeight->setEnabled(enable);

	if (!ignoreItemChange) {
		obs_bounds_type lastType = obs_sceneitem_get_bounds_type(item);
		if (lastType == OBS_BOUNDS_NONE) {
			OBSSource source = obs_sceneitem_get_source(item);
			int width  = (int)obs_source_get_width(source);
			int height = (int)obs_source_get_height(source);

			ui->boundsWidth->setValue(width);
			ui->boundsHeight->setValue(height);
		}
	}

	OnControlChanged();
}
void OBSBasic::RemoveSceneItemFromSource(const char* name)
{
	std::string str_name = name;
	auto delayDelete = [=](){
		obs_source_t * source = obs_get_source_by_name(str_name.c_str());
		for (int i = 0; i < ui->sources->count(); i++) {
			QListWidgetItem *listItem = ui->sources->item(i);

			OBSSceneItem item = GetOBSRef<OBSSceneItem>(listItem);
			obs_source_t * item_source = obs_sceneitem_get_source(item);
			if (source == item_source) {
				DeleteListItem(ui->sources, listItem);
				obs_source_release(source);
				obs_sceneitem_remove(item);
				return;
			}
		}

		obs_source_release(source);
	};

	base::GetUIMessageLoop()->PostTask(FROM_HERE, base::Lambda(delayDelete));
}
void BiLiOBSMainWid::SaveScene()
{
	obs_data_t* sceneData;

	std::list<obs_scene_t*> scenes;

	//移除未使用的source
	for (OBSSource& source : OBSEnumSources())
	{
		obs_scene_t* scene = obs_scene_from_source(source);
		if (scene)
			scenes.push_back(scene);
	}

	std::list<obs_source_t*> sourcesToRemove;

	//遍历所有source,找出有在场景中出现的,其他删掉
	for (OBSSource& source : OBSEnumSources())
	{
		if (obs_scene_from_source(source) == 0)
		{
			//如果是场景那么就不执行这里面的代码,只对场景元素执行里面的代码
			bool isReferred = false;

			//遍历每个场景里的全部source,看看有没有当前的
			for (obs_scene_t* scene : scenes)
			{
				for (OBSSceneItem& sceneItem : OBSEnumSceneItems(scene))
				{
					obs_source_t* sceneItemSource = obs_sceneitem_get_source(sceneItem);
					if (sceneItemSource == source)
					{
						//找到了,标记找到,并停止当前查找
						isReferred = true;
						break;
					}
				}

				//如果已经找到,就不需要在下一个场景中找
				if (isReferred)
					break;
			}

			//没被引用的放到待删除里
			if (isReferred == false)
				sourcesToRemove.push_back(source);
		}
	}

	//删
	for (auto x : sourcesToRemove)
		obs_source_remove(x);


	//保存
	sceneData = BiliSceneConfig::Get();
	if (sceneData)
	{
		BiliConfigFile::SaveSceneData(sceneData);
		obs_data_release(sceneData);
	}
}