rework edge plugin, add crikey plugin, text tumbler tweak, eyedropper coords
[goodguy/history.git] / cinelerra-5.1 / plugins / crikey / crikeywindow.C
diff --git a/cinelerra-5.1/plugins/crikey/crikeywindow.C b/cinelerra-5.1/plugins/crikey/crikeywindow.C
new file mode 100644 (file)
index 0000000..f8fcd1f
--- /dev/null
@@ -0,0 +1,360 @@
+/*
+ * CINELERRA
+ * Copyright (C) 2014 Adam Williams <broadcast at earthling dot net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#include "automation.h"
+#include "bcdisplayinfo.h"
+#include "clip.h"
+#include "crikey.h"
+#include "crikeywindow.h"
+#include "cwindow.h"
+#include "cwindowgui.h"
+#include "edl.h"
+#include "edlsession.h"
+#include "language.h"
+#include "mwindow.h"
+#include "plugin.h"
+#include "pluginserver.h"
+#include "theme.h"
+#include "track.h"
+
+#define COLOR_W 50
+#define COLOR_H 30
+
+CriKeyNum::CriKeyNum(CriKeyWindow *gui, int x, int y, float &output)
+ : BC_TumbleTextBox(gui, output, -32767.0f, 32767.0f, x, y, 80)
+{
+       this->gui = gui;
+       this->output = &output;
+       set_increment(1);
+       set_precision(1);
+}
+
+CriKeyNum::~CriKeyNum()
+{
+}
+
+int CriKeyNum::handle_event()
+{
+       *output = atof(get_text());
+       gui->plugin->send_configure_change();
+       return 1;
+}
+
+int CriKeyDrawModeItem::handle_event()
+{
+       ((CriKeyDrawMode *)get_popup_menu())->update(id);
+       return 1;
+}
+CriKeyDrawMode::CriKeyDrawMode(CriKeyWindow *gui, int x, int y)
+ : BC_PopupMenu(x, y, 100, "", 1)
+{
+       this->gui = gui;
+       draw_modes[DRAW_ALPHA]     = _("Alpha");
+       draw_modes[DRAW_EDGE]      = _("Edge");
+       draw_modes[DRAW_MASK]      = _("Mask");
+       mode = -1;
+}
+void CriKeyDrawMode::create_objects()
+{
+       for( int i=0; i<DRAW_MODES; ++i )
+               add_item(new CriKeyDrawModeItem(draw_modes[i], i));
+       update(gui->plugin->config.draw_mode);
+}
+void CriKeyDrawMode::update(int mode)
+{
+       if( this->mode == mode ) return;
+       this->mode = mode;
+       set_text(draw_modes[mode]);
+       gui->plugin->config.draw_mode = mode;
+       gui->plugin->send_configure_change();
+}
+
+int CriKeyKeyModeItem::handle_event()
+{
+       ((CriKeyKeyMode *)get_popup_menu())->update(id);
+       return 1;
+}
+CriKeyKeyMode::CriKeyKeyMode(CriKeyWindow *gui, int x, int y)
+ : BC_PopupMenu(x, y, 100, "", 1)
+{
+       this->gui = gui;
+       key_modes[KEY_SEARCH]      = _("Search");
+       key_modes[KEY_SEARCH_ALL]  = _("Search all");
+       key_modes[KEY_POINT]       = _("Point");
+       this->mode = -1;
+}
+void CriKeyKeyMode::create_objects()
+{
+       for( int i=0; i<KEY_MODES; ++i )
+               add_item(new CriKeyKeyModeItem(key_modes[i], i));
+       update(gui->plugin->config.key_mode);
+}
+void CriKeyKeyMode::update(int mode)
+{
+       if( this->mode == mode ) return;
+       this->mode = mode;
+       set_text(key_modes[mode]);
+       gui->draw_key(mode);
+       gui->plugin->send_configure_change();
+}
+
+CriKeyColorButton::CriKeyColorButton(CriKeyWindow *gui, int x, int y)
+ : BC_GenericButton(x, y, _("Color"))
+{
+       this->gui = gui;
+}
+int CriKeyColorButton::handle_event()
+{
+       gui->start_color_thread();
+       return 1;
+}
+
+CriKeyColorPicker::CriKeyColorPicker(CriKeyColorButton *color_button)
+ : ColorPicker(0, _("Color"))
+{
+       this->color_button = color_button;
+}
+
+void CriKeyColorPicker::start(int color)
+{
+       start_window(this->color = color, 0, 1);
+}
+
+void CriKeyColorPicker::handle_done_event(int result)
+{
+       if( !result ) {
+               CriKeyWindow *gui = color_button->gui;
+               gui->lock_window("CriKeyColorPicker::handle_done_event");
+               gui->update_color(color);
+               gui->plugin->config.color = color;
+               gui->plugin->send_configure_change();
+               gui->unlock_window();
+       }
+}
+
+int CriKeyColorPicker::handle_new_color(int color, int alpha)
+{
+       CriKeyWindow *gui = color_button->gui;
+       gui->lock_window("CriKeyColorPicker::handle_new_color");
+       gui->update_color(this->color = color);
+       gui->flush();
+       gui->unlock_window();
+       return 1;
+}
+
+
+void CriKeyWindow::start_color_thread()
+{
+       unlock_window();
+       delete color_picker;
+       color_picker = new CriKeyColorPicker(color_button);
+       color_picker->start(plugin->config.color);
+       lock_window("CriKeyWindow::start_color_thread");
+}
+
+
+CriKeyWindow::CriKeyWindow(CriKey *plugin)
+ : PluginClientWindow(plugin, 320, 220, 320, 220, 0)
+{
+       this->plugin = plugin;
+       this->color_button = 0;
+       this->color_picker = 0;
+       this->title_x = 0;  this->point_x = 0;
+       this->title_y = 0;  this->point_y = 0;
+       this->dragging = 0; this->drag = 0;
+}
+
+CriKeyWindow::~CriKeyWindow()
+{
+       delete color_picker;
+}
+
+void CriKeyWindow::create_objects()
+{
+       int x = 10, y = 10;
+       int margin = plugin->get_theme()->widget_border;
+       BC_Title *title;
+       add_subwindow(title = new BC_Title(x, y, _("Threshold:")));
+       y += title->get_h() + margin;
+       add_subwindow(threshold = new CriKeyThreshold(this, x, y, get_w() - x * 2));
+       y += threshold->get_h() + margin;
+       add_subwindow(title = new BC_Title(x, y+5, _("Draw mode:")));
+       int x1 = x + title->get_w() + 10 + margin;
+       add_subwindow(draw_mode = new CriKeyDrawMode(this, x1, y));
+       draw_mode->create_objects();
+       y += draw_mode->get_h() + margin;
+       add_subwindow(title = new BC_Title(x, y+5, _("Key mode:")));
+       add_subwindow(key_mode = new CriKeyKeyMode(this, x1, y));
+       y += key_mode->get_h() + margin;
+       key_x = x + 10 + margin;  key_y = y + 10 + margin;
+       key_mode->create_objects();
+
+        if( plugin->config.drag )
+                grab(plugin->server->mwindow->cwindow->gui);
+       show_window(1);
+}
+
+int CriKeyWindow::grab_event(XEvent *event)
+{
+       if( key_mode->mode != KEY_POINT ) return 0;
+
+       switch( event->type ) {
+       case ButtonPress:
+               if( dragging ) return 0;
+               dragging = 1;
+               break;
+       case ButtonRelease:
+               if( !dragging ) return 0;
+               dragging = 0;
+               return 1;
+       case MotionNotify:
+               if( dragging ) break;
+       default:
+               return 0;
+       }
+       MWindow *mwindow = plugin->server->mwindow;
+       CWindowGUI *cwindow_gui = mwindow->cwindow->gui;
+       CWindowCanvas *canvas = cwindow_gui->canvas;
+       float cursor_x = canvas->get_canvas()->get_relative_cursor_x();
+       float cursor_y = canvas->get_canvas()->get_relative_cursor_y();
+       canvas->canvas_to_output(mwindow->edl, 0, cursor_x, cursor_y);
+       int64_t position = plugin->get_source_position();
+       float projector_x, projector_y, projector_z;
+       Track *track = plugin->server->plugin->track;
+       int track_w = track->track_w, track_h = track->track_h;
+       track->automation->get_projector(
+               &projector_x, &projector_y, &projector_z,
+               position, PLAY_FORWARD);
+       projector_x += mwindow->edl->session->output_w / 2;
+       projector_y += mwindow->edl->session->output_h / 2;
+       float output_x = (cursor_x - projector_x) / projector_z + track_w / 2;
+       float output_y = (cursor_y - projector_y) / projector_z + track_h / 2;
+       point_x->update((int64_t)(plugin->config.point_x = output_x));
+       point_y->update((int64_t)(plugin->config.point_y = output_y));
+       plugin->send_configure_change();
+       return 1;
+}
+
+void CriKeyWindow::done_event(int result)
+{
+        ungrab(client->server->mwindow->cwindow->gui);
+       if( color_picker ) color_picker->close_window();
+}
+
+void CriKeyWindow::draw_key(int mode)
+{
+       int margin = plugin->get_theme()->widget_border;
+       int x = key_x, y = key_y;
+       delete color_picker;  color_picker = 0;
+       delete color_button;  color_button = 0;
+       delete title_x;  title_x = 0;
+       delete point_x;  point_x = 0;
+       delete title_y;  title_y = 0;
+       delete point_y;  point_y = 0;
+       delete drag;     drag = 0;
+
+       clear_box(x,y, get_w()-x,get_h()-y);
+       flash(x,y, get_w()-x,get_h()-y);
+
+       switch( mode ) {
+       case KEY_SEARCH:
+       case KEY_SEARCH_ALL:
+               add_subwindow(color_button = new CriKeyColorButton(this, x, y));
+               x += color_button->get_w() + margin;
+               color_x = x;  color_y = y;
+               update_color(plugin->config.color);
+               break;
+       case KEY_POINT:
+               add_subwindow(title_x = new BC_Title(x, y, _("X:")));
+               int x1 = x + title_x->get_w() + margin, y1 = y;
+               point_x = new CriKeyNum(this, x1, y, plugin->config.point_x);
+               point_x->create_objects();
+               y += point_x->get_h() + margin;
+               add_subwindow(title_y = new BC_Title(x, y, _("Y:")));
+               point_y = new CriKeyNum(this, x1, y, plugin->config.point_y);
+               point_y->create_objects();
+               x1 += point_x->get_w() + margin;
+               add_subwindow(drag = new CriKeyDrag(this, x1, y1));
+               break;
+       }
+       plugin->config.key_mode = mode;
+       show_window(1);
+}
+
+void CriKeyWindow::update_color(int color)
+{
+       set_color(color);
+       draw_box(color_x, color_y, COLOR_W, COLOR_H);
+       set_color(BLACK);
+       draw_rectangle(color_x, color_y, COLOR_W, COLOR_H);
+       flash(color_x, color_y, COLOR_W, COLOR_H);
+}
+
+void CriKeyWindow::update_gui()
+{
+       threshold->update(plugin->config.threshold);
+       draw_mode->update(plugin->config.draw_mode);
+       key_mode->update(plugin->config.key_mode);
+       switch( plugin->config.key_mode ) {
+       case KEY_POINT:
+               point_x->update(plugin->config.point_x);
+               point_y->update(plugin->config.point_y);
+               break;
+       case KEY_SEARCH:
+       case KEY_SEARCH_ALL:
+               update_color(plugin->config.color);
+               break;
+       }
+}
+
+
+CriKeyThreshold::CriKeyThreshold(CriKeyWindow *gui, int x, int y, int w)
+ : BC_FSlider(x, y, 0, w, w, 0, 1, gui->plugin->config.threshold, 0)
+{
+       this->gui = gui;
+       set_precision(0.005);
+}
+
+int CriKeyThreshold::handle_event()
+{
+       gui->plugin->config.threshold = get_value();
+       gui->plugin->send_configure_change();
+       return 1;
+}
+
+
+CriKeyDrag::CriKeyDrag(CriKeyWindow *gui, int x, int y)
+ : BC_CheckBox(x, y, gui->plugin->config.drag, _("Drag"))
+{
+       this->gui = gui;
+}
+int CriKeyDrag::handle_event()
+{
+        int value = get_value();
+        gui->plugin->config.drag = value;
+       CWindowGUI *cwindow_gui = gui->plugin->server->mwindow->cwindow->gui;
+        if( value )
+                gui->grab(cwindow_gui);
+        else
+                gui->ungrab(cwindow_gui);
+        gui->plugin->send_configure_change();
+        return 1;
+}
+