1 // -*-c++-*-
2 /*
3 ** Surge Synthesizer is Free and Open Source Software
4 **
5 ** Surge is made available under the Gnu General Public License, v3.0
6 ** https://www.gnu.org/licenses/gpl-3.0.en.html
7 **
8 ** Copyright 2004-2020 by various individuals as described by the Git transaction log
9 **
10 ** All source at: https://github.com/surge-synthesizer/surge.git
11 **
12 ** Surge was a commercial product from 2004-2018, with Copyright and ownership
13 ** in that period held by Claes Johanson at Vember Audio. Claes made Surge
14 ** open source in September 2018.
15 */
16 
17 #pragma once
18 #include "vstcontrols.h"
19 #include "SurgeBitmaps.h"
20 #include "SurgeParamConfig.h"
21 #include "CursorControlGuard.h"
22 #include "SkinSupport.h"
23 
24 class CMenuAsSlider : public VSTGUI::CControl,
25                       public Surge::UI::SkinConsumingComponent,
26                       public Surge::UI::CursorControlAdapter<CMenuAsSlider>
27 {
28   public:
29     CMenuAsSlider(const VSTGUI::CPoint &loc, VSTGUI::IControlListener *listener, long tag,
30                   std::shared_ptr<SurgeBitmaps> bitmapStore, SurgeStorage *storage = nullptr)
31         : CMenuAsSlider(loc, VSTGUI::CPoint(133, 22), listener, tag, bitmapStore, storage)
32     {
33     }
34     CMenuAsSlider(const VSTGUI::CPoint &loc, const VSTGUI::CPoint &size,
35                   VSTGUI::IControlListener *listener, long tag,
36                   std::shared_ptr<SurgeBitmaps> bitmapStore, SurgeStorage *storage = nullptr);
37     virtual ~CMenuAsSlider();
38     virtual void draw(VSTGUI::CDrawContext *) override;
setLabel(const char * lab)39     void setLabel(const char *lab) { label = lab; }
40 
41     virtual bool onWheel(const VSTGUI::CPoint &where, const float &distane,
42                          const VSTGUI::CButtonState &buttons) override;
43 
44     virtual VSTGUI::CMouseEventResult onMouseDown(
45         VSTGUI::CPoint &where,
46         const VSTGUI::CButtonState &buttons) override; ///< called when a mouse down event occurs
47     virtual VSTGUI::CMouseEventResult onMouseUp(VSTGUI::CPoint &where,
48                                                 const VSTGUI::CButtonState &buttons) override;
49     virtual VSTGUI::CMouseEventResult onMouseMoved(VSTGUI::CPoint &where,
50                                                    const VSTGUI::CButtonState &buttons) override;
51 
onMouseEntered(VSTGUI::CPoint & where,const VSTGUI::CButtonState & buttons)52     virtual VSTGUI::CMouseEventResult onMouseEntered(VSTGUI::CPoint &where,
53                                                      const VSTGUI::CButtonState &buttons) override
54     {
55         isHover = true;
56         wheelDistance = 0;
57         invalid();
58         return VSTGUI::kMouseEventHandled;
59     }
60 
onMouseExited(VSTGUI::CPoint & where,const VSTGUI::CButtonState & buttons)61     virtual VSTGUI::CMouseEventResult onMouseExited(VSTGUI::CPoint &where,
62                                                     const VSTGUI::CButtonState &buttons) override
63     {
64         isHover = false;
65         wheelDistance = 0;
66         invalid();
67         return VSTGUI::kMouseEventHandled;
68     }
69 
setMinMax(int i,int x)70     void setMinMax(int i, int x)
71     {
72         iMin = i;
73         iMax = x;
74     }
75 
setDeactivated(bool d)76     void setDeactivated(bool d) { deactivated = d; }
77     bool deactivated = false;
78 
79     CLASS_METHODS(CMenuAsSlider, CControl)
80     bool in_hover = false;
81     SurgeStorage *storage = nullptr;
82 
83     int bgid = IDB_MENU_AS_SLIDER;
setBackgroundID(int q)84     void setBackgroundID(int q)
85     {
86         bgid = q;
87         onSkinChanged();
88     }
89 
90     std::string bgrs = "";
setBackgroundBitmapResource(const std::string & b)91     void setBackgroundBitmapResource(const std::string &b)
92     {
93         bgrs = b;
94         onSkinChanged();
95     }
96 
97     bool filtermode = false;
setFilterMode(bool b)98     void setFilterMode(bool b)
99     {
100         filtermode = b;
101         invalid();
102     }
103 
104     enum
105     {
106         ABOVE,
107         BELOW,
108         LEFT,
109         RIGHT
110     } glyphLocation = LEFT;
111     std::string glyphImage = "", glyphImageHover = "";
112     int glyphW = 18, glyphH = 18;
113     void setGlyphSettings(const std::string &img, const std::string &imghov,
114                           const std::string &location, int w, int h);
115     virtual void onSkinChanged() override;
116 
117     VSTGUI::CRect dragRegion;
118     bool hasDragRegion = false;
119     VSTGUI::CPoint dragStart;
120     void setDragRegion(const VSTGUI::CRect &dragRegion);
121 
122     int dglphyid = -1, dglyphsize = -1;
123     void setDragGlyph(int id, int size = 18)
124     {
125         dglphyid = id;
126         glyphW = size;
127         glyphH = size;
128         dglyphsize = size;
129         onSkinChanged();
130     }
131     std::vector<std::pair<int, int>> glyphIndexMap;
132 
133     std::vector<int> intOrdering;
134     float nextValueInOrder(float valueFrom, int inc);
135 
136   private:
137     VSTGUI::CBitmap *pBackground = nullptr, *pBackgroundHover = nullptr, *pGlyph = nullptr,
138                     *pGlyphHover = nullptr;
139     std::string label = "";
140     bool isHover = false;
141     bool isDragRegionDrag = false;
142     enum
143     {
144         unk,
145         dirx,
146         diry
147     } dragDir = unk;
148     float wheelDistance = 0;
149 
150     int iMin = 0, iMax = 10;
151 };
152