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.

253 lines
7.0KB

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