$(OBJDIR)/wwindow.o \
$(OBJDIR)/zoombar.o \
$(OBJDIR)/zoompanel.o \
+ $(OBJDIR)/zwindow.o \
+ $(OBJDIR)/zwindowgui.o \
# $(OBJDIR)/renderfarmfsclient.o \
# $(OBJDIR)/renderfarmfsserver.o \
if(nested_edl)
{
- return (int64_t)(nested_edl->tracks->total_playable_length() *
+ return (int64_t)(nested_edl->tracks->total_length() *
edl->session->sample_rate + 0.5);
}
#include "intautos.h"
#include "language.h"
#include "localsession.h"
+#include "mainsession.h"
#include "mainundo.h"
#include "mwindow.h"
#include "mwindowgui.h"
#include "patchbay.h"
#include "theme.h"
#include "trackcanvas.h"
+#include "zwindow.h"
-
-
-
-APatchGUI::APatchGUI(MWindow *mwindow,
- PatchBay *patchbay,
- ATrack *track,
- int x,
- int y)
- : PatchGUI(mwindow,
- patchbay,
- track,
- x,
- y)
+APatchGUI::APatchGUI(MWindow *mwindow, PatchBay *patchbay,
+ ATrack *track, int x, int y)
+ : PatchGUI(mwindow, patchbay, track, x, y)
{
data_type = TRACK_AUDIO;
this->atrack = track;
APatchGUI::~APatchGUI()
{
- if(fade) delete fade;
- if(meter) delete meter;
- if(pan) delete pan;
+ if( fade ) delete fade;
+ if( meter ) delete meter;
+ if( pan ) delete pan;
}
void APatchGUI::create_objects()
{
int y1 = PatchGUI::reposition(x, y);
- if(fade) fade->reposition_window(fade->get_x(),
- y1 + y);
+ if( fade )
+ fade->reposition_window(fade->get_x(), y1+y);
y1 += mwindow->theme->fade_h;
-
- if(meter) meter->reposition_window(meter->get_x(),
- y1 + y,
- -1,
- meter->get_w());
+ if( meter )
+ meter->reposition_window(meter->get_x(), y1+y, -1, meter->get_w());
y1 += mwindow->theme->meter_h;
-
- if(pan) pan->reposition_window(pan->get_x(),
- y1 + y);
-
- if(nudge) nudge->reposition_window(nudge->get_x(),
- y1 + y);
-
+ if( mix )
+ mix->reposition_window(mix->get_x(), y1+y);
+ if( pan )
+ pan->reposition_window(pan->get_x(), y1+y);
+ if( nudge )
+ nudge->reposition_window(nudge->get_x(), y1+y);
y1 += mwindow->theme->pan_h;
+
return y1;
}
int x1 = 0;
int y1 = PatchGUI::update(x, y);
- if(fade)
- {
- if(h - y1 < mwindow->theme->fade_h)
- {
+ if( fade ) {
+ if( h - y1 < mwindow->theme->fade_h ) {
delete fade;
fade = 0;
}
- else
- {
+ else {
FloatAuto *previous = 0, *next = 0;
double unit_position = mwindow->edl->local_session->get_selectionstart(1);
unit_position = mwindow->edl->align_to_frame(unit_position, 0);
unit_position = atrack->to_units(unit_position, 0);
FloatAutos *ptr = (FloatAutos*)atrack->automation->autos[AUTOMATION_FADE];
- float value = ptr->get_value(
- (long)unit_position,
- PLAY_FORWARD,
- previous,
- next);
- fade->update(fade->get_w(),
- value,
+ float value = ptr->get_value((long)unit_position, PLAY_FORWARD, previous, next);
+ fade->update(fade->get_w(), value,
mwindow->edl->local_session->automation_mins[AUTOGROUPTYPE_AUDIO_FADE],
mwindow->edl->local_session->automation_maxs[AUTOGROUPTYPE_AUDIO_FADE]);
}
}
else
- if(h - y1 >= mwindow->theme->fade_h)
- {
- patchbay->add_subwindow(fade = new AFadePatch(mwindow,
- this,
- x1 + x,
- y1 + y,
+ if( h - y1 >= mwindow->theme->fade_h ) {
+ patchbay->add_subwindow(fade = new AFadePatch(mwindow, this, x1+x, y1+y,
patchbay->get_w() - 10));
}
y1 += mwindow->theme->fade_h;
- if(meter)
- {
- if(h - y1 < mwindow->theme->meter_h)
- {
- delete meter;
- meter = 0;
+ if( meter ) {
+ if( h - y1 < mwindow->theme->meter_h ) {
+ delete meter; meter = 0;
}
}
else
- if(h - y1 >= mwindow->theme->meter_h)
- {
- patchbay->add_subwindow(meter = new AMeterPatch(mwindow,
- this,
- x1 + x,
- y1 + y));
+ if( h - y1 >= mwindow->theme->meter_h ) {
+ patchbay->add_subwindow(meter = new AMeterPatch(mwindow, this, x1+x, y1+y));
}
y1 += mwindow->theme->meter_h;
- x1 += 10;
-
- if(pan)
- {
- if(h - y1 < mwindow->theme->pan_h)
- {
- delete pan;
- pan = 0;
- delete nudge;
- nudge = 0;
+
+ if( pan ) {
+ if( h - y1 < mwindow->theme->pan_h ) {
+ delete mix; mix = 0;
+ delete pan; pan = 0;
+ delete nudge; nudge = 0;
}
- else
- {
- if(pan->get_total_values() != mwindow->edl->session->audio_channels)
- {
+ else {
+ if( mwindow->session->selected_zwindow >= 0 ) {
+ int v = mwindow->mixer_track_active(track);
+ mix->update(v);
+ }
+ if( pan->get_total_values() != mwindow->edl->session->audio_channels ) {
pan->change_channels(mwindow->edl->session->audio_channels,
mwindow->edl->session->achannel_positions);
}
- else
- {
+ else {
int handle_x, handle_y;
PanAuto *previous = 0, *next = 0;
double unit_position = mwindow->edl->local_session->get_selectionstart(1);
unit_position = mwindow->edl->align_to_frame(unit_position, 0);
unit_position = atrack->to_units(unit_position, 0);
PanAutos *ptr = (PanAutos*)atrack->automation->autos[AUTOMATION_PAN];
- ptr->get_handle(handle_x,
- handle_y,
- (long)unit_position,
- PLAY_FORWARD,
- previous,
- next);
+ ptr->get_handle(handle_x, handle_y, (long)unit_position,
+ PLAY_FORWARD, previous, next);
pan->update(handle_x, handle_y);
}
nudge->update();
}
}
else
- if(h - y1 >= mwindow->theme->pan_h)
- {
- patchbay->add_subwindow(pan = new APanPatch(mwindow,
- this,
- x1 + x,
- y1 + y));
- x1 += pan->get_w() + 10;
- patchbay->add_subwindow(nudge = new NudgePatch(mwindow,
- this,
- x1 + x,
- y1 + y,
- patchbay->get_w() - x1 - 10));
+ if( h - y1 >= mwindow->theme->pan_h ) {
+ patchbay->add_subwindow(mix = new AMixPatch(mwindow, this, x1+x, y1+y+5));
+ x1 += mix->get_w() + 10;
+ patchbay->add_subwindow(pan = new APanPatch(mwindow, this, x1+x, y1+y));
+ x1 += pan->get_w() + 20;
+ patchbay->add_subwindow(nudge = new NudgePatch(mwindow, this, x1+x, y1+y,
+ patchbay->get_w() - x1-x - 10));
}
y1 += mwindow->theme->pan_h;
void APatchGUI::synchronize_fade(float value_change)
{
- if(fade && !change_source)
- {
+ if( fade && !change_source ) {
fade->update(fade->get_value() + value_change);
fade->update_edl();
}
int AFadePatch::handle_event()
{
- if(shift_down())
- {
+ if( shift_down() ) {
update(0.0);
set_tooltip(get_caption());
}
patch->change_source = 1;
float change = update_edl();
- if(patch->track->gang && patch->track->record)
+ if( patch->track->gang && patch->track->record )
patch->patchbay->synchronize_faders(change, TRACK_AUDIO, patch->track);
patch->change_source = 0;
mwindow->sync_parameters(CHANGE_PARAMS);
- if(mwindow->edl->session->auto_conf->autos[AUTOMATION_FADE])
- {
+ if( mwindow->edl->session->auto_conf->autos[AUTOMATION_FADE] ) {
mwindow->gui->draw_overlays(1);
}
return 1;
mwindow->sync_parameters(CHANGE_PARAMS);
- if(need_undo && mwindow->edl->session->auto_conf->autos[AUTOMATION_PAN])
- {
+ if( need_undo && mwindow->edl->session->auto_conf->autos[AUTOMATION_PAN] ) {
mwindow->gui->draw_overlays(1);
}
return 1;
AMeterPatch::AMeterPatch(MWindow *mwindow, APatchGUI *patch, int x, int y)
- : BC_Meter(x,
- y,
- METER_HORIZ,
- patch->patchbay->get_w() - 10,
- mwindow->edl->session->min_meter_db,
- mwindow->edl->session->max_meter_db,
- mwindow->edl->session->meter_format,
- 0,
- -1)
+ : BC_Meter(x, y, METER_HORIZ, patch->patchbay->get_w() - 10,
+ mwindow->edl->session->min_meter_db, mwindow->edl->session->max_meter_db,
+ mwindow->edl->session->meter_format, 0, -1)
{
this->mwindow = mwindow;
this->patch = patch;
int AMeterPatch::button_press_event()
{
- if(cursor_inside() && is_event_win() && get_buttonpress() == 1)
- {
+ if( cursor_inside() && is_event_win() && get_buttonpress() == 1 ) {
mwindow->reset_meters();
return 1;
}
return 0;
}
+AMixPatch::AMixPatch(MWindow *mwindow, APatchGUI *patch, int x, int y)
+ : MixPatch(mwindow, patch, x, y)
+{
+ set_tooltip(_("Mixer"));
+}
+
+AMixPatch::~AMixPatch()
+{
+}
+
APatchGUI *patch;
};
+class AMixPatch : public MixPatch
+{
+public:
+ AMixPatch(MWindow *mwindow, APatchGUI *patch, int x, int y);
+ ~AMixPatch();
+};
+
#endif
#include "tracks.h"
#include "vwindow.h"
#include "vwindowgui.h"
+#include "zwindow.h"
AssetPopup::AssetPopup(MWindow *mwindow, AWindowGUI *gui)
add_item(index = new AssetPopupBuildIndex(mwindow, this));
add_item(view = new AssetPopupView(mwindow, this));
add_item(view_window = new AssetPopupViewWindow(mwindow, this));
+ add_item(mixer = new AssetPopupMixer(mwindow, this));
add_item(new AssetPopupPaste(mwindow, this));
add_item(menu_item = new BC_MenuItem(_("Match...")));
menu_item->add_submenu(submenu = new BC_SubMenu());
return 1;
}
+AssetPopupMixer::AssetPopupMixer(MWindow *mwindow, AssetPopup *popup)
+ : BC_MenuItem(_("Open Mixers"))
+{
+ this->mwindow = mwindow;
+ this->popup = popup;
+}
+
+AssetPopupMixer::~AssetPopupMixer()
+{
+}
+
+int AssetPopupMixer::handle_event()
+{
+ mwindow->select_zwindow(0);
+ for( int i=0; i<mwindow->session->drag_assets->total; ++i ) {
+ Indexable *indexable = mwindow->session->drag_assets->values[i];
+ ArrayList<Indexable*> new_assets;
+ new_assets.append(indexable);
+ Track *track = mwindow->edl->tracks->last;
+ mwindow->load_assets(&new_assets, -1, LOADMODE_NEW_TRACKS, 0, 0, 0, 0, 0, 0);
+ track = !track ? mwindow->edl->tracks->first : track->next;
+ Mixer *mixer = 0;
+ ZWindow *zwindow = mwindow->get_mixer(mixer);
+ while( track ) {
+ track->play = track->record = 0;
+ mixer->mixer_ids.append(track->get_mixer_id());
+ track = track->next;
+ }
+ char *path = indexable->path;
+ char *tp = strrchr(path, '/');
+ if( !tp ) tp = path; else ++tp;
+ zwindow->set_title(tp);
+ zwindow->start();
+ }
+ mwindow->queue_mixers(mwindow->edl,CURRENT_FRAME,0,0,1,0);
+ mwindow->resync_guis();
+ return 1;
+}
AssetPopupPaste::AssetPopupPaste(MWindow *mwindow, AssetPopup *popup)
: BC_MenuItem(_("Paste"))
AssetPopupBuildIndex *index;
AssetPopupView *view;
AssetPopupViewWindow *view_window;
+ AssetPopupMixer *mixer;
AWindowListFormat *format;
};
AssetPopup *popup;
};
+class AssetPopupMixer : public BC_MenuItem
+{
+public:
+ AssetPopupMixer(MWindow *mwindow, AssetPopup *popup);
+ ~AssetPopupMixer();
+
+ int handle_event();
+
+ MWindow *mwindow;
+ AssetPopup *popup;
+};
+
class AssetPopupPaste : public BC_MenuItem
{
public:
class AssetPopupBuildIndex;
class AssetPopupView;
class AssetPopupViewWindow;
+class AssetPopupMixer;
class AssetPopupPaste;
class AssetMatchSize;
class AssetMatchRate;
if(position)
{
+ mwindow->queue_mixers(mwindow->edl, CURRENT_FRAME,1,0,1,0);
playback_engine->que->send_command(CURRENT_FRAME,
CHANGE_NONE,
mwindow->edl,
void CWindowSlider::set_position()
{
- double new_length = mwindow->edl->tracks->total_playable_length();
+ double new_length = mwindow->edl->tracks->total_length();
// if(mwindow->edl->local_session->preview_end <= 0 ||
// mwindow->edl->local_session->preview_end > new_length)
// mwindow->edl->local_session->preview_end = new_length;
for(int i = 0; i < clips.size(); i++)
clips.get(i)->Garbage::remove_user();
clips.remove_all();
+ mixers.remove_all_objects();
}
if(load_flags & LOAD_TIMEBAR)
new_folder(folder);
}
else
+ if(file->tag.title_is("MIXERS"))
+ {
+ if((load_flags & LOAD_SESSION))
+ mixers.load(file);
+ else
+ result = file->skip_tag();
+ }
+ else
if(file->tag.title_is("ASSETS"))
{
if(load_flags & LOAD_ASSETS)
copy_session(edl);
copy_assets(edl);
copy_clips(edl);
+ copy_mixers(edl);
tracks->copy_from(edl->tracks);
labels->copy_from(edl->labels);
return 0;
}
}
+void EDL::copy_mixers(EDL *edl)
+{
+ if(this == edl) return;
+ mixers.copy_from(edl->mixers);
+}
+
void EDL::copy_session(EDL *edl, int session_only)
{
if(this == edl) return;
output_path,
1,
0);
+ mixers.save(file);
}
file->append_newline();
if(new_nested_edl)
{
- length = new_nested_edl->tracks->total_playable_length();
+ length = new_nested_edl->tracks->total_length();
layers = 1;
channels = new_nested_edl->session->audio_channels;
}
int64_t EDL::get_audio_samples()
{
- return (int64_t)(tracks->total_playable_length() *
+ return (int64_t)(tracks->total_length() *
session->sample_rate);
}
int64_t EDL::get_video_frames()
{
- return (int64_t)(tracks->total_playable_length() *
+ return (int64_t)(tracks->total_length() *
session->frame_rate);
}
#include "theme.inc"
#include "tracks.inc"
#include "vedit.inc"
+#include "zwindow.h"
// Loading and saving are built on load and copy except for automation:
int copy_all(EDL *edl);
void copy_assets(EDL *edl);
void copy_clips(EDL *edl);
+ void copy_mixers(EDL *edl);
// Copy pan and fade settings from edl
void synchronize_params(EDL *edl);
// Determine if the positions are equivalent if they're within half a frame
ArrayList<EDL*> vwindow_edls;
// is the vwindow_edl shared and therefore should not be deleted in destructor
// int vwindow_edl_shared;
+ Mixers mixers;
// Media files
// Shared between all EDLs
{
this->auto_toggle = auto_toggle;
this->color = 0;
- for( int i=0; i<3; ++i )
+ for( int i=0; i<3; ++i ) {
vframes[i] = new VFrame(w, w, BC_RGBA8888, -1);
+ vframes[i]->clear_frame();
+ }
}
GWindowColorButton::~GWindowColorButton()
{
}
-PatchGUI *KeyframePopupShow::get_patchgui(Track *track)
-{
- PatchGUI *patchgui = 0;
- TimelinePane **panes = mwindow->gui->pane;
- for( int i=0; i<TOTAL_PANES && !patchgui; ++i ) {
- if( !panes[i] ) continue;
- PatchBay *patchbay = panes[i]->patchbay;
- if( !patchbay ) continue;
- for( int j=0; j<patchbay->patches.total && !patchgui; ++j ) {
- if( patchbay->patches.values[j]->track == track )
- patchgui = patchbay->patches.values[j];
- }
- }
- return patchgui;
-}
-
int KeyframePopupShow::handle_event()
{
MWindowGUI *mgui = mwindow->gui;
default: {
show_window = 0;
- PatchGUI *patchgui = get_patchgui(popup->keyframe_automation->track);
+ PatchGUI *patchgui = mwindow->get_patchgui(popup->keyframe_automation->track);
if( !patchgui ) break;
switch( popup->keyframe_autos->autoidx ) {
public:
KeyframePopupShow(MWindow *mwindow, KeyframePopup *popup);
~KeyframePopupShow();
- PatchGUI *get_patchgui(Track *track);
int handle_event();
MWindow *mwindow;
windowmenu->add_item(new BC_MenuItem("-"));
windowmenu->add_item(split_x = new SplitX(mwindow));
windowmenu->add_item(split_y = new SplitY(mwindow));
+ windowmenu->add_item(mixer_viewer = new MixerViewer(mwindow));
windowmenu->add_item(new TileWindows(mwindow,_("Default positions"),-1,_("Ctrl-P"),'p'));
windowmenu->add_item(new TileWindows(mwindow,_("Tile left"),0));
windowmenu->add_item(new TileWindows(mwindow,_("Tile right"),1));
}
+MixerViewer::MixerViewer(MWindow *mwindow)
+ : BC_MenuItem(_("Mixer Viewer"), _("Shift-M"), 'M')
+{
+ this->mwindow = mwindow;
+ set_shift(1);
+}
+
+int MixerViewer::handle_event()
+{
+ mwindow->start_mixer();
+ return 1;
+}
+
class KeyframeCurveTypeItem;
class SplitX;
class SplitY;
+class MixerViewer;
#include "arraylist.h"
ShowLWindow *show_lwindow;
SplitX *split_x;
SplitY *split_y;
+ MixerViewer *mixer_viewer;
};
// ========================================= edit
MWindow *mwindow;
};
+class MixerViewer : public BC_MenuItem
+{
+public:
+ MixerViewer(MWindow *mwindow);
+ int handle_event();
+ MWindow *mwindow;
+};
+
#endif
cwindow_fullscreen = 0;
rwindow_fullscreen = 0;
vwindow_fullscreen = 0;
+ zwindow_fullscreen = 0;
+ selected_zwindow = -1;
actual_frame_rate = 0;
window_config = 0;
a_x11_host[0] = 0;
int cwindow_fullscreen;
int rwindow_fullscreen;
int vwindow_fullscreen;
-
+ int zwindow_fullscreen;
+ int selected_zwindow;
double actual_frame_rate;
if(mwindow->edl->local_session->get_selectionend() ==
mwindow->edl->local_session->get_selectionstart())
- total_end = mwindow->edl->tracks->total_playable_length();
+ total_end = mwindow->edl->tracks->total_length();
else
total_end = mwindow->edl->local_session->get_selectionend();
#include "theme.h"
#include "threadloader.h"
#include "timebar.h"
+#include "timelinepane.h"
#include "tipwindow.h"
#include "trackcanvas.h"
#include "track.h"
#include "wavecache.h"
#include "wwindow.h"
#include "zoombar.h"
+#include "zwindow.h"
+#include "zwindowgui.h"
#include "exportedl.h"
#include "defaultformats.h"
plugin_gui_lock = new Mutex("MWindow::plugin_gui_lock");
dead_plugin_lock = new Mutex("MWindow::dead_plugin_lock");
vwindows_lock = new Mutex("MWindow::vwindows_lock");
+ zwindows_lock = new Mutex("MWindow::zwindows_lock");
brender_lock = new Mutex("MWindow::brender_lock");
keyframe_gui_lock = new Mutex("MWindow::keyframe_gui_lock");
if( twindow && twindow->is_running() ) twindow->close_window();
if( wwindow && wwindow->is_running() ) wwindow->close_window();
vwindows.remove_all_objects();
+ zwindows.remove_all_objects();
gui->close(0);
if( awindow ) awindow->join();
if( cwindow ) cwindow->join();
close_gui(twindow);
close_gui(wwindow);
vwindows.remove_all_objects();
+ zwindows.remove_all_objects();
gui->close(0);
join();
#endif
delete dead_plugin_lock;
delete plugin_gui_lock;
delete vwindows_lock;
+ delete zwindows_lock;
delete brender_lock;
delete keyframe_gui_lock;
colormodels.remove_all_objects();
return vwindow;
}
+ZWindow *MWindow::get_mixer(Mixer *&mixer)
+{
+ zwindows_lock->lock("MWindow::get_mixer");
+ if( !mixer ) mixer = edl->mixers.new_mixer();
+ ZWindow *zwindow = 0;
+ for( int i=0; !zwindow && i<zwindows.size(); ++i )
+ if( !zwindows[i]->is_running() ) zwindow = zwindows[i];
+ if( !zwindow )
+ zwindows.append(zwindow = new ZWindow(this));
+ zwindow->idx = mixer->idx;
+ zwindows_lock->unlock();
+ return zwindow;
+}
+
+void MWindow::del_mixer(ZWindow *zwindow)
+{
+ zwindows_lock->lock("MWindow::del_mixer 0");
+ edl->mixers.del_mixer(zwindow->idx);
+ zwindow->idx = -1;
+ if( session->selected_zwindow >= 0 ) {
+ int i = zwindows.number_of(zwindow);
+ if( i >= 0 && i < session->selected_zwindow )
+ --session->selected_zwindow;
+ else if( i == session->selected_zwindow )
+ session->selected_zwindow = -1;
+ }
+ zwindows_lock->unlock();
+ gui->lock_window("MWindow::del_mixer 1");
+ gui->update_mixers(0, -1);
+ gui->unlock_window();
+}
+
+void MWindow::start_mixer()
+{
+ Mixer *mixer = 0;
+ ZWindow *zwindow = get_mixer(mixer);
+ const char *title = 0;
+
+ for( Track *track=edl->tracks->first; track!=0; track=track->next ) {
+ PatchGUI *patchgui = get_patchgui(track);
+ if( !patchgui || !patchgui->mixer ) continue;
+ mixer->mixer_ids.append(track->get_mixer_id());
+ if( !title ) title = track->title;
+ }
+
+ session->selected_zwindow = -1;
+ gui->lock_window("MWindow::start_mixer");
+ gui->update_mixers(0, 0);
+ gui->unlock_window();
+
+ zwindow->set_title(title);
+ zwindow->start();
+ queue_mixers(edl,CURRENT_FRAME,0,0,1,0);
+}
+
+int MWindow::mixer_track_active(Track *track)
+{
+ int i = session->selected_zwindow;
+ if( i < 0 || i >= zwindows.size() ) return 0;
+ ZWindow *zwindow = zwindows[i];
+ Mixer *mixer = edl->mixers.get_mixer(zwindow->idx);
+ if( !mixer ) return 0;
+ int n = mixer->mixer_ids.number_of(track->get_mixer_id());
+ return n >= 0 ? 1 : 0;
+}
+
+void MWindow::update_mixer_tracks()
+{
+ zwindows_lock->lock("MixPatch::handle_event");
+ int i = session->selected_zwindow;
+ if( i >= 0 && i < zwindows.size() ) {
+ ZWindow *zwindow = zwindows[i];
+ zwindow->update_mixer_ids();
+ }
+ zwindows_lock->unlock();
+}
+
+void MWindow::queue_mixers(EDL *edl, int command, int wait_tracking,
+ int use_inout, int update_refresh, int toggle_audio)
+{
+ zwindows_lock->lock("MWindow::queue_mixers");
+ for( int vidx=0; vidx<zwindows.size(); ++vidx ) {
+ ZWindow *zwindow = zwindows[vidx];
+ if( !zwindow->running() ) continue;
+ Mixer *mixer = edl->mixers.get_mixer(zwindow->idx);
+ if( !mixer || !mixer->mixer_ids.size() ) continue;
+ int k = -1;
+ for( Track *track = edl->tracks->first; k<0 && track!=0; track=track->next ) {
+ if( track->data_type != TRACK_VIDEO ) continue;
+ int mixer_id = track->get_mixer_id();
+ k = mixer->mixer_ids.size();
+ while( --k >= 0 && mixer_id != mixer->mixer_ids[k] );
+ }
+ if( k < 0 ) continue;
+ EDL *mixer_edl = new EDL(this->edl);
+ mixer_edl->create_objects();
+ mixer_edl->copy_all(edl);
+ mixer_edl->remove_vwindow_edls();
+ for( Track *track = mixer_edl->tracks->first; track!=0; track=track->next ) {
+ k = mixer->mixer_ids.size();
+ while( --k >= 0 && track->get_mixer_id() != mixer->mixer_ids[k] );
+ if( k >= 0 ) {
+ track->record = 1;
+ track->play = track->data_type == TRACK_VIDEO ? 1 : 0;
+ }
+ else
+ track->record = track->play = 0;
+ }
+ zwindow->change_source(mixer_edl);
+ zwindow->issue_command(command,
+ wait_tracking, use_inout, update_refresh, toggle_audio);
+ }
+ zwindows_lock->unlock();
+}
+
+void MWindow::stop_mixers()
+{
+ for( int vidx=0; vidx<zwindows.size(); ++vidx ) {
+ ZWindow *zwindow = zwindows[vidx];
+ if( !zwindow->running() ) continue;
+ zwindow->issue_command(STOP, 0, 0, 0, 0);
+ }
+}
+
+int MWindow::select_zwindow(ZWindow *zwindow)
+{
+ int ret = 0, n = zwindows.number_of(zwindow);
+ if( session->selected_zwindow != n ) {
+ session->selected_zwindow = n;
+ for( int i=0; i<zwindows.size(); ++i ) {
+ ZWindow *zwindow = zwindows[i];
+ if( !zwindow->running() ) continue;
+ ZWindowGUI *zgui = zwindow->zgui;
+ zgui->lock_window("MWindow::select_zwindow 0");
+ zwindow->highlighted = i == n ? 1 : 0;
+ if( zgui->draw_overlays() )
+ zgui->canvas->get_canvas()->flash(1);
+ zgui->unlock_window();
+ }
+ ret = 1;
+ gui->lock_window("MWindow::select_window 1");
+ gui->update_mixers(0, -1);
+ gui->unlock_window();
+ }
+ return ret;
+}
+
+
void MWindow::init_cache()
{
audio_cache = new CICache(preferences);
if( !vwindow->is_running() ) continue;
vwindow->playback_engine->stop_playback();
}
+ for(int i = 0; i < zwindows.size(); i++) {
+ ZWindow *zwindow = zwindows[i];
+ if( !zwindow->is_running() ) continue;
+ zwindow->zgui->playback_engine->stop_playback();
+ }
if( locked ) gui->lock_window("MWindow::stop_playback");
}
edl->session->proxy_use_scaler = 0;
edl->session->proxy_auto_scale = 0;
edl->local_session->preview_start = 0;
- edl->local_session->preview_end = edl->tracks->total_playable_length();
+ edl->local_session->preview_end = edl->tracks->total_length();
edl->local_session->loop_playback = 0;
edl->local_session->set_selectionstart(0);
edl->local_session->set_selectionend(0);
}
else
{
+ queue_mixers(edl,CURRENT_FRAME,0,0,1,0);
cwindow->playback_engine->que->send_command(CURRENT_FRAME,
change_type,
edl,
if(debug) PRINT_TRACE
// Close all the vwindows
- if(load_mode == LOADMODE_REPLACE ||
- load_mode == LOADMODE_REPLACE_CONCATENATE) {
+ if( load_mode == LOADMODE_REPLACE ||
+ load_mode == LOADMODE_REPLACE_CONCATENATE ) {
if(debug) PRINT_TRACE
int first_vwindow = 0;
if(session->show_vwindow) first_vwindow = 1;
vwindow->close_window();
}
if(debug) PRINT_TRACE
+ select_zwindow(0);
+ for( int i=0; i<zwindows.size(); ++i ) {
+ ZWindow *zwindow = zwindows[i];
+ if( !zwindow->is_running() ) continue;
+ zwindow->close_window();
+ }
+
+ for( int i=0; i<edl->mixers.size(); ++i ) {
+ Mixer *mixer = edl->mixers[i];
+ ZWindow *zwindow = get_mixer(mixer);
+ zwindow->set_title(mixer->title);
+ zwindow->start();
+ }
}
- else if(vwindows.size()) {
- VWindow *vwindow = vwindows[DEFAULT_VWINDOW];
- if( vwindow->is_running() ) {
- vwindow->gui->lock_window("MWindow::update_project");
- vwindow->update(1);
- vwindow->gui->unlock_window();
+ else {
+ if(vwindows.size()) {
+ VWindow *vwindow = vwindows[DEFAULT_VWINDOW];
+ if( vwindow->is_running() ) {
+ vwindow->gui->lock_window("MWindow::update_project");
+ vwindow->update(1);
+ vwindow->gui->unlock_window();
+ }
}
}
if(debug) PRINT_TRACE
gui->lock_window("MWindow::update_project");
+ gui->update_mixers(0, 0);
gui->flush();
if(debug) PRINT_TRACE
}
void MWindow::reset_caches()
{
+ gui->resource_thread->get_video_source(0);
+ gui->resource_thread->get_audio_source(0);
frame_cache->remove_all();
wave_cache->remove_all();
audio_cache->remove_all();
return (PanAuto*)ptr->get_prev_auto( (long)unit_position, PLAY_FORWARD, current);
}
+PatchGUI *MWindow::get_patchgui(Track *track)
+{
+ PatchGUI *patchgui = 0;
+ TimelinePane **panes = gui->pane;
+ for( int i=0; i<TOTAL_PANES && !patchgui; ++i ) {
+ if( !panes[i] ) continue;
+ PatchBay *patchbay = panes[i]->patchbay;
+ if( !patchbay ) continue;
+ for( int j=0; j<patchbay->patches.total && !patchgui; ++j ) {
+ if( patchbay->patches.values[j]->track == track )
+ patchgui = patchbay->patches.values[j];
+ }
+ }
+ return patchgui;
+}
#include "videowindow.inc"
#include "vpatchgui.h"
#include "vwindow.inc"
+#include "zwindow.inc"
#include "wwindow.inc"
#include "wavecache.inc"
void dump_plugindb(FILE *fp);
void stop_playback(int wait=0);
-
-
+ void queue_mixers(EDL *edl, int command, int wait_tracking,
+ int use_inout, int update_refresh, int toggle_audio);
+ void stop_mixers();
+ ZWindow *get_mixer(Mixer *&mixer);
+ void del_mixer(ZWindow *zwindow);
+ int mixer_track_active(Track *track);
+ void update_mixer_tracks();
+ void start_mixer();
+ int select_zwindow(ZWindow *zwindow);
int load_filenames(ArrayList<char*> *filenames,
int load_mode = LOADMODE_REPLACE,
FloatAuto* get_float_auto(PatchGUI *patch,int idx);
IntAuto* get_int_auto(PatchGUI *patch,int idx);
PanAuto* get_pan_auto(PatchGUI *patch);
+ PatchGUI *get_patchgui(Track *track);
int modify_edithandles();
int modify_pluginhandles();
// Viewer
Mutex *vwindows_lock;
ArrayList<VWindow*> vwindows;
+// Mixer
+ Mutex *zwindows_lock;
+ ArrayList<ZWindow*> zwindows;
// Asset manager
AWindow *awindow;
// Automation window
N_("Cinelerra: Loading")
N_("Cinelerra: Locate file")
N_("Cinelerra: Mask")
+N_("Cinelerra: Mixer")
N_("Cinelerra: New folder")
N_("Cinelerra: New Project")
N_("Cinelerra: Normalize")
}
source->copy(src_start, src_start + overwrite_len,
- 1, 0, 0, &file, "", 1);
+ 0, 0, 0, &file, "", 1);
// HACK around paste_edl get_start/endselection on its own
// so we need to clear only when not using both io points
if( !new_edls->total ) return 0;
//PRINT_TRACE
-// double original_length = edl->tracks->total_playable_length();
+// double original_length = edl->tracks->total_length();
// double original_preview_end = edl->local_session->preview_end;
//PRINT_TRACE
edl = new EDL;
edl->create_objects();
edl->copy_session(new_edls->values[0]);
+ edl->copy_mixers(new_edls->values[0]);
gui->mainmenu->update_toggles(0);
gui->unlock_window();
gwindow->gui->update_toggles(1);
// Fix preview range
// if( EQUIV(original_length, original_preview_end) )
// {
-// edl->local_session->preview_end = edl->tracks->total_playable_length();
+// edl->local_session->preview_end = edl->tracks->total_length();
// }
// Start examining next batch of index files
}
+void MWindowGUI::update_mixers(Track *track, int v)
+{
+ for( int i=0; i<TOTAL_PANES; ++i ) {
+ if( !pane[i] ) continue;
+ PatchBay *patchbay = pane[i]->patchbay;
+ if( !patchbay ) continue;
+ for( int j=0; j<patchbay->patches.total; ++j ) {
+ PatchGUI *patchgui = patchbay->patches.values[j];
+ if( !patchgui->mix ) continue;
+ if( !track || patchgui->track == track ) {
+ patchgui->mix->update(v>=0 ? v :
+ mwindow->mixer_track_active(patchgui->track));
+ }
+ }
+ }
+}
+
PaneButton::PaneButton(MWindow *mwindow, int x, int y)
: BC_Button(x, y, mwindow->theme->get_image_set("pane"))
{
#include "statusbar.inc"
#include "swindow.inc"
#include "timelinepane.inc"
+#include "track.inc"
#include "trackcanvas.inc"
#include "trackscroll.inc"
#include "transitionpopup.inc"
void set_playing_back(int value);
void set_editing_mode(int flush);
void set_meter_format(int mode, int min, int max);
+ void update_mixers(Track *track, int v);
int translation_event();
int resize_event(int w, int h); // handle a resize event
#include "tracks.h"
#include "transportque.h"
#include "vframe.h"
-
+#include "zwindow.h"
PatchGUI::PatchGUI(MWindow *mwindow,
mute = 0;
expand = 0;
nudge = 0;
+ mix = 0;
change_source = 0;
- track_id = -1;
- if(track) track_id = track->get_id();
+ track_id = track ? track->get_id() : -1;
+ mixer = 0;
}
PatchGUI::~PatchGUI()
{
- if(title) delete title;
- if(record) delete record;
- if(play) delete play;
-// if(automate) delete automate;
- if(gang) delete gang;
- if(draw) delete draw;
- if(mute) delete mute;
- if(expand) delete expand;
- if(nudge) delete nudge;
+ delete title;
+ delete record;
+ delete play;
+// delete automate;
+ delete gang;
+ delete draw;
+ delete mute;
+ delete expand;
+ delete nudge;
+ delete mix;
}
void PatchGUI::create_objects()
}
+MixPatch::MixPatch(MWindow *mwindow, PatchGUI *patch, int x, int y)
+ : BC_Toggle(x, y, mwindow->theme->get_image_set("mixpatch_data"),
+ patch->mixer, "", 0, 0, 0)
+{
+ this->mwindow = mwindow;
+ this->patch = patch;
+}
+
+MixPatch::~MixPatch()
+{
+}
+
+int MixPatch::handle_event()
+{
+ int v = patch->track ? get_value() : 0;
+ if( patch->mixer != v ) {
+ if( patch->track )
+ mwindow->gui->update_mixers(patch->track, v);
+ else
+ update(v);
+ mwindow->update_mixer_tracks();
+ }
+ return 1;
+}
+void MixPatch::update(int v)
+{
+ patch->mixer = v;
+ BC_Toggle::update(v);
+}
class MutePatch;
class ExpandPatch;
class NudgePatch;
+class MixPatch;
class PatchGUI
{
// Used by update routines so non-existent track doesn't need to be dereferenced
// to know it doesn't match the current EDL.
int track_id;
- int data_type;
+ int data_type, mixer;
int x, y;
// Don't synchronize the fader if this is true.
int change_source;
MutePatch *mute;
ExpandPatch *expand;
NudgePatch *nudge;
+ MixPatch *mix;
char string_return[BCTEXTLEN];
};
PatchGUI *patch;
};
+class MixPatch : public BC_Toggle
+{
+public:
+ MixPatch(MWindow *mwindow, PatchGUI *patch, int x, int y);
+ ~MixPatch();
+ int handle_event();
+ void update(int v);
+
+ MWindow *mwindow;
+ PatchGUI *patch;
+};
+
#endif
renderengine_lock->unlock();
}
+
+void PlaybackEngine::issue_command(EDL *edl, int command, int wait_tracking,
+ int use_inout, int update_refresh, int toggle_audio)
+{
+//printf("PlayTransport::handle_transport 1 %d\n", command);
+// Stop requires transferring the output buffer to a refresh buffer.
+ int do_stop = 0, resume = 0;
+ int prev_command = this->command->command;
+ int prev_single_frame = this->command->single_frame();
+ int prev_audio = this->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 FAST_REWIND: // Commands that play back
+ case NORMAL_REWIND:
+ case SLOW_REWIND:
+ case SINGLE_FRAME_REWIND:
+ case SINGLE_FRAME_FWD:
+ case SLOW_FWD:
+ case NORMAL_FWD:
+ case FAST_FWD:
+ 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;
+ }
+// Resume or change direction
+ switch( prev_command ) {
+ default:
+ que->send_command(STOP, CHANGE_NONE, 0, 0);
+ interrupt_playback(wait_tracking);
+ resume = 1;
+// fall through
+ case STOP:
+ case COMMAND_NONE:
+ case SINGLE_FRAME_FWD:
+ case SINGLE_FRAME_REWIND:
+// Start from scratch
+ que->send_command(command, CHANGE_NONE, edl,
+ 1, resume, use_inout, toggle_audio,
+ mwindow->preferences->forward_render_displacement);
+ break;
+ }
+ break;
+
+// Commands that stop
+ case STOP:
+ case REWIND:
+ case GOTO_END:
+ do_stop = 1;
+ break;
+ }
+
+ if( do_stop ) {
+ que->send_command(STOP, CHANGE_NONE, 0, 0);
+ interrupt_playback(wait_tracking);
+ }
+}
+
void run();
void stop_playback();
+ void issue_command(EDL *edl, int command, int wait_tracking,
+ int use_inout, int update_refresh, int toggle_audio);
// Maintain caches through console changes
CICache *audio_cache, *video_cache;
int PlayTransport::keypress_event()
{
- int result = 1;
int key = subwindow->get_keypress();
+ return do_keypress(key);
+}
+
+int PlayTransport::do_keypress(int key)
+{
+ int result = 1;
// unqualified keys, still holding lock
switch( key ) {
case HOME:
void PlayTransport::handle_transport(int command,
int wait_tracking, int use_inout, int update_refresh, int toggle_audio)
{
- if( !get_edl() ) return;
-
-// Stop requires transferring the output buffer to a refresh buffer.
- int do_stop = 0;
- int resume = 0;
-//printf("PlayTransport::handle_transport 1 %d\n", command);
- int prev_command = engine->command->command;
- 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 FAST_REWIND: // Commands that play back
- case NORMAL_REWIND:
- case SLOW_REWIND:
- case SINGLE_FRAME_REWIND:
- case SINGLE_FRAME_FWD:
- case SLOW_FWD:
- case NORMAL_FWD:
- case FAST_FWD:
- 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;
- }
-// Resume or change direction
- switch( prev_command ) {
- default:
- engine->que->send_command(STOP, CHANGE_NONE, 0, 0);
- engine->interrupt_playback(wait_tracking);
- resume = 1;
-// fall through
- case STOP:
- case COMMAND_NONE:
- case SINGLE_FRAME_FWD:
- case SINGLE_FRAME_REWIND:
-// Start from scratch
- engine->que->send_command(command, CHANGE_NONE, get_edl(),
- 1, resume, use_inout, toggle_audio,
- mwindow->preferences->forward_render_displacement);
- break;
- }
- break;
-
-// Commands that stop
- case STOP:
- case REWIND:
- case GOTO_END:
- do_stop = 1;
- break;
- }
-
- if( do_stop ) {
- engine->que->send_command(STOP, CHANGE_NONE, 0, 0);
- engine->interrupt_playback(wait_tracking);
- }
+ EDL *edl = get_edl();
+ if( !edl ) return;
+ if( !is_vwindow() )
+ mwindow->queue_mixers(edl, command, wait_tracking, use_inout, update_refresh, toggle_audio);
+ engine->issue_command(edl, command, wait_tracking, use_inout, update_refresh, toggle_audio);
}
-
EDL* PlayTransport::get_edl()
{
return mwindow->edl;
void PlayTransport::change_position(double position)
{
- EDL *edl = get_edl();
- if( !edl ) return;
+ if( !get_edl() ) return;
int prev_command = engine->command->command;
// stop transport
if( prev_command != STOP && prev_command != COMMAND_NONE &&
static int get_transport_width(MWindow *mwindow);
int flip_vertical(int vertical, int &x, int &y);
int keypress_event();
+ int do_keypress(int key);
// Abstract TransportQue::send_command.
// wait_tracking - causes stop to wail until the final tracking position
// is updated before returning
// Get the EDL to play back with default to mwindow->edl
virtual EDL* get_edl();
void change_position(double position);
+ virtual int is_vwindow() { return 0; }
// playback parameters
int reverse;
delete interrupt_lock;
delete first_frame_lock;
delete config;
- edl->Garbage::remove_user();
+ if( edl ) edl->Garbage::remove_user();
}
EDL* RenderEngine::get_edl()
SaveAs::SaveAs(MWindow *mwindow)
: BC_MenuItem(_("Save as..."), "Shift-S", 'S'), Thread()
{
+ set_shift(1);
this->mwindow = mwindow;
quit_now = 0;
}
new_image("awindow_icon", "heroine_icon.png");
new_image("record_icon", "heroine_icon.png");
new_image("clip_icon", "clip_icon.png");
+ new_image_set("mixpatch_data", 5, "mixpatch_up.png", "mixpatch_hi.png",
+ "mixpatch_checked.png", "mixpatch_dn.png", "mixpatch_checkedhi.png");
new_image("aeffect_icon", "aeffect_icon.png");
widget_border;
vdivision_x = 280;
- vtime_x = vdivision_x;
- vtime_y = vedit_y + 20;
+ vtime_x = vedit_x + 20; //vdivision_x;
+ vtime_y = vedit_y + 30; //+ 20;
}
else
{
edl_length = 0;
if( get_edl() ) {
-//printf("TimeBar::get_edl_length 1 %f\n", get_edl()->tracks->total_playable_length());
- edl_length = get_edl()->tracks->total_playable_length();
+//printf("TimeBar::get_edl_length 1 %f\n", get_edl()->tracks->total_length());
+ edl_length = get_edl()->tracks->total_length();
}
//printf("TimeBar::get_edl_length 2\n");
track_w = edl->session->output_w;
track_h = edl->session->output_h;
id = EDL::next_id();
+ mixer_id = -1;
}
Track::~Track()
this->gang = track->gang;
this->record = track->record;
this->nudge = track->nudge;
+ this->mixer_id = track->mixer_id;
this->play = track->play;
this->track_w = track->track_w;
this->track_h = track->track_h;
gang = file->tag.get_property("GANG", gang);
draw = file->tag.get_property("DRAW", draw);
nudge = file->tag.get_property("NUDGE", nudge);
+ mixer_id = file->tag.get_property("MIXER_ID", mixer_id);
expand_view = file->tag.get_property("EXPAND", expand_view);
track_w = file->tag.get_property("TRACK_W", track_w);
track_h = file->tag.get_property("TRACK_H", track_h);
file->tag.set_title("TRACK");
file->tag.set_property("RECORD", record);
file->tag.set_property("NUDGE", nudge);
+ file->tag.set_property("MIXER_ID", mixer_id);
file->tag.set_property("PLAY", play);
file->tag.set_property("GANG", gang);
file->tag.set_property("DRAW", draw);
return 0;
}
+int Track::get_mixer_id()
+{
+ if( mixer_id < 0 ) {
+ int v = 0;
+ for( Track *track=tracks->first; track!=0; track=track->next )
+ if( track->mixer_id > v ) v = track->mixer_id;
+ mixer_id = v + 1;
+ }
+ return mixer_id;
+}
+
virtual int load_header(FileXML *file, uint32_t load_flags) { return 0; };
virtual int load_derived(FileXML *file, uint32_t load_flags) { return 0; };
void equivalent_output(Track *track, double *result);
+ int get_mixer_id();
virtual void copy_from(Track *track);
Track& operator=(Track& track);
int plugin_used(int64_t position, int64_t direction);
-
-
-
virtual int copy_settings(Track *track);
void shift_keyframes(int64_t position, int64_t length);
void shift_effects(int64_t position, int64_t length, int edit_autos);
int data_type;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
int load_automation(FileXML *file);
int load_edits(FileXML *file);
int pixel; // pixel position from top of track view
// Dimensions of this track if video
int track_w, track_h;
-
-
-
+ int mixer_id;
private:
// Identification of the track
// Thread::cancel();
Thread::join();
+ mwindow->stop_mixers();
// Final position is updated continuously during playback
// Get final position
double position = get_tracking_position();
double total = 0;
for(Track *current = first; current; current = NEXT)
{
- double length = current->get_length();
- if(length > total) total = length;
+ if( current->play )
+ {
+ double length = current->get_length();
+ if(length > total) total = length;
+ }
}
return total;
}
double Tracks::total_recordable_length()
{
- double total = 0;
+ double total = -1;
for(Track *current = first; current; current = NEXT)
{
if(current->record)
double total = 0;
for(Track *current = first; current; current = NEXT)
{
- if(current->get_length() > total) total = current->get_length();
+ double length = current->get_length();
+ if(length > total) total = length;
}
return total;
}
end_position = end;
}
else {
+// starting play at or past end, play to end of media (for mixers)
+ if( start >= length )
+ length = edl->tracks->total_length();
switch( command ) {
case SLOW_FWD:
case FAST_FWD:
if(edl->local_session->outpoint_valid())
end_position = edl->local_session->get_outpoint();
- else
+ else {
end_position = edl->tracks->total_playable_length();
+ if( start_position >= end_position )
+ end_position = edl->tracks->total_length();
+ }
}
void TransportCommand::playback_range_project()
if(nested_edl)
{
- return (int64_t)(nested_edl->tracks->total_playable_length() *
+ return (int64_t)(nested_edl->tracks->total_length() *
edl->session->frame_rate + 0.5);
}
}
else
{
- max_position = Units::to_int64(nested_edl->tracks->total_playable_length() *
+ max_position = Units::to_int64(nested_edl->tracks->total_length() *
frame_rate - 1);
}
#include "trackcanvas.h"
#include "vpatchgui.h"
#include "vtrack.h"
+#include "vwindow.h"
#include <string.h>
-
-
-
VPatchGUI::VPatchGUI(MWindow *mwindow, PatchBay *patchbay, VTrack *track, int x, int y)
: PatchGUI(mwindow, patchbay, track, x, y)
{
VPatchGUI::~VPatchGUI()
{
- if(fade) delete fade;
- if(mode) delete mode;
+ if( fade ) delete fade;
+ if( mode ) delete mode;
}
void VPatchGUI::create_objects()
//int x1 = 0;
int y1 = PatchGUI::reposition(x, y);
- if(fade) fade->reposition_window(fade->get_x(),
- y1 + y);
-
+ if( fade )
+ fade->reposition_window(fade->get_x(), y1+y);
y1 += mwindow->theme->fade_h;
-
- if(mode) mode->reposition_window(mode->get_x(),
- y1 + y);
-
- if(nudge) nudge->reposition_window(nudge->get_x(),
- y1 + y);
-
-
+ if( mix )
+ mix->reposition_window(mix->get_x(), y1+y);
+ if( mode )
+ mode->reposition_window(mode->get_x(), y1+y);
+ if( nudge )
+ nudge->reposition_window(nudge->get_x(), y1+y);
y1 += mwindow->theme->mode_h;
-
return y1;
}
int x1 = 0;
int y1 = PatchGUI::update(x, y);
- if(fade)
- {
- if(h - y1 < mwindow->theme->fade_h)
- {
+ if( fade ) {
+ if( h - y1 < mwindow->theme->fade_h ) {
delete fade;
fade = 0;
}
- else
- {
+ else {
fade->update(fade->get_w(), mwindow->get_float_auto(this, AUTOMATION_FADE)->get_value(),
mwindow->edl->local_session->automation_mins[AUTOGROUPTYPE_VIDEO_FADE],
mwindow->edl->local_session->automation_maxs[AUTOGROUPTYPE_VIDEO_FADE]);
}
}
else
- if(h - y1 >= mwindow->theme->fade_h)
- {
- patchbay->add_subwindow(fade = new VFadePatch(mwindow,
- this,
- x1 + x,
- y1 + y,
+ if( h - y1 >= mwindow->theme->fade_h ) {
+ patchbay->add_subwindow(fade = new VFadePatch(mwindow, this, x1+x, y1+y,
patchbay->get_w() - 10));
}
y1 += mwindow->theme->fade_h;
- if(mode)
- {
- if(h - y1 < mwindow->theme->mode_h)
- {
- delete mode;
- mode = 0;
- delete nudge;
- nudge = 0;
+ if( mode ) {
+ if( h - y1 < mwindow->theme->mode_h ) {
+ delete mix; mix = 0;
+ delete mode; mode = 0;
+ delete nudge; nudge = 0;
}
- else
- {
+ else {
+ if( mwindow->session->selected_zwindow >= 0 ) {
+ int v = mwindow->mixer_track_active(track);
+ mix->update(v);
+ }
mode->update(mwindow->get_int_auto(this, AUTOMATION_MODE)->value);
nudge->update();
}
}
else
- if(h - y1 >= mwindow->theme->mode_h)
- {
- patchbay->add_subwindow(mode = new VModePatch(mwindow,
- this,
- x1 + x,
- y1 + y));
+ if( h - y1 >= mwindow->theme->mode_h ) {
+ patchbay->add_subwindow(mix = new VMixPatch(mwindow, this, x1+x, y1+y+5));
+ x1 += mix->get_w();
+ patchbay->add_subwindow(mode = new VModePatch(mwindow, this, x1+x, y1+y));
mode->create_objects();
- x1 += mode->get_w() + 10;
- patchbay->add_subwindow(nudge = new NudgePatch(mwindow,
- this,
- x1 + x,
- y1 + y,
- patchbay->get_w() - x1 - 10));
+ x1 += mode->get_w();
+ patchbay->add_subwindow(nudge = new NudgePatch(mwindow, this, x1+x, y1+y,
+ patchbay->get_w() - x1-x - 10));
}
-
-
-
-
y1 += mwindow->theme->mode_h;
-
return y1;
}
void VPatchGUI::synchronize_fade(float value_change)
{
- if(fade && !change_source)
- {
+ if( fade && !change_source ) {
fade->update(Units::to_int64(fade->get_value() + value_change));
fade->update_edl();
}
int VFadePatch::handle_event()
{
- if(shift_down())
- {
+ if( shift_down() ) {
update(100);
set_tooltip(get_caption());
}
float change = update_edl();
- if(patch->track->gang && patch->track->record)
+ if( patch->track->gang && patch->track->record )
patch->patchbay->synchronize_faders(change, TRACK_VIDEO, patch->track);
patch->change_source = 0;
mwindow->restart_brender();
mwindow->sync_parameters(CHANGE_PARAMS);
mwindow->gui->lock_window("VFadePatch::handle_event");
- if(mwindow->edl->session->auto_conf->autos[AUTOMATION_FADE])
- {
+ if( mwindow->edl->session->auto_conf->autos[AUTOMATION_FADE] ) {
mwindow->gui->draw_overlays(1);
}
return 1;
}
-
-
-
VModePatch::VModePatch(MWindow *mwindow, VPatchGUI *patch, int x, int y)
: BC_PopupMenu(x, y, patch->patchbay->mode_icons[0]->get_w() + 20,
"", 1, mwindow->theme->get_image_set("mode_popup", 0), 10)
int VModePatch::handle_event()
{
// Set menu items
-// for(int i = 0; i < total_items(); i++)
+// for( int i = 0; i < total_items(); i++ )
// {
// VModePatchItem *item = (VModePatchItem*)get_item(i);
-// if(item->mode == mode)
+// if( item->mode == mode )
// item->set_checked(1);
// else
// item->set_checked(0);
mwindow->sync_parameters(CHANGE_PARAMS);
- if(mwindow->edl->session->auto_conf->autos[AUTOMATION_MODE])
- {
+ if( mwindow->edl->session->auto_conf->autos[AUTOMATION_MODE] ) {
mwindow->gui->draw_overlays(1);
}
mwindow->session->changes_made = 1;
void VModePatch::update(int mode)
{
set_icon(patch->patchbay->mode_to_icon(mode));
- for(int i = 0; i < total_items(); i++)
- {
+ for( int i = 0; i < total_items(); i++ ) {
VModePatchItem *item = (VModePatchItem*)get_item(i);
item->set_checked(item->mode == mode);
VModePatchSubMenu *submenu = (VModePatchSubMenu *)item->get_submenu();
const char* VModePatch::mode_to_text(int mode)
{
- switch(mode) {
+ switch( mode ) {
case TRANSFER_NORMAL: return _("Normal");
case TRANSFER_ADDITION: return _("Addition");
case TRANSFER_SUBTRACT: return _("Subtract");
{
this->popup = popup;
this->mode = mode;
- if(this->mode == popup->mode) set_checked(1);
+ if( this->mode == popup->mode ) set_checked(1);
}
int VModePatchItem::handle_event()
this->submenu = submenu;
this->mode = mode;
VModePatch *popup = submenu->mode_item->popup;
- if(this->mode == popup->mode) set_checked(1);
+ if( this->mode == popup->mode ) set_checked(1);
}
VModeSubMenuItem::~VModeSubMenuItem()
{
}
+VMixPatch::VMixPatch(MWindow *mwindow, VPatchGUI *patch, int x, int y)
+ : MixPatch(mwindow, patch, x, y)
+{
+ set_tooltip(_("Mixer"));
+}
+
+VMixPatch::~VMixPatch()
+{
+}
int handle_event();
};
+class VMixPatch : public MixPatch
+{
+public:
+ VMixPatch(MWindow *mwindow, VPatchGUI *patch, int x, int y);
+ ~VMixPatch();
+};
#endif
//printf("VWindowGUI::update_points 2\n");
long pixel = (long)((double)edl->local_session->in_point /
- edl->tracks->total_playable_length() *
+ edl->tracks->total_length() *
(mwindow->theme->vtimebar_w -
2 *
mwindow->theme->in_point[0]->get_w())) +
//printf("VWindowGUI::update_points 10\n");
pixel = (long)((double)edl->local_session->out_point /
- (edl->tracks->total_playable_length() + 0.5) *
+ (edl->tracks->total_length() + 0.5) *
(mwindow->theme->vtimebar_w -
2 *
mwindow->theme->in_point[0]->get_w())) +
EDL* get_edl();
void goto_start();
void goto_end();
+ int is_vwindow() { return 1; }
VWindowGUI *gui;
};
--- /dev/null
+
+/*
+ * CINELERRA
+ * Copyright (C) 1997-2012 Adam Williams <broadcast at earthling dot net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include "bcdialog.h"
+#include "edl.h"
+#include "filexml.h"
+#include "language.h"
+#include "mainsession.h"
+#include "mwindow.h"
+#include "mwindowgui.h"
+#include "patchbay.h"
+#include "patchgui.h"
+#include "playbackengine.h"
+#include "renderengine.h"
+#include "timelinepane.h"
+#include "track.h"
+#include "transportque.h"
+#include "zwindow.h"
+#include "zwindowgui.h"
+
+Mixers::Mixers()
+{
+}
+
+Mixers::~Mixers()
+{
+ remove_all_objects();
+}
+
+Mixer *Mixers::new_mixer()
+{
+ int idx = 0;
+ for( int i=0; i<size(); ++i ) {
+ Mixer *mixer = get(i);
+ if( idx < mixer->idx ) idx = mixer->idx;
+ }
+ return append(new Mixer(idx+1));
+}
+
+Mixer *Mixers::get_mixer(int idx)
+{
+ for( int i=0; i<size(); ++i ) {
+ Mixer *mixer = get(i);
+ if( mixer->idx == idx ) return mixer;
+ }
+ return 0;
+}
+
+void Mixers::del_mixer(int idx)
+{
+ Mixer *mixer = get_mixer(idx);
+ if( mixer ) remove_object(mixer);
+}
+
+void Mixer::set_title(const char *tp)
+{
+ strncpy(title, tp, sizeof(title));
+ title[sizeof(title)-1] = 0;
+}
+
+void Mixers::save(FileXML *file)
+{
+ file->tag.set_title("MIXERS");
+ file->append_tag();
+ file->append_newline();
+ for( int i=0; i<size(); ++i ) {
+ Mixer *mixer = get(i);
+ mixer->save(file);
+ }
+ file->tag.set_title("/MIXERS");
+ file->append_tag();
+ file->append_newline();
+}
+
+int Mixers::load(FileXML *file)
+{
+ int result = 0;
+ while( !(result = file->read_tag()) ) {
+ if( file->tag.title_is("/MIXERS") ) break;
+ if( file->tag.title_is("MIXER") ) {
+ Mixer *mixer = new_mixer();
+ file->tag.get_property("TITLE", mixer->title);
+ mixer->x = file->tag.get_property("X", mixer->x);
+ mixer->y = file->tag.get_property("Y", mixer->y);
+ mixer->w = file->tag.get_property("W", mixer->w);
+ mixer->h = file->tag.get_property("H", mixer->h);
+ mixer->load(file);
+ }
+ }
+ return 0;
+}
+
+void Mixers::copy_from(Mixers &that)
+{
+ remove_all_objects();
+ for( int i=0; i<that.size(); ++i ) {
+ Mixer *mixer = new_mixer();
+ mixer->copy_from(*that[i]);
+ }
+}
+
+void Mixer::save(FileXML *file)
+{
+ file->tag.set_title("MIXER");
+ file->tag.set_property("TITLE",title);
+ file->tag.set_property("X",x);
+ file->tag.set_property("Y",y);
+ file->tag.set_property("W",w);
+ file->tag.set_property("H",h);
+ file->append_tag();
+ file->append_newline();
+ for( int i=0; i<mixer_ids.size(); ++i ) {
+ file->tag.set_title("MIX");
+ file->tag.set_property("ID", mixer_ids[i]);
+ file->append_tag();
+ file->tag.set_title("/MIX");
+ file->append_tag();
+ file->append_newline();
+ }
+ file->tag.set_title("/MIXER");
+ file->append_tag();
+ file->append_newline();
+}
+
+Mixer::Mixer(int idx)
+{
+ this->idx = idx;
+ title[0] = 0;
+ x = y = 100 + idx*64;
+ w = 400; h = 300;
+}
+void Mixer::reposition(int x, int y, int w, int h)
+{
+ this->x = x; this->y = y;
+ this->w = w; this->h = h;
+}
+
+int Mixer::load(FileXML *file)
+{
+ int result = 0;
+ while( !(result = file->read_tag()) ) {
+ if( file->tag.title_is("/MIXER") ) break;
+ if( file->tag.title_is("MIX") ) {
+ mixer_ids.append(file->tag.get_property("ID", 0));
+ }
+ }
+ return 0;
+}
+
+void Mixer::copy_from(Mixer &that)
+{
+ mixer_ids.remove_all();
+ strncpy(title, that.title, sizeof(title));
+ title[sizeof(title)-1] = 0;
+ x = that.x; y = that.y;
+ w = that.w; h = that.h;
+ for( int i=0; i<that.mixer_ids.size(); ++i )
+ mixer_ids.append(that.mixer_ids[i]);
+}
+
+
+ZWindow::ZWindow(MWindow *mwindow)
+ : BC_DialogThread()
+{
+ this->mwindow = mwindow;
+ idx = -1;
+ edl = 0;
+ highlighted = 0;
+ title[0] = 0;
+ zgui = 0;
+}
+
+ZWindow::~ZWindow()
+{
+ close_window();
+ if( edl )
+ edl->remove_user();
+}
+
+BC_Window* ZWindow::new_gui()
+{
+ Mixer *mixer = mwindow->edl->mixers.get_mixer(idx);
+ zgui = new ZWindowGUI(mwindow, this, mixer);
+ zgui->create_objects();
+ return zgui;
+}
+
+void ZWindow::handle_done_event(int result)
+{
+}
+void ZWindow::handle_close_event(int result)
+{
+ zgui = 0;
+}
+
+void ZWindow::change_source(EDL *edl)
+{
+ if( this->edl && edl != this->edl )
+ this->edl->remove_user();
+ this->edl = edl;
+ if( edl != 0 ) {
+ zgui->playback_engine->que->send_command(CURRENT_FRAME, CHANGE_ALL, edl, 1);
+ }
+}
+
+void ZWindow::issue_command(int command, int wait_tracking,
+ int use_inout, int update_refresh, int toggle_audio)
+{
+ zgui->playback_engine->issue_command(edl, command,
+ wait_tracking, use_inout, update_refresh, toggle_audio);
+}
+
+void ZWindow::update_mixer_ids()
+{
+ if( !running() ) return;
+ Mixer *mixer = mwindow->edl->mixers.get_mixer(idx);
+ if( !mixer ) return;
+ mixer->mixer_ids.remove_all();
+ PatchBay *patchbay = mwindow->gui->pane[0]->patchbay;
+ for( int i=0; i<patchbay->patches.size(); ++i ) {
+ PatchGUI *patchgui = patchbay->patches[i];
+ if( !patchgui->mixer ) continue;
+ int mixer_id = patchgui->track->get_mixer_id();
+ if( mixer->mixer_ids.number_of(mixer_id) >= 0 ) continue;
+ mixer->mixer_ids.append(mixer_id);
+ }
+}
+
+void ZWindow::set_title(const char *tp)
+{
+ char *cp = title, *ep = cp + sizeof(title)-1;
+ cp += snprintf(title, ep-cp, _("Mixer %d"), idx);
+ if( tp ) cp += snprintf(cp, ep-cp, ": %s", tp);
+ Mixer *mixer = mwindow->edl->mixers.get_mixer(idx);
+ if( mixer && tp != mixer->title ) mixer->set_title(tp);
+}
+
+void ZWindow::reposition(int x, int y, int w, int h)
+{
+ Mixer *mixer = mwindow->edl->mixers.get_mixer(idx);
+ if( mixer ) mixer->reposition(x, y, w, h);
+}
+
--- /dev/null
+
+/*
+ * CINELERRA
+ * Copyright (C) 1997-2012 Adam Williams <broadcast at earthling dot net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __ZWINDOW_H__
+#define __ZWINDOW_H__
+
+#include "arraylist.h"
+#include "bcdialog.h"
+#include "bcwindow.h"
+#include "edl.inc"
+#include "filexml.inc"
+#include "mwindow.inc"
+#include "playbackengine.inc"
+#include "renderengine.inc"
+#include "zwindowgui.inc"
+
+class Mixer {
+public:
+ int idx;
+ int x, y, w, h;
+ ArrayList<int> mixer_ids;
+ char title[BCSTRLEN];
+
+ Mixer(int idx);
+ void save(FileXML *file);
+ int load(FileXML *file);
+ void copy_from(Mixer &that);
+ void set_title(const char *tp);
+ void reposition(int x, int y, int w, int h);
+};
+
+class Mixers : public ArrayList<Mixer *>
+{
+public:
+ Mixers();
+ ~Mixers();
+ Mixer *new_mixer();
+ Mixer *get_mixer(int idx);
+ void del_mixer(int idx);
+ void save(FileXML *file);
+ int load(FileXML *file);
+ void copy_from(Mixers &that);
+};
+
+
+class ZWindow : public BC_DialogThread
+{
+public:
+ ZWindow(MWindow *mwindow);
+ ~ZWindow();
+
+ void handle_done_event(int result);
+ void handle_close_event(int result);
+ void change_source(EDL *edl);
+ void issue_command(int command, int wait_tracking,
+ int use_inout, int update_refresh, int toggle_audio);
+ void update_mixer_ids();
+ void set_title(const char *tp);
+ void reposition(int x, int y, int w, int h);
+
+ BC_Window *new_gui();
+ MWindow *mwindow;
+ ZWindowGUI *zgui;
+ EDL* edl;
+
+ int idx;
+ int highlighted;
+ char title[BCTEXTLEN];
+};
+
+#endif
--- /dev/null
+
+/*
+ * CINELERRA
+ * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __ZWINDOW_INC__
+#define __ZWINDOW_INC__
+
+class Mixer;
+class Mixers;
+class ZWindow;
+
+#endif
--- /dev/null
+
+/*
+ * CINELERRA
+ * Copyright (C) 1997-2011 Adam Williams <broadcast at earthling dot net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include "bcwindow.h"
+#include "canvas.h"
+#include "edl.h"
+#include "edlsession.h"
+#include "keys.h"
+#include "language.h"
+#include "localsession.h"
+#include "mainmenu.h"
+#include "mainsession.h"
+#include "mbuttons.h"
+#include "mwindow.h"
+#include "mwindowgui.h"
+#include "playbackengine.h"
+#include "playtransport.h"
+#include "renderengine.h"
+#include "theme.h"
+#include "tracks.h"
+#include "transportque.h"
+#include "zwindow.h"
+#include "zwindowgui.h"
+
+ZWindowGUI::ZWindowGUI(MWindow *mwindow, ZWindow *zwindow, Mixer *mixer)
+ : BC_Window(mixer->title, mixer->x, mixer->y, mixer->w, mixer->h,
+ 100, 100, 1, 1, 0)
+{
+ this->mwindow = mwindow;
+ this->zwindow = zwindow;
+
+ canvas = 0;
+ playback_engine = 0;
+ highlighted = 0;
+}
+
+ZWindowGUI::~ZWindowGUI()
+{
+ delete playback_engine;
+ delete canvas;
+}
+
+void ZWindowGUI::create_objects()
+{
+ lock_window("ZWindowGUI::create_objects");
+
+ canvas = new ZWindowCanvas(mwindow, this, 10,10, get_w()-20,get_h()-20);
+ canvas->create_objects(mwindow->edl);
+ playback_engine = new PlaybackEngine(mwindow, canvas);
+ playback_engine->create_objects();
+
+ deactivate();
+ show_window();
+ unlock_window();
+}
+
+int ZWindowGUI::resize_event(int w, int h)
+{
+ canvas->reposition_window(0, 10,10, w-20,h-20);
+ zwindow->reposition(get_x(), get_y(), w, h);
+ BC_WindowBase::resize_event(w, h);
+ return 1;
+}
+
+int ZWindowGUI::translation_event()
+{
+ zwindow->reposition(get_x(), get_y(), get_w(), get_h());
+ return 0;
+}
+
+int ZWindowGUI::close_event()
+{
+ mwindow->del_mixer(zwindow);
+ set_done(0);
+ return 1;
+}
+
+int ZWindowGUI::keypress_event()
+{
+ int key = get_keypress();
+ if( key == 'w' || key == 'W' ) {
+ close_event();
+ return 1;
+ }
+ unlock_window();
+ int result = 1;
+ switch( key ) {
+ case 'f':
+ if( mwindow->session->zwindow_fullscreen )
+ canvas->stop_fullscreen();
+ else
+ canvas->start_fullscreen();
+ break;
+ case ESC:
+ if( mwindow->session->zwindow_fullscreen )
+ canvas->stop_fullscreen();
+ break;
+ default:
+ mwindow->gui->lock_window("ZWindowGUI::keypress_event");
+ result = mwindow->gui->mbuttons->transport->do_keypress(key);
+ mwindow->gui->unlock_window();
+ }
+
+ lock_window("ZWindowGUI::keypress_event 1");
+ return result;
+}
+
+int ZWindowGUI::button_press_event()
+{
+ mwindow->select_zwindow(zwindow);
+ if( get_double_click() ) {
+ unlock_window();
+ mwindow->gui->lock_window("ZWindowGUI::button_press_event 0");
+ LocalSession *local_session = mwindow->edl->local_session;
+ double start = local_session->get_selectionstart(1);
+ double end = local_session->get_selectionend(1);
+ if( EQUIV(start, end) ) {
+ start = mwindow->edl->tracks->total_recordable_length();
+ if( start < 0 ) start = end;
+ }
+ if( (end-start) > 1e-4 ) {
+ LocalSession *zlocal_session = zwindow->edl->local_session;
+ zlocal_session->set_selectionstart(end);
+ zlocal_session->set_selectionend(end);
+ zlocal_session->set_inpoint(start);
+ zlocal_session->set_outpoint(end);
+ double orig_inpoint = local_session->get_inpoint();
+ double orig_outpoint = local_session->get_outpoint();
+ local_session->set_selectionstart(end);
+ local_session->set_selectionend(end);
+ local_session->set_inpoint(start);
+ local_session->set_outpoint(end);
+ mwindow->overwrite(zwindow->edl);
+ local_session->set_inpoint(orig_inpoint);
+ local_session->set_outpoint(orig_outpoint);
+ mwindow->gui->update_timebar(1);
+ }
+ mwindow->gui->unlock_window();
+ lock_window("ZWindowGUI::button_press_event 1");
+ }
+ if( !canvas->get_canvas() ) return 0;
+ return canvas->button_press_event_base(canvas->get_canvas());
+}
+
+int ZWindowGUI::cursor_leave_event()
+{
+ if( !canvas->get_canvas() ) return 0;
+ return canvas->cursor_leave_event_base(canvas->get_canvas());
+}
+
+int ZWindowGUI::cursor_enter_event()
+{
+ if( !canvas->get_canvas() ) return 0;
+ return canvas->cursor_enter_event_base(canvas->get_canvas());
+}
+
+int ZWindowGUI::button_release_event()
+{
+ if( !canvas->get_canvas() ) return 0;
+ return canvas->button_release_event();
+}
+
+int ZWindowGUI::cursor_motion_event()
+{
+ BC_WindowBase *cvs = canvas->get_canvas();
+ if( !cvs ) return 0;
+ cvs->unhide_cursor();
+ return canvas->cursor_motion_event();
+}
+
+int ZWindowGUI::draw_overlays()
+{
+ BC_WindowBase *cvs = canvas->get_canvas();
+ if( !cvs || cvs->get_video_on() ) return 0;
+ if( highlighted != zwindow->highlighted ) {
+ highlighted = zwindow->highlighted;
+ cvs->set_color(WHITE);
+ cvs->set_inverse();
+ cvs->draw_rectangle(0, 0, cvs->get_w(), cvs->get_h());
+ cvs->draw_rectangle(1, 1, cvs->get_w() - 2, cvs->get_h() - 2);
+ cvs->set_opaque();
+ }
+ return 1;
+}
+
+ZWindowCanvas::ZWindowCanvas(MWindow *mwindow, ZWindowGUI *gui,
+ int x, int y, int w, int h)
+ : Canvas(mwindow, gui, x,y, w,h, 0,0,0)
+{
+ this->mwindow = mwindow;
+ this->gui = gui;
+}
+
+void ZWindowCanvas::close_source()
+{
+ gui->unlock_window();
+ gui->zwindow->zgui->playback_engine->interrupt_playback(1);
+ gui->lock_window("ZWindowCanvas::close_source");
+ EDL *edl = gui->zwindow->edl;
+ if( edl ) {
+ gui->zwindow->edl = 0;
+ edl->remove_user();
+ }
+}
+
+
+void ZWindowCanvas::draw_refresh(int flush)
+{
+ EDL *edl = gui->zwindow->edl;
+ BC_WindowBase *cvs = get_canvas();
+ int dirty = 0;
+
+ if( !cvs->get_video_on() ) {
+ cvs->clear_box(0, 0, cvs->get_w(), cvs->get_h());
+ gui->highlighted = 0;
+ dirty = 1;
+ }
+ if( !cvs->get_video_on() && refresh_frame && edl ) {
+ float in_x1, in_y1, in_x2, in_y2;
+ float out_x1, out_y1, out_x2, out_y2;
+ get_transfers(edl,
+ in_x1, in_y1, in_x2, in_y2,
+ out_x1, out_y1, out_x2, out_y2);
+ cvs->draw_vframe(refresh_frame,
+ (int)out_x1, (int)out_y1, (int)(out_x2 - out_x1), (int)(out_y2 - out_y1),
+ (int)in_x1, (int)in_y1, (int)(in_x2 - in_x1), (int)(in_y2 - in_y1), 0);
+ dirty = 1;
+ }
+
+ if( gui->draw_overlays() )
+ dirty = 1;
+
+ if( dirty )
+ cvs->flash(flush);
+}
+
+int ZWindowCanvas::get_fullscreen()
+{
+ return mwindow->session->zwindow_fullscreen;
+}
+
+void ZWindowCanvas::set_fullscreen(int value)
+{
+ mwindow->session->zwindow_fullscreen = value;
+}
+
--- /dev/null
+
+/*
+ * CINELERRA
+ * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __ZWINDOWGUI_H__
+#define __ZWINDOWGUI_H__
+
+#include "bcwindow.h"
+#include "canvas.h"
+#include "mwindow.h"
+#include "renderengine.inc"
+
+class ZWindowGUI;
+class ZWindowCanvas;
+
+class ZWindowGUI : public BC_Window
+{
+public:
+ ZWindowGUI(MWindow *mwindow, ZWindow *vwindow, Mixer *mixer);
+ ~ZWindowGUI();
+
+ void create_objects();
+ int resize_event(int w, int h);
+ int translation_event();
+ int close_event();
+ int keypress_event();
+ int button_press_event();
+ int cursor_leave_event();
+ int cursor_enter_event();
+ int button_release_event();
+ int cursor_motion_event();
+ int select_window(int n);
+ int draw_overlays();
+
+ MWindow *mwindow;
+ ZWindow *zwindow;
+ ZWindowCanvas *canvas;
+
+ TransportCommand *command;
+ PlaybackEngine *playback_engine;
+ RenderEngine *render_engine;
+ int highlighted;
+};
+
+class ZWindowCanvas : public Canvas
+{
+public:
+ ZWindowCanvas(MWindow *mwindow, ZWindowGUI *gui,
+ int x, int y, int w, int h);
+
+ void draw_refresh(int flush = 1);
+ void close_source();
+ int get_fullscreen();
+ void set_fullscreen(int value);
+
+ MWindow *mwindow;
+ ZWindowGUI *gui;
+};
+
+#endif
--- /dev/null
+
+/*
+ * CINELERRA
+ * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __ZWINDOWGUI_INC__
+#define __ZWINDOWGUI_INC__
+
+class ZWindowGUI;
+
+#endif
else
this->display_name[0] = 0;
- put_title(_(title));
+ put_title(title);
if(bg_pixmap) shared_bg_pixmap = 1;
subwindows = new BC_SubWindowList;
void BC_WindowBase::set_title(const char *text, int utf8)
{
// utf8>0: wm + net_wm, utf8=0: wm only, utf<0: net_wm only
- put_title(_(text));
+ put_title(text);
const unsigned char *wm_title = (const unsigned char *)title;
int title_len = strlen((const char *)title);
if( utf8 >= 0 ) {