1
0

BrowserToolbar.cpp 19 KB

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