rework proxy scaler, fix crop-gui coord, video_data tweak for proxy_format
[goodguy/cinelerra.git] / cinelerra-5.1 / cinelerra / cwindowtool.C
index 0b0b6069fa55c9697d286f2c4f4595b5853d0a4b..8ba0e3b2c7bbc85cbcdf1c7f5d452f15427a18a4 100644 (file)
@@ -360,7 +360,7 @@ CWindowCoord::CWindowCoord(CWindowToolGUI *gui, int x, int y, float value, int l
 }
 
 CWindowCoord::CWindowCoord(CWindowToolGUI *gui, int x, int y, int value)
- : BC_TumbleTextBox(gui, (int64_t)value, (int64_t)-65536, (int64_t)65536, x, y, 70, 3)
+ : BC_TumbleTextBox(gui, (int64_t)value, (int64_t)-65536, (int64_t)65536, x, y, 70)
 {
        this->gui = gui;
 }
@@ -372,20 +372,20 @@ int CWindowCoord::handle_event()
 }
 
 
-CWindowCropOK::CWindowCropOK(MWindow *mwindow, CWindowToolGUI *gui, int x, int y)
- : BC_GenericButton(x, y, _("Do it"))
+CWindowCropApply::CWindowCropApply(MWindow *mwindow, CWindowCropGUI *crop_gui, int x, int y)
+ : BC_GenericButton(x, y, _("Apply"))
 {
        this->mwindow = mwindow;
-       this->gui = gui;
+       this->crop_gui = crop_gui;
 }
-int CWindowCropOK::handle_event()
+int CWindowCropApply::handle_event()
 {
-       mwindow->crop_video();
+       mwindow->crop_video(crop_gui->crop_mode->mode);
        return 1;
 }
 
 
-int CWindowCropOK::keypress_event()
+int CWindowCropApply::keypress_event()
 {
        if(get_keypress() == 0xd)
        {
@@ -395,7 +395,50 @@ int CWindowCropOK::keypress_event()
        return 0;
 }
 
+const char *CWindowCropOpMode::crop_ops[] = {
+       N_("Reformat"),
+       N_("Resize"),
+       N_("Shrink"),
+};
 
+CWindowCropOpMode::CWindowCropOpMode(MWindow *mwindow, CWindowCropGUI *crop_gui,
+                       int mode, int x, int y)
+ : BC_PopupMenu(x, y, 140, _(crop_ops[mode]), 1)
+{
+        this->mwindow = mwindow;
+        this->crop_gui = crop_gui;
+        this->mode = mode;
+}
+CWindowCropOpMode::~CWindowCropOpMode()
+{
+}
+
+void CWindowCropOpMode::create_objects()
+{
+       for( int id=0,nid=sizeof(crop_ops)/sizeof(crop_ops[0]); id<nid; ++id )
+               add_item(new CWindowCropOpItem(this, _(crop_ops[id]), id));
+       handle_event();
+}
+
+int CWindowCropOpMode::handle_event()
+{
+       set_text(_(crop_ops[mode]));
+       return 1;
+}
+
+CWindowCropOpItem::CWindowCropOpItem(CWindowCropOpMode *popup, const char *text, int id)
+ : BC_MenuItem(text)
+{
+       this->popup = popup;
+       this->id = id;
+}
+
+int CWindowCropOpItem::handle_event()
+{
+       popup->set_text(get_text());
+       popup->mode = id;
+       return popup->handle_event();
+}
 
 
 
@@ -430,17 +473,19 @@ void CWindowCropGUI::create_objects()
        add_subwindow(title = new BC_Title(x, y, _("W:")));
        column1 = MAX(column1, title->get_w());
        y += pad;
-       add_subwindow(new CWindowCropOK(mwindow, thread->tool_gui, x, y));
+       add_subwindow(new CWindowCropApply(mwindow, this, x, y));
 
        x += column1 + 5;
        y = 10;
        x1 = new CWindowCoord(thread->tool_gui, x, y,
                mwindow->edl->session->crop_x1);
        x1->create_objects();
+       x1->set_boundaries((int64_t)0, (int64_t)65536);
        y += pad;
        width = new CWindowCoord(thread->tool_gui, x, y,
                mwindow->edl->session->crop_x2 - mwindow->edl->session->crop_x1);
        width->create_objects();
+       width->set_boundaries((int64_t)1, (int64_t)65536);
 
 
        x += x1->get_w() + 10;
@@ -458,10 +503,19 @@ void CWindowCropGUI::create_objects()
        y1 = new CWindowCoord(thread->tool_gui, x, y,
                mwindow->edl->session->crop_y1);
        y1->create_objects();
+       y1->set_boundaries((int64_t)0, (int64_t)65536);
        y += pad;
+
        height = new CWindowCoord(thread->tool_gui, x, y,
                mwindow->edl->session->crop_y2 - mwindow->edl->session->crop_y1);
        height->create_objects();
+       height->set_boundaries((int64_t)1, (int64_t)65536);
+       y += pad;
+
+       add_subwindow(crop_mode = new CWindowCropOpMode(mwindow, this,
+                               CROP_REFORMAT, x, y));
+       crop_mode->create_objects();
+
        unlock_window();
 }
 
