nested_renderengine->command->command = command;
result = 0;
}
+ if( edit_sample_rate <= 0 )
+ result = 1;
if( !result ) {
// speed_buffer is (have_speed ? speed_temp : buffer)
BC_SubMenu *submenu;
add_item(info = new AssetPopupInfo(mwindow, this));
add_item(format = new AWindowListFormat(mwindow, gui));
- add_item(new AssetPopupSort(mwindow, this));
+ add_item(open_edl = new AssetPopupOpenEDL(mwindow, this));
+ add_item(to_clip = new AssetPopupToClip(mwindow, this));
+ add_item(sort = new AssetPopupSort(mwindow, this));
add_item(index = new AssetPopupBuildIndex(mwindow, this));
add_item(view = new AssetPopupView(mwindow, this));
add_item(view_window = new AssetPopupViewWindow(mwindow, this));
add_item(open_mixer = new AssetPopupOpenMixer(mwindow, this));
add_item(insert_mixer = new AssetPopupInsertMixer(mwindow, this));
- add_item(new AssetPopupPaste(mwindow, this));
+ add_item(paste = new AssetPopupPaste(mwindow, this));
add_item(menu_item = new BC_MenuItem(_("Match...")));
menu_item->add_submenu(submenu = new BC_SubMenu());
submenu->add_submenuitem(new AssetMatchSize(mwindow, this));
}
+AssetPopupOpenEDL::AssetPopupOpenEDL(MWindow *mwindow, AssetPopup *popup)
+ : BC_MenuItem(_("Open EDL"))
+{
+ this->mwindow = mwindow;
+ this->popup = popup;
+}
+AssetPopupOpenEDL::~AssetPopupOpenEDL()
+{
+}
+
+int AssetPopupOpenEDL::handle_event()
+{
+ int assets_total = mwindow->session->drag_assets->size();
+ if( assets_total ) {
+ popup->unlock_window();
+ Indexable *idxbl = mwindow->session->drag_assets->get(0);
+ EDL *edl = idxbl && !idxbl->is_asset ? (EDL *)idxbl : 0;
+ if( edl )
+ mwindow->stack_push(edl);
+ else
+ eprintf(_("media is not EDL:\n%s"), idxbl->path);
+ popup->lock_window("AssetPopupOpenEDL::handle_event");
+ }
+ return 1;
+}
+
+
+AssetPopupToClip::AssetPopupToClip(MWindow *mwindow, AssetPopup *popup)
+ : BC_MenuItem(_("EDL to clip"))
+{
+ this->mwindow = mwindow;
+ this->popup = popup;
+}
+
+AssetPopupToClip::~AssetPopupToClip()
+{
+}
+
+int AssetPopupToClip::handle_event()
+{
+ mwindow->media_to_clip();
+ return 1;
+}
+
+
AssetPopupBuildIndex::AssetPopupBuildIndex(MWindow *mwindow, AssetPopup *popup)
: BC_MenuItem(_("Rebuild index"))
{
AssetPopupInfo *info;
+ AWindowListFormat *format;
+ AssetPopupOpenEDL *open_edl;
+ AssetPopupToClip *to_clip;
+ AssetPopupSort *sort;
AssetPopupBuildIndex *index;
AssetPopupView *view;
AssetPopupViewWindow *view_window;
AssetPopupOpenMixer *open_mixer;
AssetPopupInsertMixer *insert_mixer;
- AWindowListFormat *format;
+ AssetPopupPaste *paste;
};
class AssetPopupInfo : public BC_MenuItem
AssetPopup *popup;
};
+class AssetPopupOpenEDL : public BC_MenuItem
+{
+public:
+ AssetPopupOpenEDL(MWindow *mwindow, AssetPopup *popup);
+ ~AssetPopupOpenEDL();
+
+ int handle_event();
+
+ MWindow *mwindow;
+ AssetPopup *popup;
+};
+
+class AssetPopupToClip : public BC_MenuItem
+{
+public:
+ AssetPopupToClip(MWindow *mwindow, AssetPopup *popup);
+ ~AssetPopupToClip();
+
+ int handle_event();
+
+ MWindow *mwindow;
+ AssetPopup *popup;
+};
+
class AssetPopupSort : public BC_MenuItem
{
public:
class AssetPopup;
class AssetPopupInfo;
+class AssetPopupOpenEDL;
+class AssetPopupToClip;
class AssetPopupSort;
class AssetPopupBuildIndex;
class AssetPopupView;
}
-void CacheBase::remove_asset(Asset *asset)
+void CacheBase::remove_item(int source_id, char *path)
{
CacheItemBase *current, *next;
lock->lock("CacheBase::remove_id");
for( current=first; current; current=next ) {
next = current->next;
- if( (current->path && !strcmp(current->path, asset->path)) ||
- current->source_id == asset->id)
+ if( current->source_id == source_id ||
+ (path && current->path && !strcmp(current->path, path)) )
del_item(current);
}
lock->unlock();
-//printf("CacheBase::remove_asset: removed %d entries for %s\n", total, asset->path);
}
-
+void CacheBase::remove_item(Indexable *idxbl)
+{
+ remove_item(idxbl->id, idxbl->path);
+}
+void CacheBase::remove_asset(Asset *asset)
+{
+ remove_item(asset);
+}
void CacheBase::del_item(CacheItemBase *item)
{
// Delete item.
void del_item(CacheItemBase *item);
int delete_item(CacheItemBase *item);
-// Remove all items with the asset id.
+// Remove all items with the same source_id or matching path if set
+ void remove_item(int source_id, char *path);
+ void remove_item(Indexable *idxbl);
void remove_asset(Asset *asset);
// Called when done with the item returned by get_.
// Ignore if item was 0.
BC_SubMenu *submenu;
add_item(info = new ClipPopupInfo(mwindow, this));
add_item(format = new AWindowListFormat(mwindow, gui));
- add_item(new ClipPopupSort(mwindow, this));
+ add_item(sort = new ClipPopupSort(mwindow, this));
+ add_item(open_edl = new ClipPopupOpenEDL(mwindow, this));
+ add_item(to_media = new ClipPopupToMedia(mwindow, this));
add_item(view = new ClipPopupView(mwindow, this));
add_item(view_window = new ClipPopupViewWindow(mwindow, this));
- add_item(new ClipPopupCopy(mwindow, this));
- add_item(new ClipPopupNest(mwindow, this));
- add_item(new ClipPopupUnNest(mwindow, this));
- add_item(new ClipPopupPaste(mwindow, this));
+ add_item(copy = new ClipPopupCopy(mwindow, this));
+ add_item(paste = new ClipPopupPaste(mwindow, this));
add_item(menu_item = new BC_MenuItem(_("Match...")));
menu_item->add_submenu(submenu = new BC_SubMenu());
submenu->add_submenuitem(new ClipMatchSize(mwindow, this));
}
-ClipPopupNest::ClipPopupNest(MWindow *mwindow, ClipPopup *popup)
- : BC_MenuItem(_("Nest"))
+ClipPopupToMedia::ClipPopupToMedia(MWindow *mwindow, ClipPopup *popup)
+ : BC_MenuItem(_("Nest to Media"))
{
this->mwindow = mwindow;
this->popup = popup;
}
-ClipPopupNest::~ClipPopupNest()
+ClipPopupToMedia::~ClipPopupToMedia()
{
}
-int ClipPopupNest::handle_event()
+int ClipPopupToMedia::handle_event()
{
- MWindowGUI *gui = mwindow->gui;
- gui->lock_window("ClipPopupNest::handle_event 1");
- if( mwindow->edl->session->proxy_scale != 1 ) {
+ if( mwindow->edl->session->proxy_scale == 1 )
+ mwindow->clip_to_media();
+ else
eprintf("Nesting not allowed when proxy scale != 1");
- return 1;
- }
- int clips_total = mwindow->session->drag_clips->total;
- for( int i=0; i<clips_total; ++i ) {
- EDL *edl = mwindow->edl;
- time_t dt; time(&dt);
- struct tm dtm; localtime_r(&dt, &dtm);
- char path[BCSTRLEN];
- sprintf(path, _("Nested_%02d%02d%02d-%02d%02d%02d"),
- dtm.tm_year+1900, dtm.tm_mon+1, dtm.tm_mday,
- dtm.tm_hour, dtm.tm_min, dtm.tm_sec);
- EDL *clip = mwindow->session->drag_clips->values[i];
- EDL *nested = edl->new_nested(clip, path);
- EDL *new_clip = edl->create_nested_clip(nested);
- new_clip->folder_no = AW_CLIP_FOLDER;
- sprintf(new_clip->local_session->clip_icon,
- "clip_%02d%02d%02d-%02d%02d%02d.png",
- dtm.tm_year+1900, dtm.tm_mon+1, dtm.tm_mday,
- dtm.tm_hour, dtm.tm_min, dtm.tm_sec);
- snprintf(new_clip->local_session->clip_title,
- sizeof(new_clip->local_session->clip_title),
- _("Nested: %s"), clip->local_session->clip_title);
- strcpy(new_clip->local_session->clip_notes,
- clip->local_session->clip_notes);
- int idx = edl->clips.number_of(clip);
- if( idx >= 0 ) {
- edl->clips[idx] = new_clip;
- clip->remove_user();
- }
- else
- edl->clips.append(new_clip);
- mwindow->mainindexes->add_next_asset(0, nested);
- }
- mwindow->mainindexes->start_build();
- popup->gui->async_update_assets();
- gui->unlock_window();
return 1;
}
-ClipPopupUnNest::ClipPopupUnNest(MWindow *mwindow, ClipPopup *popup)
- : BC_MenuItem(_("UnNest"))
+ClipPopupOpenEDL::ClipPopupOpenEDL(MWindow *mwindow, ClipPopup *popup)
+ : BC_MenuItem(_("Open EDL"))
{
this->mwindow = mwindow;
this->popup = popup;
}
-ClipPopupUnNest::~ClipPopupUnNest()
+
+ClipPopupOpenEDL::~ClipPopupOpenEDL()
{
}
-int ClipPopupUnNest::handle_event()
+int ClipPopupOpenEDL::handle_event()
{
- EDL *nested_edl = 0;
- MWindowGUI *gui = mwindow->gui;
- gui->lock_window("ClipPopupUnNest::handle_event 1");
int clips_total = mwindow->session->drag_clips->total;
- for( int i=0; i<clips_total; ++i ) {
- EDL *clip = mwindow->session->drag_clips->values[i];
- Track *track = clip->tracks->first;
- Edit *edit = track ? track->edits->first : 0;
- nested_edl = edit && !edit->next && !edit->asset ? edit->nested_edl : 0;
- while( nested_edl && (track=track->next)!=0 ) {
- Edit *edit = track->edits->first;
- if( !edit || edit->next ||
- ( edit->nested_edl != nested_edl &&
- strcmp(edit->nested_edl->path, nested_edl->path) ) )
- nested_edl = 0;
- }
- if( nested_edl ) {
- EDL *edl = mwindow->edl;
- EDL *new_clip = new EDL(edl);
- new_clip->create_objects();
- new_clip->copy_all(nested_edl);
- new_clip->folder_no = AW_CLIP_FOLDER;
- int idx = edl->clips.number_of(clip);
- if( idx >= 0 ) {
- edl->clips[idx] = new_clip;
- clip->remove_user();
- }
- else
- edl->clips.append(new_clip);
- popup->gui->async_update_assets();
- }
+ if( clips_total ) {
+ popup->unlock_window();
+ EDL *clip = mwindow->session->drag_clips->values[0];
+ mwindow->stack_push(clip);
+ popup->lock_window("ClipPopupOpenEDL::handle_event");
}
- gui->unlock_window();
return 1;
}
ClipPopupInfo *info;
+ AWindowListFormat *format;
+ ClipPopupSort *sort;
+ ClipPopupOpenEDL *open_edl;
ClipPopupView *view;
ClipPopupViewWindow *view_window;
- AWindowListFormat *format;
+ ClipPopupCopy *copy;
+ ClipPopupToMedia *to_media;
+ ClipPopupPaste *paste;
};
class ClipPopupInfo : public BC_MenuItem
AWindowGUI *gui;
};
-class ClipPopupNest : public BC_MenuItem
+class ClipPopupToMedia : public BC_MenuItem
{
public:
- ClipPopupNest(MWindow *mwindow, ClipPopup *popup);
- ~ClipPopupNest();
+ ClipPopupToMedia(MWindow *mwindow, ClipPopup *popup);
+ ~ClipPopupToMedia();
int handle_event();
ClipPopup *popup;
};
-class ClipPopupUnNest : public BC_MenuItem
+class ClipPopupOpenEDL : public BC_MenuItem
{
public:
- ClipPopupUnNest(MWindow *mwindow, ClipPopup *popup);
- ~ClipPopupUnNest();
+ ClipPopupOpenEDL(MWindow *mwindow, ClipPopup *popup);
+ ~ClipPopupOpenEDL();
int handle_event();
class ClipMatchSize;
class ClipMatchRate;
class ClipMatchAll;
-class ClipPopupProjectRemove;
-class ClipPopupDiskRemove;
+class ClipPopupDelete;
class ClipPasteToFolder;
-class ClipListMenu;
class ClipListFormat;
+class ClipListMenu;
+class ClipPopupToMedia;
+class ClipPopupOpenEDL;
#endif
int w = ColorWindow::calculate_w();
int h = ColorWindow::calculate_h();
if( ok_cancel )
- h += bmax(BC_OKButton::calculate_h(),BC_CancelButton::calculate_h());
+ h += bmax(ColorOK::calculate_h(),ColorCancel::calculate_h());
int root_w = display_info.get_root_w(), root_h = display_info.get_root_h();
if( x+w > root_w ) x = root_w - w;
if( y+h > root_h ) y = root_h - h;
aph_a->create_objects(); aph_a->set_tooltip(_("Alpha"));
}
if( ok_cancel ) {
- add_tool(new BC_OKButton(window));
- add_tool(new BC_CancelButton(window));
+ add_tool(new ColorOK(this, window));
+ add_tool(new ColorCancel(this, window));
}
create_objects(this);
}
+ColorOK::ColorOK(ColorGUI *gui, BC_WindowBase *window)
+ : BC_OKButton(window)
+{
+ this->gui = gui;
+ this->window = window;
+}
+int ColorOK::handle_event()
+{
+ gui->ok_cancel = 0;
+ gui->close_gui();
+ window->sync_display();
+ return 1;
+}
+
+ColorCancel::ColorCancel(ColorGUI *gui, BC_WindowBase *window)
+ : BC_CancelButton(window)
+{
+ this->gui = gui;
+ this->window = window;
+}
+int ColorCancel::handle_event()
+{
+ gui->ok_cancel = 1;
+ gui->close_gui();
+ window->sync_display();
+ return 1;
+}
+
int ColorGUI::close_gui()
{
+ if( button_grabbed ) {
+ button_grabbed = 0;
+ window->ungrab_buttons();
+ window->ungrab_cursor();
+ }
window->set_done(ok_cancel ? 1 : 0);
return 1;
}
if( gui->window->grab_buttons() ) {
gui->window->grab_cursor();
gui->button_grabbed = 1;
- gui->button_press_gui(); // redraw face HI
+ return BC_Button::button_press_event(); // redraw face HI
}
return 1;
}
ColorPicker *thread;
};
+class ColorOK : public BC_OKButton
+{
+public:
+ ColorOK(ColorGUI *gui, BC_WindowBase *window);
+ int handle_event();
+
+ BC_WindowBase *window;
+ ColorGUI *gui;
+};
+
+class ColorCancel : public BC_CancelButton
+{
+public:
+ ColorCancel(ColorGUI *gui, BC_WindowBase *window);
+ int handle_event();
+
+ BC_WindowBase *window;
+ ColorGUI *gui;
+};
class PaletteWheel : public BC_SubWindow
{
#include "automation.h"
#include "autos.h"
+#include "bccolors.h"
#include "bcsignals.h"
#include "canvas.h"
#include "clip.h"
gui->eyedrop_visible = 1;
}
-// Decompression coefficients straight out of jpeglib
-#define V_TO_R 1.40200
-#define V_TO_G -0.71414
-
-#define U_TO_G -0.34414
-#define U_TO_B 1.77200
-
-#define GET_COLOR(type, components, max, do_yuv) \
-{ \
+#define GET_COLOR(type, components, max, do_yuv) { \
type *row = (type*)(refresh_frame->get_rows()[i]) + \
j * components; \
float red = (float)*row++ / max; \
float green = (float)*row++ / max; \
float blue = (float)*row++ / max; \
if( do_yuv ) \
- { \
- float r = red + V_TO_R * (blue - 0.5); \
- float g = red + U_TO_G * (green - 0.5) + V_TO_G * (blue - 0.5); \
- float b = red + U_TO_B * (green - 0.5); \
- mwindow->edl->local_session->red += r; \
- mwindow->edl->local_session->green += g; \
- mwindow->edl->local_session->blue += b; \
- if( r > mwindow->edl->local_session->red_max ) mwindow->edl->local_session->red_max = r; \
- if( g > mwindow->edl->local_session->green_max ) mwindow->edl->local_session->green_max = g; \
- if( b > mwindow->edl->local_session->blue_max ) mwindow->edl->local_session->blue_max = b; \
- } \
- else \
- { \
- mwindow->edl->local_session->red += red; \
- mwindow->edl->local_session->green += green; \
- mwindow->edl->local_session->blue += blue; \
- if( red > mwindow->edl->local_session->red_max ) mwindow->edl->local_session->red_max = red; \
- if( green > mwindow->edl->local_session->green_max ) mwindow->edl->local_session->green_max = green; \
- if( blue > mwindow->edl->local_session->blue_max ) mwindow->edl->local_session->blue_max = blue; \
- } \
+ YUV::yuv.yuv_to_rgb_f(red, green, blue, red, green-0.5, blue-0.5); \
+ mwindow->edl->local_session->red += red; \
+ mwindow->edl->local_session->green += green; \
+ mwindow->edl->local_session->blue += blue; \
+ if( red > mwindow->edl->local_session->red_max ) mwindow->edl->local_session->red_max = red; \
+ if( green > mwindow->edl->local_session->green_max ) mwindow->edl->local_session->green_max = green; \
+ if( blue > mwindow->edl->local_session->blue_max ) mwindow->edl->local_session->blue_max = blue; \
}
-
-
mwindow->edl->local_session->red = 0;
mwindow->edl->local_session->green = 0;
mwindow->edl->local_session->blue = 0;
float y, u, v;
YUV::yuv.rgb_to_yuv_f(r, g, b, y, u, v);
this->y->update(y);
- this->u->update(u); u += 0.5;
- this->v->update(v); v += 0.5;
+ this->u->update(u += 0.5);
+ this->v->update(v += 0.5);
int yx = 255*y + 0.5; bclamp(yx,0,255);
int ux = 255*u + 0.5; bclamp(ux,0,255);
int i = masks.size();
while( --i >= 0 ) {
if( strcmp(masks[i]->name, nm) ) continue;
- masks.remove_object_number(i);
+ masks.remove_object_number(i++);
}
mask = new SubMask(0, -1);
strncpy(mask->name, nm, sizeof(mask->name)-1);
int i = masks.size();
while( --i >= 0 ) {
if( strcmp(masks[i]->name, nm) ) continue;
- masks.remove_object_number(i);
+ masks.remove_object_number(i++);
}
save_masks(masks);
masks.remove_all_objects();
#include "edits.h"
#include "edl.h"
#include "edlsession.h"
+#include "file.h"
#include "filexml.h"
#include "floatauto.h"
#include "floatautos.h"
}
}
-EDL *EDL::new_nested(EDL *edl, const char *path)
+EDL *EDL::new_nested_edl(EDL *edl, const char *path)
{
EDL *nested = new EDL; // no parent for nested edl
nested->create_objects();
return nested;
}
+EDL *EDL::get_nested_edl()
+{
+ Track *track = tracks->first;
+ Edit *edit = track ? track->edits->first : 0;
+ EDL *nested = edit && !edit->next && !edit->asset ? edit->nested_edl : 0;
+ while( nested && (track=track->next)!=0 ) {
+ Edit *edit = track->edits->first;
+ if( !edit || edit->next ||
+ ( edit->nested_edl != nested &&
+ strcmp(edit->nested_edl->path, nested->path) ) )
+ nested = 0;
+ }
+ return nested;
+}
+
+
EDL *EDL::create_nested_clip(EDL *nested)
{
EDL *new_edl = new EDL(this); // parent for clip edl
void EDL::create_nested(EDL *nested)
{
+ int video_tracks = 0, audio_tracks = 0;
+ for( Track *track=nested->tracks->first; track!=0; track=track->next ) {
+ if( track->data_type == TRACK_VIDEO && track->record ) ++video_tracks;
+ if( track->data_type == TRACK_AUDIO && track->record ) ++audio_tracks;
+ }
+// renderengine properties
+ if( video_tracks > 0 )
+ video_tracks = 1;
+ if( audio_tracks > 0 )
+ audio_tracks = nested->session->audio_channels;
+
// Keep frame rate, sample rate, and output size unchanged.
// Nest all video & audio outputs
+ session->video_channels = video_tracks;
+ session->audio_channels = audio_tracks;
session->video_tracks = 1;
- session->audio_tracks = nested->session->audio_channels;
+ session->audio_tracks = audio_tracks;
create_default_tracks();
insert_asset(0, nested, 0, 0, 0);
}
+void EDL::overwrite_clip(EDL *clip)
+{
+ int folder = folder_no;
+ char clip_title[BCTEXTLEN]; strcpy(clip_title, local_session->clip_title);
+ char clip_notes[BCTEXTLEN]; strcpy(clip_notes, local_session->clip_notes);
+ char clip_icon[BCSTRLEN]; strcpy(clip_icon, local_session->clip_icon);
+ copy_all(clip);
+ folder_no = folder;
+ strcpy(local_session->clip_title, clip_title);
+ strcpy(local_session->clip_notes, clip_notes);
+ strcpy(local_session->clip_icon, clip_icon);
+ if( !clip_icon[0] ) return;
+// discard old clip icon to reconstruct
+ char clip_icon_path[BCTEXTLEN];
+ snprintf(clip_icon_path, sizeof(clip_icon_path),
+ "%s/%s", File::get_config_path(), clip_icon);
+ remove(clip_icon_path);
+}
+
void EDL::retrack()
{
int min_w = session->output_w, min_h = session->output_h;
if( new_nested_edl ) {
length = new_nested_edl->tracks->total_length();
- layers = 1;
+ layers = new_nested_edl->session->video_channels;
channels = new_nested_edl->session->audio_channels;
}
int copy_assets(int copy_flags, double start, double end,
FileXML *file, const char *output_path);
void copy_indexables(EDL *edl);
- EDL *new_nested(EDL *edl, const char *path);
+ EDL *new_nested_edl(EDL *edl, const char *path);
+ EDL *get_nested_edl();
EDL *create_nested_clip(EDL *nested);
void create_nested(EDL *nested);
+ void overwrite_clip(EDL *clip);
void paste_silence(double start, double end,
int edit_labels /* = 1 */,
int edit_plugins,
}
-
extern long cin_timezone;
ArrayList<PluginServer*>* MWindow::plugindb = 0;
}
}
-void MWindow::close_mixers(int destroy)
+void MWindow::close_mixers(int result)
{
ArrayList<ZWindow*> closed;
zwindows_lock->lock("MWindow::close_mixers");
ZWindow *zwindow = zwindows[i];
if( zwindow->idx < 0 ) continue;
zwindow->idx = -1;
- zwindow->destroy = destroy;
ZWindowGUI *zgui = zwindow->zgui;
zgui->lock_window("MWindow::select_zwindow 0");
- zgui->set_done(0);
+ zgui->set_done(result);
zgui->unlock_window();
closed.append(zwindow);
}
if(debug) PRINT_TRACE
}
+void MWindow::stack_push(EDL *new_edl)
+{
+// needs gui lock
+ gui->lock_window("MWindow::stack_push");
+ if( stack.size() < 9 ) {
+ undo_before();
+ StackItem &item = stack.append();
+ item.edl = edl;
+ item.new_edl = new_edl;
+ item.undo = undo;
+ edl = new_edl;
+ edl->add_user();
+ strcpy(session->filename, edl->path);
+ undo = new MainUndo(this);
+ gui->stack_button->update();
+ update_project(LOADMODE_REPLACE);
+ }
+ gui->unlock_window();
+}
+
+void MWindow::stack_pop()
+{
+ if( !stack.size() ) return;
+// writes on config_path/backup%d.xml
+ save_backup();
+// already have gui lock
+ forget_nested_edl(edl);
+ StackItem &item = stack.last();
+// session edl replaced, overwrite and save clip data
+ if( item.new_edl != edl && item.new_edl->parent_edl )
+ item.new_edl->overwrite_clip(edl);
+ edl->remove_user();
+ edl = item.edl;
+ delete undo;
+ undo = item.undo;
+ stack.remove();
+ strcpy(session->filename, edl->path);
+ update_project(LOADMODE_REPLACE);
+ undo_after(_("open edl"), LOAD_ALL);
+ gui->stack_button->update();
+}
+
+void MWindow::forget_nested_edl(EDL *nested)
+{
+ frame_cache->remove_item(nested);
+ wave_cache->remove_item(nested);
+ if( gui->render_engine &&
+ gui->render_engine_id == nested->id ) {
+ delete gui->render_engine;
+ gui->render_engine = 0;
+ }
+ if( gui->resource_thread->render_engine_id == nested->id ) {
+ gui->resource_thread->render_engine_id = -1;
+ delete gui->resource_thread->render_engine;
+ gui->resource_thread->render_engine = 0;
+ }
+}
+
+void MWindow::clip_to_media()
+{
+ if( edl->session->proxy_scale != 1 ) {
+ eprintf("Nesting not allowed when proxy scale != 1");
+ return;
+ }
+ undo_before();
+ int clips_total = session->drag_clips->total;
+ for( int i=0; i<clips_total; ++i ) {
+ EDL *clip = session->drag_clips->values[i];
+ time_t dt; time(&dt);
+ struct tm dtm; localtime_r(&dt, &dtm);
+ char path[BCSTRLEN], *cp = path, *ep = cp+sizeof(path)-1;
+ cp += snprintf(cp, ep-cp, _("Nested_%02d%02d%02d-%02d%02d%02d_"),
+ dtm.tm_year+1900, dtm.tm_mon+1, dtm.tm_mday,
+ dtm.tm_hour, dtm.tm_min, dtm.tm_sec);
+ cp += snprintf(cp, ep-cp, clip->local_session->clip_title);
+ EDL *nested = edl->new_nested_edl(clip, path);
+ edl->clips.remove(clip);
+ clip->remove_user();
+ mainindexes->add_next_asset(0, nested);
+ }
+ undo_after(_("clip2media"), LOAD_ALL);
+ mainindexes->start_build();
+ awindow->gui->async_update_assets();
+}
+
+void MWindow::media_to_clip()
+{
+ undo_before();
+ int assets_total = session->drag_assets->total;
+ for( int i=0; i<assets_total; ++i ) {
+ Indexable *idxbl = session->drag_assets->values[i];
+ if( idxbl->is_asset ) {
+ eprintf(_("media is not EDL:\n%s"), idxbl->path);
+ continue;
+ }
+ char clip_title[BCSTRLEN];
+ int name_ok = 0;
+ while( !name_ok ) {
+ name_ok = 1;
+ sprintf(clip_title, _("Clip %d"), session->clip_number++);
+ for( int i=0; name_ok && i<edl->clips.size(); ++i ) {
+ char *title = edl->clips[i]->local_session->clip_title;
+ if( !strcasecmp(clip_title, title) ) name_ok = 0;
+ }
+ }
+ EDL *nested = (EDL *)idxbl;
+ EDL *clip = edl->add_clip(nested);
+ strcpy(clip->local_session->clip_title, clip_title);
+ snprintf(clip->local_session->clip_notes,
+ sizeof(clip->local_session->clip_notes),
+ _("From: %s"), nested->path);
+ }
+ undo_after(_("media2clip"), LOAD_ALL);
+ awindow->gui->async_update_assets();
+}
+
void MWindow::update_preferences(Preferences *prefs)
{
if( prefs != preferences )
}
+void MWindow::get_backup_path(char *path, int len)
+{
+ char *cp = path, *ep = cp + len-1;
+ cp += snprintf(cp, ep-cp, "%s/", File::get_config_path());
+ int idx = stack.size();
+ cp += snprintf(cp, ep-cp, idx ? BACKUPn_FILE : BACKUP_FILE, idx);
+}
+
void MWindow::save_backup()
{
FileXML file;
edl->optimize();
edl->set_path(session->filename);
+
char backup_path[BCTEXTLEN], backup_path1[BCTEXTLEN];
- snprintf(backup_path, sizeof(backup_path), "%s/%s",
- File::get_config_path(), BACKUP_FILE);
- snprintf(backup_path1, sizeof(backup_path1), "%s/%s",
- File::get_config_path(), BACKUP_FILE1);
+ get_backup_path(backup_path, sizeof(backup_path));
rename(backup_path, backup_path1);
edl->save_xml(&file, backup_path);
file.terminate_string();
FileSystem fs;
fs.complete_path(backup_path);
- if(file.write_to_file(backup_path))
- {
+ if(file.write_to_file(backup_path)) {
char string2[256];
sprintf(string2, _("Couldn't open %s for writing."), backup_path);
gui->show_message(string2);
path_list.set_array_delete();
char *out_path;
char backup_path[BCTEXTLEN];
- snprintf(backup_path, sizeof(backup_path), "%s/%s",
- File::get_config_path(), BACKUP_FILE);
+ get_backup_path(backup_path, sizeof(backup_path));
FileSystem fs;
fs.complete_path(backup_path);
#define FONT_SEARCHPATH "fonts"
+class StackItem
+{
+public:
+ EDL *edl, *new_edl;
+ MainUndo *undo;
+};
+
+class Stack : public ArrayList<StackItem>
+{
+public:
+};
+
class MWindow : public Thread
{
int get_tracks_height();
// Total horizontal pixels in timeline
int get_tracks_width();
+// session stack
+ void stack_push(EDL *edl);
+ void stack_pop();
+ void forget_nested_edl(EDL *nested);
+ void clip_to_media();
+ void media_to_clip();
// Show windows
void show_vwindow();
void show_awindow();
void create_mixers(double position = 0);
void refresh_mixers(int dir=1);
void stop_mixers();
- void close_mixers(int destroy=1);
+ void close_mixers(int result=1);
void open_mixers();
ZWindow *get_mixer(Mixer *&mixer);
void del_mixer(ZWindow *zwindow);
void split_y();
void crop_video(int mode);
void update_plugins();
+ void get_backup_path(char *path, int len);
// Call after every edit operation
void save_backup();
void load_backup();
// Main undo stack
MainUndo *undo;
int undo_command;
+// session stack
+ Stack stack;
BC_Hash *defaults;
Assets *assets;
time_t now; time(&now);
struct tm dtm; localtime_r(&now, &dtm);
char *cp = new_edl->local_session->clip_notes;
- int n, sz = sizeof(new_edl->local_session->clip_notes)-1;
- if( txt && *txt ) {
- n = snprintf(cp, sz, "%s", txt);
- cp += n; sz -= n;
- }
- n = snprintf(cp, sz,
+ char *ep = cp + sizeof(new_edl->local_session->clip_notes)-1;
+ if( txt && *txt )
+ cp += snprintf(cp, ep-cp, "%s", txt);
+ cp += snprintf(cp, ep-cp,
"%02d/%02d/%02d %02d:%02d:%02d, +%s\n",
dtm.tm_year+1900, dtm.tm_mon+1, dtm.tm_mday,
dtm.tm_hour, dtm.tm_min, dtm.tm_sec, duration);
- cp += n; sz -= n;
if( path && *path ) {
FileSystem fs;
char title[BCTEXTLEN];
fs.extract_name(title, path);
- n = snprintf(cp, sz, "%s", title);
- cp += n; sz -= n;
+ cp += snprintf(cp, ep-cp, "%s", title);
}
- cp[n] = 0;
sprintf(new_edl->local_session->clip_icon,
- "clip_%02d%02d%02d-%02d%02d%02d.png",
+ "clip_%02d%02d%02d-%02d%02d%02d-%d.png",
dtm.tm_year+1900, dtm.tm_mon+1, dtm.tm_mday,
- dtm.tm_hour, dtm.tm_min, dtm.tm_sec);
+ dtm.tm_hour, dtm.tm_min, dtm.tm_sec,
+ new_edl->id);
new_edl->folder_no = AW_CLIP_FOLDER;
edl->update_assets(new_edl);
int cur_x, cur_y;
drag_popup = 0;
render_engine = 0;
+ render_engine_id = -1;
for(int i = 0; i < TOTAL_PANES; i++)
pane[i] = 0;
if(debug) printf("MWindowGUI::create_objects %d\n", __LINE__);
- int x = get_w() - MainShBtns::calculate_w(-1, 0, -1);
- add_subwindow(mainmenu = new MainMenu(mwindow, this, x));
- mainmenu->create_objects();
- add_subwindow(mainshbtns = new MainShBtns(mwindow, x, -1));
+ int x1 = get_w() - MainShBtns::calculate_w(-1, 0, -1) - xS(5);
+ add_subwindow(mainshbtns = new MainShBtns(mwindow, x1, -1));
mainshbtns->load(mwindow->preferences);
+ int x2 = x1 - mwindow->theme->stack_button_w - xS(5);
+ add_subwindow(stack_button = new StackButton(mwindow, x2, yS(2)));
+ add_subwindow(mainmenu = new MainMenu(mwindow, this, x2));
+ mainmenu->create_objects();
mwindow->theme->get_mwindow_sizes(this, get_w(), get_h());
mwindow->theme->draw_mwindow_bg(this);
if(debug) printf("MWindowGUI::create_objects %d\n", __LINE__);
add_subwindow(mbuttons = new MButtons(mwindow, this));
mbuttons->create_objects();
- int x1 = mbuttons->get_x() + mbuttons->get_w(), y1 = mbuttons->get_y()+yS(2);
- add_subwindow(proxy_toggle = new ProxyToggle(mwindow, mbuttons, x1, y1));
- x1 += proxy_toggle->get_w() + xS(3);
+ int y1 = mbuttons->get_y()+yS(2);
+ add_subwindow(proxy_toggle = new ProxyToggle(mwindow, mbuttons, x2, y1));
add_subwindow(ffmpeg_toggle = new FFMpegToggle(mwindow, mbuttons, x1, y1));
pane[TOP_LEFT_PANE] = new TimelinePane(mwindow,
//printf("MWindowGUI::resize_event %d\n", __LINE__);
mwindow->session->mwindow_w = w;
mwindow->session->mwindow_h = h;
- int x = w - MainShBtns::calculate_w(-1, 0, -1);
- mainmenu->resize_event(x, mainmenu->get_h());
- mainshbtns->reposition_window(x, -1);
+ int x1 = get_w() - MainShBtns::calculate_w(-1, 0, -1) - xS(5);
+ mainshbtns->reposition_window(x1, -1);
+ int x2 = x1 - mwindow->theme->stack_button_w - xS(5);
+ stack_button->reposition_window(x2, stack_button->get_y());
+ mainmenu->resize_event(x2, mainmenu->get_h());
mwindow->theme->get_mwindow_sizes(this, w, h);
mwindow->theme->draw_mwindow_bg(this);
mbuttons->resize_event();
- int x1 = mbuttons->get_x() + mbuttons->get_w(), y1 = mbuttons->get_y()+yS(2);
- proxy_toggle->reposition_window(x1, y1);
- x1 += proxy_toggle->get_w() + xS(3);
+ int y1 = mbuttons->get_y()+yS(2);
+ proxy_toggle->reposition_window(x2, y1);
ffmpeg_toggle->reposition_window(x1, y1);
statusbar->resize_event();
zoombar->resize_event();
int MWindowGUI::show_window(int flush)
{
int ret = BC_WindowBase::show_window(flush);
+ stack_button->update();
update_proxy_toggle();
return ret;
}
}
+StackButton::StackButton(MWindow *mwindow, int x, int y)
+ : BC_GenericButton(x, y, mwindow->theme->stack_button_w, "0")
+{
+ this->mwindow = mwindow;
+ set_tooltip(_("Return to previous EDL"));
+}
+
+int StackButton::handle_event()
+{
+ mwindow->stack_pop();
+ return 1;
+}
+
+void StackButton::update()
+{
+ char text[BCSTRLEN];
+ int i = mwindow->stack.size();
+ sprintf(text, "%d", i);
+ set_text(text);
+ draw_face();
+ int hidden = is_hidden();
+ if( !i && !hidden )
+ hide_window();
+ else if( hidden )
+ show_window();
+}
+
+
ProxyToggle::ProxyToggle(MWindow *mwindow, MButtons *mbuttons, int x, int y)
: BC_Toggle(x, y, ( !mwindow->edl->session->proxy_use_scaler ?
mwindow->theme->proxy_p_toggle :
MButtons *mbuttons;
};
+class StackButton : public BC_GenericButton
+{
+public:
+ StackButton(MWindow *mwindow, int x, int y);
+ int handle_event();
+ void update();
+
+ MWindow *mwindow;
+};
+
class ProxyToggle : public BC_Toggle
{
public:
MButtons *mbuttons;
FFMpegToggle *ffmpeg_toggle;
ProxyToggle *proxy_toggle;
+ StackButton *stack_button;
PaneDivider *x_divider;
PaneDivider *y_divider;
TimelinePane *pane[TOTAL_PANES];
// Run-time configuration directory
#define DEAMON_PORT 400
#define BACKUP_FILE "backup.xml"
+#define BACKUPn_FILE "backup%d.xml"
#define BACKUP_FILE1 "backup.prev"
#define LAYOUT_FILE "layout%d_rc"
#define LAYOUT_NAME_LEN 8
prev_l = 0;
operation_count = 0;
render_engine = 0;
+ render_engine_id = -1;
audio_asset = 0;
audio_source = 0;
mtransport_margin = 0;
toggle_margin = 0;
control_pixels = xS(50);
+ stack_button_w = xS(32);
timebar_cursor_color = RED;
BC_WindowBase::get_resources()->bg_color = BLOND;
{
mbuttons_x = 0;
mbuttons_y = gui->menu_h() + yS(1);
- mbuttons_w = w - (ffmpeg_toggle[0]->get_w()+2 + proxy_p_toggle[0]->get_w()+xS(2));
+ mbuttons_w = w - (ffmpeg_toggle[0]->get_w()+xS(2) +
+ proxy_p_toggle[0]->get_w()+xS(2) +
+ stack_button_w);
mbuttons_h = get_image("mbutton_bg")->get_h();
mclock_x = window_border - xS(5);
mclock_y = mbuttons_y-1 + mbuttons_h;
int adivider_x, adivider_y, adivider_w, adivider_h;
int afolders_x, afolders_y, afolders_w, afolders_h;
int alist_x, alist_y, alist_w, alist_h;
+ int stack_button_w;
int audio_color;
// audio zero crossing
int zero_crossing_color;
idx = -1;
edl = 0;
highlighted = 0;
- destroy = 1;
title[0] = 0;
zgui = 0;
}
void ZWindow::handle_done_event(int result)
{
- idx = -1;
stop_playback(1);
- if( destroy )
+ if( result )
mwindow->del_mixer(this);
+ idx = -1;
}
void ZWindow::handle_close_event(int result)
{
ZWindowGUI *zgui;
EDL* edl;
- int idx, destroy;
+ int idx;
int highlighted;
char title[BCTEXTLEN];
};
int ZWindowGUI::close_event()
{
- set_done(0);
+ set_done(1);
return 1;
}
--- /dev/null
+matroska pcm_s16le
+# PCM signed 16-bit little-endian (pcm_s16le) in
+# Matroska (Audio) container.
+# The extension should be "mka".
+# ffmpeg --help encoder=pcm_s16le
+# ffmpeg --help muxer=matroska
--- /dev/null
+matroska pcm_s16le
+# PCM signed 16-bit little-endian (pcm_s16le) in
+# Matroska container.
+# If only audio is exported, the extension should
+# be "mka".
+# ffmpeg --help encoder=pcm_s16le
+# ffmpeg --help muxer=matroska
--- /dev/null
+w64 pcm_s16le
+# Pure audio format.
+# PCM signed 16-bit little-endian (pcm_s16le) in
+# Sony Pictures Digital Wave 64 (Wave64, .w64)
+# ffmpeg --help encoder=pcm_s16le
+# ffmpeg --help muxer=w64
--- /dev/null
+matroska pcm_s24le
+# PCM signed 24-bit little-endian (pcm_s24le) in
+# Matroska container.
+# If only audio is exported, the extension should
+# be "mka".
+# ffmpeg --help encoder=pcm_s24le
+# ffmpeg --help muxer=matroska
--- /dev/null
+matroska pcm_s24le
+# PCM signed 24-bit little-endian (pcm_s24le) in
+# Matroska (Audio) container.
+# The extension should be "mka".
+# ffmpeg --help encoder=pcm_s24le
+# ffmpeg --help muxer=matroska
--- /dev/null
+w64 pcm_s24le
+# Pure audio format.
+# PCM signed 24-bit little-endian (pcm_s24le) in
+# Sony Pictures Digital Wave 64 (Wave64, .w64)
+# ffmpeg --help encoder=pcm_s24le
+# ffmpeg --help muxer=w64
--- /dev/null
+matroska pcm_s32le
+# PCM signed 32-bit little-endian (pcm_s32le) in
+# Matroska (Audio) container.
+# The extension should be "mka".
+# ffmpeg --help encoder=pcm_s32le
+# ffmpeg --help muxer=matroska
--- /dev/null
+matroska pcm_s32le
+# PCM signed 32-bit little-endian (pcm_s32le) in
+# Matroska container.
+# If only audio is exported, the extension should
+# be "mka".
+# ffmpeg --help encoder=pcm_s32le
+# ffmpeg --help muxer=matroska
--- /dev/null
+w64 pcm_s32le
+# Pure audio format.
+# PCM signed 32-bit little-endian (pcm_s32le) in
+# Sony Pictures Digital Wave 64 (Wave64, .w64)
+# ffmpeg --help encoder=pcm_s32le
+# ffmpeg --help muxer=w64
return 0;
}
-
+void BC_GenericButton::set_text(const char *cp)
+{
+ strncpy(text, cp, sizeof(text));
+ draw_face();
+}
class BC_GenericButton : public BC_Button
{
+ int color;
+ char text[BCTEXTLEN];
public:
BC_GenericButton(int x, int y,
const char *text, VFrame **data = 0, int color=-1);
int draw_face(int flash = 1);
static int calculate_w(BC_WindowBase *gui, const char *text);
static int calculate_h();
+ void set_text(const char *cp);
const char *get_text () { return text; }
-private:
- int color;
- char text[BCTEXTLEN];
};
class BC_OKTextButton : public BC_GenericButton
// Not a fix, but much better than nothing.
static int inited = 0;
if( inited ) return;
+ XGrabServer(display);
+ XSync(display, 0);
inited = 1;
int cur_font = current_font;
// locale encodings, needed glyphs to be preloaded
draw_text(5,5, text, 0);
}
set_font(cur_font);
+ XUngrabServer(display);
}
void BC_WindowBase::init_im()
#include "bcsignals.h"
#include "guicast.h"
-
-
+/*
+c++ x.C -I/mnt1/build5/cinelerra-5.1/guicast \
+ -L/mnt1/build5/cinelerra-5.1/guicast/x86_64 -lguicast \
+ -DHAVE_GL -DHAVE_XFT -I/usr/include/freetype2 -lGL -lX11 -lXext \
+ -lXinerama -lXv -lpng -lfontconfig -lfreetype -lXft -pthread
+*/
class TestWindow : public BC_Window
{
void create_objects()
{
+ lock_window("TestWindow::create_objects");
set_color(BLACK);
set_font(LARGEFONT);
draw_text(10, 50, "Hello world");
flash();
flush();
+ unlock_window();
};
};
int main()
{
- new BC_Signals;
+ BC_Signals signals;
+ BC_WindowBase::init_resources(1.);
TestWindow window;
window.create_objects();
window.run_window();
is_keyframe = 0;
pixel_rgb = 0x000000; // BLACK
pixel_yuv = 0x008080;
+ draw_alpha = 1.f;
+ draw_flags = ALIAS_OFF;
stipple = 0;
clear_color = 0x000000;
clear_alpha = 0x00;
// a (~alpha) transparency, 0x00==solid .. 0xff==transparent
void VFrame::set_pixel_color(int rgb, int a)
{
- pixel_rgb = (rgb&0xffffff) | ~a<<24;
+ pixel_rgb = (~a<<24) | (rgb&0xffffff);
int ir = 0xff & (pixel_rgb >> 16);
int ig = 0xff & (pixel_rgb >> 8);
int ib = 0xff & (pixel_rgb >> 0);
YUV::yuv.rgb_to_yuv_8(ir, ig, ib);
- pixel_yuv = (~a<<24) | (ir<<16) | (ig<<8) | (ib<<0);
+ pixel_yuv = (~a<<24) | (ir<<16) | (ig<<8) | (ib<<0);
}
void VFrame::set_stiple(int mask)
{
stipple = mask;
}
-
-int VFrame::draw_pixel(int x, int y)
+void VFrame::set_draw_alpha(float alpha)
{
- if( x < 0 || y < 0 || x >= get_w() || y >= get_h() ) return 1;
-
-#define DRAW_PIXEL(type, r, g, b, comps, a) { \
- type **rows = (type**)get_rows(); \
- type *rp = rows[y], *bp = rp + x*comps; \
- bp[0] = r; \
- if( comps > 1 ) { bp[1] = g; bp[2] = b; } \
- if( comps == 4 ) bp[3] = a; \
+ draw_alpha = alpha;
+}
+void VFrame::set_draw_flags(int flags)
+{
+ draw_flags = flags;
}
+
+int VFrame::draw_pixel(float x, float y, float a)
+{
+ int ix = x, iy = y;
+ if( ix < 0 || iy < 0 || ix >= get_w() || iy >= get_h() ) return 1;
+ if( a <= 0 ) return 0;
+ if( a > 1 ) a = 1;
+ int color = BC_CModels::is_yuv(color_model) ? pixel_yuv : pixel_rgb;
float fr = 0, fg = 0, fb = 0, fa = 0;
- int pixel_color = BC_CModels::is_yuv(color_model) ? pixel_yuv : pixel_rgb;
- int ir = (0xff & (pixel_color >> 16));
- int ig = (0xff & (pixel_color >> 8));
- int ib = (0xff & (pixel_color >> 0));
- int ia = (0xff & (pixel_color >> 24)) ^ 0xff; // transparency, not opacity
- if( (x+y) & stipple ) {
+ int ir = (0xff & (color >> 16));
+ int ig = (0xff & (color >> 8));
+ int ib = (0xff & (color >> 0));
+ int ia = (0xff & ~(color >> 24)); // transparency, not opacity
+ if( (ix+iy) & stipple ) {
ir = 255 - ir; ig = 255 - ig; ib = 255 - ib;
}
int rr = (ir<<8) | ir, gg = (ig<<8) | ig, bb = (ib<<8) | ib, aa = (ia<<8) | ia;
+ float fmax = 65535.f; fa = aa/fmax;
if( BC_CModels::is_float(color_model) ) {
- fr = rr/65535.f; fg = gg/65535.f; fb = bb/65535.f; fa = aa/65535.f;
+ fr = rr/fmax; fg = gg/fmax; fb = bb/fmax;
}
+#define DRAW_PIXEL(cmdl, type, r, g, b, ofs, max, comps) \
+case cmdl: { \
+ float src_a = fa*draw_alpha, src_1a = 1 - src_a; \
+ type **rows = (type**)get_rows(); \
+ type *rp = rows[iy], *bp = rp + ix*comps; \
+ bp[0] = src_a * r + src_1a * bp[0]; \
+ if( comps > 1 ) { \
+ bp[1] = src_a * (g-ofs) + src_1a * (bp[1]-ofs) + ofs; \
+ bp[2] = src_a * (b-ofs) + src_1a * (bp[2]-ofs) + ofs; \
+ } \
+ if( comps == 4 ) \
+ bp[3] = src_a * max + src_1a * bp[3]; \
+ break;\
+}
+
switch(get_color_model()) {
- case BC_A8:
- DRAW_PIXEL(uint8_t, ib, 0, 0, 1, 0);
- break;
- case BC_RGB888:
- case BC_YUV888:
- DRAW_PIXEL(uint8_t, ir, ig, ib, 3, 0);
- break;
- case BC_RGBA8888:
- case BC_YUVA8888:
- DRAW_PIXEL(uint8_t, ir, ig, ib, 4, ia);
- break;
- case BC_RGB161616:
- case BC_YUV161616:
- DRAW_PIXEL(uint16_t, rr, gg, bb, 3, 0);
- break;
- case BC_RGBA16161616:
- case BC_YUVA16161616:
- DRAW_PIXEL(uint16_t, rr, gg, bb, 4, aa);
- break;
- case BC_RGB_FLOAT:
- DRAW_PIXEL(float, fr, fg, fb, 3, 0);
- break;
- case BC_RGBA_FLOAT:
- DRAW_PIXEL(float, fr, fg, fb, 4, fa);
- break;
+ DRAW_PIXEL(BC_A8, uint8_t, ib, 0, 0, 0x00, 0xff, 1);
+ DRAW_PIXEL(BC_RGB888, uint8_t, ir, ig, ib, 0x00, 0xff, 3);
+ DRAW_PIXEL(BC_YUV888, uint8_t, ir, ig, ib, 0x80, 0xff, 3);
+ DRAW_PIXEL(BC_RGBA8888, uint8_t, ir, ig, ib, 0x00, 0xff, 4);
+ DRAW_PIXEL(BC_YUVA8888, uint8_t, ir, ig, ib, 0x80, 0xff, 4);
+ DRAW_PIXEL(BC_RGB161616, uint16_t, rr, gg, bb, 0x0000, 0xffff, 3);
+ DRAW_PIXEL(BC_YUV161616, uint16_t, rr, gg, bb, 0x8000, 0xffff, 3);
+ DRAW_PIXEL(BC_RGBA16161616, uint16_t, rr, gg, bb, 0x0000, 0xffff, 4);
+ DRAW_PIXEL(BC_YUVA16161616, uint16_t, rr, gg, bb, 0x8000, 0xffff, 4);
+ DRAW_PIXEL(BC_RGB_FLOAT, float, fr, fg, fb, 0., 1., 3);
+ DRAW_PIXEL(BC_RGBA_FLOAT, float, fr, fg, fb, 0., 1., 4);
}
return 0;
}
+int VFrame::draw_pixel(float x, float y, float frac, int axis)
+{
+ if( draw_flags ) {
+ int xs = axis, ys = 1-axis;
+ if( draw_flags & ALIAS_TOP ) draw_pixel(x-xs, y-ys, 1-frac);
+ draw_pixel(x, y, draw_flags & ALIAS_CTR ? 1-frac : 1);
+ if( draw_flags & ALIAS_BOT ) draw_pixel(x+xs, y+ys, frac);
+ }
+ else
+ draw_pixel(x, y);
+ return 0;
+}
-// Bresenham's
-void VFrame::draw_line(int x1, int y1, int x2, int y2)
+void VFrame::draw_line(float x1, float y1, float x2, float y2)
{
if( y1 > y2 ) {
int tx = x1; x1 = x2; x2 = tx;
int ty = y1; y1 = y2; y2 = ty;
}
-
- int x = x1, y = y1;
- int dx = x2-x1, dy = y2-y1;
- int dx2 = 2*dx, dy2 = 2*dy;
- if( dx < 0 ) dx = -dx;
- int r = dx > dy ? dx : dy, n = r;
- int dir = 0;
- if( dx2 < 0 ) dir += 1;
- if( dy >= dx ) {
- if( dx2 >= 0 ) do { /* +Y, +X */
- draw_pixel(x, y++);
- if( (r -= dx2) < 0 ) { r += dy2; ++x; }
- } while( --n >= 0 );
- else do { /* +Y, -X */
- draw_pixel(x, y++);
- if( (r += dx2) < 0 ) { r += dy2; --x; }
- } while( --n >= 0 );
+ float dx = x2-x1, dy = y2-y1;
+ float s = dx ? dy/dx : 1;
+ float t = dy ? dx/dy : 0;
+ int xs = dx < 0 ? -1 : 1;
+ dx *= xs;
+ int idx = (int)x2 - (int)x1;
+ int idy = (int)y2 - (int)y1;
+ int d = dx >= dy ? abs(idx) : idy;
+ float x = x1, y = y1;
+ if( dx > dy ) {
+ draw_pixel(x, y, y-(int)y, 0);
+ while( --d >= 0 ) {
+ y = y1 + ((x += xs) - x1) * s;
+ draw_pixel(x, y, y-(int)y, 0);
+ }
}
else {
- if( dx2 >= 0 ) do { /* +X, +Y */
- draw_pixel(x++, y);
- if( (r -= dy2) < 0 ) { r += dx2; ++y; }
- } while( --n >= 0 );
- else do { /* -X, +Y */
- draw_pixel(x--, y);
- if( (r -= dy2) < 0 ) { r -= dx2; ++y; }
- } while( --n >= 0 );
+ draw_pixel(x, y, x-(int)x, 1);
+ while( --d >= 0 ) {
+ x = x1 + (++y - y1) * t;
+ draw_pixel(x, y, x-(int)x, 1);
+ }
}
}
if( abs(rr) < abs(r) )
moveX(rr);
}
-xit: vframe->draw_pixel(sx, sy);
+xit:
+// vframe->draw_pixel(sx, sy);
+ float vx = abs(dx), vy = abs(dy);
+ float vv = 4*(vx > vy ? dx : dy);
+ float frac = vv ? -r / vv : 0;
+ frac = (1+frac) / 2;
+ bclamp(frac, 0, 1);
+ int axis = abs(dx) >= abs(dy) ? 1 : 0;
+ vframe->draw_pixel(sx, sy, frac, axis);
}
void VFrame::draw_smooth(int x1, int y1, int x2, int y2, int x3, int y3)
xmxx = ex; xmxy = ey;
}
if( xs > 0 )
- vframe->draw_pixel(sx, sy);
+ vframe->draw_pixel(sx, sy, 0, 0);
while( xs*(sx-xmxx) < 0 && (xs*dx < 0 || rx() < 0) ) {
moveX(rx());
- vframe->draw_pixel(sx, sy);
+ vframe->draw_pixel(sx, sy, 0, 0);
}
}
else if( y1 < y2 && y3 < y2 ) {
smooth_line lt(this), rt(this); // Q on top
lt.init0(x1, y1, x2, y2, x3, y3, 1);
- draw_pixel(lt.sx, lt.sy);
+ draw_pixel(lt.sx, lt.sy, 0, 0);
rt.init0(x1, y1, x2, y2, x3, y3, -1);
- draw_pixel(rt.sx, rt.sy);
+ draw_pixel(rt.sx, rt.sy, 0, 0);
while( !lt.done || !rt.done ) {
lt.draw();
rt.draw();
else {
smooth_line pt(this); // Q in between
pt.init0(x1, y1, x2, y2, x3, y3, 0);
- draw_pixel(pt.sx, pt.sy);
+ draw_pixel(pt.sx, pt.sy, 0, 1);
while( !pt.done ) {
pt.draw();
}
#define MAX_STACK_ELEMENTS 255
#define SHM_MIN_SIZE 2048
+#define ALIAS_OFF 0
+#define ALIAS_TOP 1
+#define ALIAS_CTR 2
+#define ALIAS_BOT 4
+#define ALIAS_DBL 5
+#define ALIAS_NRM 6
+
// Scene graph for 3D models
// Defined by the subclass
class VFrameScene
void copy_stacks(VFrame *src);
// Updates the params with values from src
void copy_params(VFrame *src);
-
// This clears the stacks and the param table
void clear_stacks();
- virtual int draw_pixel(int x, int y);
- int pixel_rgb, pixel_yuv, stipple;
+// pixel drawing
+ virtual int draw_pixel(float x, float y, float a=1.f);
+ virtual int draw_pixel(float x, float y, float frac, int axis);
+ void set_draw_alpha(float a);
+ void set_draw_flags(int flags);
+ int pixel_rgb, pixel_yuv, stipple, draw_flags;
+ float draw_alpha;
void set_pixel_color(int rgb, int a=0xff);
void set_stiple(int mask);
- void draw_line(int x1, int y1, int x2, int y2);
+ void draw_line(float x1, float y1, float x2, float y2);
void draw_smooth(int x1, int y1, int x2, int y2, int x3, int y3);
void smooth_draw(int x1, int y1, int x2, int y2, int x3, int y3);
void draw_rect(int x1, int y1, int x2, int y2);
void create_objects();
void update();
+ int close_event() { return colors->close_gui(); }
+ int cursor_motion_event() { return colors->cursor_motion_gui(); }
+ int button_press_event() { return colors->button_press_gui(); }
+ int button_release_event() { return colors->button_release_gui(); }
+ void done_event(int result) { colors->close_gui(); }
+
ForegroundMain *plugin;
ForegroundColors *colors;
};
SketcherConfig::SketcherConfig()
{
drag = 1;
+ aliasing = 0;
cv_selected = 0;
pt_selected = 0;
}
int SketcherConfig::equivalent(SketcherConfig &that)
{
if( this->drag != that.drag ) return 0;
+ if( this->aliasing != that.aliasing ) return 0;
if( this->cv_selected != that.cv_selected ) return 0;
if( this->pt_selected != that.pt_selected ) return 0;
if( this->curves.size() != that.curves.size() ) return 0;
void SketcherConfig::copy_from(SketcherConfig &that)
{
this->drag = that.drag;
+ this->aliasing = that.aliasing;
this->cv_selected = that.cv_selected;
this->pt_selected = that.pt_selected;
int m = curves.size(), n = that.curves.size();
this->cv_selected = prev.cv_selected;
this->pt_selected = prev.pt_selected;
this->drag = prev.drag;
+ this->aliasing = prev.aliasing;
double next_scale = (double)(current_frame - prev_frame) / (next_frame - prev_frame);
double prev_scale = (double)(next_frame - current_frame) / (next_frame - prev_frame);
output.tag.set_title("SKETCHER");
output.tag.set_property("DRAG", config.drag);
+ output.tag.set_property("ALIASING", config.aliasing);
output.tag.set_property("CV_SELECTED", config.cv_selected);
output.tag.set_property("PT_SELECTED", config.pt_selected);
output.append_tag();
while( !(result=input.read_tag()) ) {
if( input.tag.title_is("SKETCHER") ) {
config.drag = input.tag.get_property("DRAG", config.drag);
+ config.aliasing = input.tag.get_property("ALIASING", config.aliasing);
config.cv_selected = input.tag.get_property("CV_SELECTED", 0);
config.pt_selected = input.tag.get_property("PT_SELECTED", 0);
}
}
-int SketcherVPen::draw_pixel(int x, int y)
+int SketcherVPen::draw_mask(int x, int y)
{
- if( x >= 0 && x < vfrm->get_w() &&
- y >= 0 && y < vfrm->get_h() )
- msk[vfrm->get_w()*y + x] = 0xff;
+ int w = vfrm->get_w(), h = vfrm->get_h();
+ if( x < 0 || x >= w ) return 1;
+ if( y < 0 || y >= h ) return 1;
+ msk[w * y + x] = 0xff;
return 0;
}
-int SketcherPenSquare::draw_pixel(int x, int y)
+int SketcherVPen::draw_pixel(float x, float y, float frac, int axis)
{
+ draw_mask(x, y);
+ return VFrame::draw_pixel(x, y, frac, axis);
+}
+
+int SketcherPenSquare::draw_pixel(float x, float y, float a)
+{
+ vfrm->set_draw_alpha(a);
vfrm->draw_line(x-n, y, x+n, y);
for( int i=-n; i<n; ++i )
vfrm->draw_line(x-n, y+i, x+n, y+i);
- return SketcherVPen::draw_pixel(x, y);
+ return 0;
}
-int SketcherPenPlus::draw_pixel(int x, int y)
+int SketcherPenPlus::draw_pixel(float x, float y, float a)
{
+ vfrm->set_draw_alpha(a);
if( n > 1 ) {
vfrm->draw_line(x-n, y, x+n, y);
vfrm->draw_line(x, y-n, x, y+n);
}
else
vfrm->draw_pixel(x, y);
- return SketcherVPen::draw_pixel(x, y);
+ return 0;
}
-int SketcherPenSlant::draw_pixel(int x, int y)
+int SketcherPenSlant::draw_pixel(float x, float y, float a)
{
+ vfrm->set_draw_alpha(a);
vfrm->draw_line(x-n, y+n, x+n, y-n);
vfrm->draw_line(x-n+1, y+n, x+n+1, y-n);
vfrm->draw_line(x-n, y+n+1, x+n, y-n+1);
- return SketcherVPen::draw_pixel(x, y);
+ return 0;
}
-int SketcherPenXlant::draw_pixel(int x, int y)
+int SketcherPenXlant::draw_pixel(float x, float y, float a)
{
+ vfrm->set_draw_alpha(a);
vfrm->draw_line(x-n, y+n, x+n, y-n);
vfrm->draw_line(x-n+1, y+n, x+n+1, y-n);
vfrm->draw_line(x-n, y+n+1, x+n, y-n+1);
vfrm->draw_line(x-n, y-n, x+n, y+n);
vfrm->draw_line(x-n+1, y-n, x+n+1, y+n);
vfrm->draw_line(x-n, y-n+1, x+n, y-n+1);
- return SketcherVPen::draw_pixel(x, y);
+ return 0;
}
public:
SketcherPoint *next();
bool exists() { return stack.size() > 0; }
+ void draw_pixel(int x, int y) { img->draw_pixel(x, y); }
void start_at(int x, int y);
void run();
FillRegion(SketcherPoints &pts, SketcherVPen *vpen);
void FillRegion::run()
{
+ img->set_draw_alpha(1);
while( stack.size() > 0 ) {
int y, ilt, irt;
pop(y, ilt, irt);
int ofs = y*w + ilt;
for( int x=ilt; x<=irt; ++x,++ofs ) {
+ draw_pixel(x, y);
if( msk[ofs] ) continue;
msk[ofs] = 0xff;
- img->draw_pixel(x, y);
int lt = x, rt = x;
int lofs = ofs;
for( int i=lt; --i>=0; ) {
+ draw_pixel(i, y);
if( msk[--lofs] ) break;
- img->draw_pixel(i, y);
msk[lofs] = 0xff; lt = i;
}
int rofs = ofs;
for( int i=rt; ++i< w; ) {
+ draw_pixel(i, y);
if( msk[++rofs] ) break;
- img->draw_pixel(i, y);
msk[rofs] = 0xff; rt = i;
}
if( y+1 < h ) push(y+1, lt, rt);
return 0;
}
-
-void SketcherCurve::draw(VFrame *img)
+void SketcherCurve::draw(VFrame *img, int alias)
{
if( !points.size() ) return;
+ img->set_pixel_color(color, (~color>>24)&0xff);
const float fmx = 16383;
SketcherVPen *vpen = new_vpen(img);
+ vpen->set_draw_flags(alias);
FillRegion fill(points, vpen);
SketcherPoint *pnt0 = fill.next();
SketcherPoint *pnt1 = pnt0 ? fill.next() : 0;
vpen->draw_line(pnt0->x, pnt0->y, pnt1->x, pnt1->y);
}
else if( pnt0 ) {
- vpen->draw_pixel(pnt0->x, pnt0->y);
+ vpen->draw_pixel(pnt0->x, pnt0->y, 1);
}
delete vpen;
}
int m = cv->points.size();
if( !m ) continue;
img->clear_frame();
- img->set_pixel_color(cv->color, (~cv->color>>24)&0xff);
- cv->draw(img);
+ int alias = config.aliasing < 0 ? ALIAS_OFF :
+ config.aliasing > 0 ? ALIAS_DBL : ALIAS_NRM;
+ cv->draw(img, alias);
overlay_frame->overlay(out, img, 0,0,w,h, 0,0,w,h,
- 1.f, TRANSFER_NORMAL, NEAREST_NEIGHBOR);
+ 1.f, TRANSFER_SRC_OVER, NEAREST_NEIGHBOR);
}
if( config.drag ) {
int n;
uint8_t *msk;
+ int draw_mask(int x, int y);
SketcherVPen(VFrame *vfrm, int n)
: VFrame(vfrm->get_data(), -1, vfrm->get_y()-vfrm->get_data(),
vfrm->get_u()-vfrm->get_data(), vfrm->get_v()-vfrm->get_data(),
}
~SketcherVPen() { delete [] msk; }
- void draw_line(float x1, float y1, float x2, float y2) {
- VFrame::draw_line(int(x1+.5f),int(y1+.5f), int(x2+.5f),int(y2+.5f));
- }
void draw_smooth(float x1, float y1, float x2, float y2, float x3, float y3) {
VFrame::draw_smooth(int(x1+.5f),int(y1+.5f),
int(x2+.5f),int(y2+.5f), int(x3+.5f),int(y3+.5f));
}
- virtual int draw_pixel(int x, int y) = 0;
+ virtual int draw_pixel(float x, float y, float a) = 0;
+ int draw_pixel(float x, float y, float frac, int axis);
};
class SketcherPenSquare : public SketcherVPen
{
public:
SketcherPenSquare(VFrame *vfrm, int n) : SketcherVPen(vfrm, n) {}
- int draw_pixel(int x, int y);
+ int draw_pixel(float x, float y, float a);
};
class SketcherPenPlus : public SketcherVPen
{
public:
SketcherPenPlus(VFrame *vfrm, int n) : SketcherVPen(vfrm, n) {}
- int draw_pixel(int x, int y);
+ int draw_pixel(float x, float y, float a);
};
class SketcherPenSlant : public SketcherVPen
{
public:
SketcherPenSlant(VFrame *vfrm, int n) : SketcherVPen(vfrm, n) {}
- int draw_pixel(int x, int y);
+ int draw_pixel(float x, float y, float a);
};
class SketcherPenXlant : public SketcherVPen
{
public:
SketcherPenXlant(VFrame *vfrm, int n) : SketcherVPen(vfrm, n) {}
- int draw_pixel(int x, int y);
+ int draw_pixel(float x, float y, float a);
};
double nearest_point(int &pi, coord x, coord y);
SketcherVPen *new_vpen(VFrame *out);
- void draw(VFrame *img);
+ void draw(VFrame *img, int flags);
};
class SketcherCurves : public ArrayList<SketcherCurve *>
{
void dump();
int drag;
+ int aliasing;
int cv_selected, pt_selected;
};
}
+SketcherAliasItem::SketcherAliasItem(SketcherAliasing *popup, int v)
+ : BC_MenuItem(popup->alias_to_text(v))
+{
+ this->popup = popup;
+ this->v = v;
+}
+
+int SketcherAliasItem::handle_event()
+{
+ popup->set_text(get_text());
+ popup->plugin->config.aliasing = v;
+ popup->gui->send_configure_change();
+ return 1;
+}
+
+
+SketcherAliasing::SketcherAliasing(SketcherWindow *gui, Sketcher *plugin,
+ int x, int y)
+ : BC_PopupMenu(x, y, xS(64),
+ alias_to_text(plugin->config.aliasing), 1, 0, xS(3))
+{
+ this->gui = gui;
+ this->plugin = plugin;
+}
+SketcherAliasing::~SketcherAliasing()
+{
+}
+
+void SketcherAliasing::create_objects()
+{
+ add_item(new SketcherAliasItem(this, -1));
+ add_item(new SketcherAliasItem(this, 0));
+ add_item(new SketcherAliasItem(this, 1));
+}
+
+const char *SketcherAliasing::alias_to_text(int alias)
+{
+ if( alias < 0 ) return _("Off");
+ if( alias > 0 ) return _("Dbl");
+ return _("On");
+}
+
+
+
SketcherWindow::SketcherWindow(Sketcher *plugin)
- : PluginClientWindow(plugin, xS(380), yS(620), xS(380), yS(620), 0)
+ : PluginClientWindow(plugin, xS(400), yS(620), xS(400), yS(620), 0)
{
this->plugin = plugin;
this->title_pen = 0; this->curve_pen = 0;
x1 += title_width->get_w() + margin;
curve_width = new SketcherCurveWidth(this, x1, y, cv->width);
curve_width->create_objects();
+ x1 += curve_width->get_w() + margin;
+ aliasing = new SketcherAliasing(this, plugin, x1, y);
+ add_subwindow(aliasing); dy = bmax(dy,aliasing->get_h());
+ aliasing->create_objects();
y += dy + 2*margin; dy = 0;
x1 = get_w()-x - BC_Title::calculate_w(this, curve_text, LARGEFONT);
* 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
- *
*/
#ifndef __SKETCHERWINDOW_H__
class SketcherCurveUp;
class SketcherCurveDn;
class SketcherCurveWidth;
+class SketcherAliasItem;
+class SketcherAliasing;
class SketcherCurveList;
class SketcherPointX;
class SketcherPointY;
int width;
};
+class SketcherAliasItem : public BC_MenuItem
+{
+public:
+ SketcherAliasItem(SketcherAliasing *popup, int v);
+ int handle_event();
+
+ SketcherAliasing *popup;
+ int v;
+};
+
+class SketcherAliasing : public BC_PopupMenu
+{
+public:
+ SketcherAliasing(SketcherWindow *gui, Sketcher *plugin,
+ int x, int y);
+ ~SketcherAliasing();
+
+ const char *alias_to_text(int alias);
+ void create_objects();
+
+ Sketcher *plugin;
+ SketcherWindow *gui;
+};
+
class SketcherCurveList : public BC_ListBox
{
public:
SketcherCurveUp *curve_up;
SketcherCurveDn *curve_dn;
SketcherCurveWidth *curve_width;
+ SketcherAliasing *aliasing;
SketcherCurveList *curve_list;
SketcherResetCurves *reset_curves;
}
TracerWindow::TracerWindow(Tracer *plugin)
- : PluginClientWindow(plugin, xS(400), yS(420), xS(400), yS(420), 0)
+ : PluginClientWindow(plugin, xS(460), yS(420), xS(460), yS(420), 0)
{
this->plugin = plugin;
this->title_x = 0; this->point_x = 0;
TracerPoint *pt = hot_point >= 0 ? plugin->config.points[hot_point] : 0;
point_x = new TracerPointX(this, x1, y, !pt ? 0 : pt->x);
point_x->create_objects();
- x1 += point_x->get_w() + margin;
+ x1 += point_x->get_w() + margin + xS(20);
add_subwindow(new_point = new TracerNewPoint(this, plugin, x1, y));
- x1 += new_point->get_w() + margin;
+ x1 += new_point->get_w() + margin + xS(30);
add_subwindow(point_up = new TracerPointUp(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 TracerPointY(this, x1, y, !pt ? 0 : pt->y);
point_y->create_objects();
- x1 += point_y->get_w() + margin;
+ x1 += point_y->get_w() + margin + xS(20);
add_subwindow(del_point = new TracerDelPoint(this, plugin, x1, y));
- x1 += del_point->get_w() + margin;
+ x1 += del_point->get_w() + margin + xS(30);
add_subwindow(point_dn = new TracerPointDn(this, x1, y));
y += point_y->get_h() + margin + yS(10);
}
TracerNewPoint::TracerNewPoint(TracerWindow *gui, Tracer *plugin, int x, int y)
- : BC_GenericButton(x, y, xS(80), _("New"))
+ : BC_GenericButton(x, y, xS(100), _("New"))
{
this->gui = gui;
this->plugin = plugin;
}
TracerDelPoint::TracerDelPoint(TracerWindow *gui, Tracer *plugin, int x, int y)
- : BC_GenericButton(x, y, xS(80), C_("Del"))
+ : BC_GenericButton(x, y, xS(100), C_("Del"))
{
this->gui = gui;
this->plugin = plugin;
#: cinelerra/awindowgui.C:1428 cinelerra/awindowgui.C:2364
#: cinelerra/awindowgui.C:2384
msgid "awindowgui#Title"
-msgstr "awindowgui#Título"
+msgstr "Título"
#: cinelerra/awindowgui.C:1429 cinelerra/awindowgui.C:2365
msgid "Comments"
#: cinelerra/channelinfo.C:347
msgid "channelinfo#Title"
-msgstr "channelinfo#Título"
+msgstr "Título"
#: cinelerra/channelinfo.C:348 cinelerra/dbwindow.C:596
#: cinelerra/recordbatches.C:22
#: cinelerra/colorpicker.C:179
msgid "colorpicker#H:"
-msgstr "colorpicker#H:"
+msgstr "H:"
#: cinelerra/colorpicker.C:180
msgid "colorpicker#S:"
-msgstr "colorpicker#S:"
+msgstr "S:"
#: cinelerra/colorpicker.C:181
msgid "colorpicker_value#V:"
-msgstr "colorpicker_value#V:"
+msgstr "V:"
#: cinelerra/colorpicker.C:182
msgid "colorpicker#R:"
-msgstr "colorpicker#R:"
+msgstr "R:"
#: cinelerra/colorpicker.C:183
msgid "colorpicker#G:"
-msgstr "colorpicker#G:"
+msgstr "G:"
#: cinelerra/colorpicker.C:184
msgid "colorpicker#B:"
-msgstr "colorpicker#B:"
+msgstr "B:"
#: cinelerra/colorpicker.C:185
msgid "colorpicker#Y:"
-msgstr "colorpicker#Y:"
+msgstr "Y:"
#: cinelerra/colorpicker.C:186
msgid "colorpicker#U:"
-msgstr "colorpicker#U:"
+msgstr "U:"
#: cinelerra/colorpicker.C:187
msgid "colorpicker_Cr#V:"
-msgstr "colorpicker_Cr#V:"
+msgstr "V:"
#: cinelerra/colorpicker.C:189
msgid "colorpicker#A:"
-msgstr "colorpicker#A:"
+msgstr "A:"
#: cinelerra/colorpicker.C:205
msgid "Hue"
#: cinelerra/dbwindow.C:595
msgid "dbwindow#Title"
-msgstr "dbwindow#Título"
+msgstr "Título"
#: cinelerra/dbwindow.C:597
msgid "Access time"
#: cinelerra/keyframegui.C:761
msgid "keyframegui#Save"
-msgstr "keyframegui#Guardar"
+msgstr "Guardar"
#: cinelerra/keyframepopup.C:103
msgid "Show Plugin Settings"
#: plugins/crikey/crikeywindow.C:610
msgid "crikeywindow#Del"
-msgstr "crikeywindow#Borrar"
+msgstr "Borrar"
#: plugins/crop/crop.C:143
msgid "Crop & Position"
#: plugins/sketcher/sketcherwindow.C:859 plugins/sketcher/sketcherwindow.C:1234
msgid "sketcherwindow#Del"
-msgstr "sketcherwindow#Supr"
+msgstr "Borrar"
#: plugins/sketcher/sketcherwindow.C:992
msgid "Type"
#: plugins/timefront/timefront.C:513
msgid "timefront#Square"
-msgstr "timefront#Cuadrado"
+msgstr "Cuadrado"
#: plugins/timefront/timefront.C:599
msgid "Inversion"
#: plugins/tracer/tracerwindow.C:615
msgid "tracerwindow#Del"
-msgstr "tracerwindow#Supr"
+msgstr "Borrar"
#: plugins/translate/translatewin.C:61
msgid "In X:"