context-bar-controls.cpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731
  1. #include "window-basic-main.hpp"
  2. #include "context-bar-controls.hpp"
  3. #include "qt-wrappers.hpp"
  4. #include "obs-app.hpp"
  5. #include <QStandardItemModel>
  6. #include <QColorDialog>
  7. #include <QFontDialog>
  8. #include "ui_browser-source-toolbar.h"
  9. #include "ui_device-select-toolbar.h"
  10. #include "ui_game-capture-toolbar.h"
  11. #include "ui_image-source-toolbar.h"
  12. #include "ui_color-source-toolbar.h"
  13. #include "ui_text-source-toolbar.h"
  14. #ifdef _WIN32
  15. #define get_os_module(win, mac, linux) obs_get_module(win)
  16. #define get_os_text(mod, win, mac, linux) obs_module_get_locale_text(mod, win)
  17. #elif __APPLE__
  18. #define get_os_module(win, mac, linux) obs_get_module(mac)
  19. #define get_os_text(mod, win, mac, linux) obs_module_get_locale_text(mod, mac)
  20. #else
  21. #define get_os_module(win, mac, linux) obs_get_module(linux)
  22. #define get_os_text(mod, win, mac, linux) obs_module_get_locale_text(mod, linux)
  23. #endif
  24. /* ========================================================================= */
  25. SourceToolbar::SourceToolbar(QWidget *parent, OBSSource source)
  26. : QWidget(parent),
  27. weakSource(OBSGetWeakRef(source)),
  28. props(obs_source_properties(source), obs_properties_destroy)
  29. {
  30. }
  31. void SourceToolbar::SaveOldProperties(obs_source_t *source)
  32. {
  33. oldData = obs_data_create();
  34. OBSDataAutoRelease oldSettings = obs_source_get_settings(source);
  35. obs_data_apply(oldData, oldSettings);
  36. obs_data_set_string(oldData, "undo_sname", obs_source_get_name(source));
  37. }
  38. void SourceToolbar::SetUndoProperties(obs_source_t *source, bool repeatable)
  39. {
  40. if (!oldData) {
  41. blog(LOG_ERROR, "%s: somehow oldData was null.", __FUNCTION__);
  42. return;
  43. }
  44. OBSBasic *main = reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
  45. OBSSource currentSceneSource = main->GetCurrentSceneSource();
  46. if (!currentSceneSource)
  47. return;
  48. std::string scene_name = obs_source_get_name(currentSceneSource);
  49. auto undo_redo = [scene_name,
  50. main = std::move(main)](const std::string &data) {
  51. OBSDataAutoRelease settings =
  52. obs_data_create_from_json(data.c_str());
  53. OBSSourceAutoRelease source = obs_get_source_by_name(
  54. obs_data_get_string(settings, "undo_sname"));
  55. obs_source_reset_settings(source, settings);
  56. OBSSourceAutoRelease scene_source =
  57. obs_get_source_by_name(scene_name.c_str());
  58. main->SetCurrentScene(scene_source.Get(), true);
  59. main->UpdateContextBar();
  60. };
  61. OBSDataAutoRelease new_settings = obs_data_create();
  62. OBSDataAutoRelease curr_settings = obs_source_get_settings(source);
  63. obs_data_apply(new_settings, curr_settings);
  64. obs_data_set_string(new_settings, "undo_sname",
  65. obs_source_get_name(source));
  66. std::string undo_data(obs_data_get_json(oldData));
  67. std::string redo_data(obs_data_get_json(new_settings));
  68. if (undo_data.compare(redo_data) != 0)
  69. main->undo_s.add_action(
  70. QTStr("Undo.Properties")
  71. .arg(obs_source_get_name(source)),
  72. undo_redo, undo_redo, undo_data, redo_data, repeatable);
  73. oldData = nullptr;
  74. }
  75. /* ========================================================================= */
  76. BrowserToolbar::BrowserToolbar(QWidget *parent, OBSSource source)
  77. : SourceToolbar(parent, source), ui(new Ui_BrowserSourceToolbar)
  78. {
  79. ui->setupUi(this);
  80. }
  81. BrowserToolbar::~BrowserToolbar()
  82. {
  83. delete ui;
  84. }
  85. void BrowserToolbar::on_refresh_clicked()
  86. {
  87. OBSSource source = GetSource();
  88. if (!source) {
  89. return;
  90. }
  91. obs_property_t *p = obs_properties_get(props.get(), "refreshnocache");
  92. obs_property_button_clicked(p, source.Get());
  93. }
  94. /* ========================================================================= */
  95. ComboSelectToolbar::ComboSelectToolbar(QWidget *parent, OBSSource source)
  96. : SourceToolbar(parent, source), ui(new Ui_DeviceSelectToolbar)
  97. {
  98. ui->setupUi(this);
  99. }
  100. ComboSelectToolbar::~ComboSelectToolbar()
  101. {
  102. delete ui;
  103. }
  104. static int FillPropertyCombo(QComboBox *c, obs_property_t *p,
  105. const std::string &cur_id, bool is_int = false)
  106. {
  107. size_t count = obs_property_list_item_count(p);
  108. int cur_idx = -1;
  109. for (size_t i = 0; i < count; i++) {
  110. const char *name = obs_property_list_item_name(p, i);
  111. std::string id;
  112. if (is_int) {
  113. id = std::to_string(obs_property_list_item_int(p, i));
  114. } else {
  115. const char *val = obs_property_list_item_string(p, i);
  116. id = val ? val : "";
  117. }
  118. if (cur_id == id)
  119. cur_idx = (int)i;
  120. c->addItem(name, id.c_str());
  121. }
  122. return cur_idx;
  123. }
  124. void UpdateSourceComboToolbarProperties(QComboBox *combo, OBSSource source,
  125. obs_properties_t *props,
  126. const char *prop_name, bool is_int)
  127. {
  128. std::string cur_id;
  129. OBSDataAutoRelease settings = obs_source_get_settings(source);
  130. if (is_int) {
  131. cur_id = std::to_string(obs_data_get_int(settings, prop_name));
  132. } else {
  133. cur_id = obs_data_get_string(settings, prop_name);
  134. }
  135. combo->blockSignals(true);
  136. obs_property_t *p = obs_properties_get(props, prop_name);
  137. int cur_idx = FillPropertyCombo(combo, p, cur_id, is_int);
  138. if (cur_idx == -1 || obs_property_list_item_disabled(p, cur_idx)) {
  139. if (cur_idx == -1) {
  140. combo->insertItem(
  141. 0,
  142. QTStr("Basic.Settings.Audio.UnknownAudioDevice"));
  143. cur_idx = 0;
  144. }
  145. SetComboItemEnabled(combo, cur_idx, false);
  146. }
  147. combo->setCurrentIndex(cur_idx);
  148. combo->blockSignals(false);
  149. }
  150. void ComboSelectToolbar::Init()
  151. {
  152. OBSSource source = GetSource();
  153. if (!source) {
  154. return;
  155. }
  156. UpdateSourceComboToolbarProperties(ui->device, source, props.get(),
  157. prop_name, is_int);
  158. }
  159. void UpdateSourceComboToolbarValue(QComboBox *combo, OBSSource source, int idx,
  160. const char *prop_name, bool is_int)
  161. {
  162. QString id = combo->itemData(idx).toString();
  163. OBSDataAutoRelease settings = obs_data_create();
  164. if (is_int) {
  165. obs_data_set_int(settings, prop_name, id.toInt());
  166. } else {
  167. obs_data_set_string(settings, prop_name, QT_TO_UTF8(id));
  168. }
  169. obs_source_update(source, settings);
  170. }
  171. void ComboSelectToolbar::on_device_currentIndexChanged(int idx)
  172. {
  173. OBSSource source = GetSource();
  174. if (idx == -1 || !source) {
  175. return;
  176. }
  177. SaveOldProperties(source);
  178. UpdateSourceComboToolbarValue(ui->device, source, idx, prop_name,
  179. is_int);
  180. SetUndoProperties(source);
  181. }
  182. AudioCaptureToolbar::AudioCaptureToolbar(QWidget *parent, OBSSource source)
  183. : ComboSelectToolbar(parent, source)
  184. {
  185. }
  186. void AudioCaptureToolbar::Init()
  187. {
  188. delete ui->activateButton;
  189. ui->activateButton = nullptr;
  190. obs_module_t *mod =
  191. get_os_module("win-wasapi", "mac-capture", "linux-pulseaudio");
  192. if (!mod) {
  193. return;
  194. }
  195. const char *device_str =
  196. get_os_text(mod, "Device", "CoreAudio.Device", "Device");
  197. ui->deviceLabel->setText(device_str);
  198. prop_name = "device_id";
  199. ComboSelectToolbar::Init();
  200. }
  201. WindowCaptureToolbar::WindowCaptureToolbar(QWidget *parent, OBSSource source)
  202. : ComboSelectToolbar(parent, source)
  203. {
  204. }
  205. void WindowCaptureToolbar::Init()
  206. {
  207. delete ui->activateButton;
  208. ui->activateButton = nullptr;
  209. obs_module_t *mod =
  210. get_os_module("win-capture", "mac-capture", "linux-capture");
  211. const char *device_str = get_os_text(mod, "WindowCapture.Window",
  212. "WindowUtils.Window", "Window");
  213. ui->deviceLabel->setText(device_str);
  214. #if !defined(_WIN32) && !defined(__APPLE__) //linux
  215. prop_name = "capture_window";
  216. #else
  217. prop_name = "window";
  218. #endif
  219. #ifdef __APPLE__
  220. is_int = true;
  221. #endif
  222. ComboSelectToolbar::Init();
  223. }
  224. DisplayCaptureToolbar::DisplayCaptureToolbar(QWidget *parent, OBSSource source)
  225. : ComboSelectToolbar(parent, source)
  226. {
  227. }
  228. void DisplayCaptureToolbar::Init()
  229. {
  230. delete ui->activateButton;
  231. ui->activateButton = nullptr;
  232. obs_module_t *mod =
  233. get_os_module("win-capture", "mac-capture", "linux-capture");
  234. const char *device_str =
  235. get_os_text(mod, "Monitor", "DisplayCapture.Display", "Screen");
  236. ui->deviceLabel->setText(device_str);
  237. is_int = true;
  238. #ifdef _WIN32
  239. prop_name = "monitor";
  240. #elif __APPLE__
  241. prop_name = "display";
  242. #else
  243. prop_name = "screen";
  244. #endif
  245. ComboSelectToolbar::Init();
  246. }
  247. /* ========================================================================= */
  248. DeviceCaptureToolbar::DeviceCaptureToolbar(QWidget *parent, OBSSource source)
  249. : QWidget(parent),
  250. weakSource(OBSGetWeakRef(source)),
  251. ui(new Ui_DeviceSelectToolbar)
  252. {
  253. ui->setupUi(this);
  254. delete ui->deviceLabel;
  255. delete ui->device;
  256. ui->deviceLabel = nullptr;
  257. ui->device = nullptr;
  258. OBSDataAutoRelease settings = obs_source_get_settings(source);
  259. active = obs_data_get_bool(settings, "active");
  260. obs_module_t *mod = obs_get_module("win-dshow");
  261. if (!mod)
  262. return;
  263. activateText = obs_module_get_locale_text(mod, "Activate");
  264. deactivateText = obs_module_get_locale_text(mod, "Deactivate");
  265. ui->activateButton->setText(active ? deactivateText : activateText);
  266. }
  267. DeviceCaptureToolbar::~DeviceCaptureToolbar()
  268. {
  269. delete ui;
  270. }
  271. void DeviceCaptureToolbar::on_activateButton_clicked()
  272. {
  273. OBSSource source = OBSGetStrongRef(weakSource);
  274. if (!source) {
  275. return;
  276. }
  277. OBSDataAutoRelease settings = obs_source_get_settings(source);
  278. bool now_active = obs_data_get_bool(settings, "active");
  279. bool desyncedSetting = now_active != active;
  280. active = !active;
  281. const char *text = active ? deactivateText : activateText;
  282. ui->activateButton->setText(text);
  283. if (desyncedSetting) {
  284. return;
  285. }
  286. calldata_t cd = {};
  287. calldata_set_bool(&cd, "active", active);
  288. proc_handler_t *ph = obs_source_get_proc_handler(source);
  289. proc_handler_call(ph, "activate", &cd);
  290. calldata_free(&cd);
  291. }
  292. /* ========================================================================= */
  293. GameCaptureToolbar::GameCaptureToolbar(QWidget *parent, OBSSource source)
  294. : SourceToolbar(parent, source), ui(new Ui_GameCaptureToolbar)
  295. {
  296. obs_property_t *p;
  297. int cur_idx;
  298. ui->setupUi(this);
  299. obs_module_t *mod = obs_get_module("win-capture");
  300. if (!mod)
  301. return;
  302. ui->modeLabel->setText(obs_module_get_locale_text(mod, "Mode"));
  303. ui->windowLabel->setText(
  304. obs_module_get_locale_text(mod, "WindowCapture.Window"));
  305. OBSDataAutoRelease settings = obs_source_get_settings(source);
  306. std::string cur_mode = obs_data_get_string(settings, "capture_mode");
  307. std::string cur_window = obs_data_get_string(settings, "window");
  308. ui->mode->blockSignals(true);
  309. p = obs_properties_get(props.get(), "capture_mode");
  310. cur_idx = FillPropertyCombo(ui->mode, p, cur_mode);
  311. ui->mode->setCurrentIndex(cur_idx);
  312. ui->mode->blockSignals(false);
  313. ui->window->blockSignals(true);
  314. p = obs_properties_get(props.get(), "window");
  315. cur_idx = FillPropertyCombo(ui->window, p, cur_window);
  316. ui->window->setCurrentIndex(cur_idx);
  317. ui->window->blockSignals(false);
  318. if (cur_idx != -1 && obs_property_list_item_disabled(p, cur_idx)) {
  319. SetComboItemEnabled(ui->window, cur_idx, false);
  320. }
  321. UpdateWindowVisibility();
  322. }
  323. GameCaptureToolbar::~GameCaptureToolbar()
  324. {
  325. delete ui;
  326. }
  327. void GameCaptureToolbar::UpdateWindowVisibility()
  328. {
  329. QString mode = ui->mode->currentData().toString();
  330. bool is_window = (mode == "window");
  331. ui->windowLabel->setVisible(is_window);
  332. ui->window->setVisible(is_window);
  333. }
  334. void GameCaptureToolbar::on_mode_currentIndexChanged(int idx)
  335. {
  336. OBSSource source = GetSource();
  337. if (idx == -1 || !source) {
  338. return;
  339. }
  340. QString id = ui->mode->itemData(idx).toString();
  341. SaveOldProperties(source);
  342. OBSDataAutoRelease settings = obs_data_create();
  343. obs_data_set_string(settings, "capture_mode", QT_TO_UTF8(id));
  344. obs_source_update(source, settings);
  345. SetUndoProperties(source);
  346. UpdateWindowVisibility();
  347. }
  348. void GameCaptureToolbar::on_window_currentIndexChanged(int idx)
  349. {
  350. OBSSource source = GetSource();
  351. if (idx == -1 || !source) {
  352. return;
  353. }
  354. QString id = ui->window->itemData(idx).toString();
  355. SaveOldProperties(source);
  356. OBSDataAutoRelease settings = obs_data_create();
  357. obs_data_set_string(settings, "window", QT_TO_UTF8(id));
  358. obs_source_update(source, settings);
  359. SetUndoProperties(source);
  360. }
  361. /* ========================================================================= */
  362. ImageSourceToolbar::ImageSourceToolbar(QWidget *parent, OBSSource source)
  363. : SourceToolbar(parent, source), ui(new Ui_ImageSourceToolbar)
  364. {
  365. ui->setupUi(this);
  366. obs_module_t *mod = obs_get_module("image-source");
  367. ui->pathLabel->setText(obs_module_get_locale_text(mod, "File"));
  368. OBSDataAutoRelease settings = obs_source_get_settings(source);
  369. std::string file = obs_data_get_string(settings, "file");
  370. ui->path->setText(file.c_str());
  371. }
  372. ImageSourceToolbar::~ImageSourceToolbar()
  373. {
  374. delete ui;
  375. }
  376. void ImageSourceToolbar::on_browse_clicked()
  377. {
  378. OBSSource source = GetSource();
  379. if (!source) {
  380. return;
  381. }
  382. obs_property_t *p = obs_properties_get(props.get(), "file");
  383. const char *desc = obs_property_description(p);
  384. const char *filter = obs_property_path_filter(p);
  385. const char *default_path = obs_property_path_default_path(p);
  386. QString path = OpenFile(this, desc, default_path, filter);
  387. if (path.isEmpty()) {
  388. return;
  389. }
  390. ui->path->setText(path);
  391. SaveOldProperties(source);
  392. OBSDataAutoRelease settings = obs_data_create();
  393. obs_data_set_string(settings, "file", QT_TO_UTF8(path));
  394. obs_source_update(source, settings);
  395. SetUndoProperties(source);
  396. }
  397. /* ========================================================================= */
  398. static inline QColor color_from_int(long long val)
  399. {
  400. return QColor(val & 0xff, (val >> 8) & 0xff, (val >> 16) & 0xff,
  401. (val >> 24) & 0xff);
  402. }
  403. static inline long long color_to_int(QColor color)
  404. {
  405. auto shift = [&](unsigned val, int shift) {
  406. return ((val & 0xff) << shift);
  407. };
  408. return shift(color.red(), 0) | shift(color.green(), 8) |
  409. shift(color.blue(), 16) | shift(color.alpha(), 24);
  410. }
  411. ColorSourceToolbar::ColorSourceToolbar(QWidget *parent, OBSSource source)
  412. : SourceToolbar(parent, source), ui(new Ui_ColorSourceToolbar)
  413. {
  414. ui->setupUi(this);
  415. OBSDataAutoRelease settings = obs_source_get_settings(source);
  416. unsigned int val = (unsigned int)obs_data_get_int(settings, "color");
  417. color = color_from_int(val);
  418. UpdateColor();
  419. }
  420. ColorSourceToolbar::~ColorSourceToolbar()
  421. {
  422. delete ui;
  423. }
  424. void ColorSourceToolbar::UpdateColor()
  425. {
  426. QPalette palette = QPalette(color);
  427. ui->color->setFrameStyle(QFrame::Sunken | QFrame::Panel);
  428. ui->color->setText(color.name(QColor::HexRgb));
  429. ui->color->setPalette(palette);
  430. ui->color->setStyleSheet(
  431. QString("background-color :%1; color: %2;")
  432. .arg(palette.color(QPalette::Window)
  433. .name(QColor::HexRgb))
  434. .arg(palette.color(QPalette::WindowText)
  435. .name(QColor::HexRgb)));
  436. ui->color->setAutoFillBackground(true);
  437. ui->color->setAlignment(Qt::AlignCenter);
  438. }
  439. void ColorSourceToolbar::on_choose_clicked()
  440. {
  441. OBSSource source = GetSource();
  442. if (!source) {
  443. return;
  444. }
  445. obs_property_t *p = obs_properties_get(props.get(), "color");
  446. const char *desc = obs_property_description(p);
  447. QColorDialog::ColorDialogOptions options;
  448. options |= QColorDialog::ShowAlphaChannel;
  449. #ifndef _WIN32
  450. options |= QColorDialog::DontUseNativeDialog;
  451. #endif
  452. QColor newColor = QColorDialog::getColor(color, this, desc, options);
  453. if (!newColor.isValid()) {
  454. return;
  455. }
  456. color = newColor;
  457. UpdateColor();
  458. SaveOldProperties(source);
  459. OBSDataAutoRelease settings = obs_data_create();
  460. obs_data_set_int(settings, "color", color_to_int(color));
  461. obs_source_update(source, settings);
  462. SetUndoProperties(source);
  463. }
  464. /* ========================================================================= */
  465. extern void MakeQFont(obs_data_t *font_obj, QFont &font, bool limit = false);
  466. TextSourceToolbar::TextSourceToolbar(QWidget *parent, OBSSource source)
  467. : SourceToolbar(parent, source), ui(new Ui_TextSourceToolbar)
  468. {
  469. ui->setupUi(this);
  470. OBSDataAutoRelease settings = obs_source_get_settings(source);
  471. const char *id = obs_source_get_unversioned_id(source);
  472. bool ft2 = strcmp(id, "text_ft2_source") == 0;
  473. bool read_from_file = obs_data_get_bool(
  474. settings, ft2 ? "from_file" : "read_from_file");
  475. OBSDataAutoRelease font_obj = obs_data_get_obj(settings, "font");
  476. MakeQFont(font_obj, font);
  477. // Use "color1" if it's a freetype source and "color" elsewise
  478. unsigned int val = (unsigned int)obs_data_get_int(
  479. settings,
  480. (strncmp(obs_source_get_id(source), "text_ft2_source", 15) == 0)
  481. ? "color1"
  482. : "color");
  483. color = color_from_int(val);
  484. const char *text = obs_data_get_string(settings, "text");
  485. bool single_line = !read_from_file &&
  486. (!text || (strchr(text, '\n') == nullptr));
  487. ui->emptySpace->setVisible(!single_line);
  488. ui->text->setVisible(single_line);
  489. if (single_line)
  490. ui->text->setText(text);
  491. }
  492. TextSourceToolbar::~TextSourceToolbar()
  493. {
  494. delete ui;
  495. }
  496. void TextSourceToolbar::on_selectFont_clicked()
  497. {
  498. OBSSource source = GetSource();
  499. if (!source) {
  500. return;
  501. }
  502. QFontDialog::FontDialogOptions options;
  503. uint32_t flags;
  504. bool success;
  505. #ifndef _WIN32
  506. options = QFontDialog::DontUseNativeDialog;
  507. #endif
  508. font = QFontDialog::getFont(&success, font, this, "Pick a Font",
  509. options);
  510. if (!success) {
  511. return;
  512. }
  513. OBSDataAutoRelease font_obj = obs_data_create();
  514. obs_data_set_string(font_obj, "face", QT_TO_UTF8(font.family()));
  515. obs_data_set_string(font_obj, "style", QT_TO_UTF8(font.styleName()));
  516. obs_data_set_int(font_obj, "size", font.pointSize());
  517. flags = font.bold() ? OBS_FONT_BOLD : 0;
  518. flags |= font.italic() ? OBS_FONT_ITALIC : 0;
  519. flags |= font.underline() ? OBS_FONT_UNDERLINE : 0;
  520. flags |= font.strikeOut() ? OBS_FONT_STRIKEOUT : 0;
  521. obs_data_set_int(font_obj, "flags", flags);
  522. SaveOldProperties(source);
  523. OBSDataAutoRelease settings = obs_data_create();
  524. obs_data_set_obj(settings, "font", font_obj);
  525. obs_source_update(source, settings);
  526. SetUndoProperties(source);
  527. }
  528. void TextSourceToolbar::on_selectColor_clicked()
  529. {
  530. OBSSource source = GetSource();
  531. if (!source) {
  532. return;
  533. }
  534. bool freetype =
  535. strncmp(obs_source_get_id(source), "text_ft2_source", 15) == 0;
  536. obs_property_t *p =
  537. obs_properties_get(props.get(), freetype ? "color1" : "color");
  538. const char *desc = obs_property_description(p);
  539. QColorDialog::ColorDialogOptions options;
  540. options |= QColorDialog::ShowAlphaChannel;
  541. #ifndef _WIN32
  542. options |= QColorDialog::DontUseNativeDialog;
  543. #endif
  544. QColor newColor = QColorDialog::getColor(color, this, desc, options);
  545. if (!newColor.isValid()) {
  546. return;
  547. }
  548. color = newColor;
  549. SaveOldProperties(source);
  550. OBSDataAutoRelease settings = obs_data_create();
  551. if (freetype) {
  552. obs_data_set_int(settings, "color1", color_to_int(color));
  553. obs_data_set_int(settings, "color2", color_to_int(color));
  554. } else {
  555. obs_data_set_int(settings, "color", color_to_int(color));
  556. }
  557. obs_source_update(source, settings);
  558. SetUndoProperties(source);
  559. }
  560. void TextSourceToolbar::on_text_textChanged()
  561. {
  562. OBSSource source = GetSource();
  563. if (!source) {
  564. return;
  565. }
  566. SaveOldProperties(source);
  567. OBSDataAutoRelease settings = obs_data_create();
  568. obs_data_set_string(settings, "text", QT_TO_UTF8(ui->text->text()));
  569. obs_source_update(source, settings);
  570. SetUndoProperties(source, true);
  571. }