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.

246 lines
6.5KB

  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 = {};
  35. // -------------------------------------------------------------------------
  36. class CarlaToolkitGtk : public CarlaBridgeToolkit
  37. {
  38. public:
  39. CarlaToolkitGtk(CarlaBridgeClient* const client, const char* const uiTitle)
  40. : CarlaBridgeToolkit(client, uiTitle),
  41. settings("Cadence", appName)
  42. {
  43. carla_debug("CarlaToolkitGtk::CarlaToolkitGtk(%p, \"%s\")", client, uiTitle);
  44. window = nullptr;
  45. lastX = 0;
  46. lastY = 0;
  47. lastWidth = 0;
  48. lastHeight = 0;
  49. }
  50. ~CarlaToolkitGtk()
  51. {
  52. carla_debug("CarlaToolkitGtk::~CarlaToolkitGtk()");
  53. if (window)
  54. gtk_widget_destroy(window);
  55. }
  56. void init()
  57. {
  58. carla_debug("CarlaToolkitGtk::init()");
  59. CARLA_ASSERT(! window);
  60. gtk_init(&gargc, &gargv);
  61. window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  62. gtk_window_resize(GTK_WINDOW(window), 30, 30);
  63. gtk_widget_hide(window);
  64. }
  65. void exec(const bool showGui)
  66. {
  67. carla_debug("CarlaToolkitGtk::exec(%s)", bool2str(showGui));
  68. CARLA_ASSERT(window);
  69. CARLA_ASSERT(kClient);
  70. GtkWidget* const widget = (GtkWidget*)kClient->getWidget();
  71. gtk_container_add(GTK_CONTAINER(window), widget);
  72. gtk_window_set_resizable(GTK_WINDOW(window), kClient->isResizable());
  73. gtk_window_set_title(GTK_WINDOW(window), kUiTitle);
  74. if (settings.contains(QString("%1/pos_x").arg(kUiTitle)))
  75. {
  76. gtk_window_get_position(GTK_WINDOW(window), &lastX, &lastY);
  77. bool hasX, hasY;
  78. lastX = settings.value(QString("%1/pos_x").arg(kUiTitle), lastX).toInt(&hasX);
  79. lastY = settings.value(QString("%1/pos_y").arg(kUiTitle), lastY).toInt(&hasY);
  80. if (hasX && hasY)
  81. gtk_window_move(GTK_WINDOW(window), lastX, lastY);
  82. if (kClient->isResizable())
  83. {
  84. gtk_window_get_size(GTK_WINDOW(window), &lastWidth, &lastHeight);
  85. bool hasWidth, hasHeight;
  86. lastWidth = settings.value(QString("%1/width").arg(kUiTitle), lastWidth).toInt(&hasWidth);
  87. lastHeight = settings.value(QString("%1/height").arg(kUiTitle), lastHeight).toInt(&hasHeight);
  88. if (hasWidth && hasHeight)
  89. gtk_window_resize(GTK_WINDOW(window), lastWidth, lastHeight);
  90. }
  91. }
  92. if (showGui)
  93. show();
  94. else
  95. kClient->sendOscUpdate();
  96. // Timer
  97. g_timeout_add(50, gtk_ui_timeout, this);
  98. g_signal_connect(window, "destroy", G_CALLBACK(gtk_ui_destroy), this);
  99. // First idle
  100. handleTimeout();
  101. // Main loop
  102. gtk_main();
  103. }
  104. void quit()
  105. {
  106. carla_debug("CarlaToolkitGtk::quit()");
  107. if (window)
  108. {
  109. gtk_widget_destroy(window);
  110. gtk_main_quit();
  111. window = nullptr;
  112. }
  113. }
  114. void show()
  115. {
  116. carla_debug("CarlaToolkitGtk::show()");
  117. CARLA_ASSERT(window);
  118. if (window)
  119. gtk_widget_show_all(window);
  120. }
  121. void hide()
  122. {
  123. carla_debug("CarlaToolkitGtk::hide()");
  124. CARLA_ASSERT(window);
  125. if (window)
  126. {
  127. #ifdef BRIDGE_GTK2
  128. gtk_widget_hide_all(window);
  129. #else
  130. gtk_widget_hide(window);
  131. #endif
  132. }
  133. }
  134. void resize(int width, int height)
  135. {
  136. carla_debug("CarlaToolkitGtk::resize(%i, %i)", width, height);
  137. CARLA_ASSERT(window);
  138. if (window)
  139. gtk_window_resize(GTK_WINDOW(window), width, height);
  140. }
  141. // ---------------------------------------------------------------------
  142. protected:
  143. GtkWidget* window;
  144. QSettings settings;
  145. gint lastX, lastY, lastWidth, lastHeight;
  146. void handleDestroy()
  147. {
  148. carla_debug("CarlaToolkitGtk::handleDestroy()");
  149. window = nullptr;
  150. settings.setValue(QString("%1/pos_x").arg(kUiTitle), lastX);
  151. settings.setValue(QString("%1/pos_y").arg(kUiTitle), lastY);
  152. settings.setValue(QString("%1/width").arg(kUiTitle), lastWidth);
  153. settings.setValue(QString("%1/height").arg(kUiTitle), lastHeight);
  154. settings.sync();
  155. }
  156. gboolean handleTimeout()
  157. {
  158. if (window)
  159. {
  160. gtk_window_get_position(GTK_WINDOW(window), &lastX, &lastY);
  161. gtk_window_get_size(GTK_WINDOW(window), &lastWidth, &lastHeight);
  162. }
  163. // FIXME?
  164. return kClient->isOscControlRegistered() ? kClient->oscIdle() : false;
  165. }
  166. // ---------------------------------------------------------------------
  167. private:
  168. static void gtk_ui_destroy(GtkWidget*, gpointer data)
  169. {
  170. CARLA_ASSERT(data);
  171. if (CarlaToolkitGtk* const _this_ = (CarlaToolkitGtk*)data)
  172. _this_->handleDestroy();
  173. gtk_main_quit();
  174. }
  175. static gboolean gtk_ui_timeout(gpointer data)
  176. {
  177. CARLA_ASSERT(data);
  178. if (CarlaToolkitGtk* const _this_ = (CarlaToolkitGtk*)data)
  179. return _this_->handleTimeout();
  180. return false;
  181. }
  182. };
  183. // -------------------------------------------------------------------------
  184. CarlaBridgeToolkit* CarlaBridgeToolkit::createNew(CarlaBridgeClient* const client, const char* const uiTitle)
  185. {
  186. return new CarlaToolkitGtk(client, uiTitle);
  187. }
  188. CARLA_BRIDGE_END_NAMESPACE