@@ -2077,7 +2131,7 @@ int CWindowMaskDrawBoundary::handle_event()
 
 
 CWindowMaskFeather::CWindowMaskFeather(MWindow *mwindow, CWindowMaskGUI *gui, int x, int y)
- : BC_TumbleTextBox(gui, 0, -FEATHER_MAX, FEATHER_MAX, x, y, 64, 2)
+ : BC_TumbleTextBox(gui, 0, INT_MIN, INT_MAX, x, y, 64, 2)
 {
        this->mwindow = mwindow;
        this->gui = gui;
@@ -2124,7 +2178,6 @@ int CWindowMaskFeather::update_value(float v)
                        if( !gui->mask_enables[i]->get_value() ) continue;
                        SubMask *sub_mask = keyframe->get_submask(i);
                        float feather = sub_mask->feather + change;
-                       bclamp(feather, -FEATHER_MAX, FEATHER_MAX);
                        sub_mask->feather = feather;
                }
 #ifdef USE_KEYFRAME_SPANNING
@@ -2140,13 +2193,15 @@ int CWindowMaskFeather::update_value(float v)
 int CWindowMaskFeather::handle_event()
 {
        float v = atof(get_text());
+       if( fabsf(v) > MAX_FEATHER )
+               BC_TumbleTextBox::update((float)(v>=0 ? MAX_FEATHER : -MAX_FEATHER));
        gui->feather_slider->update(v);
        return gui->feather->update_value(v);
 }
 
 CWindowMaskFeatherSlider::CWindowMaskFeatherSlider(MWindow *mwindow,
                CWindowMaskGUI *gui, int x, int y, int w, float v)
- : BC_FSlider(x, y, 0, w, w, -FEATHER_MAX, FEATHER_MAX, v)
+ : BC_FSlider(x, y, 0, w, w, -FEATHER_MAX-5, FEATHER_MAX+5, v)
 {
        this->mwindow = mwindow;
        this->gui = gui;
@@ -2154,6 +2209,7 @@ CWindowMaskFeatherSlider::CWindowMaskFeatherSlider(MWindow *mwindow,
        timer = new Timer();
        stick = 0;
        last_v = 0;
+       max = FEATHER_MAX;
 }
 
 CWindowMaskFeatherSlider::~CWindowMaskFeatherSlider()
@@ -2163,32 +2219,46 @@ CWindowMaskFeatherSlider::~CWindowMaskFeatherSlider()
 
 int CWindowMaskFeatherSlider::handle_event()
 {
+       int sticky = 0;
        float v = get_value();
-       if( stick > 0 ) {
-               int64_t ms = timer->get_difference();
-               if( ms < 250 && --stick > 0 ) {
-                       if( get_value() == 0 ) return 1;
-                       update(v = 0);
+       if( fabsf(v) > MAX_FEATHER )
+               v = v>=0 ? MAX_FEATHER : -MAX_FEATHER;
+       if( stick && timer->get_difference() >= 250 )
+               stick = 0; // no events for .25 sec
+       if( stick && (last_v * (v-last_v)) < 0 )
+               stick = 0; // dv changed direction
+       if( stick ) {
+               if( --stick > 0 ) {
+                       timer->update();
+                       update(last_v);
+                       return 1;
                }
-               else {
-                       stick = 0;
-                       last_v = v;
+               if( last_v ) {
+                       max *= 1.25;
+                       if( max > MAX_FEATHER ) max = MAX_FEATHER;
+                       update(get_w(), v=last_v, -max-5, max+5);
+                       button_release_event();
                }
        }
-       else if( (last_v>=0 && v<0) || (last_v<0 && v>=0) ) {
-               stick = 16;
-               v = 0;
-       }
-       else
-               last_v = v;
-       timer->update();
+       else if( v > max ) { v = max;  sticky = 24; }
+       else if( v < -max ) { v = -max; sticky = 24; }
+       else if( v>=0 ? last_v<0 : last_v>=0 ) { v = 0;  sticky = 16; }
+       if( sticky ) { update(v);  stick = sticky;  timer->update(); }
+       last_v = v;
        gui->feather->BC_TumbleTextBox::update(v);
        return gui->feather->update_value(v);
 }
 
 int CWindowMaskFeatherSlider::update(float v)
 {
-       return BC_FSlider::update(v);
+       float vv = fabsf(v);
+       if( vv > MAX_FEATHER ) vv = MAX_FEATHER;
+       while( max < vv ) max *= 1.25;
+       return update(get_w(), v, -max-5, max+5);
+}
+int CWindowMaskFeatherSlider::update(int r, float v, float mn, float mx)
+{
+       return BC_FSlider::update(r, v, mn, mx);
 }
 
 CWindowMaskFade::CWindowMaskFade(MWindow *mwindow, CWindowMaskGUI *gui, int x, int y)