4 * Copyright (C) 1997-2014 Adam Williams <broadcast at earthling dot net>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include "bcdisplayinfo.h"
23 #include "bcsignals.h"
26 #include "automation.h"
28 #include "cwindowgui.h"
30 #include "edlsession.h"
34 #include "pluginserver.h"
37 #include "titlerwindow.h"
38 #include "bcfontentry.h"
42 static const int timeunit_formats[] =
53 TitleWindow::TitleWindow(TitleMain *client)
54 : PluginClientWindow(client,
55 client->config.window_w, client->config.window_h, 100, 100, 1)
57 //printf("TitleWindow::TitleWindow %d %d %d\n", __LINE__, client->config.window_w, client->config.window_h);
58 this->client = client;
72 title_x = 0; title_y = 0;
73 x_title = 0; y_title = 0;
74 title_w = 0; title_h = 0;
75 w_title = 0; h_title = 0;
76 top = 0; mid = 0; bottom = 0;
77 left = 0; center = 0; right = 0;
78 loop = 0; motion = 0; speed = 0;
88 color_x = color_y = 0;
95 TitleWindow::~TitleWindow()
97 ungrab(client->server->mwindow->cwindow->gui);
98 for( int j=0; j<fonts.size(); ++j ) {
99 // delete the pixmaps but not the vframes since they're static
100 delete fonts.get(j)->get_icon();
103 sizes.remove_all_objects();
104 delete timecode_format;
110 void TitleWindow::create_objects()
113 int margin = client->get_theme()->widget_border;
114 char string[BCTEXTLEN];
118 client->build_previews(this);
120 sizes.append(new BC_ListBoxItem("8"));
121 sizes.append(new BC_ListBoxItem("9"));
122 sizes.append(new BC_ListBoxItem("10"));
123 sizes.append(new BC_ListBoxItem("11"));
124 sizes.append(new BC_ListBoxItem("12"));
125 sizes.append(new BC_ListBoxItem("13"));
126 sizes.append(new BC_ListBoxItem("14"));
127 sizes.append(new BC_ListBoxItem("16"));
128 sizes.append(new BC_ListBoxItem("18"));
129 sizes.append(new BC_ListBoxItem("20"));
130 sizes.append(new BC_ListBoxItem("22"));
131 sizes.append(new BC_ListBoxItem("24"));
132 sizes.append(new BC_ListBoxItem("26"));
133 sizes.append(new BC_ListBoxItem("28"));
134 sizes.append(new BC_ListBoxItem("32"));
135 sizes.append(new BC_ListBoxItem("36"));
136 sizes.append(new BC_ListBoxItem("40"));
137 sizes.append(new BC_ListBoxItem("48"));
138 sizes.append(new BC_ListBoxItem("56"));
139 sizes.append(new BC_ListBoxItem("64"));
140 sizes.append(new BC_ListBoxItem("72"));
141 sizes.append(new BC_ListBoxItem("100"));
142 sizes.append(new BC_ListBoxItem("128"));
143 sizes.append(new BC_ListBoxItem("256"));
144 sizes.append(new BC_ListBoxItem("512"));
145 sizes.append(new BC_ListBoxItem("1024"));
147 paths.append(new BC_ListBoxItem(TitleMain::motion_to_text(NO_MOTION)));
148 paths.append(new BC_ListBoxItem(TitleMain::motion_to_text(BOTTOM_TO_TOP)));
149 paths.append(new BC_ListBoxItem(TitleMain::motion_to_text(TOP_TO_BOTTOM)));
150 paths.append(new BC_ListBoxItem(TitleMain::motion_to_text(RIGHT_TO_LEFT)));
151 paths.append(new BC_ListBoxItem(TitleMain::motion_to_text(LEFT_TO_RIGHT)));
155 // Construct font list
156 ArrayList<BC_FontEntry*> *fontlist = get_resources()->fontlist;
158 for( int i=0; i<fontlist->size(); ++i ) {
160 for( int j=0; j<fonts.size(); ++j ) {
161 if( !strcasecmp(fonts.get(j)->get_text(),
162 fontlist->get(i)->displayname) ) {
168 BC_ListBoxItem *item = 0;
170 fonts.append(item = new
171 BC_ListBoxItem(fontlist->get(i)->displayname));
172 if( !strcmp(client->config.font, item->get_text()) )
173 item->set_selected(1);
174 if( fontlist->values[i]->image ) {
175 VFrame *vframe = fontlist->get(i)->image;
176 BC_Pixmap *icon = new BC_Pixmap(this, vframe, PIXMAP_ALPHA);
177 item->set_icon(icon);
178 item->set_icon_vframe(vframe);
187 for( int i=0; i<fonts.size()-1; ++i ) {
188 if( strcmp(fonts.values[i]->get_text(),
189 fonts.values[i + 1]->get_text()) > 0 ) {
190 BC_ListBoxItem *temp = fonts.values[i + 1];
191 fonts.values[i + 1] = fonts.values[i];
192 fonts.values[i] = temp;
198 add_tool(font_title = new BC_Title(x, y, _("Font:")));
199 font = new TitleFont(client, this, x, y + font_title->get_h());
200 font->create_objects();
202 add_subwindow(font_tumbler = new TitleFontTumble(client, this, x, y+margin));
203 x += font_tumbler->get_w() + margin;
206 add_tool(size_title = new BC_Title(x1, y1+margin, _("Size:")));
207 sprintf(string, "%.2f", client->config.size);
208 x1 += size_title->get_w() + margin;
209 size = new TitleSize(client, this, x1, y1+margin, string);
210 size->create_objects();
211 int x2 = x1 + size->get_w(), y2 = y1 + size->get_h() + margin;
212 add_subwindow(size_tumbler = new TitleSizeTumble(client, this, x2, y1+margin));
214 add_tool(pitch_title = new BC_Title(x-5, y2+margin, _("Pitch:")));
215 pitch = new TitlePitch(client, this, x1, y2+margin, &client->config.line_pitch);
216 pitch->create_objects();
218 int x3 = x2 + size_tumbler->get_w() + 50;
219 int y3 = pitch->get_y() + pitch->get_h();
221 add_tool(style_title = new BC_Title(x=x3, y, _("Style:")));
222 add_tool(italic = new TitleItalic(client, this, x, y + 20));
223 int w1 = italic->get_w();
224 add_tool(bold = new TitleBold(client, this, x, y + 50));
225 if( bold->get_w() > w1 ) w1 = bold->get_w();
226 add_tool(drag = new TitleDrag(client, this, x, y + 80));
227 if( drag->get_w() > w1 ) w1 = drag->get_w();
228 if( client->config.drag )
229 grab(client->server->mwindow->cwindow->gui);
232 add_tool(justify_title = new BC_Title(x, y, _("Justify:")));
233 add_tool(left = new TitleLeft(client, this, x, y + 20));
235 add_tool(center = new TitleCenter(client, this, x, y + 50));
236 if( center->get_w() > w1 ) w1 = center->get_w();
237 add_tool(right = new TitleRight(client, this, x, y + 80));
238 if( right->get_w() > w1 ) w1 = right->get_w();
241 add_tool(top = new TitleTop(client, this, x, y + 20));
242 add_tool(mid = new TitleMid(client, this, x, y + 50));
243 add_tool(bottom= new TitleBottom(client, this, x, y + 80));
248 w1 = BC_Title::calculate_w(this, _("X:"));
249 if( (x1 = BC_Title::calculate_w(this, _("Y:"))) > w1 ) w1 = x1;
250 if( (x1 = BC_Title::calculate_w(this, _("W:"))) > w1 ) w1 = x1;
251 if( (x1 = BC_Title::calculate_w(this, _("H:"))) > w1 ) w1 = x1;
252 add_tool(x_title = new BC_Title(x1=x, y, _("X:")));
254 title_x = new TitleX(client, this, x1, y);
255 title_x->create_objects();
256 x1 += title_x->get_w()+margin;
257 add_tool(y_title = new BC_Title(x1, y, _("Y:")));
259 title_y = new TitleY(client, this, x1, y);
260 title_y->create_objects();
261 x1 += title_y->get_w();
262 y1 = y + title_y->get_h();
264 add_tool(w_title = new BC_Title(x1=x, y1, _("W:")));
266 title_w = new TitleW(client, this, x1, y1);
267 title_w->create_objects();
268 x1 += title_w->get_w()+margin;
269 add_tool(h_title = new BC_Title(x1, y1, _("H:")));
271 title_h = new TitleH(client, this, x1, y1);
272 title_h->create_objects();
273 x1 += title_h->get_w();
276 add_tool(motion_title = new BC_Title(x1=x, y, _("Motion:")));
277 x1 += motion_title->get_w()+margin;
278 motion = new TitleMotion(client, this, x1, y);
279 motion->create_objects();
280 add_tool(loop = new TitleLoop(client, x, y1));
281 x = margin; y = y1 + loop->get_h()+20;
283 add_tool(dropshadow_title = new BC_Title(x, y, _("Drop shadow:")));
284 w1 = dropshadow_title->get_w();
285 dropshadow = new TitleDropShadow(client, this, x, y + 20);
286 dropshadow->create_objects();
287 if( dropshadow->get_w() > w1 ) w1 = dropshadow->get_w();
290 add_tool(fadein_title = new BC_Title(x, y, _("Fade in (sec):")));
291 w1 = fadein_title->get_w();
292 add_tool(fade_in = new TitleFade(client, this, &client->config.fade_in, x, y + 20));
293 if( fade_in->get_w() > w1 ) w1 = fade_in->get_w();
296 add_tool(fadeout_title = new BC_Title(x, y, _("Fade out (sec):")));
297 w1 = fadeout_title->get_w();
298 add_tool(fade_out = new TitleFade(client, this, &client->config.fade_out, x, y + 20));
299 if( fade_out->get_w() > w1 ) w1 = fade_out->get_w();
302 add_tool(speed_title = new BC_Title(x, y1=y, _("Speed:")));
303 w1 = speed_title->get_w();
304 y += speed_title->get_h() + 5;
305 speed = new TitleSpeed(client, this, x, y);
306 speed->create_objects();
307 if( speed->get_w() > w1 ) w1 = speed->get_w();
309 y2 = y + speed->get_h() + 10;
311 color_x = x3; color_y = y = y1;
312 color_thread = new TitleColorThread(client, this, 0);
313 x1 = color_x + COLOR_W + 2*margin;
315 add_tool(color_button = new TitleColorButton(client, this, x1, y1));
317 outline_color_x = x3; outline_color_y = y;
318 outline_color_thread = new TitleColorThread(client, this, 1);
319 y1 = outline_color_y + 5;
320 add_tool(outline_color_button = new TitleOutlineColorButton(client, this, x1, y1));
323 add_tool(outline_title = new BC_Title(x, y, _("Outline:")));
324 y1 = y + outline_title->get_h() + margin;
325 outline = new TitleOutline(client, this, x, y1);
326 outline->create_objects();
327 x += outline->get_w() + 2*margin;
329 // to different to be used
330 add_tool(stroker_title = new BC_Title(x, y, _("Stroker:")));
331 stroker = new TitleStroker(client, this, x, y1);
332 stroker->create_objects();
333 x += stroker->get_w() + margin;
335 y += outline_title->get_h() + margin;
336 add_tool(timecode = new TitleTimecode(client, x1=x, y));
337 x += timecode->get_w() + margin;
338 add_tool(timecode_format = new TitleTimecodeFormat(client, x, y,
339 Units::print_time_format(client->config.timecode_format, string)));
340 timecode_format->create_objects();
341 y += timecode_format->get_h() + margin;
344 add_tool(background = new TitleBackground(client, this, x, y));
345 x += background->get_w() + margin;
346 add_tool(background_path = new TitleBackgroundPath(client, this, x, y));
347 x += background_path->get_w() + 2*margin;
348 add_tool(loop_playback = new TitleLoopPlayback(client, x, y));
349 y += loop_playback->get_h() + 10;
352 add_tool(text_title = new BC_Title(x, y, _("Text:")));
353 y += text_title->get_h() + margin;
355 text = new TitleText(client, this, x, y, get_w()-margin - x, get_h() - y - 10);
356 text->create_objects();
358 add_tool(cur_popup = new TitleCurPopup(client, this));
359 cur_popup->create_objects();
365 int TitleWindow::resize_event(int w, int h)
367 client->config.window_w = w;
368 client->config.window_h = h;
370 clear_box(0, 0, w, h);
371 font_title->reposition_window(font_title->get_x(), font_title->get_y());
372 font->reposition_window(font->get_x(), font->get_y());
373 font_tumbler->reposition_window(font_tumbler->get_x(), font_tumbler->get_y());
374 x_title->reposition_window(x_title->get_x(), x_title->get_y());
375 title_x->reposition_window(title_x->get_x(), title_x->get_y());
376 y_title->reposition_window(y_title->get_x(), y_title->get_y());
377 title_y->reposition_window(title_y->get_x(), title_y->get_y());
378 w_title->reposition_window(w_title->get_x(), w_title->get_y());
379 title_w->reposition_window(title_w->get_x(), title_w->get_y());
380 h_title->reposition_window(h_title->get_x(), h_title->get_y());
381 title_h->reposition_window(title_h->get_x(), title_h->get_y());
382 style_title->reposition_window(style_title->get_x(), style_title->get_y());
383 italic->reposition_window(italic->get_x(), italic->get_y());
384 bold->reposition_window(bold->get_x(), bold->get_y());
385 drag->reposition_window(drag->get_x(), drag->get_y());
386 size_title->reposition_window(size_title->get_x(), size_title->get_y());
387 size->reposition_window(size->get_x(), size->get_y());
388 size_tumbler->reposition_window(size_tumbler->get_x(), size_tumbler->get_y());
389 pitch_title->reposition_window(pitch_title->get_x(), pitch_title->get_y());
390 pitch->reposition_window(pitch->get_x(), pitch->get_y());
392 color_button->reposition_window(color_button->get_x(), color_button->get_y());
393 outline_color_button->reposition_window(outline_color_button->get_x(), outline_color_button->get_y());
394 motion_title->reposition_window(motion_title->get_x(), motion_title->get_y());
395 motion->reposition_window(motion->get_x(), motion->get_y());
396 loop->reposition_window(loop->get_x(), loop->get_y());
397 dropshadow_title->reposition_window(dropshadow_title->get_x(), dropshadow_title->get_y());
398 dropshadow->reposition_window(dropshadow->get_x(), dropshadow->get_y());
399 fadein_title->reposition_window(fadein_title->get_x(), fadein_title->get_y());
400 fade_in->reposition_window(fade_in->get_x(), fade_in->get_y());
401 fadeout_title->reposition_window(fadeout_title->get_x(), fadeout_title->get_y());
402 fade_out->reposition_window(fade_out->get_x(), fade_out->get_y());
403 text_title->reposition_window(text_title->get_x(), text_title->get_y());
404 timecode->reposition_window(timecode->get_x(), timecode->get_y());
405 text->reposition_window(text->get_x(), text->get_y(), w - text->get_x() - 10,
406 BC_TextBox::pixels_to_rows(this, MEDIUMFONT, h - text->get_y() - 10));
407 justify_title->reposition_window(justify_title->get_x(), justify_title->get_y());
408 left->reposition_window(left->get_x(), left->get_y());
409 center->reposition_window(center->get_x(), center->get_y());
410 right->reposition_window(right->get_x(), right->get_y());
411 top->reposition_window(top->get_x(), top->get_y());
412 mid->reposition_window(mid->get_x(), mid->get_y());
413 bottom->reposition_window(bottom->get_x(), bottom->get_y());
414 speed_title->reposition_window(speed_title->get_x(), speed_title->get_y());
415 speed->reposition_window(speed->get_x(), speed->get_y());
422 int TitleWindow::grab_event(XEvent *event)
424 switch( event->type ) {
426 if( !dragging ) break;
429 if( !dragging ) return 0;
433 if( dragging ) break;
437 MWindow *mwindow = client->server->mwindow;
438 CWindowGUI *cwindow_gui = mwindow->cwindow->gui;
439 CWindowCanvas *canvas = cwindow_gui->canvas;
440 float cursor_x = canvas->get_canvas()->get_relative_cursor_x();
441 float cursor_y = canvas->get_canvas()->get_relative_cursor_y();
442 canvas->canvas_to_output(mwindow->edl, 0, cursor_x, cursor_y);
443 int64_t position = client->get_source_position();
444 float projector_x, projector_y, projector_z;
445 Track *track = client->server->plugin->track;
446 int track_w = track->track_w, track_h = track->track_h;
447 track->automation->get_projector(
448 &projector_x, &projector_y, &projector_z,
449 position, PLAY_FORWARD);
450 projector_x += mwindow->edl->session->output_w / 2;
451 projector_y += mwindow->edl->session->output_h / 2;
452 cursor_x = (cursor_x - projector_x) / projector_z + track_w / 2;
453 cursor_y = (cursor_y - projector_y) / projector_z + track_h / 2;
454 int title_x = client->config.title_x, title_y = client->config.title_y;
455 int title_w = client->config.title_w, title_h = client->config.title_h;
456 if( !title_w ) title_w = track_w;
457 if( !title_h ) title_h = track_h;
458 int r = MIN(track_w, track_h)/100 + 2;
459 int x0 = title_x, x1 = title_x+(title_w+1)/2, x2 = title_x+title_w;
460 int y0 = title_y, y1 = title_y+(title_h+1)/2, y2 = title_y+title_h;
461 int drag_dx = 0, drag_dy = 0;
462 if( !dragging ) { // clockwise
463 if( abs(drag_dx = cursor_x-x0) < r && // x0,y0
464 abs(drag_dy = cursor_y-y0) < r ) dragging = 1;
465 else if( abs(drag_dx = cursor_x-x1) < r && // x1,y0
466 abs(drag_dy = cursor_y-y0) < r ) dragging = 2;
467 else if( abs(drag_dx = cursor_x-x2) < r && // x2,y0
468 abs(drag_dy = cursor_y-y0) < r ) dragging = 3;
469 else if( abs(drag_dx = cursor_x-x2) < r && // x2,y1
470 abs(drag_dy = cursor_y-y1) < r ) dragging = 4;
471 else if( abs(drag_dx = cursor_x-x2) < r && // x2,y2
472 abs(drag_dy = cursor_y-y2) < r ) dragging = 5;
473 else if( abs(drag_dx = cursor_x-x1) < r && // x1,y2
474 abs(drag_dy = cursor_y-y2) < r ) dragging = 6;
475 else if( abs(drag_dx = cursor_x-x0) < r && // x0,y2
476 abs(drag_dy = cursor_y-y2) < r ) dragging = 7;
477 else if( abs(drag_dx = cursor_x-x0) < r && // x0,y1
478 abs(drag_dy = cursor_y-y1) < r ) dragging = 8;
479 else if( abs(drag_dx = cursor_x-x1) < r && // x1,y1
480 abs(drag_dy = cursor_y-y1) < r ) dragging = 9;
485 int cur_x = cursor_x - drag_dx, dx = cur_x - x0;
486 int cur_y = cursor_y - drag_dy, dy = cur_y - y0;
487 if( !dx && !dy ) return 1;
488 int cur_w = title_w - dx; if( cur_w < 1 ) cur_w = 1;
489 int cur_h = title_h - dy; if( cur_h < 1 ) cur_h = 1;
490 this->title_x->update((int64_t)(client->config.title_x = cur_x));
491 this->title_y->update((int64_t)(client->config.title_y = cur_y));
492 this->title_w->update((int64_t)(client->config.title_w = cur_w));
493 this->title_h->update((int64_t)(client->config.title_h = cur_h));
496 int cur_y = cursor_y - drag_dy, dy = cur_y - y0;
498 int cur_h = title_h - dy; if( cur_h < 1 ) cur_h = 1;
499 this->title_y->update((int64_t)(client->config.title_y = cur_y));
500 this->title_h->update((int64_t)(client->config.title_h = cur_h));
503 int cur_x = cursor_x - drag_dx, dx = cur_x - x2;
504 int cur_y = cursor_y - drag_dy, dy = cur_y - y0;
505 int cur_w = title_w + dx; if( cur_w < 1 ) cur_w = 1;
506 int cur_h = title_h - dy; if( cur_h < 1 ) cur_h = 1;
507 this->title_w->update((int64_t)(client->config.title_w = cur_w));
508 this->title_y->update((int64_t)(client->config.title_y = cur_y));
509 this->title_h->update((int64_t)(client->config.title_h = cur_h));
512 int cur_x = cursor_x - drag_dx, dx = cur_x - x2;
514 int cur_w = title_w + dx; if( cur_w < 1 ) cur_w = 1;
515 this->title_w->update((int64_t)(client->config.title_w = cur_w));
518 int cur_x = cursor_x - drag_dx, dx = cur_x - x2;
519 int cur_y = cursor_y - drag_dy, dy = cur_y - y2;
520 int cur_w = title_w + dx; if( cur_w < 1 ) cur_w = 1;
521 int cur_h = title_h + dy; if( cur_h < 1 ) cur_h = 1;
522 this->title_w->update((int64_t)(client->config.title_w = cur_w));
523 this->title_h->update((int64_t)(client->config.title_h = cur_h));
526 int cur_y = cursor_y - drag_dy, dy = cur_y - y2;
527 if( client->config.title_h == cur_y ) return 1;
528 int cur_h = title_h + dy; if( cur_h < 1 ) cur_h = 1;
529 this->title_h->update((int64_t)(client->config.title_h = cur_h));
532 int cur_x = cursor_x - drag_dx, dx = cur_x - x0;
533 int cur_y = cursor_y - drag_dy, dy = cur_y - y2;
534 int cur_w = title_w - dx; if( cur_w < 1 ) cur_w = 1;
535 int cur_h = title_h + dy; if( cur_h < 1 ) cur_h = 1;
536 this->title_x->update((int64_t)(client->config.title_x = cur_x));
537 this->title_w->update((int64_t)(client->config.title_w = cur_w));
538 this->title_h->update((int64_t)(client->config.title_h = cur_h));
541 int cur_x = cursor_x - drag_dx, dx = cur_x - x0;
543 int cur_w = title_w - dx; if( cur_w < 1 ) cur_w = 1;
544 this->title_x->update((int64_t)(client->config.title_x = cur_x));
545 this->title_w->update((int64_t)(client->config.title_w = cur_w));
548 int cur_x = cursor_x - drag_dx, dx = cur_x - x1;
549 int cur_y = cursor_y - drag_dy, dy = cur_y - y1;
550 if( title_x == cur_x && title_y == cur_y ) return 1;
551 this->title_x->update((int64_t)(client->config.title_x += dx));
552 this->title_y->update((int64_t)(client->config.title_y += dy));
555 client->send_configure_change();
559 void TitleWindow::previous_font()
561 int current_font = font->get_number();
563 if( current_font < 0 ) current_font = fonts.total - 1;
565 if( current_font < 0 || current_font >= fonts.total ) return;
567 for( int i=0; i<fonts.total; ++i ) {
568 fonts.values[i]->set_selected(i == current_font);
571 font->update(fonts.values[current_font]->get_text());
572 strcpy(client->config.font, fonts.values[current_font]->get_text());
573 client->send_configure_change();
576 void TitleWindow::next_font()
578 int current_font = font->get_number();
580 if( current_font >= fonts.total ) current_font = 0;
582 if( current_font < 0 || current_font >= fonts.total ) return;
584 for( int i=0; i<fonts.total; ++i ) {
585 fonts.values[i]->set_selected(i == current_font);
588 font->update(fonts.values[current_font]->get_text());
589 strcpy(client->config.font, fonts.values[current_font]->get_text());
590 client->send_configure_change();
595 void TitleWindow::update_color()
597 //printf("TitleWindow::update_color %x\n", client->config.color);
598 set_color(client->config.color);
599 draw_box(color_x, color_y, COLOR_W, COLOR_H);
600 flash(color_x, color_y, COLOR_W, COLOR_H);
601 set_color(client->config.outline_color);
602 draw_box(outline_color_x, outline_color_y, COLOR_W, COLOR_H);
604 draw_rectangle(color_x, color_y, COLOR_W, COLOR_H);
605 draw_rectangle(outline_color_x, outline_color_y, COLOR_W, COLOR_H);
606 flash(outline_color_x, outline_color_y, COLOR_W, COLOR_H);
609 void TitleWindow::update_justification()
611 left->update(client->config.hjustification == JUSTIFY_LEFT);
612 center->update(client->config.hjustification == JUSTIFY_CENTER);
613 right->update(client->config.hjustification == JUSTIFY_RIGHT);
614 top->update(client->config.vjustification == JUSTIFY_TOP);
615 mid->update(client->config.vjustification == JUSTIFY_MID);
616 bottom->update(client->config.vjustification == JUSTIFY_BOTTOM);
619 void TitleWindow::update()
621 title_x->update((int64_t)client->config.title_x);
622 title_y->update((int64_t)client->config.title_y);
623 title_w->update((int64_t)client->config.title_w);
624 title_h->update((int64_t)client->config.title_h);
625 italic->update(client->config.style & BC_FONT_ITALIC);
626 bold->update(client->config.style & BC_FONT_BOLD);
627 size->update(client->config.size);
628 motion->update(TitleMain::motion_to_text(client->config.motion_strategy));
629 loop->update(client->config.loop);
630 dropshadow->update((int64_t)client->config.dropshadow);
631 fade_in->update((float)client->config.fade_in);
632 fade_out->update((float)client->config.fade_out);
633 font->update(client->config.font);
634 text->update(&client->config.wtext[0]);
635 speed->update(client->config.pixels_per_second);
636 outline->update((int64_t)client->config.outline_size);
638 stroker->update((int64_t)client->config.stroke_width);
640 timecode->update(client->config.timecode);
641 timecode_format->update(client->config.timecode_format);
642 background->update(client->config.background);
643 background_path->update(client->config.background_path);
644 loop_playback->update((int64_t)client->config.loop_playback);
646 char string[BCTEXTLEN];
647 for( int i=0; i<lengthof(timeunit_formats); ++i ) {
648 if( timeunit_formats[i] == client->config.timecode_format ) {
649 timecode_format->set_text(
650 Units::print_time_format(timeunit_formats[i], string));
654 update_justification();
659 TitleFontTumble::TitleFontTumble(TitleMain *client, TitleWindow *window, int x, int y)
662 this->client = client;
663 this->window = window;
665 int TitleFontTumble::handle_up_event()
667 window->previous_font();
671 int TitleFontTumble::handle_down_event()
679 TitleSizeTumble::TitleSizeTumble(TitleMain *client, TitleWindow *window, int x, int y)
682 this->client = client;
683 this->window = window;
686 int TitleSizeTumble::handle_up_event()
688 int current_index = -1;
689 int current_difference = -1;
690 for( int i=0; i<window->sizes.size(); ++i ) {
691 int size = atoi(window->sizes.get(i)->get_text());
692 if( current_index < 0 ||
693 abs(size - client->config.size) < current_difference ) {
695 current_difference = abs(size - client->config.size);
700 if( current_index >= window->sizes.size() ) current_index = 0;
703 client->config.size = atoi(window->sizes.get(current_index)->get_text());
704 window->size->update(client->config.size);
705 client->send_configure_change();
709 int TitleSizeTumble::handle_down_event()
711 int current_index = -1;
712 int current_difference = -1;
713 for( int i=0; i<window->sizes.size(); ++i ) {
714 int size = atoi(window->sizes.get(i)->get_text());
715 if( current_index < 0 ||
716 abs(size - client->config.size) < current_difference ) {
718 current_difference = abs(size - client->config.size);
723 if( current_index < 0 ) current_index = window->sizes.size() - 1;
726 client->config.size = atoi(window->sizes.get(current_index)->get_text());
727 window->size->update(client->config.size);
728 client->send_configure_change();
732 TitleBold::TitleBold(TitleMain *client, TitleWindow *window, int x, int y)
733 : BC_CheckBox(x, y, client->config.style & BC_FONT_BOLD, _("Bold"))
735 this->client = client;
736 this->window = window;
739 int TitleBold::handle_event()
741 client->config.style =
742 (client->config.style & ~BC_FONT_BOLD) |
743 (get_value() ? BC_FONT_BOLD : 0);
744 client->send_configure_change();
748 TitleItalic::TitleItalic(TitleMain *client, TitleWindow *window, int x, int y)
749 : BC_CheckBox(x, y, client->config.style & BC_FONT_ITALIC, _("Italic"))
751 this->client = client;
752 this->window = window;
754 int TitleItalic::handle_event()
756 client->config.style =
757 (client->config.style & ~BC_FONT_ITALIC) |
758 (get_value() ? BC_FONT_ITALIC : 0);
759 client->send_configure_change();
765 TitleSize::TitleSize(TitleMain *client, TitleWindow *window, int x, int y, char *text)
766 : BC_PopupTextBox(window,
774 this->client = client;
775 this->window = window;
777 TitleSize::~TitleSize()
780 int TitleSize::handle_event()
782 client->config.size = atol(get_text());
783 //printf("TitleSize::handle_event 1 %s\n", get_text());
784 client->send_configure_change();
787 void TitleSize::update(int size)
789 char string[BCTEXTLEN];
790 sprintf(string, "%d", size);
791 BC_PopupTextBox::update(string);
795 TitlePitch(TitleMain *client, TitleWindow *window, int x, int y, int *value)
796 : BC_TumbleTextBox(window, *value, 0, INT_MAX, x, y, 64)
798 this->client = client;
799 this->window = window;
808 int TitlePitch::handle_event()
810 *value = atol(get_text());
811 client->send_configure_change();
815 TitleColorButton::TitleColorButton(TitleMain *client, TitleWindow *window, int x, int y)
816 : BC_GenericButton(x, y, _("Color..."))
818 this->client = client;
819 this->window = window;
821 int TitleColorButton::handle_event()
823 window->color_thread->start_window(client->config.color,
824 client->config.alpha);
827 TitleOutlineColorButton::TitleOutlineColorButton(TitleMain *client, TitleWindow *window, int x, int y)
828 : BC_GenericButton(x, y, _("Outline color..."))
830 this->client = client;
831 this->window = window;
833 int TitleOutlineColorButton::handle_event()
835 window->outline_color_thread->start_window(client->config.outline_color,
836 client->config.outline_alpha);
841 TitleMotion::TitleMotion(TitleMain *client, TitleWindow *window, int x, int y)
842 : BC_PopupTextBox(window, &window->paths,
843 client->motion_to_text(client->config.motion_strategy),
846 this->client = client;
847 this->window = window;
849 int TitleMotion::handle_event()
851 client->config.motion_strategy = client->text_to_motion(get_text());
852 client->send_configure_change();
856 TitleLoop::TitleLoop(TitleMain *client, int x, int y)
857 : BC_CheckBox(x, y, client->config.loop, _("Loop"))
859 this->client = client;
861 int TitleLoop::handle_event()
863 client->config.loop = get_value();
864 client->send_configure_change();
867 TitleTimecode::TitleTimecode(TitleMain *client, int x, int y)
868 : BC_CheckBox(x, y, client->config.timecode, _("Stamp timecode"))
870 this->client = client;
872 int TitleTimecode::handle_event()
874 client->config.timecode = get_value();
875 client->send_configure_change();
879 TitleTimecodeFormat::TitleTimecodeFormat(TitleMain *client, int x, int y, const char *text)
880 : BC_PopupMenu(x, y, 100, text, 1)
882 this->client = client;
885 int TitleTimecodeFormat::handle_event()
887 client->config.timecode_format = Units::text_to_format(get_text());
888 client->send_configure_change();
892 void TitleTimecodeFormat::create_objects()
894 char string[BCTEXTLEN];
895 for( int i=0; i<lengthof(timeunit_formats); ++i ) {
896 add_item(new BC_MenuItem(
897 Units::print_time_format(timeunit_formats[i], string)));
902 int TitleTimecodeFormat::update(int timecode_format)
904 char string[BCTEXTLEN];
905 for( int i=0; i<lengthof(timeunit_formats); ++i ) {
906 if( timeunit_formats[i] == timecode_format ) {
907 set_text(Units::print_time_format(timeunit_formats[i], string));
914 TitleFade::TitleFade(TitleMain *client, TitleWindow *window,
915 double *value, int x, int y)
916 : BC_TextBox(x, y, 80, 1, (float)*value)
918 this->client = client;
919 this->window = window;
924 int TitleFade::handle_event()
926 *value = atof(get_text());
927 client->send_configure_change();
931 TitleFont::TitleFont(TitleMain *client, TitleWindow *window, int x, int y)
932 : BC_PopupTextBox(window, &window->fonts, client->config.font,
933 x, y, 200, 500, LISTBOX_ICON_LIST)
935 this->client = client;
936 this->window = window;
938 int TitleFont::handle_event()
940 strcpy(client->config.font, get_text());
941 client->send_configure_change();
945 TitleText::TitleText(TitleMain *client, TitleWindow *window,
946 int x, int y, int w, int h)
947 : BC_ScrollTextBox(window, x, y, w,
948 BC_TextBox::pixels_to_rows(window, MEDIUMFONT, h),
949 client->config.wtext, 8192)
951 this->client = client;
952 this->window = window;
953 //printf("TitleText::TitleText %s\n", client->config.text);
956 int TitleText::button_press_event()
958 if( get_buttonpress() == 3 ) {
959 window->cur_ibeam = get_ibeam_letter();
960 window->cur_popup->activate_menu();
963 return BC_ScrollTextBox::button_press_event();
966 int TitleText::handle_event()
968 int len = sizeof(client->config.wtext) / sizeof(wchar_t);
969 wcsncpy(client->config.wtext, get_wtext(), len);
970 client->config.wtext[len-1] = 0;
971 client->config.wlen = wcslen(client->config.wtext);
972 client->send_configure_change();
977 TitleDropShadow::TitleDropShadow(TitleMain *client, TitleWindow *window, int x, int y)
978 : BC_TumbleTextBox(window, (int64_t)client->config.dropshadow,
979 (int64_t)-1000, (int64_t)1000, x, y, 70)
981 this->client = client;
982 this->window = window;
984 int TitleDropShadow::handle_event()
986 client->config.dropshadow = atol(get_text());
987 client->send_configure_change();
992 TitleOutline::TitleOutline(TitleMain *client, TitleWindow *window, int x, int y)
993 : BC_TumbleTextBox(window, (int64_t)client->config.outline_size,
994 (int64_t)0, (int64_t)1000, x, y, 70)
996 this->client = client;
997 this->window = window;
999 int TitleOutline::handle_event()
1001 client->config.outline_size = atol(get_text());
1002 client->send_configure_change();
1006 TitleStroker::TitleStroker(TitleMain *client, TitleWindow *window, int x, int y)
1007 : BC_TumbleTextBox(window, (int64_t)client->config.stroke_width,
1008 (int64_t)0, (int64_t)1000, x, y, 70)
1010 this->client = client;
1011 this->window = window;
1013 int TitleStroker::handle_event()
1015 client->config.stroke_width = atol(get_text());
1016 if( client->config.stroke_width > 1 )
1017 client->config.style |= BC_FONT_OUTLINE;
1019 client->config.style &= ~BC_FONT_OUTLINE;
1020 client->send_configure_change();
1025 TitleX::TitleX(TitleMain *client, TitleWindow *window, int x, int y)
1026 : BC_TumbleTextBox(window, (int64_t)client->config.title_x,
1027 (int64_t)-32767, (int64_t)32767, x, y, 50)
1029 this->client = client;
1030 this->window = window;
1032 int TitleX::handle_event()
1034 client->config.title_x = atol(get_text());
1035 client->send_configure_change();
1039 TitleY::TitleY(TitleMain *client, TitleWindow *window, int x, int y)
1040 : BC_TumbleTextBox(window, (int64_t)client->config.title_y,
1041 (int64_t)-32767, (int64_t)32767, x, y, 50)
1043 this->client = client;
1044 this->window = window;
1046 int TitleY::handle_event()
1048 client->config.title_y = atol(get_text());
1049 client->send_configure_change();
1053 TitleW::TitleW(TitleMain *client, TitleWindow *window, int x, int y)
1054 : BC_TumbleTextBox(window, (int64_t)client->config.title_w,
1055 (int64_t)0, (int64_t)32767, x, y, 50)
1057 this->client = client;
1058 this->window = window;
1060 int TitleW::handle_event()
1062 client->config.title_w = atol(get_text());
1063 client->send_configure_change();
1067 TitleH::TitleH(TitleMain *client, TitleWindow *window, int x, int y)
1068 : BC_TumbleTextBox(window, (int64_t)client->config.title_h,
1069 (int64_t)0, (int64_t)32767, x, y, 50)
1071 this->client = client;
1072 this->window = window;
1074 int TitleH::handle_event()
1076 client->config.title_h = atol(get_text());
1077 client->send_configure_change();
1081 TitleSpeed::TitleSpeed(TitleMain *client, TitleWindow *window, int x, int y)
1082 : BC_TumbleTextBox(window, (float)client->config.pixels_per_second,
1083 (float)0, (float)1000, x, y, 100)
1085 this->client = client;
1091 int TitleSpeed::handle_event()
1093 client->config.pixels_per_second = atof(get_text());
1094 client->send_configure_change();
1099 TitleLeft::TitleLeft(TitleMain *client, TitleWindow *window, int x, int y)
1100 : BC_Radial(x, y, client->config.hjustification == JUSTIFY_LEFT, _("Left"))
1102 this->client = client;
1103 this->window = window;
1105 int TitleLeft::handle_event()
1107 client->config.hjustification = JUSTIFY_LEFT;
1108 window->update_justification();
1109 client->send_configure_change();
1113 TitleCenter::TitleCenter(TitleMain *client, TitleWindow *window, int x, int y)
1114 : BC_Radial(x, y, client->config.hjustification == JUSTIFY_CENTER, _("Center"))
1116 this->client = client;
1117 this->window = window;
1119 int TitleCenter::handle_event()
1121 client->config.hjustification = JUSTIFY_CENTER;
1122 window->update_justification();
1123 client->send_configure_change();
1127 TitleRight::TitleRight(TitleMain *client, TitleWindow *window, int x, int y)
1128 : BC_Radial(x, y, client->config.hjustification == JUSTIFY_RIGHT, _("Right"))
1130 this->client = client;
1131 this->window = window;
1133 int TitleRight::handle_event()
1135 client->config.hjustification = JUSTIFY_RIGHT;
1136 window->update_justification();
1137 client->send_configure_change();
1143 TitleTop::TitleTop(TitleMain *client, TitleWindow *window, int x, int y)
1144 : BC_Radial(x, y, client->config.vjustification == JUSTIFY_TOP, _("Top"))
1146 this->client = client;
1147 this->window = window;
1149 int TitleTop::handle_event()
1151 client->config.vjustification = JUSTIFY_TOP;
1152 window->update_justification();
1153 client->send_configure_change();
1157 TitleMid::TitleMid(TitleMain *client, TitleWindow *window, int x, int y)
1158 : BC_Radial(x, y, client->config.vjustification == JUSTIFY_MID, _("Mid"))
1160 this->client = client;
1161 this->window = window;
1163 int TitleMid::handle_event()
1165 client->config.vjustification = JUSTIFY_MID;
1166 window->update_justification();
1167 client->send_configure_change();
1171 TitleBottom::TitleBottom(TitleMain *client, TitleWindow *window, int x, int y)
1172 : BC_Radial(x, y, client->config.vjustification == JUSTIFY_BOTTOM, _("Bottom"))
1174 this->client = client;
1175 this->window = window;
1177 int TitleBottom::handle_event()
1179 client->config.vjustification = JUSTIFY_BOTTOM;
1180 window->update_justification();
1181 client->send_configure_change();
1187 TitleColorThread::TitleColorThread(TitleMain *client, TitleWindow *window, int is_outline)
1190 this->client = client;
1191 this->window = window;
1192 this->is_outline = is_outline;
1195 int TitleColorThread::handle_new_color(int output, int alpha)
1198 client->config.outline_color = output;
1199 client->config.outline_alpha = alpha;
1202 client->config.color = output;
1203 client->config.alpha = alpha;
1206 window->lock_window("TitleColorThread::handle_new_color");
1207 window->update_color();
1209 window->unlock_window();
1211 client->send_configure_change();
1215 TitleDrag::TitleDrag(TitleMain *client, TitleWindow *window, int x, int y)
1216 : BC_CheckBox(x, y, client->config.drag, _("Drag"))
1218 this->client = client;
1219 this->window = window;
1222 int TitleDrag::handle_event()
1224 int value = get_value();
1225 client->config.drag = value;
1227 window->grab(client->server->mwindow->cwindow->gui);
1229 window->ungrab(client->server->mwindow->cwindow->gui);
1230 client->send_configure_change();
1234 TitleBackground::TitleBackground(TitleMain *client, TitleWindow *window, int x, int y)
1235 : BC_CheckBox(x, y, client->config.background, _("Background:"))
1237 this->client = client;
1238 this->window = window;
1241 int TitleBackground::handle_event()
1243 client->config.background = get_value();
1244 client->send_configure_change();
1248 TitleBackgroundPath::TitleBackgroundPath(TitleMain *client, TitleWindow *window, int x, int y)
1249 : BC_TextBox(x, y, 240, 1, client->config.background_path)
1251 this->client = client;
1252 this->window = window;
1255 int TitleBackgroundPath::handle_event()
1257 strncpy(client->config.background_path, get_text(), sizeof(client->config.background_path));
1258 client->send_configure_change();
1262 TitleLoopPlayback::TitleLoopPlayback(TitleMain *client, int x, int y)
1263 : BC_CheckBox(x, y, client->config.loop_playback, _("Loop playback"))
1265 this->client = client;
1267 int TitleLoopPlayback::handle_event()
1269 client->config.loop_playback = get_value();
1270 client->send_configure_change();
1275 TitleCurPopup::TitleCurPopup(TitleMain *client, TitleWindow *window)
1276 : BC_PopupMenu(0, 0, 0, "", 0)
1278 this->client = client;
1279 this->window = window;
1281 int TitleCurPopup::handle_event()
1283 printf("cur popup\n");
1286 void TitleCurPopup::create_objects()
1288 TitleCurItem *cur_item;
1289 TitleCurSubMenu *sub_menu;
1290 add_item(cur_item = new TitleCurItem(this, "nudge"));
1291 cur_item->add_submenu(sub_menu = new TitleCurSubMenu(cur_item));
1292 sub_menu->add_submenuitem(new TitleCurSubMenuItem(sub_menu,"nudge"));
1293 sub_menu->add_submenuitem(new TitleCurSubMenuItem(sub_menu,"/nudge"));
1294 add_item(cur_item = new TitleCurItem(this, "color"));
1295 cur_item->add_submenu(sub_menu = new TitleCurSubMenu(cur_item));
1296 sub_menu->add_submenuitem(new TitleCurSubMenuItem(sub_menu,"color"));
1297 sub_menu->add_submenuitem(new TitleCurSubMenuItem(sub_menu,"/color"));
1298 add_item(cur_item = new TitleCurItem(this, "alpha"));
1299 cur_item->add_submenu(sub_menu = new TitleCurSubMenu(cur_item));
1300 sub_menu->add_submenuitem(new TitleCurSubMenuItem(sub_menu,"alpha"));
1301 sub_menu->add_submenuitem(new TitleCurSubMenuItem(sub_menu,"/alpha"));
1302 add_item(cur_item = new TitleCurItem(this, "font"));
1303 cur_item->add_submenu(sub_menu = new TitleCurSubMenu(cur_item));
1304 sub_menu->add_submenuitem(new TitleCurSubMenuItem(sub_menu,"font"));
1305 sub_menu->add_submenuitem(new TitleCurSubMenuItem(sub_menu,"/font"));
1306 add_item(cur_item = new TitleCurItem(this, "size"));
1307 cur_item->add_submenu(sub_menu = new TitleCurSubMenu(cur_item));
1308 sub_menu->add_submenuitem(new TitleCurSubMenuItem(sub_menu,"size"));
1309 sub_menu->add_submenuitem(new TitleCurSubMenuItem(sub_menu,"/size"));
1310 add_item(cur_item = new TitleCurItem(this, "bold"));
1311 cur_item->add_submenu(sub_menu = new TitleCurSubMenu(cur_item));
1312 sub_menu->add_submenuitem(new TitleCurSubMenuItem(sub_menu,"bold"));
1313 sub_menu->add_submenuitem(new TitleCurSubMenuItem(sub_menu,"/bold"));
1314 add_item(cur_item = new TitleCurItem(this, "italic"));
1315 cur_item->add_submenu(sub_menu = new TitleCurSubMenu(cur_item));
1316 sub_menu->add_submenuitem(new TitleCurSubMenuItem(sub_menu,"italic"));
1317 sub_menu->add_submenuitem(new TitleCurSubMenuItem(sub_menu,"/italic"));
1318 add_item(cur_item = new TitleCurItem(this, "caps"));
1319 cur_item->add_submenu(sub_menu = new TitleCurSubMenu(cur_item));
1320 sub_menu->add_submenuitem(new TitleCurSubMenuItem(sub_menu,"caps"));
1321 sub_menu->add_submenuitem(new TitleCurSubMenuItem(sub_menu,"/caps"));
1322 add_item(cur_item = new TitleCurItem(this, "ul"));
1323 cur_item->add_submenu(sub_menu = new TitleCurSubMenu(cur_item));
1324 sub_menu->add_submenuitem(new TitleCurSubMenuItem(sub_menu,"ul"));
1325 sub_menu->add_submenuitem(new TitleCurSubMenuItem(sub_menu,"/ul"));
1326 add_item(cur_item = new TitleCurItem(this, "blink"));
1327 cur_item->add_submenu(sub_menu = new TitleCurSubMenu(cur_item));
1328 sub_menu->add_submenuitem(new TitleCurSubMenuItem(sub_menu,"blink"));
1329 sub_menu->add_submenuitem(new TitleCurSubMenuItem(sub_menu,"/blink"));
1330 add_item(cur_item = new TitleCurItem(this, "fixed"));
1331 cur_item->add_submenu(sub_menu = new TitleCurSubMenu(cur_item));
1332 sub_menu->add_submenuitem(new TitleCurSubMenuItem(sub_menu,"fixed"));
1333 sub_menu->add_submenuitem(new TitleCurSubMenuItem(sub_menu,"/fixed"));
1334 add_item(cur_item = new TitleCurItem(this, "sup"));
1335 cur_item->add_submenu(sub_menu = new TitleCurSubMenu(cur_item));
1336 sub_menu->add_submenuitem(new TitleCurSubMenuItem(sub_menu,"sup"));
1337 sub_menu->add_submenuitem(new TitleCurSubMenuItem(sub_menu,"/sup"));
1340 TitleCurItem::TitleCurItem(TitleCurPopup *popup, const char *text)
1343 this->popup = popup;
1345 int TitleCurItem::handle_event()
1350 TitleCurSubMenu::TitleCurSubMenu(TitleCurItem *cur_item)
1352 this->cur_item = cur_item;
1354 TitleCurSubMenu::~TitleCurSubMenu()
1358 TitleCurSubMenuItem::TitleCurSubMenuItem(TitleCurSubMenu *submenu, const char *text)
1361 this->submenu = submenu;
1363 TitleCurSubMenuItem::~TitleCurSubMenuItem()
1366 int TitleCurSubMenuItem::handle_event()
1369 sprintf(id, "<%s>",get_text());
1370 int ilen = strlen(id);
1371 TitleMain *client = submenu->cur_item->popup->client;
1372 TitleWindow *window = submenu->cur_item->popup->window;
1374 wchar_t *wtext = client->config.wtext;
1375 int wsize = sizeof(client->config.wtext)-1;
1376 int wlen = client->config.wlen;
1377 int ibeam_letter = window->cur_ibeam;
1378 if( ibeam_letter < 0 ) ibeam_letter = 0;
1379 if( ibeam_letter > wlen ) ibeam_letter = wlen;
1381 for( int i=wlen-1, j=wlen+ilen-1; i>=ibeam_letter; --i,--j ) {
1382 if( j >= wsize ) continue;
1383 wtext[j] = wtext[i];
1385 for( int i=ibeam_letter, j=0; j<ilen; ++i,++j ) {
1386 if( i >= wsize ) break;
1390 if( (wlen+=ilen) > wsize ) wlen = wsize;
1392 window->text->update(wtext);
1393 client->config.wlen = wlen;
1394 client->send_configure_change();