X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=futatabi%2Fmainwindow.h;h=1fbfb948de072a866f1c38b9edcab4445d3fa5d9;hb=ec86648ba1772001c26d23845d54ac7254cc92e5;hp=4e3800ef083ae6df812719735f9a219ddcac9fdb;hpb=44606be7327eb9160b9de6c7be5c5006a3d5670e;p=nageru diff --git a/futatabi/mainwindow.h b/futatabi/mainwindow.h index 4e3800e..1fbfb94 100644 --- a/futatabi/mainwindow.h +++ b/futatabi/mainwindow.h @@ -3,38 +3,67 @@ #include "clip_list.h" #include "db.h" +#include "midi_mapper.h" +#include "player.h" #include "state.pb.h" -#include #include #include +#include +#include +#include +#include #include -#include #include +#include #include namespace Ui { class MainWindow; } // namespace Ui +struct FrameOnDisk; +class JPEGFrameView; class Player; +class QPushButton; +class QTableView; -class MainWindow : public QMainWindow { +class MainWindow : public QMainWindow, public ControllerReceiver { Q_OBJECT public: MainWindow(); + ~MainWindow(); // HTTP callback. TODO: Does perhaps not belong to MainWindow? std::pair get_queue_status() const; -//private: - Ui::MainWindow *ui; + void display_frame(unsigned stream_idx, const FrameOnDisk &frame); + + // ControllerReceiver interface. + void preview() override; + void queue() override; + void play() override; + void next() override; + void toggle_lock() override; + void jog(int delta) override; + void switch_camera(unsigned camera_idx) override; + void set_master_speed(float speed) override; + void cue_in() override; + void cue_out() override; + + // Raw receivers are not used. + void controller_changed(unsigned controller) override {} + void note_on(unsigned note) override {} private: + Ui::MainWindow *ui; + QLabel *disk_free_label; - Player *preview_player, *live_player; + std::unique_ptr preview_player, live_player; + bool preview_playing = false; DB db; + unsigned num_cameras; // State when doing a scrub operation on a timestamp with the mouse. bool scrubbing = false; @@ -42,7 +71,8 @@ private: int64_t scrub_pts_origin; // Which element (e.g. pts_in on clip 4) we are scrubbing. - enum ScrubType { SCRUBBING_CLIP_LIST, SCRUBBING_PLAYLIST } scrub_type; + enum ScrubType { SCRUBBING_CLIP_LIST, + SCRUBBING_PLAYLIST } scrub_type; int scrub_row; int scrub_column; @@ -50,6 +80,16 @@ private: int last_mousewheel_camera_row = -1; int leftover_angle_degrees = 0; + // Normally, jog is only allowed if in the focus (well, selection) is + // on the in or out pts columns. However, changing camera (even when + // using a MIDI button) on the clip list changes the highlight, + // and we'd like to keep on jogging. Thus, as a special case, if you + // change to a camera column on the clip list (and don't change which + // clip you're looking at), the last column you were at will be stored here. + // If you then try to jog, we'll fetch the value from here and highlight it. + // Doing pretty much anything else is going to reset it back to -1, though. + int hidden_jog_column = -1; + // Some operations, notably scrubbing and scrolling, happen in so large increments // that we want to group them instead of saving to disk every single time. // If they happen (ie., we get a callback from the model that it's changed) while @@ -60,6 +100,13 @@ private: std::string deferred_change_id; StateProto deferred_state; + // NOTE: The undo stack always has the current state on top. + std::deque undo_stack, redo_stack; + + // If we need to blink the lock light, we do so for only a second. + // This timer signals that we should end it. + QTimer *lock_blink_timeout; + // Before a change that should be deferred (see above), currently_deferring_model_changes // must be set to true, and current_change_id must be given contents describing what's // changed to avoid accidental grouping. @@ -69,41 +116,86 @@ private: mutable std::mutex queue_status_mu; std::string queue_status; // Under queue_status_mu. + struct FrameAndDisplay { + QFrame *frame; + JPEGFrameView *display; + QPushButton *preview_btn; + bool hidden = false; + }; + std::vector displays; + + // Used to get tally information, if a tally URL is set. + QNetworkAccessManager http; + QNetworkReply *http_reply = nullptr; + + MIDIMapper midi_mapper; + + void change_num_cameras(); + void relayout_displays(); void cue_in_clicked(); void cue_out_clicked(); void queue_clicked(); void preview_clicked(); void preview_angle_clicked(unsigned stream_idx); void play_clicked(); - void live_player_clip_done(); - std::pair live_player_get_next_clip(); - void live_player_clip_progress(const std::map &progress); + void next_clicked(); + void stop_clicked(); + void speed_slider_changed(int percent); + void speed_lock_clicked(); + void preview_player_done(); + void live_player_done(); + void live_player_clip_progress(const std::map &progress, TimeRemaining time_remaining); void set_output_status(const std::string &status); void playlist_duplicate(); void playlist_remove(); void playlist_move(int delta); + enum JogDestination { JOG_CLIP_LIST, JOG_PLAYLIST }; + void jog_internal(JogDestination jog_destination, int column, int row, int stream_idx, int pts_delta); + void defer_timer_expired(); void content_changed(); // In clip_list or play_list. void state_changed(const StateProto &state); // Called post-filtering. + void save_settings(); + + void lock_blink_timer_expired(); - enum Rounding { FIRST_AT_OR_AFTER, LAST_BEFORE }; + enum Rounding { FIRST_AT_OR_AFTER, + LAST_BEFORE }; void preview_single_frame(int64_t pts, unsigned stream_idx, Rounding rounding); // Also covers when the playlist itself changes. void playlist_selection_changed(); void clip_list_selection_changed(const QModelIndex ¤t, const QModelIndex &previous); + std::vector get_playlist(size_t start_row, size_t end_row); void resizeEvent(QResizeEvent *event) override; bool eventFilter(QObject *watched, QEvent *event) override; void report_disk_space(off_t free_bytes, double estimated_seconds_left); + void midi_mapping_triggered(); void exit_triggered(); + void export_cliplist_clip_multitrack_triggered(); + void export_playlist_clip_interpolated_triggered(); void manual_triggered(); void about_triggered(); + void undo_triggered(); + void redo_triggered(); + void quality_toggled(int quality, bool checked); + void in_padding_toggled(double seconds, bool checked); + void out_padding_toggled(double seconds, bool checked); + void hide_camera_toggled(unsigned camera_idx, bool checked); void highlight_camera_input(int stream_idx); + void enable_or_disable_preview_button(); + void enable_or_disable_queue_button(); + + template + void replace_model(QTableView *view, Model **model, Model *new_model); + + void start_tally(); + void tally_received(); private slots: void relayout();