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.

250 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. #include <gtk/gtk.h>
  20. CARLA_BRIDGE_START_NAMESPACE
  21. // -------------------------------------------------------------------------
  22. #if defined(BRIDGE_GTK2)
  23. static const char* const appName = "Carla-Gtk2UIs";
  24. #elif defined(BRIDGE_GTK3)
  25. static const char* const appName = "Carla-Gtk3UIs";
  26. #else
  27. static const char* const appName = "Carla-UIs";
  28. #endif
  29. static int gargc = 0;
  30. static char** gargv = nullptr;
  31. // -------------------------------------------------------------------------
  32. class CarlaBridgeToolkitGtk : public CarlaBridgeToolkit
  33. {
  34. public:
  35. CarlaBridgeToolkitGtk(CarlaBridgeClient* const client, const char* const uiTitle)
  36. : CarlaBridgeToolkit(client, uiTitle),
  37. fNeedsShow(false),
  38. fWindow(nullptr),
  39. fLastX(0),
  40. fLastY(0),
  41. fLastWidth(0),
  42. fLastHeight(0)
  43. {
  44. carla_debug("CarlaBridgeToolkitGtk::CarlaBridgeToolkitGtk(%p, \"%s\")", client, uiTitle);
  45. }
  46. ~CarlaBridgeToolkitGtk() override
  47. {
  48. CARLA_ASSERT(fWindow == nullptr);
  49. carla_debug("CarlaBridgeToolkitGtk::~CarlaBridgeToolkitGtk()");
  50. }
  51. void init() override
  52. {
  53. CARLA_ASSERT(fWindow == nullptr);
  54. carla_debug("CarlaBridgeToolkitGtk::init()");
  55. gtk_init(&gargc, &gargv);
  56. fWindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  57. gtk_window_resize(GTK_WINDOW(fWindow), 30, 30);
  58. gtk_widget_hide(fWindow);
  59. }
  60. void exec(const bool showGui) override
  61. {
  62. CARLA_ASSERT(kClient != nullptr);
  63. CARLA_ASSERT(fWindow != nullptr);
  64. carla_debug("CarlaBridgeToolkitGtk::exec(%s)", bool2str(showGui));
  65. GtkWidget* const widget((GtkWidget*)kClient->getWidget());
  66. gtk_container_add(GTK_CONTAINER(fWindow), widget);
  67. gtk_window_set_resizable(GTK_WINDOW(fWindow), kClient->isResizable());
  68. gtk_window_set_title(GTK_WINDOW(fWindow), kUiTitle);
  69. #if 0
  70. {
  71. QSettings settings("falkTX", appName);
  72. if (settings.contains(QString("%1/pos_x").arg(kUiTitle)))
  73. {
  74. gtk_window_get_position(GTK_WINDOW(fWindow), &fLastX, &fLastY);
  75. bool hasX, hasY;
  76. fLastX = settings.value(QString("%1/pos_x").arg(kUiTitle), fLastX).toInt(&hasX);
  77. fLastY = settings.value(QString("%1/pos_y").arg(kUiTitle), fLastY).toInt(&hasY);
  78. if (hasX && hasY)
  79. gtk_window_move(GTK_WINDOW(fWindow), fLastX, fLastY);
  80. if (kClient->isResizable())
  81. {
  82. gtk_window_get_size(GTK_WINDOW(fWindow), &fLastWidth, &fLastHeight);
  83. bool hasWidth, hasHeight;
  84. fLastWidth = settings.value(QString("%1/width").arg(kUiTitle), fLastWidth).toInt(&hasWidth);
  85. fLastHeight = settings.value(QString("%1/height").arg(kUiTitle), fLastHeight).toInt(&hasHeight);
  86. if (hasWidth && hasHeight)
  87. gtk_window_resize(GTK_WINDOW(fWindow), fLastWidth, fLastHeight);
  88. }
  89. }
  90. if (settings.value("Engine/UIsAlwaysOnTop", true).toBool())
  91. gtk_window_set_keep_above(GTK_WINDOW(fWindow), true);
  92. }
  93. #endif
  94. if (showGui || fNeedsShow)
  95. {
  96. show();
  97. fNeedsShow = false;
  98. }
  99. g_timeout_add(30, 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("CarlaBridgeToolkitGtk::quit()");
  109. if (fWindow != nullptr)
  110. {
  111. gtk_widget_destroy(fWindow);
  112. fWindow = nullptr;
  113. if (gtk_main_level() != 0)
  114. gtk_main_quit();
  115. }
  116. }
  117. void show() override
  118. {
  119. carla_debug("CarlaBridgeToolkitGtk::show()");
  120. fNeedsShow = true;
  121. if (fWindow != nullptr)
  122. gtk_widget_show_all(fWindow);
  123. }
  124. void hide() override
  125. {
  126. carla_debug("CarlaBridgeToolkitGtk::hide()");
  127. fNeedsShow = false;
  128. if (fWindow != nullptr)
  129. gtk_widget_hide(fWindow);
  130. }
  131. void resize(int width, int height) override
  132. {
  133. CARLA_ASSERT(fWindow != nullptr);
  134. carla_debug("CarlaBridgeToolkitGtk::resize(%i, %i)", width, height);
  135. if (fWindow != nullptr)
  136. gtk_window_resize(GTK_WINDOW(fWindow), width, height);
  137. }
  138. // ---------------------------------------------------------------------
  139. protected:
  140. bool fNeedsShow;
  141. GtkWidget* fWindow;
  142. gint fLastX;
  143. gint fLastY;
  144. gint fLastWidth;
  145. gint fLastHeight;
  146. void handleDestroy()
  147. {
  148. carla_debug("CarlaBridgeToolkitGtk::handleDestroy()");
  149. fWindow = nullptr;
  150. #if 0
  151. QSettings settings("falkTX", appName);
  152. settings.setValue(QString("%1/pos_x").arg(kUiTitle), fLastX);
  153. settings.setValue(QString("%1/pos_y").arg(kUiTitle), fLastY);
  154. settings.setValue(QString("%1/width").arg(kUiTitle), fLastWidth);
  155. settings.setValue(QString("%1/height").arg(kUiTitle), fLastHeight);
  156. #endif
  157. }
  158. gboolean handleTimeout()
  159. {
  160. if (fWindow != nullptr)
  161. {
  162. gtk_window_get_position(GTK_WINDOW(fWindow), &fLastX, &fLastY);
  163. gtk_window_get_size(GTK_WINDOW(fWindow), &fLastWidth, &fLastHeight);
  164. }
  165. kClient->uiIdle();
  166. return kClient->oscIdle();
  167. }
  168. // ---------------------------------------------------------------------
  169. private:
  170. static void gtk_ui_destroy(GtkWidget*, gpointer data)
  171. {
  172. CARLA_ASSERT(data != nullptr);
  173. if (CarlaBridgeToolkitGtk* const _this_ = (CarlaBridgeToolkitGtk*)data)
  174. _this_->handleDestroy();
  175. gtk_main_quit();
  176. }
  177. static gboolean gtk_ui_timeout(gpointer data)
  178. {
  179. CARLA_ASSERT(data != nullptr);
  180. if (CarlaBridgeToolkitGtk* const _this_ = (CarlaBridgeToolkitGtk*)data)
  181. return _this_->handleTimeout();
  182. return false;
  183. }
  184. };
  185. // -------------------------------------------------------------------------
  186. CarlaBridgeToolkit* CarlaBridgeToolkit::createNew(CarlaBridgeClient* const client, const char* const uiTitle)
  187. {
  188. return new CarlaBridgeToolkitGtk(client, uiTitle);
  189. }
  190. // -------------------------------------------------------------------------
  191. CARLA_BRIDGE_END_NAMESPACE