1
+ #include " OGUIVideoTimeline.h"
2
+ #include " OGUIWindow.h"
3
+ #include " OGUIUtils.h"
4
+ #include " nanovg.h"
5
+ #include < sstream>
6
+ #include < iostream>
7
+ #include < iomanip>
8
+ #include < GLFW/glfw3.h>
9
+
10
+ namespace OpenCVGUI {
11
+
12
+ OGUIVideoTimeline::OGUIVideoTimeline (OGUIWindow* window, std::string title): OGUIArea(window)
13
+ {
14
+ this ->title = title;
15
+ time_pos = 0 ;
16
+ time_pos_msec = 0 ;
17
+ _playing= false ;
18
+ }
19
+
20
+ string OGUIVideoTimeline::format_secs (int sec) {
21
+ int min = sec / 60 ;
22
+ int hours = min / 60 ;
23
+
24
+ std::stringstream ss;
25
+ ss << std::setfill (' 0' ) << std::setw (2 ) << hours;
26
+ ss << " :" ;
27
+ ss << std::setfill (' 0' ) << std::setw (2 ) << min%60 ;
28
+ ss << " :" ;
29
+ ss << std::setfill (' 0' ) << std::setw (2 ) << sec%60 ;
30
+ return ss.str ();
31
+ }
32
+
33
+ bool OGUIVideoTimeline::is_playing ()
34
+ {
35
+ return _playing;
36
+ }
37
+
38
+ void OGUIVideoTimeline::draw (int x, int y, int width, int height)
39
+ {
40
+ this ->x =x;
41
+ this ->y =y;
42
+ this ->width = width;
43
+ this ->height = height;
44
+ NVGcontext* vg= (NVGcontext*)(window->vg );
45
+ nvgScissor (vg, x, y, width, height);
46
+ OGUIArea::draw (x,y,width,height);
47
+
48
+ drawTitle (true );
49
+
50
+ int offset_time=150 ;
51
+
52
+
53
+ // Draw tracks
54
+ for (int i=0 ; i<tracks.size (); i++){
55
+ Track* track= tracks[i];
56
+ track->draw (vg, x, y+43 +i*40 , width, 40 , this ->window ->mouse_x , this ->window ->mouse_y );
57
+ }
58
+
59
+ if (isMouseIn () && this ->window ->mouse_state == GLFW_PRESS){
60
+ // check if is in the header track part
61
+ if (this ->window ->mouse_x > x+offset_time && this ->window ->mouse_y > y+22 && this ->window ->mouse_y < y+height)
62
+ time_pos = this ->window ->mouse_x - x - offset_time;
63
+ time_pos_msec = time_pos*100 ;
64
+ }
65
+
66
+ // Draw header time
67
+ nvgBeginPath (vg);
68
+ nvgRect (vg, x+offset_time, y + 22 , width-offset_time, 20 );
69
+ nvgFillColor (vg, nvgRGBA (0 , 0 , 0 , 50 ));
70
+ nvgFill (vg);
71
+
72
+ // Draw time dragger
73
+ nvgBeginPath (vg);
74
+ nvgRect (vg, x + offset_time + time_pos, y+22 , 1 , height);
75
+ nvgFillColor (vg, nvgRGBA (255 ,255 ,255 , 255 ));
76
+ nvgFill (vg);
77
+
78
+ nvgBeginPath (vg);
79
+ nvgMoveTo (vg, x + offset_time - 5 + time_pos, y + 22 );
80
+ nvgLineTo (vg, x + offset_time + time_pos, y + 22 + 5 );
81
+ nvgLineTo (vg, x + offset_time + 5 + time_pos, y + 22 );
82
+ nvgFillColor (vg, nvgRGBA (255 ,255 ,255 , 255 ));
83
+ nvgFill (vg);
84
+
85
+
86
+ // Draw ticks
87
+ for (int i=offset_time; i<width; i=i+25 ){
88
+ int t= (i-offset_time)%100 ;
89
+ nvgBeginPath (vg);
90
+ if (t==0 )
91
+ nvgRect (vg, x + i, y+28 , 1 , 14 );
92
+ else
93
+ nvgRect (vg, x + i, y+37 , 1 , 5 );
94
+ nvgFillColor (vg, nvgRGBA (255 ,255 ,255 , 125 ));
95
+ nvgFill (vg);
96
+ }
97
+ // Draw time texts
98
+ for (int i=offset_time; i<width; i=i+100 ){
99
+ int start_time = i-offset_time;
100
+ int sec=start_time/10 ;
101
+ drawLabel (vg, format_secs (sec).c_str (), x + i + 2 , y+32 , " sans" , 12 .0f , 255 ,255 ,255 ,125 );
102
+ }
103
+
104
+ // draw right header tracks
105
+ nvgBeginPath (vg);
106
+ nvgRect (vg, x, y + 22 , offset_time - 1 , 20 );
107
+ nvgFillColor (vg, nvgRGBA (0 , 0 , 0 , 50 ));
108
+ nvgFill (vg);
109
+
110
+ if (drawBasicButton (vg, this ->window , " \uF04b " , x+2 , y + 22 , 20 , 20 , this ->window ->mouse_x , this ->window ->mouse_y , " icons" , 16 )){
111
+ _playing= true ;
112
+ }
113
+
114
+ if (drawBasicButton (vg, this ->window , " \uF04c " , x+24 , y + 22 , 20 , 20 , this ->window ->mouse_x , this ->window ->mouse_y , " icons" , 16 )){
115
+ _playing= false ;
116
+ }
117
+
118
+ // draw actual time
119
+ int act_secs = time_pos_msec/1000 ;
120
+ string actuall_time_str = format_secs (act_secs);
121
+ drawLabel (vg, actuall_time_str.c_str (), x + 52 , y+32 , " sans" , 16 .0f , 255 ,255 ,255 ,255 );
122
+
123
+ // draw right header tracks
124
+ nvgBeginPath (vg);
125
+ nvgRect (vg, x, y + 43 , offset_time - 1 , height - 21 );
126
+ nvgFillColor (vg, nvgRGBA (0 , 0 , 0 , 50 ));
127
+ nvgFill (vg);
128
+
129
+
130
+ }
131
+
132
+ void OGUIVideoTimeline::updateScrollStatus (double xoffset,double yoffset)
133
+ {
134
+ if (isMouseIn ()){
135
+
136
+ }
137
+ }
138
+
139
+ void OGUIVideoTimeline::addTrack (Track *track)
140
+ {
141
+ tracks.push_back (track);
142
+ }
143
+
144
+ int OGUIVideoTimeline::get_time_pos ()
145
+ {
146
+ return time_pos_msec;
147
+ }
148
+
149
+ void OGUIVideoTimeline::set_time_pos (int pos_ms)
150
+ {
151
+ time_pos_msec = pos_ms;
152
+ time_pos = pos_ms/100 ;
153
+ }
154
+
155
+
156
+ Track::Track (string title, VideoCapture* videocap)
157
+ {
158
+ this ->title = title;
159
+ this ->videocap = videocap;
160
+ double fps = this ->videocap ->get (CAP_PROP_FPS);
161
+ double frame_count = this ->videocap ->get (CAP_PROP_FRAME_COUNT);
162
+ duration = frame_count/fps;
163
+ this ->videocap ->set (CAP_PROP_POS_MSEC, 0 );
164
+ this ->videocap ->read (this ->thumbnail );
165
+ // this->thumbnail = thumbnail;
166
+ cvtColor (thumbnail, thumbnail, COLOR_BGR2RGBA);
167
+ nvg_thumbnail_id=-1 ;
168
+ }
169
+
170
+ void Track::draw (void * vvg, int x, int y, int width, int height, int mouse_x, int mouse_y)
171
+ {
172
+ NVGcontext* vg= (NVGcontext*)(vvg);
173
+ const int offset_time=150 ;
174
+ nvgBeginPath (vg);
175
+ nvgRect (vg, x + offset_time, y, width-offset_time, 38 );
176
+ nvgFillColor (vg, nvgRGBA (0 , 0 , 0 , 20 ));
177
+ nvgFill (vg);
178
+
179
+ nvgBeginPath (vg);
180
+ nvgRect (vg, x, y + 39 , width, 1 );
181
+ nvgFillColor (vg, nvgRGBA (255 ,255 ,255 , 20 ));
182
+ nvgFill (vg);
183
+
184
+ // Draw box of duration time size
185
+ nvgBeginPath (vg);
186
+ nvgRect (vg, x + offset_time, y, duration*10 , 38 );
187
+ nvgFillColor (vg, nvgRGBA (255 , 0 , 0 , 20 ));
188
+ nvgFill (vg);
189
+
190
+ // Draw thumbnail
191
+ int w=thumbnail.cols *40 /thumbnail.rows ;
192
+ int h=40 ;
193
+ if (nvg_thumbnail_id==-1 ){
194
+ thumb_data= thumbnail.data ;
195
+ nvg_thumbnail_id= nvgCreateImageRGBA (vg, thumbnail.cols , thumbnail.rows , NVG_IMAGE_NEAREST, thumb_data);
196
+ // nvgUpdateImage(vg, nvg_thumbnail_id, thumbnail.data);
197
+ }
198
+
199
+
200
+ NVGpaint imgPaint = nvgImagePattern (vg, x+offset_time, y, w, h, 0 , nvg_thumbnail_id, 1 );
201
+ nvgBeginPath (vg);
202
+ nvgRect (vg, x+offset_time, y, w, h);
203
+ nvgFillPaint (vg, imgPaint);
204
+ nvgFill (vg);
205
+
206
+ drawLabel (vg, title.c_str (), x + 10 , y+20 , " sans" , 16 .0f , 255 ,255 ,255 ,255 );
207
+
208
+ for (auto m:markers){
209
+ m.draw (vg, x+offset_time, y, mouse_x, mouse_y);
210
+ }
211
+
212
+ }
213
+
214
+ void Track::add_marker (string title, int start, int end, NVGcolor color)
215
+ {
216
+ markers.push_back (TimeMarker (title, start, end, color));
217
+ }
218
+
219
+ void TimeMarker::draw (void * vvg, int x, int y, int mouse_x, int mouse_y)
220
+ {
221
+ NVGcontext* vg= (NVGcontext*)(vvg);
222
+ nvgBeginPath (vg);
223
+ int w= (end-start)/100 ;
224
+ int s = x + start/100 ;
225
+ nvgRect (vg, s, y, w, 5 );
226
+ nvgFillColor (vg, color);
227
+ nvgFill (vg);
228
+
229
+ if (mouse_x > s && mouse_x< s+w && mouse_y > y && mouse_y < y+5 )
230
+ {
231
+ nvgBeginPath (vg);
232
+ nvgRect (vg, mouse_x+12 , mouse_y+12 , title.length ()*8 , 20 );
233
+ nvgFillColor (vg, nvgRGBA (0 , 0 , 0 , 200 ));
234
+ nvgFill (vg);
235
+
236
+ drawLabel (vg, title.c_str (), mouse_x+16 , mouse_y+22 , " sans" , 16 .0f , 255 ,255 ,255 ,255 );
237
+ }
238
+ }
239
+
240
+ }
0 commit comments