The JUCE cross-platform C++ framework, with DISTRHO/KXStudio specific changes
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.

178 lines
5.7KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2017 - ROLI Ltd.
  5. JUCE is an open source library subject to commercial or open-source
  6. licensing.
  7. By using JUCE, you agree to the terms of both the JUCE 5 End-User License
  8. Agreement and JUCE 5 Privacy Policy (both updated and effective as of the
  9. 27th April 2017).
  10. End User License Agreement: www.juce.com/juce-5-licence
  11. Privacy Policy: www.juce.com/juce-5-privacy-policy
  12. Or: You may also use this code under the terms of the GPL v3 (see
  13. www.gnu.org/licenses).
  14. JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
  15. EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
  16. DISCLAIMED.
  17. ==============================================================================
  18. */
  19. #pragma once
  20. #include "../JuceLibraryCode/JuceHeader.h"
  21. //==============================================================================
  22. class OSCLogListBox : public ListBox, private ListBoxModel, private AsyncUpdater
  23. {
  24. public:
  25. //==============================================================================
  26. OSCLogListBox()
  27. {
  28. setModel (this);
  29. }
  30. //==============================================================================
  31. ~OSCLogListBox()
  32. {
  33. }
  34. //==============================================================================
  35. int getNumRows() override
  36. {
  37. return oscLogList.size();
  38. }
  39. //==============================================================================
  40. void paintListBoxItem (int row, Graphics& g, int width, int height, bool rowIsSelected) override
  41. {
  42. ignoreUnused (rowIsSelected);
  43. if (isPositiveAndBelow (row, oscLogList.size()))
  44. {
  45. g.setColour (Colours::black);
  46. g.drawText (oscLogList[row],
  47. Rectangle<int> (width, height).reduced (4, 0),
  48. Justification::centredLeft, true);
  49. }
  50. }
  51. //==============================================================================
  52. void addOSCMessage (const OSCMessage& message, int level = 0)
  53. {
  54. oscLogList.add (getIndentationString (level)
  55. + "- osc message, address = '"
  56. + message.getAddressPattern().toString()
  57. + "', "
  58. + String (message.size())
  59. + " argument(s)");
  60. if (! message.isEmpty())
  61. {
  62. for (OSCArgument* arg = message.begin(); arg != message.end(); ++arg)
  63. addOSCMessageArgument (*arg, level + 1);
  64. }
  65. triggerAsyncUpdate();
  66. }
  67. //==============================================================================
  68. void addOSCBundle (const OSCBundle& bundle, int level = 0)
  69. {
  70. OSCTimeTag timeTag = bundle.getTimeTag();
  71. oscLogList.add (getIndentationString (level)
  72. + "- osc bundle, time tag = "
  73. + timeTag.toTime().toString (true, true, true, true));
  74. for (OSCBundle::Element* element = bundle.begin(); element != bundle.end(); ++element)
  75. {
  76. if (element->isMessage())
  77. addOSCMessage (element->getMessage(), level + 1);
  78. else if (element->isBundle())
  79. addOSCBundle (element->getBundle(), level + 1);
  80. }
  81. triggerAsyncUpdate();
  82. }
  83. //==============================================================================
  84. void addOSCMessageArgument (const OSCArgument& arg, int level)
  85. {
  86. String typeAsString;
  87. String valueAsString;
  88. if (arg.isFloat32())
  89. {
  90. typeAsString = "float32";
  91. valueAsString = String (arg.getFloat32());
  92. }
  93. else if (arg.isInt32())
  94. {
  95. typeAsString = "int32";
  96. valueAsString = String (arg.getInt32());
  97. }
  98. else if (arg.isString())
  99. {
  100. typeAsString = "string";
  101. valueAsString = arg.getString();
  102. }
  103. else if (arg.isBlob())
  104. {
  105. typeAsString = "blob";
  106. const MemoryBlock& blob = arg.getBlob();
  107. valueAsString = String::fromUTF8( (const char*)blob.getData(), blob.getSize());
  108. }
  109. else
  110. {
  111. typeAsString = "(unknown)";
  112. valueAsString = "";
  113. }
  114. oscLogList.add (getIndentationString (level + 1) + "- " + typeAsString.paddedRight(' ', 12) + valueAsString);
  115. }
  116. //==============================================================================
  117. void addInvalidOSCPacket (const char* /* data */, int dataSize)
  118. {
  119. oscLogList.add ("- (" + String(dataSize) + "bytes with invalid format)");
  120. }
  121. //==============================================================================
  122. void clear()
  123. {
  124. oscLogList.clear();
  125. triggerAsyncUpdate();
  126. }
  127. //==============================================================================
  128. void handleAsyncUpdate() override
  129. {
  130. updateContent();
  131. scrollToEnsureRowIsOnscreen (oscLogList.size() - 1);
  132. repaint();
  133. }
  134. private:
  135. //==============================================================================
  136. String getIndentationString (int level)
  137. {
  138. return String().paddedRight (' ', 2 * level);
  139. }
  140. //==============================================================================
  141. StringArray oscLogList;
  142. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (OSCLogListBox)
  143. };