root / trunk / Linux / addons / ofxNCore / src / Controls / ofxGuiPoints.cpp @ 59

View | Annotate | Download (8.6 KB)

1
/*
2
 *  ofxGuiPoints.cpp
3
 *  openFrameworks
4
 *
5
 *  Created by Stefan Kirch on 18.06.08.
6
 *  Copyright 2008 alphakanal. All rights reserved.
7
 *
8
 */
9
10
//        ----------------------------------------------------------------------------------------------------
11
12
#include "ofxGuiPoints.h"
13
14
//        ----------------------------------------------------------------------------------------------------
15
16
ofxGuiPoints::ofxGuiPoints()
17
{
18
        mParamType = kofxGui_Object_Points;
19
}
20
21
//        ----------------------------------------------------------------------------------------------------
22
23
void ofxGuiPoints::init(int id, string name, int x, int y, int width, int height, ofxPoint2f min, ofxPoint2f max, ofxPoint2f value, int display, int steps)
24
{
25
        int        textHeight        = (name == "") ? 0 : mGlobals->mParamFontHeight;
26
27
        mParamId                = id;
28
        mParamName                = name;
29
30
        mObjX                        = x; 
31
        mObjY                        = y;
32
        
33
        mObjWidth                = width;
34
        mObjHeight                = textHeight + height;
35
        
36
        mDisplay                = display;
37
        mSteps                        = steps;
38
        
39
        setRange(min, max);
40
        setValue(value);
41
        setControlRegion(0, textHeight, width, height);
42
43
        mList.points.push_back(ofxPoint2f(mMinVal.x, mMinVal.y + mValDlt.y * 0.5)); 
44
        mList.points.push_back(ofxPoint2f(mMaxVal.x, mMinVal.y + mValDlt.y * 0.5));
45
        
46
        float        size        = mGlobals->mPointSize / 2.0;
47
        float        x1                = size / mCtrWidth;
48
        float        y1                = size / mCtrHeight;
49
        float        x2                = x1 * mValDlt.x;
50
        float        y2                = y1 * mValDlt.y;
51
        
52
        mDistance                = sqrt(x2 * x2 + y2 * y2);
53
}
54
55
//        ----------------------------------------------------------------------------------------------------
56
57
void ofxGuiPoints::setValue(ofxPoint2f value)
58
{
59
        mValue = value;
60
}
61
62
//        ----------------------------------------------------------------------------------------------------
63
64
void ofxGuiPoints::setRange(ofxPoint2f min, ofxPoint2f max) 
65
{
66
        mMinVal        = min;
67
        mMaxVal        = max;
68
        mValDlt        = mMaxVal / mMinVal;
69
}
70
71
//        ----------------------------------------------------------------------------------------------------
72
73
bool ofxGuiPoints::update(int id, int task, void* data, int length)
74
{
75
        bool                handled        = false;
76
        ofxPoint2f        value        = mValue;
77
        
78
        if(id == mParamId)
79
        {
80
                if(task == kofxGui_Set_Float)
81
                        setValue(ofxPoint2f(mMinVal.x + CLAMP(*(float*)data, 0.0, 1.0) * mValDlt.x, mValue.y));
82
                else if(task == kofxGui_Set_Point)
83
                        setValue(*(ofxPoint2f*)data);
84
85
                handled = true;
86
        }
87
        
88
        if(value!= mValue)
89
        {
90
                mOutVal = mList.positionToValue(mValue);
91
                mGlobals->mListener->handleGui(mParamId, kofxGui_Set_Point, &mOutVal, sizeof(ofxPoint2f));
92
        }
93
94
        return handled;
95
}
96
97
//        ----------------------------------------------------------------------------------------------------
98
99
void ofxGuiPoints::draw()
100
{
101
        glPushMatrix();
102
103
                glTranslatef(mObjX, mObjY, 0.0f);
104
        
105
                if(mParamName != "")
106
                        drawParamString(0.0, 0.0, mParamName + ": " + pointToString(mList.activePoint != -1 ? mOutVal : mValue, mDisplay), false);
107
108
                ofxPoint2f        p        = fractionToLocal(valueToFraction(mValue));
109
                
110
                float                x        = mCtrWidth * p.x;
111
                float                y        = mCtrHeight * p.y;
112
                
113
                float                d        = mGlobals->mPointSize;
114
                float                r        = d / 2.0;
115
        
116
                ofFill();
117
        
118
                //        background
119
                glColor4f(mGlobals->mCoverColor.r, mGlobals->mCoverColor.g, mGlobals->mCoverColor.b, mGlobals->mCoverColor.a);
120
                ofRect(mCtrX, mCtrY, mCtrWidth, mCtrHeight);
121
        
122
                ofNoFill();
123
        
124
                //        lines
125
                glColor4f(mGlobals->mCurveColor.r, mGlobals->mCurveColor.g, mGlobals->mCurveColor.b, mGlobals->mCurveColor.a);
126
                
127
                ofBeginShape();
128
                        for(int i = 0; i < mList.points.size(); i++)
129
                        {
130
                                ofxPoint2f p = fractionToLocal(valueToFraction(mList.points.at(i)));                                
131
                                ofVertex(p.x, p.y);
132
                        }
133
                ofEndShape(false);
134
135
                //        x-bar
136
                glColor4f(mGlobals->mAxisColor.r, mGlobals->mAxisColor.g, mGlobals->mAxisColor.b, mGlobals->mAxisColor.a);
137
                ofLine(p.x + 0.5, mCtrY, p.x + 0.5, mCtrBottom);
138
                
139
                if(mList.activePoint != -1)
140
                {
141
                        //        y-bar
142
                        glColor4f(mGlobals->mAxisColor.r, mGlobals->mAxisColor.g, mGlobals->mAxisColor.b,mGlobals->mAxisColor.a);
143
                        ofLine(mCtrX, p.y + 0.5, mCtrRight, p.y + 0.5);
144
                }
145
        
146
                //        handles                
147
                for(int i = 0; i < mList.points.size(); i++)
148
                {
149
                        glColor4f(mGlobals->mHandleColor.r, mGlobals->mHandleColor.g, mGlobals->mHandleColor.b, mGlobals->mHandleColor.a);
150
                        
151
                        ofxPoint2f p        = fractionToLocal(valueToFraction(mList.points.at(i)));
152
                        ofRect(p.x - r, p.y - r, d, d);
153
                }
154
        
155
                //        frame
156
                glColor4f(mGlobals->mFrameColor.r, mGlobals->mFrameColor.g, mGlobals->mFrameColor.b, mGlobals->mFrameColor.a);
157
                ofRect(mCtrX, mCtrY, mCtrWidth, mCtrHeight);
158
                
159
        glPopMatrix();
160
}
161
162
//        ----------------------------------------------------------------------------------------------------
163
164
bool ofxGuiPoints::mouseDragged(int x, int y, int button)
165
{
166
        if(mMouseIsDown)
167
        {
168
                ofxPoint2f        value        = mValue;
169
                ofxPoint2f        point        = fractionToValue(mouseToFraction(mouseToLocal(x, y)));
170
171
                if(mList.activePoint > -1)
172
                {
173
                        if(mList.activePoint == 0)
174
                        {
175
                                point.x = mMinVal.x;
176
                                mList.points[mList.activePoint] = point;
177
                        }
178
                        else if(mList.activePoint == mList.points.size() - 1)
179
                        {
180
                                point.x = mMaxVal.x;
181
                                mList.points[mList.activePoint] = point;
182
                        }
183
                        else
184
                        {                                
185
                                if(point.x < mList.points[mList.activePoint - 1].x)
186
                                        point.x = mList.points[mList.activePoint - 1].x;
187
                                else if(point.x > mList.points[mList.activePoint + 1].x)
188
                                        point.x = mList.points[mList.activePoint + 1].x;
189
                                        
190
                                mList.points[mList.activePoint] = point;
191
                        }
192
                }
193
                
194
                setValue(point);
195
                
196
                if(value != mValue)
197
                {
198
                        mOutVal = mList.positionToValue(point);
199
                        mGlobals->mListener->handleGui(mParamId, kofxGui_Set_Point, &mOutVal, sizeof(ofxPoint2f));
200
                }
201
        }
202
        
203
        return mMouseIsDown;
204
}
205
206
//        ----------------------------------------------------------------------------------------------------
207
208
bool ofxGuiPoints::mousePressed(int x, int y, int button)
209
{
210
        ofxPoint2f point = mouseToLocal(x, y);
211
212
        if(isPointInsideMe(point))
213
        {
214
                ofxPoint2f        inside        = fractionToValue(mouseToFraction(point));
215
                bool                onPoint        = isPointWithinDistance(inside);
216
                
217
                if(button == 2)
218
                {
219
                        if(onPoint)
220
                                mList.deleteActivePoint();
221
                        else
222
                                mList.addPointAtPosition(inside);
223
                }
224
                
225
                mMouseIsDown = true;
226
                mouseDragged(x, y, button);
227
        }
228
        else
229
        {
230
                mMouseIsDown = false;
231
        }
232
        
233
        return mMouseIsDown;
234
}
235
236
//        ----------------------------------------------------------------------------------------------------
237
238
bool ofxGuiPoints::mouseReleased(int x, int y, int button)
239
{
240
        bool handled = mMouseIsDown;
241
        
242
        if(mMouseIsDown)
243
        {
244
                mMouseIsDown                = false;
245
                mList.activePoint        = -1;
246
        }
247
        
248
        return handled;
249
}
250
251
//        ----------------------------------------------------------------------------------------------------
252
253
void ofxGuiPoints::buildFromXml()
254
{
255
        int numberOfTags = mGlobals->mXml.getNumTags("POINT");
256
257
        if(numberOfTags > 0)
258
        {
259
                mList.points.clear();
260
                
261
                for(int i = 0; i < numberOfTags; i++)
262
                {
263
                        mGlobals->mXml.pushTag("POINT", i);
264
265
                        float        x = mGlobals->mXml.getValue("X", 0.0);
266
                        float        y = mGlobals->mXml.getValue("Y", 0.0);
267
                        
268
                        mList.points.push_back(ofxPoint2f(x, y)); 
269
270
                        mGlobals->mXml.popTag();
271
                }
272
        }
273
        
274
        mOutVal = mList.positionToValue(mValue);
275
        mGlobals->mListener->handleGui(mParamId, kofxGui_Set_Point, &mOutVal, sizeof(ofxPoint2f));
276
}
277
278
//        ----------------------------------------------------------------------------------------------------
279
280
void ofxGuiPoints::saveToXml()
281
{
282
        int id = saveObjectData();
283
284
        mGlobals->mXml.setValue("OBJECT:MIN_X", mMinVal.x, id);
285
        mGlobals->mXml.setValue("OBJECT:MIN_Y", mMinVal.y, id);
286
        mGlobals->mXml.setValue("OBJECT:MAX_X", mMaxVal.x, id);
287
        mGlobals->mXml.setValue("OBJECT:MAX_Y", mMaxVal.y, id);
288
        mGlobals->mXml.setValue("OBJECT:VALUE_X", mValue.x, id);
289
        mGlobals->mXml.setValue("OBJECT:VALUE_Y", mValue.y, id);
290
                
291
        mGlobals->mXml.pushTag("OBJECT", id);
292
293
        for(int i = 0; i < mList.points.size(); i++)
294
        {
295
                ofxPoint2f p        = mList.points.at(i);                                
296
297
                id = mGlobals->mXml.addTag("POINT");
298
                
299
                mGlobals->mXml.setValue("POINT:X", p.x, id);
300
                mGlobals->mXml.setValue("POINT:Y", p.y, id);
301
        }
302
303
        mGlobals->mXml.popTag();
304
}
305
306
//        ----------------------------------------------------------------------------------------------------
307
308
ofxPoint2f ofxGuiPoints::valueToFraction(ofxPoint2f value)
309
{
310
        return ofxPoint2f((value.x - mMinVal.x) / mValDlt.x, (value.y - mMinVal.y) / mValDlt.y);
311
}
312
313
//        ----------------------------------------------------------------------------------------------------
314
315
ofxPoint2f ofxGuiPoints::fractionToValue(ofxPoint2f fraction)
316
{
317
        return ofxPoint2f((mValDlt.x * fraction.x) + mMinVal.x, (mValDlt.y * fraction.y) + mMinVal.y);
318
}
319
320
//        ----------------------------------------------------------------------------------------------------
321
322
bool ofxGuiPoints::isPointWithinDistance(ofxPoint2f position)
323
{
324
        mList.activePoint = -1;
325
        
326
        for(int i = 0; i < mList.points.size(); i++)
327
        {
328
                ofxPoint2f        point        = mList.points.at(i);
329
                float                delta        = point.distance(position);
330
                
331
                if(delta < mDistance)
332
                {
333
                        mList.activePoint = i;
334
                        break;
335
                }
336
        }
337
        
338
        return mList.activePoint != -1;
339
}