AssetCopyDialog::AssetCopyDialog(AssetListCopy *copy)
: BC_DialogThread()
{
- this->copy = copy;
+ this->copy = copy;
copy_window = 0;
}
void AssetCopyDialog::start(char *text, int x, int y)
{
- close_window();
- this->text = text;
+ close_window();
+ this->text = text;
this->x = x; this->y = y;
BC_DialogThread::start();
}
AssetCopyDialog::~AssetCopyDialog()
{
- close_window();
+ close_window();
}
BC_Window* AssetCopyDialog::new_gui()
{
- BC_DisplayInfo display_info;
+ BC_DisplayInfo display_info;
- copy_window = new AssetCopyWindow(this);
- copy_window->create_objects();
- return copy_window;
+ copy_window = new AssetCopyWindow(this);
+ copy_window->create_objects();
+ return copy_window;
}
void AssetCopyDialog::handle_done_event(int result)
void AssetCopyDialog::handle_close_event(int result)
{
- copy_window = 0;
+ copy_window = 0;
}
AssetCopyWindow::AssetCopyWindow(AssetCopyDialog *copy_dialog)
: BC_Window(_(PROGRAM_NAME ": Copy File List"),
copy_dialog->x - 500/2, copy_dialog->y - 200/2,
- 500, 200, 500, 200, 0, 0, 1)
+ 500, 200, 500, 200, 1, 0, 1)
{
- this->copy_dialog = copy_dialog;
+ this->copy_dialog = copy_dialog;
}
AssetCopyWindow::~AssetCopyWindow()
file_list->create_objects();
add_subwindow(new BC_OKButton(this));
- show_window();
+ show_window();
}
+int AssetCopyWindow::resize_event(int w, int h)
+{
+ int fx = file_list->get_x(), fy = file_list->get_y(), pad = 5;
+ int text_w = w - fx - 10;
+ int text_h = h - fy - BC_OKButton::calculate_h() - pad;
+ int text_rows = BC_TextBox::pixels_to_rows(this, MEDIUMFONT, text_h);
+ file_list->reposition_window(fx, fy, text_w, text_rows);
+ return 0;
+}
AssetListPaste::AssetListPaste(MWindow *mwindow, AWindowGUI *gui)
: BC_MenuItem(_("Paste file list"))
AssetPasteDialog::AssetPasteDialog(AssetListPaste *paste)
: BC_DialogThread()
{
- this->paste = paste;
+ this->paste = paste;
paste_window = 0;
}
AssetPasteDialog::~AssetPasteDialog()
{
- close_window();
+ close_window();
}
BC_Window* AssetPasteDialog::new_gui()
{
- paste_window = new AssetPasteWindow(this);
- paste_window->create_objects();
- return paste_window;
+ paste_window = new AssetPasteWindow(this);
+ paste_window->create_objects();
+ return paste_window;
}
void AssetPasteDialog::handle_done_event(int result)
result = mwindow->load_filenames(&path_list, LOADMODE_RESOURCESONLY, 0);
mwindow->gui->unlock_window();
path_list.remove_all_objects();
- mwindow->save_backup();
- mwindow->restart_brender();
+ mwindow->save_backup();
+ mwindow->restart_brender();
mwindow->session->changes_made = 1;
}
void AssetPasteDialog::handle_close_event(int result)
{
- paste_window = 0;
+ paste_window = 0;
}
void AssetPasteDialog::start(int x, int y)
AssetPasteWindow::AssetPasteWindow(AssetPasteDialog *paste_dialog)
: BC_Window(_(PROGRAM_NAME ": Paste File List"),
paste_dialog->x - 500/2, paste_dialog->y - 200/2,
- 500, 200, 500, 200, 0, 0, 1)
+ 500, 200, 500, 200, 1, 0, 1)
{
- this->paste_dialog = paste_dialog;
+ this->paste_dialog = paste_dialog;
}
AssetPasteWindow::~AssetPasteWindow()
file_list->create_objects();
add_subwindow(new BC_OKButton(this));
add_subwindow(new BC_CancelButton(this));
- show_window();
+ show_window();
+}
+
+int AssetPasteWindow::resize_event(int w, int h)
+{
+ int fx = file_list->get_x(), fy = file_list->get_y(), pad = 5;
+ int text_w = w - fx - 10;
+ int text_h = h - fy - BC_OKButton::calculate_h() - pad;
+ int text_rows = BC_TextBox::pixels_to_rows(this, MEDIUMFONT, text_h);
+ file_list->reposition_window(fx, fy, text_w, text_rows);
+ return 0;
}
~AssetCopyWindow();
void create_objects();
+ int resize_event(int w, int h);
AssetCopyDialog *copy_dialog;
BC_ScrollTextBox *file_list;
~AssetPasteWindow();
void create_objects();
+ int resize_event(int w, int h);
AssetPasteDialog *paste_dialog;
BC_ScrollTextBox *file_list;
timer->update();
AudioThread *audio_out = device->audio_out;
- while(attempts < 2 && !done && !device->playback_interrupted)
- {
+ while( count > 0 && attempts < 2 && !done ) {
+ if( device->playback_interrupted ) break;
// Buffers written must be equal to period_time
audio_out->Thread::enable_cancel();
int ret = snd_pcm_avail_update(get_output());
if( ret > 0 ) ret = 0;
}
audio_out->Thread::disable_cancel();
+ if( device->playback_interrupted ) break;
if( ret == 0 ) continue;
if( ret > 0 ) {
}
}
- if(renderengine->command->single_frame())
+ if(renderengine->command->single_frame() && !renderengine->command->audio_toggle)
current_render_length = 1;
if(current_render_length < 0) current_render_length = 0;
this->mwindow = mwindow;
this->cwindow = cwindow;
affected_track = 0;
- affected_x = 0;
- affected_y = 0;
- affected_z = 0;
+ affected_x = affected_y = affected_z = 0;
mask_keyframe = 0;
orig_mask_keyframe = new MaskAuto(0, 0);
affected_point = 0;
- x_offset = 0;
- y_offset = 0;
- x_origin = 0;
- y_origin = 0;
+ x_offset = y_offset = 0;
+ x_origin = y_origin = 0;
current_operation = CWINDOW_NONE;
tool_panel = 0;
- translating_zoom = 0;
active = 0;
inactive = 0;
- crop_translate = 0;
+ crop_handle = -1; crop_translate = 0;
+ crop_origin_x = crop_origin_y = 0;
+ crop_origin_x1 = crop_origin_y1 = 0;
+ crop_origin_x2 = crop_origin_y2 = 0;
eyedrop_visible = 0;
+ eyedrop_x = eyedrop_y = 0;
+ ruler_origin_x = ruler_origin_y = 0;
+ ruler_handle = -1; ruler_translate = 0;
+ center_x = center_y = center_z = 0;
+ control_in_x = control_in_y = 0;
+ control_out_x = control_out_y = 0;
+ translating_zoom = 0;
highlighted = 0;
}
// Origin for camera and projector operations during last button press
float center_x, center_y, center_z;
float control_in_x, control_in_y, control_out_x, control_out_y;
- int current_tool;
// Must recalculate the origin when pressing shift.
// Switch toggle on and off to recalculate origin.
int translating_zoom;
CWindowEyedropGUI::CWindowEyedropGUI(MWindow *mwindow, CWindowTool *thread)
- : CWindowToolGUI(mwindow,
- thread,
- _(PROGRAM_NAME ": Color"),
- 200,
- 250)
+ : CWindowToolGUI(mwindow, thread, _(PROGRAM_NAME ": Color"), 220, 250)
{
}
void CWindowEyedropGUI::create_objects()
{
int margin = mwindow->theme->widget_border;
- int x = margin;
- int y = margin;
- int x2 = 70;
+ int x = 10 + margin;
+ int y = 10 + margin;
+ int x2 = 70, x3 = x2 + 60;
lock_window("CWindowEyedropGUI::create_objects");
BC_Title *title0, *title1, *title2, *title3, *title4, *title5, *title6, *title7;
add_subwindow(title0 = new BC_Title(x, y,_("X,Y:")));
radius->create_objects();
radius->set_boundaries((int64_t)0, (int64_t)255);
-
add_subwindow(red = new BC_Title(x2, title1->get_y(), "0"));
add_subwindow(green = new BC_Title(x2, title2->get_y(), "0"));
add_subwindow(blue = new BC_Title(x2, title3->get_y(), "0"));
+ add_subwindow(rgb_hex = new BC_Title(x3, red->get_y(), "#000000"));
add_subwindow(this->y = new BC_Title(x2, title4->get_y(), "0"));
add_subwindow(this->u = new BC_Title(x2, title5->get_y(), "0"));
add_subwindow(this->v = new BC_Title(x2, title6->get_y(), "0"));
+ add_subwindow(yuv_hex = new BC_Title(x3, this->y->get_y(), "#000000"));
- y = title6->get_y() + this->v->get_h() + margin;
+ y = title6->get_y() + this->v->get_h() + 2*margin;
add_subwindow(sample = new BC_SubWindow(x, y, 50, 50));
update();
unlock_window();
radius->update((int64_t)mwindow->edl->session->eyedrop_radius);
- red->update(mwindow->edl->local_session->red);
- green->update(mwindow->edl->local_session->green);
- blue->update(mwindow->edl->local_session->blue);
+ float r = mwindow->edl->local_session->red;
+ float g = mwindow->edl->local_session->green;
+ float b = mwindow->edl->local_session->blue;
+ red->update(r);
+ green->update(g);
+ blue->update(b);
+ int rx = 255*r + 0.5; bclamp(rx,0,255);
+ int gx = 255*g + 0.5; bclamp(gx,0,255);
+ int bx = 255*b + 0.5; bclamp(bx,0,255);
+ char rgb_text[BCSTRLEN];
+ sprintf(rgb_text, "#%02x%02x%02x", rx, gx, bx);
+ rgb_hex->update(rgb_text);
float y, u, v;
YUV::rgb_to_yuv_f(mwindow->edl->local_session->red,
mwindow->edl->local_session->green,
mwindow->edl->local_session->blue,
- y,
- u,
- v);
+ y, u, v);
this->y->update(y);
- this->u->update(u);
- this->v->update(v);
-
- int red = (int)(CLIP(mwindow->edl->local_session->red, 0, 1) * 0xff);
- int green = (int)(CLIP(mwindow->edl->local_session->green, 0, 1) * 0xff);
- int blue = (int)(CLIP(mwindow->edl->local_session->blue, 0, 1) * 0xff);
- sample->set_color((red << 16) | (green << 8) | blue);
+ this->u->update(u); u += 0.5;
+ this->v->update(v); v += 0.5;
+ int yx = 255*y + 0.5; bclamp(yx,0,255);
+ int ux = 255*u + 0.5; bclamp(ux,0,255);
+ int vx = 255*v + 0.5; bclamp(vx,0,255);
+ char yuv_text[BCSTRLEN];
+ sprintf(yuv_text, "#%02x%02x%02x", yx, ux, vx);
+ yuv_hex->update(yuv_text);
+
+ int rgb = (rx << 16) | (gx << 8) | (bx << 0);
+ sample->set_color(rgb);
sample->draw_box(0, 0, sample->get_w(), sample->get_h());
sample->set_color(BLACK);
sample->draw_rectangle(0, 0, sample->get_w(), sample->get_h());
BC_Title *current;
CWindowCoord *radius;
BC_Title *red, *green, *blue, *y, *u, *v;
+ BC_Title *rgb_hex, *yuv_hex;
BC_SubWindow *sample;
};
int prev_command = engine->command->command;
int prev_direction = engine->command->get_direction();
int prev_single_frame = engine->command->single_frame();
+ int prev_audio = engine->command->audio_toggle ?
+ !prev_single_frame : prev_single_frame;
+ int cur_single_frame = TransportCommand::single_frame(command);
+ int cur_audio = toggle_audio ?
+ !cur_single_frame : cur_single_frame;
// Dispatch command
switch(command) {
case SLOW_FWD:
case NORMAL_FWD:
case FAST_FWD:
- if( prev_command == command && !prev_single_frame ) {
-// Same direction pressed twice. Stop
+ if( !prev_single_frame &&
+ prev_command == command &&
+ cur_audio == prev_audio ) {
+// Same direction pressed twice and no change in audio state, Stop
do_stop = 1;
break;
}
return *this;
}
-int TransportCommand::single_frame()
+int TransportCommand::single_frame(int command)
{
return (command == SINGLE_FRAME_FWD ||
command == SINGLE_FRAME_REWIND ||
command == CURRENT_FRAME);
}
-
-
-int TransportCommand::get_direction()
+int TransportCommand::single_frame()
{
- switch(command)
- {
- case SINGLE_FRAME_FWD:
- case NORMAL_FWD:
- case FAST_FWD:
- case SLOW_FWD:
- case CURRENT_FRAME:
- return PLAY_FORWARD;
+ return single_frame(command);
+}
- case SINGLE_FRAME_REWIND:
- case NORMAL_REWIND:
- case FAST_REWIND:
- case SLOW_REWIND:
- return PLAY_REVERSE;
- default:
- break;
+int TransportCommand::get_direction(int command)
+{
+ switch(command) {
+ case SINGLE_FRAME_FWD:
+ case NORMAL_FWD:
+ case FAST_FWD:
+ case SLOW_FWD:
+ case CURRENT_FRAME:
+ return PLAY_FORWARD;
+
+ case SINGLE_FRAME_REWIND:
+ case NORMAL_REWIND:
+ case FAST_REWIND:
+ case SLOW_REWIND:
+ return PLAY_REVERSE;
+
+ default:
+ break;
}
return PLAY_FORWARD;
}
-
-float TransportCommand::get_speed()
+int TransportCommand::get_direction()
{
- switch(command)
- {
- case SLOW_FWD:
- case SLOW_REWIND:
- return 0.5;
-
- case NORMAL_FWD:
- case NORMAL_REWIND:
- case SINGLE_FRAME_FWD:
- case SINGLE_FRAME_REWIND:
- case CURRENT_FRAME:
- return 1.;
+ return get_direction(command);
+}
- case FAST_FWD:
- case FAST_REWIND:
- return 2.;
+float TransportCommand::get_speed(int command)
+{
+ switch(command) {
+ case SLOW_FWD:
+ case SLOW_REWIND:
+ return 0.5;
+
+ case NORMAL_FWD:
+ case NORMAL_REWIND:
+ case SINGLE_FRAME_FWD:
+ case SINGLE_FRAME_REWIND:
+ case CURRENT_FRAME:
+ return 1.;
+
+ case FAST_FWD:
+ case FAST_REWIND:
+ return 2.;
}
return 0.;
}
+float TransportCommand::get_speed()
+{
+ return get_speed(command);
+}
// Assume starting without pause
void TransportCommand::set_playback_range(EDL *edl, int use_inout, int toggle_audio)
case CURRENT_FRAME:
case SINGLE_FRAME_FWD:
start_position = edl->local_session->get_selectionstart(1);
- end_position = start_position +
- 1.0 /
- edl->session->frame_rate;
+ end_position = start_position + 1.0 / edl->session->frame_rate;
break;
case SINGLE_FRAME_REWIND:
- start_position = edl->local_session->get_selectionend(1);
- end_position = start_position -
- 1.0 /
- edl->session->frame_rate;
+ end_position = edl->local_session->get_selectionend(1);
+ start_position = end_position - 1.0 / edl->session->frame_rate;
break;
}
~TransportCommand();
void reset();
+ static int single_frame(int command);
+ int single_frame();
// Get the direction based on the command
+ static int get_direction(int command);
int get_direction();
+ static float get_speed(int command);
float get_speed();
void copy_from(TransportCommand *command);
TransportCommand& operator=(TransportCommand &command);
void playback_range_project();
void playback_range_1frame();
- int single_frame();
EDL* get_edl();
void delete_edl();
void new_edl();
// data is automatically freed by XDestroyImage
data = 0;
- delete row_data;
+ delete [] row_data;
}
return 0;
}
// event_names[event->type] : "Unknown");
//}
- if( active_grab && active_grab->grab_event(event) ) {
+ if( active_grab ) {
unlock_window();
- return 0;
+ active_grab->lock_window("BC_WindowBase::dispatch_event 3");
+ result = active_grab->grab_event(event);
+ active_grab->unlock_window();
+ if( result ) return result;
+ lock_window("BC_WindowBase::dispatch_event 4");
}
-
switch(event->type) {
case ClientMessage:
// Clear the resize buffer
#include "bccmodels.h"
#include "cicolors.h"
#include "clip.h"
+#include "edlsession.h"
#include "filexml.h"
#include "crikey.h"
#include "crikeywindow.h"
}
#endif
+CriKeyPoint::CriKeyPoint(int t, int e, float x, float y)
+{
+ this->t = t; this->e = e; this->x = x; this->y = y;
+}
+CriKeyPoint::~CriKeyPoint()
+{
+}
+
CriKeyConfig::CriKeyConfig()
{
color = 0x000000;
threshold = 0.5f;
draw_mode = DRAW_ALPHA;
- key_mode = KEY_SEARCH;
- point_x = point_y = 0;
drag = 0;
+ selected = 0;
+}
+CriKeyConfig::~CriKeyConfig()
+{
+ points.remove_all_objects();
}
int CriKeyConfig::equivalent(CriKeyConfig &that)
{
- return this->color != that.color ||
- !EQUIV(this->threshold, that.threshold) ||
- this->draw_mode != that.draw_mode ||
- this->key_mode != that.key_mode ||
- !EQUIV(this->point_x, that.point_x) ||
- !EQUIV(this->point_y, that.point_y) ||
- this->drag != that.drag ? 0 : 1;
+ if( this->color != that.color ) return 0;
+ if( !EQUIV(this->threshold, that.threshold) ) return 0;
+ if( this->draw_mode != that.draw_mode ) return 0;
+ if( this->drag != that.drag ) return 0;
+ if( this->points.size() != that.points.size() ) return 0;
+ for( int i=0, n=points.size(); i<n; ++i ) {
+ CriKeyPoint *ap = this->points[i], *bp = that.points[i];
+ if( ap->t != bp->t ) return 0;
+ if( ap->e != bp->e ) return 0;
+ if( !EQUIV(ap->x, bp->x) ) return 0;
+ if( !EQUIV(ap->y, bp->y) ) return 0;
+ }
+ return 1;
}
void CriKeyConfig::copy_from(CriKeyConfig &that)
this->color = that.color;
this->threshold = that.threshold;
this->draw_mode = that.draw_mode;
- this->key_mode = that.key_mode;
- this->point_x = that.point_x;
- this->point_y = that.point_y;
this->drag = that.drag;
+ this->selected = that.selected;
+
+ points.remove_all_objects();
+ for( int i=0,n=that.points.size(); i<n; ++i ) {
+ CriKeyPoint *pt = that.points[i];
+ add_point(pt->t, pt->e, pt->x, pt->y);
+ }
}
void CriKeyConfig::interpolate(CriKeyConfig &prev, CriKeyConfig &next,
long prev_frame, long next_frame, long current_frame)
{
- copy_from(prev);
+ this->color = prev.color;
+ this->draw_mode = prev.draw_mode;
+ this->drag = prev.drag;
+ this->selected = prev.selected;
+
double next_scale = (double)(current_frame - prev_frame) / (next_frame - prev_frame);
double prev_scale = (double)(next_frame - current_frame) / (next_frame - prev_frame);
this->threshold = prev.threshold * prev_scale + next.threshold * next_scale;
- switch( prev.key_mode ) {
- case KEY_POINT: {
- this->point_x = prev.point_x * prev_scale + next.point_x * next_scale;
- this->point_y = prev.point_y * prev_scale + next.point_y * next_scale;
- break; }
- case KEY_SEARCH:
- case KEY_SEARCH_ALL: {
- float prev_target[3]; set_target(0, prev.color, prev_target);
- float next_target[3]; set_target(0, next.color, next_target);
- float target[3]; // interpolates rgb components
- for( int i=0; i<3; ++i )
- target[i] = prev_target[i] * prev_scale + next_target[i] * next_scale;
- set_color(0, target, this->color);
- break; }
+ // interpolate rgb components
+ float prev_target[3]; set_target(0, prev.color, prev_target);
+ float next_target[3]; set_target(0, next.color, next_target);
+ float target[3];
+ for( int i=0; i<3; ++i )
+ target[i] = prev_target[i] * prev_scale + next_target[i] * next_scale;
+ set_color(0, target, this->color);
+
+ points.remove_all_objects();
+ int prev_sz = prev.points.size(), next_sz = next.points.size();
+ for( int i=0; i<prev_sz; ++i ) {
+ CriKeyPoint *pt = prev.points[i], *nt = 0;
+ float x = pt->x, y = pt->y;
+ int k = next_sz; // associated by tag id in next
+ while( --k >= 0 && pt->t != (nt=next.points[k])->t );
+ if( k >= 0 ) {
+ x = x * prev_scale + nt->x * next_scale;
+ y = y * prev_scale + nt->y * next_scale;
+ }
+ add_point(pt->t, pt->e, x, y);
}
}
{
bclamp(threshold, 0.0f, 1.0f);
bclamp(draw_mode, 0, DRAW_MODES-1);
- bclamp(key_mode, 0, KEY_MODES-1);
+}
+
+int CriKeyConfig::add_point(int t, int e, float x, float y)
+{
+ int k = points.size();
+ if( t < 0 ) {
+ t = 0;
+ for( int i=k; --i>=0; ) {
+ int n = points[i]->t;
+ if( n >= t ) t = n + 1;
+ }
+ }
+ points.append(new CriKeyPoint(t, e, x, y));
+ return k;
+}
+
+void CriKeyConfig::del_point(int i)
+{
+ points.remove_object_number(i);
}
stack.remove();
}
- int w, h, threshold;
+ int w, h;
uint8_t *data, *mask;
bool edge_pixel(uint8_t *dp) { return *dp; }
public:
void fill(int x, int y);
- void set_threshold(float v) { threshold = v; }
+ void run();
FillRegion(VFrame *d, VFrame *m);
};
FillRegion::FillRegion(VFrame *d, VFrame *m)
{
- threshold = 128;
w = d->get_w();
h = d->get_h();
data = d->get_data();
void FillRegion::fill(int x, int y)
{
push(y, x, x);
+}
- do {
- int ilt, irt, lt, rt;
+void FillRegion::run()
+{
+ while( stack.size() > 0 ) {
+ int y, ilt, irt;
pop(y, ilt, irt);
int ofs = y*w + ilt;
- uint8_t *idp = data + ofs, *dp;
- uint8_t *imp = mask + ofs, *mp;
+ uint8_t *idp = data + ofs;
+ uint8_t *imp = mask + ofs;
for( int x=ilt; x<=irt; ++x,++imp,++idp ) {
- if( !*imp || edge_pixel(idp) ) continue;
+ if( !*imp ) continue;
*imp = 0;
- lt = rt = x;
- dp = idp; mp = imp;
- for( int i=lt; --i>=0; lt=i,*mp=0 )
- if( !*--mp || edge_pixel(--dp) ) break;
- dp = idp; mp = imp;
- for( int i=rt; ++i< w; rt=i,*mp=0 )
- if( !*++mp || edge_pixel(++dp) ) break;
+ if( edge_pixel(idp) ) continue;
+ int lt = x, rt = x;
+ uint8_t *ldp = idp, *lmp = imp;
+ for( int i=lt; --i>=0; ) {
+ if( !*--lmp ) break;
+ *lmp = 0; lt = i;
+ if( edge_pixel(--ldp) ) break;
+ }
+ uint8_t *rdp = idp, *rmp = imp;
+ for( int i=rt; ++i< w; rt=i,*rmp=0 ) {
+ if( !*++rmp ) break;
+ *rmp = 0; rt = i;
+ if( edge_pixel(++rdp) ) break;
+ }
if( y+1 < h ) push(y+1, lt, rt);
if( y-1 >= 0 ) push(y-1, lt, rt);
}
- } while( stack.size() > 0 );
+ }
}
engine = 0;
msk = 0;
dst = 0;
- diff_pixel = 0;
}
CriKey::~CriKey()
}
}
-float CriKey::diff_uint8(uint8_t *dp)
-{
- float scale = 1./255., v = 0;
- for( int i=0; i<comp; ++i,++dp )
- v += fabs(*dp * scale - target[i]);
- return v / comp;
-}
-float CriKey::diff_float(uint8_t *dp)
-{
- float *fp = (float *)dp, v = 0;
- for( int i=0; i<comp; ++i,++fp )
- v += fabs(*fp - target[i]);
- return v / comp;
-}
-
-void CriKey::min_key(int &ix, int &iy)
-{
- float mv = 1;
- uint8_t **src_rows = src->get_rows();
- for( int y=0; y<h; ++y ) {
- uint8_t *sp = src_rows[y];
- for( int x=0; x<w; ++x,sp+=bpp ) {
- float v = (this->*diff_pixel)(sp);
- if( v >= mv ) continue;
- mv = v; ix = x; iy = y;
- }
- }
-}
-bool CriKey::find_key(int &ix, int &iy, float thr)
-{
- uint8_t **src_rows = src->get_rows();
- uint8_t **msk_rows = msk->get_rows();
- int x = ix, y = iy;
- for( ; y<h; ++y ) {
- uint8_t *sp = src_rows[y] + x*bpp;
- uint8_t *mp = msk_rows[y] + x;
- for( ; x<w; ++x,++mp,sp+=bpp ) {
- if( !*mp ) continue;
- float v = (this->*diff_pixel)(sp);
- if( v < thr ) {
- ix = x; iy = y;
- return true;
- }
- }
- x = 0;
- }
- return false;
-}
-
const char* CriKey::plugin_title() { return _("CriKey"); }
int CriKey::is_realtime() { return 1; }
NEW_WINDOW_MACRO(CriKey, CriKeyWindow);
LOAD_CONFIGURATION_MACRO(CriKey, CriKeyConfig)
+int CriKey::new_point()
+{
+ EDLSession *session = get_edlsession();
+ float x = !session ? 0.f : session->output_w / 2.f;
+ float y = !session ? 0.f : session->output_h / 2.f;
+ return config.add_point(-1, 0, x, y);
+}
+
void CriKey::save_data(KeyFrame *keyframe)
{
FileXML output;
output.tag.set_property("COLOR", config.color);
output.tag.set_property("THRESHOLD", config.threshold);
output.tag.set_property("DRAW_MODE", config.draw_mode);
- output.tag.set_property("KEY_MODE", config.key_mode);
- output.tag.set_property("POINT_X", config.point_x);
- output.tag.set_property("POINT_Y", config.point_y);
output.tag.set_property("DRAG", config.drag);
+ output.tag.set_property("SELECTED", config.selected);
output.append_tag();
output.append_newline();
output.tag.set_title("/CRIKEY");
output.append_tag();
output.append_newline();
+ for( int i=0, n = config.points.size(); i<n; ++i ) {
+ CriKeyPoint *pt = config.points[i];
+ char point[BCSTRLEN];
+ sprintf(point,"/POINT_%d",pt->t);
+ output.tag.set_title(point+1);
+ output.tag.set_property("E", pt->e);
+ output.tag.set_property("X", pt->x);
+ output.tag.set_property("Y", pt->y);
+ output.append_tag();
+ output.tag.set_title(point+0);
+ output.append_tag();
+ output.append_newline();
+ }
output.terminate_string();
}
{
FileXML input;
input.set_shared_input(keyframe->get_data(), strlen(keyframe->get_data()));
+ config.points.remove_all_objects();
int result = 0;
while( !(result=input.read_tag()) ) {
- if(input.tag.title_is("CRIKEY")) {
+ if( input.tag.title_is("CRIKEY") ) {
config.color = input.tag.get_property("COLOR", config.color);
config.threshold = input.tag.get_property("THRESHOLD", config.threshold);
config.draw_mode = input.tag.get_property("DRAW_MODE", config.draw_mode);
- config.key_mode = input.tag.get_property("KEY_MODE", config.key_mode);
- config.point_x = input.tag.get_property("POINT_X", config.point_x);
- config.point_y = input.tag.get_property("POINT_Y", config.point_y);
config.drag = input.tag.get_property("DRAG", config.drag);
+ config.selected = input.tag.get_property("SELECTED", 0);
config.limits();
}
- else if(input.tag.title_is("/CRIKEY")) {
- result = 1;
+ else if( !strncmp(input.tag.get_title(),"POINT_",6) ) {
+ int t = atoi(input.tag.get_title() + 6);
+ int e = input.tag.get_property("E", 0);
+ float x = input.tag.get_property("X", 0.f);
+ float y = input.tag.get_property("Y", 0.f);
+ config.add_point(t, e, x, y);
}
}
+ if( !config.points.size() ) new_point();
}
void CriKey::update_gui()
}
}
+void CriKey::draw_point(VFrame *src, CriKeyPoint *pt)
+{
+ int d = bmax(w,h) / 200 + 2;
+ int r = d/2+1, x = pt->x, y = pt->y;
+ src->draw_smooth(x-r,y+0, x-r, y-r, x+0,y-r);
+ src->draw_smooth(x+0,y-r, x+r, y-r, x+r,y+0);
+ src->draw_smooth(x+r,y+0, x+r, y+r, x+0,y+r);
+ src->draw_smooth(x+0,y+r, x-r, y+r, x-r,y+0);
+ if( pt->e ) {
+ src->set_pixel_color(RED);
+ src->draw_x(pt->x, pt->y, d);
+ }
+ else {
+ src->set_pixel_color(BLUE);
+ src->draw_t(pt->x, pt->y, d);
+ }
+}
+
int CriKey::process_buffer(VFrame *frame, int64_t start_position, double frame_rate)
{
load_configuration();
if( comp > 3 ) comp = 3;
is_yuv = BC_CModels::is_yuv(color_model);
is_float = BC_CModels::is_float(color_model);
- diff_pixel = is_float ? &CriKey::diff_float : &CriKey::diff_uint8;
read_frame(src, 0, start_position, frame_rate, 0);
- switch( config.key_mode ) {
- case KEY_SEARCH:
- case KEY_SEARCH_ALL:
- set_target(is_yuv, config.color, target);
- break;
- case KEY_POINT:
- get_color(config.point_x, config.point_y);
- break;
- }
+ set_target(is_yuv, config.color, target);
if( dst && ( dst->get_w() != w || src->get_h() != h ) ) {
delete dst; dst = 0;
}
if( !dst )
dst = new VFrame(w, h, BC_A8);
- memset(dst->get_data(), 0x00, dst->get_data_size());
+ dst->clear_frame();
if( !engine )
engine = new CriKeyEngine(this,
if( h1 > 0 ) for( int x=0; x<w; ++x ) dp[x] = dp[x-w];
//crikey_pgm("/tmp/dst.pgm",dst);
- if( config.draw_mode == DRAW_EDGE ) {
- draw_mask(dst);
- return 0;
- }
-
- if( msk && ( msk->get_w() != w || msk->get_h() != h ) ) {
- delete msk; msk = 0;
- }
- if( !msk )
- msk = new VFrame(w, h, BC_A8);
- memset(msk->get_data(), 0xff, msk->get_data_size());
-
- FillRegion fill_region(dst, msk);
- fill_region.set_threshold(config.threshold);
-
- int x = 0, y = 0;
- switch( config.key_mode ) {
- case KEY_SEARCH:
- min_key(x, y);
- fill_region.fill(x, y);
- break;
- case KEY_SEARCH_ALL:
- while( find_key(x, y, config.threshold) ) {
- fill_region.fill(x, y);
- ++x;
+ if( config.draw_mode != DRAW_EDGE ) {
+ if( msk && ( msk->get_w() != w || msk->get_h() != h ) ) {
+ delete msk; msk = 0;
}
- break;
- case KEY_POINT:
- x = config.point_x, y = config.point_y;
- if( x >= 0 && x < w && y >= 0 && y < h )
- fill_region.fill(x, y);
- break;
- }
+ if( !msk )
+ msk = new VFrame(w, h, BC_A8);
+ memset(msk->get_data(), 0xff, msk->get_data_size());
+
+ FillRegion fill_region(dst, msk);
+ for( int i=0, n=config.points.size(); i<n; ++i ) {
+ CriKeyPoint *pt = config.points[i];
+ if( !pt->e ) continue;
+ float x = pt->x, y = pt->y;
+ if( x >= 0 && x < w && y >= 0 && y < h )
+ fill_region.fill(x, y);
+ }
+ fill_region.run();
+
//crikey_pgm("/tmp/msk.pgm",msk);
- if( config.draw_mode == DRAW_MASK ) {
- draw_mask(msk);
- return 0;
+ if( config.draw_mode == DRAW_MASK )
+ draw_mask(msk);
+ else
+ draw_alpha(msk);
}
+ else
+ draw_mask(dst);
- draw_alpha(msk);
+ if( config.drag ) {
+ for( int i=0, n=config.points.size(); i<n; ++i ) {
+ CriKeyPoint *pt = config.points[i];
+ src->set_pixel_color(config.selected == i ? GREEN : WHITE);
+ draw_point(src, pt);
+ }
+ }
return 0;
}
} \
v = 0; \
float a = bmin(bmin(a00, a01), bmin(a10, a11)); \
- if( a < threshold ) continue; \
+ if( a > threshold ) continue; \
float b = bmax(bmax(a00, a01), bmax(a10, a11)); \
- if( b <= threshold ) continue; \
- v = (b-a)*254 + 1; \
+ if( threshold >= b ) continue; \
+ v = 255; \
} \
} \
} break
-#ifndef EDGE_H
-#define EDGE_H
+#ifndef __CRIKEY_H__
+#define __CRIKEY_H__
#include "loadbalance.h"
#include "pluginvclient.h"
#define DRAW_MASK 2
#define DRAW_MODES 3
-#define KEY_SEARCH 0
-#define KEY_SEARCH_ALL 1
-#define KEY_POINT 2
-#define KEY_MODES 3
+enum { PT_E, PT_X, PT_Y, PT_T, PT_SZ }; // enable, x,y, tag
+
+class CriKeyPoint
+{
+public:
+ int t, e;
+ float x, y;
+
+ CriKeyPoint(int t, int e, float x, float y);
+ ~CriKeyPoint();
+};
class CriKeyConfig
{
public:
CriKeyConfig();
+ ~CriKeyConfig();
int equivalent(CriKeyConfig &that);
void copy_from(CriKeyConfig &that);
static void set_target(int is_yuv, int color, float *target);
static void set_color(int is_yuv, float *target, int &color);
+ ArrayList<CriKeyPoint *> points;
+ int add_point(int t, int e, float x, float y);
+ int add_point();
+ void del_point(int i);
+
int color;
float threshold;
- int draw_mode, key_mode;
- float point_x, point_y;
- int drag;
+ int draw_mode;
+ int drag, selected;
};
class CriKeyPackage : public LoadPackage
PLUGIN_CLASS_MEMBERS2(CriKeyConfig)
int is_realtime();
void update_gui();
+ int new_point();
void save_data(KeyFrame *keyframe);
void read_data(KeyFrame *keyframe);
int process_buffer(VFrame *frame, int64_t start_position, double frame_rate);
void draw_alpha(VFrame *msk);
- void draw_mask(VFrame *msk);
- float diff_uint8(uint8_t *tp);
- float diff_float(uint8_t *tp);
- float (CriKey::*diff_pixel)(uint8_t *dp);
- void min_key(int &ix, int &iy);
- bool find_key(int &ix, int &iy, float threshold);
+ void draw_mask(VFrame *frm);
+ void draw_point(VFrame *msk, CriKeyPoint *pt);
static void set_target(int is_yuv, int color, float *target) {
CriKeyConfig::set_target(is_yuv, color, target);
}
#include "clip.h"
#include "crikey.h"
#include "crikeywindow.h"
+#include "cstrdup.h"
#include "cwindow.h"
#include "cwindowgui.h"
#include "edl.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)
+CriKeyNum::CriKeyNum(CriKeyWindow *gui, int x, int y, float output)
+ : BC_TumbleTextBox(gui, output, -32767.0f, 32767.0f, x, y, 120)
{
this->gui = gui;
- this->output = &output;
set_increment(1);
set_precision(1);
}
{
}
-int CriKeyNum::handle_event()
+int CriKeyPointX::handle_event()
{
- *output = atof(get_text());
+ if( !CriKeyNum::handle_event() ) return 0;
+ CriKeyPoints *points = gui->points;
+ int hot_point = points->get_selection_number(0, 0);
+ if( hot_point >= 0 && hot_point < gui->plugin->config.points.size() ) {
+ float v = atof(get_text());
+ gui->plugin->config.points[hot_point]->x = v;
+ points->set_point(hot_point, PT_X, v);
+ }
+ points->update_list();
+ gui->plugin->send_configure_change();
+ return 1;
+}
+int CriKeyPointY::handle_event()
+{
+ if( !CriKeyNum::handle_event() ) return 0;
+ CriKeyPoints *points = gui->points;
+ int hot_point = points->get_selection_number(0, 0);
+ if( hot_point >= 0 && hot_point < gui->plugin->config.points.size() ) {
+ float v = atof(get_text());
+ gui->plugin->config.points[hot_point]->y = v;
+ points->set_point(hot_point, PT_Y, v);
+ }
+ points->update_list();
gui->plugin->send_configure_change();
return 1;
}
if( send ) 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, 0);
-}
-void CriKeyKeyMode::update(int mode, int send)
-{
- if( this->mode == mode ) return;
- this->mode = mode;
- set_text(key_modes[mode]);
- gui->draw_key(mode);
- if( send ) gui->plugin->send_configure_change();
-}
-
CriKeyColorButton::CriKeyColorButton(CriKeyWindow *gui, int x, int y)
: BC_GenericButton(x, y, _("Color"))
{
void CriKeyColorPicker::start(int color)
{
- start_window(this->color = color, 0, 1);
+ orig_color = this->color = color;
+ start_window(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();
- }
+ if( result ) color = orig_color;
+ 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::CriKeyWindow(CriKey *plugin)
- : PluginClientWindow(plugin, 320, 220, 320, 220, 0)
+ : PluginClientWindow(plugin, 380, 360, 380, 360, 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;
+ this->title_x = 0; this->point_x = 0;
+ this->title_y = 0; this->point_y = 0;
+ this->new_point = 0; this->del_point = 0;
+ this->point_up = 0; this->point_dn = 0;
+ this->drag = 0; this->dragging = 0;
+ this->last_x = 0; this->last_y = 0;
+ this->points = 0; this->cur_point = 0;
}
CriKeyWindow::~CriKeyWindow()
{
delete color_picker;
+ delete points;
}
void CriKeyWindow::create_objects()
y += title->get_h() + margin;
add_subwindow(threshold = new CriKeyThreshold(this, x, y, get_w() - x * 2));
y += threshold->get_h() + margin;
+ add_subwindow(color_button = new CriKeyColorButton(this, x, y));
+ int x1 = x + color_button->get_w() + margin;
+ color_x = x1; color_y = y;
+ update_color(plugin->config.color);
+ y += COLOR_H + 10 + margin ;
add_subwindow(title = new BC_Title(x, y+5, _("Draw mode:")));
- int x1 = x + title->get_w() + 10 + margin;
+ 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();
+ y += draw_mode->get_h() + 10 + margin;
+
+ CriKeyPoint *pt = plugin->config.points[plugin->config.selected];
+ add_subwindow(title_x = new BC_Title(x, y, _("X:")));
+ x1 = x + title_x->get_w() + margin;
+ point_x = new CriKeyPointX(this, x1, y, pt->x);
+ point_x->create_objects();
+ x1 += point_x->get_w() + margin;
+ add_subwindow(new_point = new CriKeyNewPoint(this, plugin, x1, y));
+ x1 += new_point->get_w() + margin;
+ add_subwindow(point_up = new CriKeyPointUp(this, x1, y));
+ y += point_x->get_h() + margin;
+ add_subwindow(title_y = new BC_Title(x, y, _("Y:")));
+ x1 = x + title_y->get_w() + margin;
+ point_y = new CriKeyPointY(this, x1, y, pt->y);
+ point_y->create_objects();
+ x1 += point_y->get_w() + margin;
+ add_subwindow(del_point = new CriKeyDelPoint(this, plugin, x1, y));
+ x1 += del_point->get_w() + margin;
+ add_subwindow(point_dn = new CriKeyPointDn(this, x1, y));
+ y += point_y->get_h() + margin + 10;
+ add_subwindow(drag = new CriKeyDrag(this, x, y));
+ x1 = x + drag->get_w() + margin + 20;
+ add_subwindow(cur_point = new CriKeyCurPoint(this, plugin, x1, y+3));
+ cur_point->update(plugin->config.selected);
+ y += drag->get_h() + margin;
+ add_subwindow(points = new CriKeyPoints(this, plugin, x, y));
+ points->update(plugin->config.selected);
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: break;
+ case ButtonRelease: break;
+ case MotionNotify: break;
+ default: return 0;
+ }
MWindow *mwindow = plugin->server->mwindow;
CWindowGUI *cwindow_gui = mwindow->cwindow->gui;
CWindowCanvas *canvas = cwindow_gui->canvas;
- int cx, cy; canvas->get_canvas()->get_relative_cursor_xy(cx, cy);
- if( cx < mwindow->theme->ccanvas_x ) return 0;
- if( cx >= mwindow->theme->ccanvas_x+mwindow->theme->ccanvas_w ) return 0;
- if( cy < mwindow->theme->ccanvas_y ) return 0;
- if( cy >= mwindow->theme->ccanvas_y+mwindow->theme->ccanvas_h ) return 0;
+ int cx, cy; cwindow_gui->get_relative_cursor_xy(cx, cy);
+ cx -= mwindow->theme->ccanvas_x;
+ cy -= mwindow->theme->ccanvas_y;
+
+ if( !dragging ) {
+ if( cx < 0 || cx >= mwindow->theme->ccanvas_w ) return 0;
+ if( cy < 0 || cy >= mwindow->theme->ccanvas_h ) return 0;
+ }
switch( event->type ) {
case ButtonPress:
if( dragging ) return 0;
- dragging = 1;
+ dragging = event->xbutton.state & ShiftMask ? -1 : 1;
break;
case ButtonRelease:
if( !dragging ) return 0;
dragging = 0;
return 1;
case MotionNotify:
- if( dragging ) break;
+ if( !dragging ) return 0;
+ break;
default:
return 0;
}
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));
+ point_x->update((int64_t)(output_x));
+ point_y->update((int64_t)(output_y));
+
+ if( dragging > 0 ) {
+ switch( event->type ) {
+ case ButtonPress: {
+ int hot_point = -1;
+ int n = plugin->config.points.size();
+ if( n > 0 ) {
+ CriKeyPoint *pt = plugin->config.points[hot_point=0];
+ double dist = DISTANCE(output_x,output_y, pt->x,pt->y);
+ for( int i=1; i<n; ++i ) {
+ pt = plugin->config.points[i];
+ double d = DISTANCE(output_x,output_y, pt->x,pt->y);
+ if( d >= dist ) continue;
+ dist = d; hot_point = i;
+ }
+ }
+ if( hot_point >= 0 ) {
+ CriKeyPoint *pt = plugin->config.points[hot_point];
+ if( pt->x == output_x && pt->y == output_y ) break;
+ points->set_point(hot_point, PT_X, pt->x = output_x);
+ points->set_point(hot_point, PT_Y, pt->y = output_y);
+ plugin->config.selected = hot_point;
+ points->set_selected(hot_point);
+ points->update_list();
+ }
+ break; }
+ case MotionNotify: {
+ int hot_point = points->get_selection_number(0, 0);
+ if( hot_point >= 0 && hot_point < plugin->config.points.size() ) {
+ CriKeyPoint *pt = plugin->config.points[hot_point];
+ if( pt->x == output_x && pt->y == output_y ) break;
+ points->set_point(hot_point, PT_X, pt->x = output_x);
+ points->set_point(hot_point, PT_Y, pt->y = output_y);
+ point_x->update(pt->x);
+ point_y->update(pt->y);
+ points->update_list();
+ }
+ break; }
+ }
+ }
+ else {
+ switch( event->type ) {
+ case MotionNotify: {
+ float dx = output_x - last_x, dy = output_y - last_y;
+ int n = plugin->config.points.size();
+ for( int i=0; i<n; ++i ) {
+ CriKeyPoint *pt = plugin->config.points[i];
+ points->set_point(i, PT_X, pt->x += dx);
+ points->set_point(i, PT_Y, pt->y += dy);
+ }
+ int hot_point = points->get_selection_number(0, 0);
+ if( hot_point >= 0 && hot_point < n ) {
+ CriKeyPoint *pt = plugin->config.points[hot_point];
+ point_x->update(pt->x);
+ point_y->update(pt->y);
+ points->update_list();
+ }
+ break; }
+ }
+ }
+
+ last_x = output_x; last_y = output_y;
plugin->send_configure_change();
return 1;
}
if( color_picker ) color_picker->close_window();
}
-void CriKeyWindow::draw_key(int mode)
+CriKeyPoints::CriKeyPoints(CriKeyWindow *gui, CriKey *plugin, int x, int y)
+ : BC_ListBox(x, y, 360, 130, LISTBOX_TEXT)
{
- 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;
+ this->gui = gui;
+ this->plugin = plugin;
+ titles[PT_E] = _("E"); widths[PT_E] = 40;
+ titles[PT_X] = _("X"); widths[PT_X] = 120;
+ titles[PT_Y] = _("Y"); widths[PT_Y] = 120;
+ titles[PT_T] = _("Tag"); widths[PT_T] = 60;
+}
+CriKeyPoints::~CriKeyPoints()
+{
+ clear();
+}
+void CriKeyPoints::clear()
+{
+ for( int i=PT_SZ; --i>=0; )
+ cols[i].remove_all_objects();
+}
+
+int CriKeyPoints::column_resize_event()
+{
+ for( int i=PT_SZ; --i>=0; )
+ widths[i] = get_column_width(i);
+ return 1;
+}
+
+int CriKeyPoints::handle_event()
+{
+ int hot_point = get_selection_number(0, 0);
+ const char *x_text = "", *y_text = "";
+ if( hot_point >= 0 && hot_point < plugin->config.points.size() ) {
+ if( get_cursor_x() < widths[0] ) {
+ plugin->config.points[hot_point]->e =
+ !plugin->config.points[hot_point]->e;
+ }
+ x_text = gui->points->cols[PT_X].get(hot_point)->get_text();
+ y_text = gui->points->cols[PT_Y].get(hot_point)->get_text();
}
- plugin->config.key_mode = mode;
- show_window(1);
+ else
+ hot_point = 0;
+ gui->point_x->update(x_text);
+ gui->point_y->update(y_text);
+ plugin->config.selected = hot_point;
+ update(hot_point);
+ gui->plugin->send_configure_change();
+ return 1;
+}
+
+int CriKeyPoints::selection_changed()
+{
+ handle_event();
+ return 1;
+}
+
+void CriKeyPoints::new_point(const char *ep, const char *xp, const char *yp, const char *tp)
+{
+ cols[PT_E].append(new BC_ListBoxItem(ep));
+ cols[PT_X].append(new BC_ListBoxItem(xp));
+ cols[PT_Y].append(new BC_ListBoxItem(yp));
+ cols[PT_T].append(new BC_ListBoxItem(tp));
+}
+
+void CriKeyPoints::del_point(int i)
+{
+ for( int n=cols[0].size()-1, c=PT_SZ; --c>=0; )
+ cols[c].remove_object_number(n-i);
+}
+
+void CriKeyPoints::set_point(int i, int c, float v)
+{
+ char s[BCSTRLEN]; sprintf(s,"%0.4f",v);
+ set_point(i,c,s);
+}
+void CriKeyPoints::set_point(int i, int c, const char *cp)
+{
+ cols[c].get(i)->set_text(cp);
+}
+
+int CriKeyPoints::set_selected(int k)
+{
+ int sz = gui->plugin->config.points.size();
+ if( !sz ) return -1;
+ bclamp(k, 0, sz-1);
+ int n = gui->points->get_selection_number(0, 0);
+ if( n >= 0 ) {
+ for( int i=0; i<PT_SZ; ++i )
+ cols[i].get(n)->set_selected(0);
+ }
+ for( int i=0; i<PT_SZ; ++i )
+ cols[i].get(k)->set_selected(1);
+ gui->cur_point->update(k);
+ return k;
+}
+void CriKeyPoints::update_list()
+{
+ int xpos = get_xposition(), ypos = get_xposition();
+ int k = get_selection_number(0, 0);
+ BC_ListBox::update(&cols[0], &titles[0],&widths[0],PT_SZ, xpos,ypos,k);
+}
+void CriKeyPoints::update(int k)
+{
+ if( k < 0 ) k = get_selection_number(0, 0);
+ gui->cur_point->update(k);
+ int xpos = get_xposition(), ypos = get_xposition();
+
+ clear();
+ ArrayList<CriKeyPoint*> &points = plugin->config.points;
+ int n = points.size();
+ for( int i=0; i<n; ++i ) {
+ CriKeyPoint *pt = points[i];
+ char etxt[BCSTRLEN]; sprintf(etxt,"%s", pt->e ? "*" : "");
+ char xtxt[BCSTRLEN]; sprintf(xtxt,"%0.4f", pt->x);
+ char ytxt[BCSTRLEN]; sprintf(ytxt,"%0.4f", pt->y);
+ char ttxt[BCSTRLEN]; sprintf(ttxt,"%d", pt->t);
+ new_point(etxt, xtxt, ytxt, ttxt);
+ }
+ if( k < n ) {
+ for( int i=PT_SZ; --i>=0; )
+ cols[i].get(k)->set_selected(1);
+ gui->point_x->update(gui->points->cols[PT_X].get(k)->get_text());
+ gui->point_y->update(gui->points->cols[PT_Y].get(k)->get_text());
+ }
+
+ BC_ListBox::update(&cols[0], &titles[0],&widths[0],PT_SZ, xpos,ypos,k);
}
void CriKeyWindow::update_color(int color)
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;
- }
+ update_color(plugin->config.color);
+ threshold->update(plugin->config.threshold);
+ cur_point->update(plugin->config.selected);
+ drag->update(plugin->config.drag);
+ points->update(plugin->config.selected);
}
int CriKeyThreshold::handle_event()
{
- gui->plugin->config.threshold = get_value();
+ float v = get_value();
+ gui->plugin->config.threshold = v;
+ gui->plugin->send_configure_change();
+ return 1;
+}
+
+
+CriKeyPointUp::CriKeyPointUp(CriKeyWindow *gui, int x, int y)
+ : BC_GenericButton(x, y, _("Up"))
+{
+ this->gui = gui;
+}
+CriKeyPointUp::~CriKeyPointUp()
+{
+}
+
+int CriKeyPointUp::handle_event()
+{
+ int n = gui->plugin->config.points.size();
+ int hot_point = gui->points->get_selection_number(0, 0);
+
+ if( n > 1 && hot_point > 0 ) {
+ CriKeyPoint *&pt0 = gui->plugin->config.points[hot_point];
+ CriKeyPoint *&pt1 = gui->plugin->config.points[--hot_point];
+ CriKeyPoint *t = pt0; pt0 = pt1; pt1 = t;
+ gui->plugin->config.selected = hot_point;
+ gui->points->update(hot_point);
+ }
gui->plugin->send_configure_change();
return 1;
}
+CriKeyPointDn::CriKeyPointDn(CriKeyWindow *gui, int x, int y)
+ : BC_GenericButton(x, y, _("Dn"))
+{
+ this->gui = gui;
+}
+CriKeyPointDn::~CriKeyPointDn()
+{
+}
+
+int CriKeyPointDn::handle_event()
+{
+ int n = gui->plugin->config.points.size();
+ int hot_point = gui->points->get_selection_number(0, 0);
+ if( n > 1 && hot_point < n-1 ) {
+ CriKeyPoint *&pt0 = gui->plugin->config.points[hot_point];
+ CriKeyPoint *&pt1 = gui->plugin->config.points[++hot_point];
+ CriKeyPoint *t = pt0; pt0 = pt1; pt1 = t;
+ gui->plugin->config.selected = hot_point;
+ gui->points->update(hot_point);
+ }
+ gui->plugin->send_configure_change();
+ return 1;
+}
CriKeyDrag::CriKeyDrag(CriKeyWindow *gui, int x, int y)
: BC_CheckBox(x, y, gui->plugin->config.drag, _("Drag"))
return 1;
}
+CriKeyNewPoint::CriKeyNewPoint(CriKeyWindow *gui, CriKey *plugin, int x, int y)
+ : BC_GenericButton(x, y, 80, _("New"))
+{
+ this->gui = gui;
+ this->plugin = plugin;
+}
+CriKeyNewPoint::~CriKeyNewPoint()
+{
+}
+int CriKeyNewPoint::handle_event()
+{
+ int k = plugin->new_point();
+ gui->points->update(k);
+ gui->plugin->send_configure_change();
+ return 1;
+}
+
+CriKeyDelPoint::CriKeyDelPoint(CriKeyWindow *gui, CriKey *plugin, int x, int y)
+ : BC_GenericButton(x, y, 80, _("Del"))
+{
+ this->gui = gui;
+ this->plugin = plugin;
+}
+CriKeyDelPoint::~CriKeyDelPoint()
+{
+}
+int CriKeyDelPoint::handle_event()
+{
+ int hot_point = gui->points->get_selection_number(0, 0);
+ if( hot_point >= 0 && hot_point < gui->plugin->config.points.size() ) {
+ plugin->config.del_point(hot_point);
+ if( !plugin->config.points.size() ) plugin->new_point();
+ int n = gui->plugin->config.points.size();
+ if( hot_point >= n && hot_point > 0 ) --hot_point;
+ gui->plugin->config.selected = hot_point;
+ gui->points->update(hot_point);
+ gui->plugin->send_configure_change();
+ }
+ return 1;
+}
+
+CriKeyCurPoint::CriKeyCurPoint(CriKeyWindow *gui, CriKey *plugin, int x, int y)
+ : BC_Title(x, y, "")
+{
+ this->gui = gui;
+ this->plugin = plugin;
+}
+CriKeyCurPoint::~CriKeyCurPoint()
+{
+}
+void CriKeyCurPoint::update(int n)
+{
+ char string[BCSTRLEN];
+ sprintf(string, _("Selected: %d "), n);
+ BC_Title::update(string);
+}
+
class CriKey;
class CriKeyWindow;
class CriKeyNum;
+class CriKeyPointX;
+class CriKeyPointY;
class CriKeyColorButton;
class CriKeyColorPicker;
class CriKeyDrawMode;
class CriKeyDrawModeItem;
-class CriKeyKeyMode;
-class CriKeyKeyModeItem;
class CriKeyThreshold;
+class CriKeyDrag;
+class CriKeyPoints;
+class CriKeyNewPoint;
+class CriKeyDelPoint;
+class CriKeyPointUp;
+class CriKeyPointDn;
+class CriKeyCurPoint;
+
class CriKeyNum : public BC_TumbleTextBox
{
public:
CriKeyWindow *gui;
- float *output;
- int handle_event();
- CriKeyNum(CriKeyWindow *gui, int x, int y, float &output);
+ CriKeyNum(CriKeyWindow *gui, int x, int y, float output);
~CriKeyNum();
};
+class CriKeyPointX : public CriKeyNum
+{
+public:
+ CriKeyPointX(CriKeyWindow *gui, int x, int y, float output)
+ : CriKeyNum(gui, x, y, output) {}
+ ~CriKeyPointX() {}
+
+ int handle_event();
+};
+class CriKeyPointY : public CriKeyNum
+{
+public:
+ CriKeyPointY(CriKeyWindow *gui, int x, int y, float output)
+ : CriKeyNum(gui, x, y, output) {}
+ ~CriKeyPointY() {}
+
+ int handle_event();
+};
class CriKeyColorButton : public BC_GenericButton
{
void handle_done_event(int result);
CriKeyColorButton *color_button;
- int color;
+ int color, orig_color;
};
class CriKeyDrawMode : public BC_PopupMenu
int id;
};
-class CriKeyKeyMode : public BC_PopupMenu
+class CriKeyThreshold : public BC_FSlider
+{
+public:
+ CriKeyThreshold(CriKeyWindow *gui, int x, int y, int w);
+ int handle_event();
+ CriKeyWindow *gui;
+};
+
+class CriKeyDrag : public BC_CheckBox
{
- const char *key_modes[KEY_MODES];
public:
- CriKeyKeyMode(CriKeyWindow *gui, int x, int y);
+ CriKeyDrag(CriKeyWindow *gui, int x, int y);
- void create_objects();
- void update(int mode, int send=1);
+ int handle_event();
CriKeyWindow *gui;
- int mode;
};
-class CriKeyKeyModeItem : public BC_MenuItem
+
+class CriKeyPoints : public BC_ListBox
{
public:
- CriKeyKeyModeItem(const char *text, int id)
- : BC_MenuItem(text) { this->id = id; }
+ CriKeyPoints(CriKeyWindow *gui, CriKey *plugin, int x, int y);
+ ~CriKeyPoints();
int handle_event();
+ int selection_changed();
+ int column_resize_event();
+ ArrayList<BC_ListBoxItem*> cols[PT_SZ];
+ void clear();
+ void new_point(const char *ep, const char *xp, const char *yp, const char *tp);
+ void del_point(int i);
+ void set_point(int i, int c, float v);
+ void set_point(int i, int c, const char *cp);
+ int set_selected(int k);
+ void update_list();
+ void update(int k);
+
+
CriKeyWindow *gui;
- int id;
+ CriKey *plugin;
+ const char *titles[PT_SZ];
+ int widths[PT_SZ];
};
-class CriKeyThreshold : public BC_FSlider
+class CriKeyNewPoint : public BC_GenericButton
{
public:
- CriKeyThreshold(CriKeyWindow *gui, int x, int y, int w);
+ CriKeyNewPoint(CriKeyWindow *gui, CriKey *plugin, int x, int y);
+ ~CriKeyNewPoint();
+
int handle_event();
+
CriKeyWindow *gui;
+ CriKey *plugin;
};
-class CriKeyDrag : public BC_CheckBox
+class CriKeyDelPoint : public BC_GenericButton
{
public:
- CriKeyDrag(CriKeyWindow *gui, int x, int y);
+ CriKeyDelPoint(CriKeyWindow *gui, CriKey *plugin, int x, int y);
+ ~CriKeyDelPoint();
+
+ int handle_event();
+
+ CriKey *plugin;
+ CriKeyWindow *gui;
+};
+
+class CriKeyPointUp : public BC_GenericButton
+{
+public:
+ CriKeyPointUp(CriKeyWindow *gui, int x, int y);
+ ~CriKeyPointUp();
+
+ int handle_event();
+
+ CriKeyWindow *gui;
+};
+
+class CriKeyPointDn : public BC_GenericButton
+{
+public:
+ CriKeyPointDn(CriKeyWindow *gui, int x, int y);
+ ~CriKeyPointDn();
int handle_event();
+
+ CriKeyWindow *gui;
+};
+
+class CriKeyCurPoint : public BC_Title
+{
+public:
+ CriKeyCurPoint(CriKeyWindow *gui, CriKey *plugin, int x, int y);
+ ~CriKeyCurPoint();
+
+ void update(int n);
+
+ CriKey *plugin;
CriKeyWindow *gui;
};
~CriKeyWindow();
void create_objects();
- void draw_key(int mode);
void update_color(int color);
void update_gui();
void start_color_thread();
CriKey *plugin;
CriKeyThreshold *threshold;
CriKeyDrawMode *draw_mode;
- CriKeyKeyMode *key_mode;
CriKeyColorButton *color_button;
CriKeyColorPicker *color_picker;
- int color_x, color_y, key_x, key_y;
+ int color_x, color_y;
BC_Title *title_x, *title_y;
- CriKeyNum *point_x, *point_y;
+ CriKeyPointX *point_x;
+ CriKeyPointY *point_y;
+ CriKeyNewPoint *new_point;
+ CriKeyDelPoint *del_point;
+ CriKeyPointUp *point_up;
+ CriKeyPointDn *point_dn;
+ CriKeyCurPoint *cur_point;
int dragging;
+ float last_x, last_y;
CriKeyDrag *drag;
+ CriKeyPoints *points;
};
#endif
int TitleWindow::grab_event(XEvent *event)
{
+ switch( event->type ) {
+ case ButtonPress: break;
+ case ButtonRelease: break;
+ case MotionNotify: break;
+ default: return 0;
+ }
+
MWindow *mwindow = client->server->mwindow;
CWindowGUI *cwindow_gui = mwindow->cwindow->gui;
CWindowCanvas *canvas = cwindow_gui->canvas;
- int cx, cy; canvas->get_canvas()->get_relative_cursor_xy(cx, cy);
- if( cx < mwindow->theme->ccanvas_x ) return 0;
- if( cx >= mwindow->theme->ccanvas_x+mwindow->theme->ccanvas_w ) return 0;
- if( cy < mwindow->theme->ccanvas_y ) return 0;
- if( cy >= mwindow->theme->ccanvas_y+mwindow->theme->ccanvas_h ) return 0;
+ int cx, cy; cwindow_gui->get_relative_cursor_xy(cx, cy);
+ cx -= mwindow->theme->ccanvas_x;
+ cy -= mwindow->theme->ccanvas_y;
+
+ if( !dragging ) {
+ if( cx < 0 || cx >= mwindow->theme->ccanvas_w ) return 0;
+ if( cy < 0 || cy >= mwindow->theme->ccanvas_h ) return 0;
+ }
switch( event->type ) {
case ButtonPress:
dragging = 0;
return 1;
case MotionNotify:
- if( dragging ) break;
+ if( !dragging ) return 0;
+ break;
default:
return 0;
}