Audio plugin host https://kx.studio/carla
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

243 lines
6.9KB

  1. /*
  2. * Carla Bridge Toolkit, Gtk version
  3. * Copyright (C) 2011-2013 Filipe Coelho <falktx@falktx.com>
  4. *
  5. * This program is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU General Public License as
  7. * published by the Free Software Foundation; either version 2 of
  8. * the License, or any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * For a full copy of the GNU General Public License see the GPL.txt file
  16. */
  17. #include "CarlaBridgeClient.hpp"
  18. #include "CarlaBridgeToolkit.hpp"
  19. #if defined(BRIDGE_COCOA) || defined(BRIDGE_HWND) || defined(BRIDGE_X11)
  20. # error Embed UI uses Qt
  21. #endif
  22. #include <gtk/gtk.h>
  23. #include <QtCore/QSettings>
  24. CARLA_BRIDGE_START_NAMESPACE
  25. // -------------------------------------------------------------------------
  26. #if defined(BRIDGE_GTK2)
  27. static const char* const appName = "Carla-Gtk2UIs";
  28. #elif defined(BRIDGE_GTK3)
  29. static const char* const appName = "Carla-Gtk3UIs";
  30. #else
  31. static const char* const appName = "Carla-UIs";
  32. #endif
  33. static int gargc = 0;
  34. static char** gargv = nullptr;
  35. // -------------------------------------------------------------------------
  36. class CarlaToolkitGtk : public CarlaBridgeToolkit
  37. {
  38. public:
  39. CarlaToolkitGtk(CarlaBridgeClient* const client, const char* const uiTitle)
  40. : CarlaBridgeToolkit(client, uiTitle),
  41. fWindow(nullptr),
  42. fLastX(0),
  43. fLastY(0),
  44. fLastWidth(0),
  45. fLastHeight(0)
  46. {
  47. carla_debug("CarlaToolkitGtk::CarlaToolkitGtk(%p, \"%s\")", client, uiTitle);
  48. }
  49. ~CarlaToolkitGtk() override
  50. {
  51. CARLA_ASSERT(fWindow == nullptr);
  52. carla_debug("CarlaToolkitGtk::~CarlaToolkitGtk()");
  53. }
  54. void init() override
  55. {
  56. CARLA_ASSERT(fWindow == nullptr);
  57. carla_debug("CarlaToolkitGtk::init()");
  58. gtk_init(&gargc, &gargv);
  59. fWindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  60. gtk_window_resize(GTK_WINDOW(fWindow), 30, 30);
  61. gtk_widget_hide(fWindow);
  62. }
  63. void exec(const bool showGui) override
  64. {
  65. CARLA_ASSERT(kClient != nullptr);
  66. CARLA_ASSERT(fWindow != nullptr);
  67. carla_debug("CarlaToolkitGtk::exec(%s)", bool2str(showGui));
  68. GtkWidget* const widget((GtkWidget*)kClient->getWidget());
  69. gtk_container_add(GTK_CONTAINER(fWindow), widget);
  70. gtk_window_set_resizable(GTK_WINDOW(fWindow), kClient->isResizable());
  71. gtk_window_set_title(GTK_WINDOW(fWindow), kUiTitle);
  72. {
  73. QSettings settings("falkTX", appName);
  74. if (settings.contains(QString("%1/pos_x").arg(kUiTitle)))
  75. {
  76. gtk_window_get_position(GTK_WINDOW(fWindow), &fLastX, &fLastY);
  77. bool hasX, hasY;
  78. fLastX = settings.value(QString("%1/pos_x").arg(kUiTitle), fLastX).toInt(&hasX);
  79. fLastY = settings.value(QString("%1/pos_y").arg(kUiTitle), fLastY).toInt(&hasY);
  80. if (hasX && hasY)
  81. gtk_window_move(GTK_WINDOW(fWindow), fLastX, fLastY);
  82. if (kClient->isResizable())
  83. {
  84. gtk_window_get_size(GTK_WINDOW(fWindow), &fLastWidth, &fLastHeight);
  85. bool hasWidth, hasHeight;
  86. fLastWidth = settings.value(QString("%1/width").arg(kUiTitle), fLastWidth).toInt(&hasWidth);
  87. fLastHeight = settings.value(QString("%1/height").arg(kUiTitle), fLastHeight).toInt(&hasHeight);
  88. if (hasWidth && hasHeight)
  89. gtk_window_resize(GTK_WINDOW(fWindow), fLastWidth, fLastHeight);
  90. }
  91. }
  92. if (settings.value("Engine/UIsAlwaysOnTop", true).toBool())
  93. gtk_window_set_keep_above(GTK_WINDOW(fWindow), true);
  94. }
  95. if (showGui)
  96. show();
  97. else
  98. kClient->sendOscUpdate();
  99. g_timeout_add(50, gtk_ui_timeout, this);
  100. g_signal_connect(fWindow, "destroy", G_CALLBACK(gtk_ui_destroy), this);
  101. // First idle
  102. handleTimeout();
  103. // Main loop
  104. gtk_main();
  105. }
  106. void quit() override
  107. {
  108. carla_debug("CarlaToolkitGtk::quit()");
  109. if (fWindow != nullptr)
  110. {
  111. gtk_widget_destroy(fWindow);
  112. fWindow = nullptr;
  113. gtk_main_quit();
  114. }
  115. }
  116. void show() override
  117. {
  118. CARLA_ASSERT(fWindow != nullptr);
  119. carla_debug("CarlaToolkitGtk::show()");
  120. if (fWindow != nullptr)
  121. gtk_widget_show_all(fWindow);
  122. }
  123. void hide() override
  124. {
  125. CARLA_ASSERT(fWindow != nullptr);
  126. carla_debug("CarlaToolkitGtk::hide()");
  127. if (fWindow != nullptr)
  128. gtk_widget_hide(fWindow);
  129. }
  130. void resize(int width, int height) override
  131. {
  132. CARLA_ASSERT(fWindow != nullptr);
  133. carla_debug("CarlaToolkitGtk::resize(%i, %i)", width, height);
  134. if (fWindow != nullptr)
  135. gtk_window_resize(GTK_WINDOW(fWindow), width, height);
  136. }
  137. // ---------------------------------------------------------------------
  138. protected:
  139. GtkWidget* fWindow;
  140. gint fLastX;
  141. gint fLastY;
  142. gint fLastWidth;
  143. gint fLastHeight;
  144. void handleDestroy()
  145. {
  146. carla_debug("CarlaToolkitGtk::handleDestroy()");
  147. fWindow = nullptr;
  148. QSettings settings("falkTX", appName);
  149. settings.setValue(QString("%1/pos_x").arg(kUiTitle), fLastX);
  150. settings.setValue(QString("%1/pos_y").arg(kUiTitle), fLastY);
  151. settings.setValue(QString("%1/width").arg(kUiTitle), fLastWidth);
  152. settings.setValue(QString("%1/height").arg(kUiTitle), fLastHeight);
  153. }
  154. gboolean handleTimeout()
  155. {
  156. if (fWindow != nullptr)
  157. {
  158. gtk_window_get_position(GTK_WINDOW(fWindow), &fLastX, &fLastY);
  159. gtk_window_get_size(GTK_WINDOW(fWindow), &fLastWidth, &fLastHeight);
  160. }
  161. kClient->uiIdle();
  162. return kClient->oscIdle();
  163. }
  164. // ---------------------------------------------------------------------
  165. private:
  166. static void gtk_ui_destroy(GtkWidget*, gpointer data)
  167. {
  168. CARLA_ASSERT(data != nullptr);
  169. if (CarlaToolkitGtk* const _this_ = (CarlaToolkitGtk*)data)
  170. _this_->handleDestroy();
  171. gtk_main_quit();
  172. }
  173. static gboolean gtk_ui_timeout(gpointer data)
  174. {
  175. CARLA_ASSERT(data != nullptr);
  176. if (CarlaToolkitGtk* const _this_ = (CarlaToolkitGtk*)data)
  177. return _this_->handleTimeout();
  178. return false;
  179. }
  180. };
  181. // -------------------------------------------------------------------------
  182. CarlaBridgeToolkit* CarlaBridgeToolkit::createNew(CarlaBridgeClient* const client, const char* const uiTitle)
  183. {
  184. return new CarlaToolkitGtk(client, uiTitle);
  185. }
  186. CARLA_BRIDGE_END_NAMESPACE