1 /* 2 ** Surge Synthesizer is Free and Open Source Software 3 ** 4 ** Surge is made available under the Gnu General Public License, v3.0 5 ** https://www.gnu.org/licenses/gpl-3.0.en.html 6 ** 7 ** Copyright 2004-2020 by various individuals as described by the Git transaction log 8 ** 9 ** All source at: https://github.com/surge-synthesizer/surge.git 10 ** 11 ** Surge was a commercial product from 2004-2018, with Copyright and ownership 12 ** in that period held by Claes Johanson at Vember Audio. Claes made Surge 13 ** open source in September 2018. 14 */ 15 16 #pragma once 17 #include "vstcontrols.h" 18 #include "Parameter.h" 19 #include <iostream> 20 #include "SkinSupport.h" 21 #include "SkinColors.h" 22 #include "RuntimeFont.h" 23 24 class CParameterTooltip : public VSTGUI::CControl, public Surge::UI::SkinConsumingComponent 25 { 26 public: CParameterTooltip(const VSTGUI::CRect & size)27 CParameterTooltip(const VSTGUI::CRect &size) : VSTGUI::CControl(size, 0, 0, 0) 28 { 29 label[0][0] = 0; 30 label[1][0] = 0; 31 visible = false; 32 last_tag = -1; 33 } 34 35 void setLabel(const char *txt1, const char *txt2, const char *txt2left = nullptr) 36 { 37 if (txt1) 38 strncpy(label[0], txt1, 256); 39 else 40 label[0][0] = 0; 41 if (txt2) 42 strncpy(label[1], txt2, 256); 43 else 44 label[1][0] = 0; 45 if (txt2left) 46 strncpy(label2left, txt2left, 256); 47 else 48 label2left[0] = 0; 49 50 setDirty(true); 51 } 52 getMaxLabelLen()53 int getMaxLabelLen() 54 { 55 auto l0len = strlen(label[0]); 56 auto l1len = strlen(label[1]) + strlen(label2left); 57 return std::max(l0len, l1len); 58 } 59 Show()60 void Show() 61 { 62 visible = true; 63 invalid(); 64 setDirty(true); 65 } Hide()66 void Hide() 67 { 68 visible = false; 69 #if TARGET_JUCE_UI 70 this->setViewSize(VSTGUI::CRect(VSTGUI::CPoint(0, 0), VSTGUI::CPoint(1, 1))); 71 #endif 72 invalid(); 73 setDirty(true); 74 } isNewTag(long tag)75 bool isNewTag(long tag) 76 { 77 bool b = (last_tag != tag); 78 last_tag = tag; 79 return b; 80 } isVisible()81 bool isVisible() { return visible; } 82 draw(VSTGUI::CDrawContext * dc)83 virtual void draw(VSTGUI::CDrawContext *dc) override 84 { 85 if (visible) 86 { 87 dc->setFont(Surge::GUI::getLatoAtSize(10)); 88 89 auto frameCol = skin->getColor(Colors::InfoWindow::Border); 90 auto bgCol = skin->getColor(Colors::InfoWindow::Background); 91 92 auto txtCol = skin->getColor(Colors::InfoWindow::Text); 93 auto mpCol = skin->getColor(Colors::InfoWindow::Modulation::Positive); 94 auto mnCol = skin->getColor(Colors::InfoWindow::Modulation::Negative); 95 auto mpValCol = skin->getColor(Colors::InfoWindow::Modulation::ValuePositive); 96 auto mnValCol = skin->getColor(Colors::InfoWindow::Modulation::ValueNegative); 97 98 auto size = getViewSize(); 99 size = size.inset(0.75, 0.75); 100 dc->setFrameColor(frameCol); 101 dc->drawRect(size); 102 VSTGUI::CRect sizem1(size); 103 sizem1.inset(1, 1); 104 dc->setFillColor(bgCol); 105 dc->drawRect(sizem1, VSTGUI::kDrawFilled); 106 dc->setFontColor(txtCol); 107 VSTGUI::CRect trect(size); 108 trect.inset(4, 1); 109 VSTGUI::CRect tupper(trect), tlower(trect); 110 tupper.bottom = tupper.top + 13; 111 tlower.top = tlower.bottom - 15; 112 113 if (hasiwstrings) 114 { 115 VSTGUI::CRect tmid(trect); 116 tmid.bottom = trect.bottom - 18; 117 tmid.top = trect.top + 15; 118 if (!extendedwsstrings) 119 { 120 tmid = tlower; 121 } 122 if (label[0][0]) 123 { 124 dc->drawString(label[0], tupper, VSTGUI::kLeftText, true); 125 } 126 127 if (!extendedwsstrings) 128 { 129 dc->drawString(iwstrings.val.c_str(), tmid, VSTGUI::kLeftText, true); 130 dc->setFontColor(mpCol); 131 dc->drawString(iwstrings.dvalplus.c_str(), tmid, VSTGUI::kRightText, true); 132 dc->setFontColor(txtCol); 133 } 134 else 135 { 136 auto valalign = VSTGUI::kCenterText; 137 if (iwstrings.dvalminus.size() == 0 && iwstrings.valminus.size() == 0) 138 valalign = VSTGUI::kLeftText; 139 140 dc->drawString(iwstrings.val.c_str(), tmid, valalign, true); 141 dc->setFontColor(mpCol); 142 dc->drawString(iwstrings.dvalplus.c_str(), tmid, VSTGUI::kRightText, true); 143 dc->setFontColor(mnCol); 144 dc->drawString(iwstrings.dvalminus.c_str(), tmid, VSTGUI::kLeftText, true); 145 146 dc->setFontColor(mpValCol); 147 dc->drawString(iwstrings.valplus.c_str(), tlower, VSTGUI::kRightText, true); 148 dc->setFontColor(mnValCol); 149 dc->drawString(iwstrings.valminus.c_str(), tlower, VSTGUI::kLeftText, true); 150 dc->setFontColor(txtCol); 151 } 152 } 153 else 154 { 155 if (label[0][0]) 156 { 157 dc->drawString(label[0], tupper, VSTGUI::kLeftText, true); 158 } 159 // dc->drawString(label[1],tlower,false,label[0][0]?kRightText:kCenterText); 160 dc->drawString(label[1], tlower, VSTGUI::kRightText, true); 161 162 if (label2left[0]) 163 { 164 dc->drawString(label2left, tlower, VSTGUI::kLeftText, true); 165 } 166 } 167 } 168 else 169 { 170 #if 0 171 auto size = getViewSize(); 172 size = size.inset(0.75, 0.75); 173 dc->setFrameColor(VSTGUI::kRedCColor); 174 dc->setFrameColor(VSTGUI::kBlueCColor); 175 dc->drawRect(size, VSTGUI::kDrawFilledAndStroked); 176 #endif 177 } 178 setDirty(false); 179 } 180 setMDIWS(const ModulationDisplayInfoWindowStrings & i)181 void setMDIWS(const ModulationDisplayInfoWindowStrings &i) 182 { 183 iwstrings = i; 184 hasiwstrings = true; 185 } 186 setExtendedMDIWS(bool b)187 void setExtendedMDIWS(bool b) { extendedwsstrings = b; } 188 clearMDIWS()189 void clearMDIWS() { hasiwstrings = false; } hasMDIWS()190 bool hasMDIWS() { return hasiwstrings; } 191 192 protected: 193 char label[2][256], label2left[256]; 194 bool visible; 195 int last_tag; 196 197 ModulationDisplayInfoWindowStrings iwstrings; 198 bool hasiwstrings = false; 199 bool extendedwsstrings = false; 200 201 CLASS_METHODS(CParameterTooltip, VSTGUI::CControl) 202 }; 203