int CWindowMaskOnTrack::handle_event()
{
- int k = get_number();
+ CWindowMaskItem *track_item = 0;
+ int k = get_number(), track_id = -1;
//printf("selected %d = %s\n", k, k<0 ? "()" : track_items[k]->get_text());
- CWindowMaskItem *track_item = k >= 0 ? (CWindowMaskItem *)track_items[k] : 0;
- Track *track = track_item ? mwindow->edl->tracks->get_track_by_id(track_item->id) : 0;
- int track_id = track_item && track && track->record ? track_item->id : -1;
+ if( k >= 0 ) {
+ track_item = (CWindowMaskItem *)track_items[k];
+ Track *track = track_item ? mwindow->edl->tracks->get_track_by_id(track_item->id) : 0;
+ if( track && track->record ) track_id = track->get_id();
+ }
+ else
+ track_id = mwindow->cwindow->mask_track_id;
set_back_color(track_id >= 0 ?
gui->get_resources()->text_background :
gui->get_resources()->text_background_disarmed);
- gui->mask_on_track->update(track_item ? track_item->get_text() : "");
+ if( mwindow->cwindow->mask_track_id != track_id )
+ gui->mask_on_track->update(track_item ? track_item->get_text() : "");
mwindow->cwindow->mask_track_id = track_id;
mwindow->edl->local_session->solo_track_id = -1;
gui->mask_solo_track->update(0);
+ gui->update();
gui->update_preview(1);
return 1;
}
void CWindowMaskOnTrack::update_items()
{
track_items.remove_all_objects();
+ int high_color = gui->get_resources()->button_highlighted;
for( Track *track=mwindow->edl->tracks->first; track; track=track->next ) {
if( track->data_type != TRACK_VIDEO ) continue;
- int color = track->record ? -1 : RED;
+ MaskAutos *mask_autos = (MaskAutos*)track->automation->autos[AUTOMATION_MASK];
+ int color = !track->record ? RED : mask_autos->first ? high_color : -1;
+ MaskAuto *mask_auto = (MaskAuto*)mask_autos->default_auto;
+ for( int i=0; color<0 && i<mask_auto->masks.size(); ++i )
+ if( mask_auto->masks[i]->points.size() > 0 ) color = high_color;
track_items.append(new CWindowMaskItem(track->title, track->get_id(), color));
}
update_list(&track_items);
mwindow->cwindow->mask_track_id = track_item ? track_item->id : -1;
mwindow->edl->local_session->solo_track_id = -1;
gui->mask_solo_track->update(0);
+ gui->update();
gui->update_preview(1);
return 1;
}
{
this->mwindow = mwindow;
this->gui = gui;
- set_tooltip(_("Show mask"));
+ set_tooltip(_("Show/Hide mask"));
}
int CWindowMaskUnclear::handle_event()
return 1;
}
+CWindowMaskHelp::CWindowMaskHelp(MWindow *mwindow, CWindowMaskGUI *gui, int x, int y)
+ : BC_CheckBox(x, y, 0, _("Help"))
+{
+ this->mwindow = mwindow;
+ this->gui = gui;
+ set_tooltip(_("Show help text"));
+}
+
+CWindowMaskHelp::~CWindowMaskHelp()
+{
+}
+
+int CWindowMaskHelp::handle_event()
+{
+ gui->helped = get_value();
+ gui->resize_window(gui->get_w(),
+ gui->helped ? gui->help_h : gui->help_y);
+ gui->update();
+ return 1;
+}
+
CWindowMaskDrawMarkers::CWindowMaskDrawMarkers(MWindow *mwindow, CWindowMaskGUI *gui, int x, int y)
: BC_CheckBox(x, y, gui->markers, _("Markers"))
{
return 1;
}
+CWindowMaskGangFocus::CWindowMaskGangFocus(MWindow *mwindow,
+ CWindowMaskGUI *gui, int x, int y)
+ : BC_Toggle(x, y, mwindow->theme->get_image_set("gangpatch_data"), 0)
+{
+ this->mwindow = mwindow;
+ this->gui = gui;
+ set_tooltip(_("Gang rotate/scale/translate"));
+}
+
+CWindowMaskGangFocus::~CWindowMaskGangFocus()
+{
+}
+
+int CWindowMaskGangFocus::handle_event()
+{
+ return 1;
+}
+
+
+CWindowMaskSmooth::CWindowMaskSmooth(MWindow *mwindow,
+ CWindowMaskGUI *gui, int x, int y)
+ : BC_GenericButton(x, y, _("Smooth"))
+{
+ this->mwindow = mwindow;
+ this->gui = gui;
+ set_tooltip(_("Smooth boundary"));
+}
+int CWindowMaskSmooth::handle_event()
+{
+ return gui->smooth_mask(0);
+}
+
+CWindowMaskGangSmooth::CWindowMaskGangSmooth(MWindow *mwindow,
+ CWindowMaskGUI *gui, int x, int y)
+ : BC_Button(x, y, mwindow->theme->get_image_set("gangpatch_data"))
+{
+ this->mwindow = mwindow;
+ this->gui = gui;
+ set_tooltip(_("Smooth All"));
+}
+int CWindowMaskGangSmooth::handle_event()
+{
+ return gui->smooth_mask(1);
+}
+
CWindowMaskBeforePlugins::CWindowMaskBeforePlugins(CWindowMaskGUI *gui, int x, int y)
: BC_CheckBox(x,
y,
if( track ) {
mwindow->undo->update_undo_before(_("del masks"), 0);
((MaskAutos*)track->automation->autos[AUTOMATION_MASK])->clear_all();
- gui->update();
- gui->update_preview();
mwindow->undo->update_undo_after(_("del masks"), LOAD_AUTOMATION);
}
+ gui->update();
+ gui->update_preview(1);
return 1;
}
CWindowMaskGUI::CWindowMaskGUI(MWindow *mwindow, CWindowTool *thread)
: CWindowToolGUI(mwindow, thread,
- _(PROGRAM_NAME ": Mask"), 400, 660)
+ _(PROGRAM_NAME ": Mask"), 430, 680)
{
this->mwindow = mwindow;
this->thread = thread;
add_subwindow(title = new BC_Title(x, y, _("Select:")));
int bw = 0, bh = 0;
BC_CheckBox::calculate_extents(this, &bw, &bh);
- int bdx = bw + margin;
+ int bdx = bw + 2*margin;
x2 = x1;
for( int i=0; i<SUBMASKS; x2+=bdx, ++i ) {
int v = i == mwindow->edl->session->cwindow_mask ? 1 : 0;
y += title_bar->get_h() + margin;
add_subwindow(title = new BC_Title(x, y, "X:"));
- focus_x = new CWindowCoord(this, x1, y, (float)0.0);
+ float cx = mwindow->edl->session->output_w / 2.f;
+ focus_x = new CWindowCoord(this, x1, y, cx);
focus_x->create_objects();
add_subwindow(focus = new CWindowMaskFocus(mwindow, this, del_x, y));
+ add_subwindow(gang_focus = new CWindowMaskGangFocus(mwindow, this, clr_x, y));
y += focus_x->get_h() + margin;
add_subwindow(title = new BC_Title(x, y, "Y:"));
- focus_y = new CWindowCoord(this, x1, y, (float)0.0);
+ float cy = mwindow->edl->session->output_h / 2.f;
+ focus_y = new CWindowCoord(this, x1, y, cy);
focus_y->create_objects();
+ add_subwindow(smooth = new CWindowMaskSmooth(mwindow, this, del_x, y));
+ add_subwindow(gang_smooth = new CWindowMaskGangSmooth(mwindow, this, clr_x, y));
y += focus_x->get_h() + 2*margin;
BC_Bar *bar;
add_subwindow(bar = new BC_Bar(x, y, get_w()-2*x));
add_subwindow(this->apply_before_plugins = new CWindowMaskBeforePlugins(this, 10, y));
y += this->apply_before_plugins->get_h();
add_subwindow(this->disable_opengl_masking = new CWindowDisableOpenGLMasking(this, 10, y));
- y += this->disable_opengl_masking->get_h() + margin;
- add_subwindow(bar = new BC_Bar(x, y, get_w()-2*x));
- y += bar->get_h() + margin;
-
- y += margin;
+ add_subwindow(help = new CWindowMaskHelp(mwindow, this, del_x, y));
+ y += this->disable_opengl_masking->get_h() + 2*margin;
+ help_y = y;
+ add_subwindow(new BC_Bar(x, y, get_w()-2*x));
+ y += bar->get_h() + 2*margin;
add_subwindow(title = new BC_Title(x, y, _(
"Shift+LMB: move an end point\n"
"Ctrl+LMB: move a control point\n"
"Alt+LMB: to drag translate the mask\n"
- "Shift+Key Delete to delete the point\n"
- "Wheel Up/Dn: rotate around pointer\n"
- "Shift+Wheel Up/Dn: scale around pointer\n"
- "Shift+MMB: Toggle focus center at pointer")));
+ "Shift+Key Delete: to delete the point\n"
+ "Shift+MMB: Set Pivot Point at pointer\n"
+ "Wheel: rotate around Pivot Point\n"
+ "Shift+Wheel: scale around Pivot Point\n"
+ "Ctrl+Wheel: rotate/scale around pointer")));
+ help_h = y + title->get_h() + 2*margin;
update();
+ resize_window(get_w(), help_y);
unlock_window();
}
void CWindowMaskGUI::done_event()
{
+ if( mwindow->in_destructor ) return;
int &solo_track_id = mwindow->edl->local_session->solo_track_id;
if( solo_track_id >= 0 ) {
solo_track_id = -1;
MaskPoint *point;
//printf("CWindowMaskGUI::update 1\n");
get_keyframe(track, autos, keyframe, mask, point, 0);
+ mwindow->cwindow->mask_track_id = track ? track->get_id() : -1;
mask_on_track->set_back_color(!track || track->record ?
get_resources()->text_background :
get_resources()->text_background_disarmed);
void CWindowMaskGUI::set_focused(int v, float cx, float cy)
{
+ CWindowGUI *cgui = mwindow->cwindow->gui;
+ cgui->unlock_window();
+ lock_window("CWindowMaskGUI::set_focused");
+ if( focused != v )
+ focus->update(focused = v);
focus_x->update(cx);
focus_y->update(cy);
- focus->update(focused = v);
+ unlock_window();
+ cgui->lock_window("CWindowCanvas::set_focused");
}
void CWindowMaskGUI::update_buttons(MaskAuto *keyframe, int k)
}
}
+int CWindowMaskGUI::smooth_mask(int gang)
+{
+ MaskAutos *autos;
+ MaskAuto *keyframe;
+ Track *track;
+ MaskPoint *point;
+ SubMask *mask;
+#ifdef USE_KEYFRAME_SPANNING
+ int create_it = 0;
+#else
+ int create_it = 1;
+#endif
+
+ mwindow->undo->update_undo_before(_("mask smooth"), this);
+
+// Get existing keyframe
+ get_keyframe(track, autos, keyframe,
+ mask, point, create_it);
+ if( track ) {
+#ifdef USE_KEYFRAME_SPANNING
+ MaskAuto temp_keyframe(mwindow->edl, autos);
+ temp_keyframe.copy_data(keyframe);
+ keyframe = &temp_keyframe;
+#endif
+ int k = mwindow->edl->session->cwindow_mask;
+ int n = gang ? keyframe->masks.size() : k+1;
+ for( int j=gang? 0 : k; j<n; ++j ) {
+ SubMask *sub_mask = keyframe->get_submask(j);
+ ArrayList<MaskPoint*> &points = sub_mask->points;
+ int psz = points.size();
+ if( psz < 3 ) continue;
+ for( int i=0; i<psz; ++i ) {
+ int i0 = i-1, i1 = i+1;
+ if( i0 < 0 ) i0 = psz-1;
+ if( i1 >= psz ) i1 = 0;
+ MaskPoint *p0 = points[i0];
+ MaskPoint *p = points[i];
+ MaskPoint *p1 = points[i1];
+ float dx = p1->x - p0->x, dy = p1->y - p0->y;
+ p->control_x1 = -dx/4; p->control_y1 = -dy/4;
+ p->control_x2 = dx/4; p->control_y2 = dy/4;
+ }
+ }
+#ifdef USE_KEYFRAME_SPANNING
+ autos->update_parameter(keyframe);
+#endif
+ update_preview();
+ }
+
+ mwindow->undo->update_undo_after(_("mask smooth"), LOAD_AUTOMATION);
+ return 1;
+}
+
CWindowRulerGUI::CWindowRulerGUI(MWindow *mwindow, CWindowTool *thread)
: CWindowToolGUI(mwindow, thread, _(PROGRAM_NAME ": Ruler"), 320, 240)
{