diff options
-rw-r--r-- | gtk2_ardour/SConscript | 1 | ||||
-rw-r--r-- | gtk2_ardour/ardour_ui.cc | 29 | ||||
-rw-r--r-- | gtk2_ardour/ardour_ui.h | 45 | ||||
-rwxr-xr-x | gtk2_ardour/arval | 2 | ||||
-rw-r--r-- | gtk2_ardour/arval-waf | 2 | ||||
-rw-r--r-- | gtk2_ardour/main.cc | 2 | ||||
-rw-r--r-- | gtk2_ardour/startup.cc | 489 | ||||
-rw-r--r-- | gtk2_ardour/startup.h | 115 | ||||
-rw-r--r-- | gtk2_ardour/wscript | 1 |
9 files changed, 632 insertions, 54 deletions
diff --git a/gtk2_ardour/SConscript b/gtk2_ardour/SConscript index 61897275e4..b625d5863e 100644 --- a/gtk2_ardour/SConscript +++ b/gtk2_ardour/SConscript @@ -241,6 +241,7 @@ sfdb_ui.cc simpleline.cc simplerect.cc splash.cc +startup.cc streamview.cc tape_region_view.cc tempo_dialog.cc diff --git a/gtk2_ardour/ardour_ui.cc b/gtk2_ardour/ardour_ui.cc index 4c5284849b..0c44a7829e 100644 --- a/gtk2_ardour/ardour_ui.cc +++ b/gtk2_ardour/ardour_ui.cc @@ -94,6 +94,7 @@ typedef uint64_t microseconds_t; #include "session_metadata_dialog.h" #include "gain_meter.h" #include "route_time_axis.h" +#include "startup.h" #include "i18n.h" @@ -176,11 +177,7 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[]) about = 0; splash = 0; - - if (ARDOUR_COMMAND_LINE::session_name.length()) { - /* only show this if we're not going to post the new session dialog */ - show_splash (); - } + _startup = 0; if (theArdourUI == 0) { theArdourUI = this; @@ -280,6 +277,17 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[]) platform_setup (); } +void +ARDOUR_UI::run_startup () +{ + if (_startup == 0) { + _startup = new ArdourStartup (); + } + + _startup->present (); + main().run(); +} + int ARDOUR_UI::create_engine () { @@ -1652,13 +1660,6 @@ ARDOUR_UI::map_transport_state () } void -ARDOUR_UI::GlobalClickBox::printer (char buf[32], Adjustment &adj, void *arg) -{ - snprintf (buf, sizeof(buf), "%s", ((GlobalClickBox *) arg)->strings[ - (int) adj.get_value()].c_str()); -} - -void ARDOUR_UI::engine_stopped () { ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_stopped)); @@ -2225,8 +2226,8 @@ ARDOUR_UI::end_loading_messages () void ARDOUR_UI::loading_message (const std::string& msg) { - show_splash (); - splash->message (msg); + // show_splash (); + // splash->message (msg); flush_pending (); } diff --git a/gtk2_ardour/ardour_ui.h b/gtk2_ardour/ardour_ui.h index f3f4d5ef3f..79643e23d0 100644 --- a/gtk2_ardour/ardour_ui.h +++ b/gtk2_ardour/ardour_ui.h @@ -82,6 +82,7 @@ class NewSessionDialog; class LocationUI; class ThemeManager; class BundleManager; +class ArdourStartup; namespace Gtkmm2ext { class TearOff; @@ -110,6 +111,8 @@ class ARDOUR_UI : public Gtkmm2ext::UI ARDOUR_UI (int *argcp, char **argvp[]); ~ARDOUR_UI(); + void run_startup (); + void show (); bool shown() { return shown_flag; } @@ -258,50 +261,16 @@ class ARDOUR_UI : public Gtkmm2ext::UI void toggle_options_window (); private: - struct GlobalClickBox : public Gtk::VBox { - Gtkmm2ext::ClickBox *box; - Gtk::Frame frame; - Gtk::Label label; - vector<string> &strings; - Gtk::Adjustment adjustment; - - static void printer (char buf[32], Gtk::Adjustment &adj, void *arg); - - GlobalClickBox (const string &str, vector<string> &vs) - : strings (vs), - adjustment (0, 0, vs.size() - 1, 1, 1, 0) { - box = new Gtkmm2ext::ClickBox (&adjustment, "ClickButton"); - label.set_text (str); - label.set_name ("GlobalButtonLabel"); - frame.add (*box); - frame.set_shadow_type (Gtk::SHADOW_IN); - pack_start (label); - pack_start (frame); - box->set_print_func (printer, this); - box->set_wrap (true); - }; - }; - - ARDOUR::AudioEngine *engine; - ARDOUR::Session *session; - - Gtk::Tooltips _tooltips; + ArdourStartup* _startup; + ARDOUR::AudioEngine *engine; + ARDOUR::Session *session; + Gtk::Tooltips _tooltips; void goto_editor_window (); void goto_mixer_window (); void toggle_editor_mixer_on_top (); bool _mixer_on_top; - Gtk::Table adjuster_table; - Gtk::Frame adjuster_frame; - Gtk::Fixed adjuster_base; - - GlobalClickBox *online_control_button; - vector<string> online_control_strings; - - GlobalClickBox *crossfade_time_button; - vector<string> crossfade_time_strings; - Gtk::ToggleButton preroll_button; Gtk::ToggleButton postroll_button; diff --git a/gtk2_ardour/arval b/gtk2_ardour/arval index f3054ef4ef..8f22794470 100755 --- a/gtk2_ardour/arval +++ b/gtk2_ardour/arval @@ -1,4 +1,4 @@ #!/bin/sh . ./ardev_common.sh export ARDOUR_RUNNING_UNDER_VALGRIND=TRUE -exec valgrind --num-callers=50 --tool=memcheck $EXECUTABLE --novst "$@" +exec valgrind --num-callers=50 --tool=memcheck $TOP/$EXECUTABLE --novst "$@" diff --git a/gtk2_ardour/arval-waf b/gtk2_ardour/arval-waf index ae7a8e3c52..439bebd6aa 100644 --- a/gtk2_ardour/arval-waf +++ b/gtk2_ardour/arval-waf @@ -1,4 +1,4 @@ #!/bin/sh . `dirname "$0"`/../build/default/gtk2_ardour/ardev_common_waf.sh export ARDOUR_RUNNING_UNDER_VALGRIND=TRUE -exec valgrind --num-callers=50 --tool=memcheck $EXECUTABLE --novst "$@" +exec valgrind --num-callers=50 --tool=memcheck $TOP/$EXECUTABLE --novst "$@" diff --git a/gtk2_ardour/main.cc b/gtk2_ardour/main.cc index 32454d69d5..f43cc03cf2 100644 --- a/gtk2_ardour/main.cc +++ b/gtk2_ardour/main.cc @@ -382,6 +382,8 @@ int main (int argc, char *argv[]) exit (1); } + ui->run_startup (); + ui->run (text_receiver); ui = 0; diff --git a/gtk2_ardour/startup.cc b/gtk2_ardour/startup.cc new file mode 100644 index 0000000000..c006452453 --- /dev/null +++ b/gtk2_ardour/startup.cc @@ -0,0 +1,489 @@ +#include <algorithm> + +#include <gtkmm/main.h> + +#include "pbd/failed_constructor.h" +#include "pbd/file_utils.h" +#include "pbd/filesystem.h" + +#include "ardour/filesystem_paths.h" +#include "ardour/recent_sessions.h" +#include "ardour/session.h" +#include "ardour/session_state_utils.h" +#include "ardour/template_utils.h" + +#include "startup.h" +#include "i18n.h" + +using namespace std; +using namespace Gtk; +using namespace Gdk; +using namespace Glib; +using namespace PBD; +using namespace ARDOUR; + +ArdourStartup* ArdourStartup::the_startup = 0; + +ArdourStartup::ArdourStartup () + : applying (false) + , ic_new_session_button (_("Open a new session")) + , ic_existing_session_button (_("Open an existing session")) + , more_new_session_options_button (_("I'd like more options for this session")) +{ + set_keep_above (true); + set_position (WIN_POS_CENTER); + + sys::path icon_file; + + if (!find_file_in_search_path (ardour_search_path() + system_data_search_path(), "ardour_icon_48px.png", icon_file)) { + throw failed_constructor(); + } + + try { + icon_pixbuf = Gdk::Pixbuf::create_from_file (icon_file.to_string()); + } + + catch (...) { + throw failed_constructor(); + } + + sys::path been_here_before = user_config_directory(); + been_here_before /= ".a3"; // XXXX use more specific version so we can catch upgrades + + if (!exists (been_here_before)) { + // XXX touch been_here_before; + setup_new_user_page (); + setup_first_time_config_page (); + } else { + setup_initial_choice_page (); + } + + setup_session_page (); + setup_more_options_page (); + setup_final_page (); + + the_startup = this; +} + +ArdourStartup::~ArdourStartup () +{ +} + +void +ArdourStartup::setup_new_user_page () +{ + Label* foomatic = manage (new Label (_("\ +Ardour is a digital audio workstation. You can use it to\n\ +record, edit and mix multi-track audio. You can produce your\n\ +own CDs, mix video soundtracks, or just experiment with new\n\ +ideas about music and sound.\n\ +\n\ +There are a few things that need to configured before you start\n\ +using the program.\ +"))); + + HBox* hbox = manage (new HBox); + HBox* vbox = manage (new HBox); + + hbox->set_border_width (12); + vbox->set_border_width (12); + + hbox->pack_start (*foomatic, false, true); + vbox->pack_start (*hbox, false, true); + + foomatic->show (); + hbox->show (); + vbox->show (); + + append_page (*vbox); + set_page_type (*vbox, ASSISTANT_PAGE_INTRO); + set_page_title (*vbox, _("Welcome to Ardour")); + set_page_header_image (*vbox, icon_pixbuf); + set_page_complete (*vbox, true); +} + +void +ArdourStartup::setup_first_time_config_page () +{ + Gtk::FileChooserButton* fcb = manage (new FileChooserButton (_("Default session folder"), FILE_CHOOSER_ACTION_SELECT_FOLDER)); + Gtk::Label* txt = manage (new Label); + HBox* hbox1 = manage (new HBox); + VBox* vbox = manage (new VBox); + + txt->set_markup (_("\ +Each project that you work on with Ardour has its own folder.\n\ +These can require a lot of disk space if you are recording audio.\n\ +\n\ +Where would you like new Ardour sessions to be stored by default?\n\ +<i>(You can put new sessions anywhere - this is just a default)</i>")); + + hbox1->set_border_width (6); + vbox->set_border_width (6); + + hbox1->pack_start (*fcb, false, true); + vbox->pack_start (*txt, false, true); + vbox->pack_start (*hbox1, false, true); + + fcb->show (); + txt->show (); + hbox1->show (); + vbox->show (); + + append_page (*vbox); + set_page_title (*vbox, _("Default folder for new sessions")); + set_page_header_image (*vbox, icon_pixbuf); + set_page_type (*vbox, ASSISTANT_PAGE_CONTENT); + + /* user can just skip all these settings if they want to */ + + set_page_complete (*vbox, true); +} + +void +ArdourStartup::setup_initial_choice_page () +{ + ic_vbox.set_spacing (6); + ic_vbox.set_border_width (6); + + RadioButton::Group g (ic_new_session_button.get_group()); + ic_existing_session_button.set_group (g); + + ic_vbox.pack_start (ic_new_session_button); + ic_vbox.pack_start (ic_existing_session_button); + + ic_new_session_button.show (); + ic_existing_session_button.show (); + ic_vbox.show (); + + append_page (ic_vbox); + set_page_title (ic_vbox, _("What would you like to do?")); + set_page_header_image (ic_vbox, icon_pixbuf); + + /* user could just click on "Forward" if default + * choice is correct. + */ + + set_page_complete (ic_vbox, true); +} + +void +ArdourStartup::setup_session_page () +{ + session_hbox.set_border_width (12); + session_vbox.set_border_width (12); + + session_vbox.pack_start (session_hbox, true, true); + session_vbox.show (); + session_hbox.show (); + + append_page (session_vbox); +} + +void +ArdourStartup::setup_final_page () +{ + final_page.set_text ("Ardour is ready for use"); + final_page.show (); + append_page (final_page); + set_page_complete (final_page, true); + set_page_header_image (final_page, icon_pixbuf); + set_page_type (final_page, ASSISTANT_PAGE_CONFIRM); +} + +void +ArdourStartup::on_cancel () +{ + exit (1); +} + +void +ArdourStartup::on_close () +{ + if (!applying) { + exit (1); + } +} + +void +ArdourStartup::on_apply () +{ + applying = true; + + // XXX do stuff and then .... + + gtk_main_quit (); +} + +void +ArdourStartup::on_prepare (Gtk::Widget* page) +{ + if (page == &session_vbox) { + if (ic_new_session_button.get_active()) { + /* new session requested */ + setup_new_session_page (); + } else { + /* existing session requested */ + setup_existing_session_page (); + } + } +} + +void +ArdourStartup::setup_new_session_page () +{ + if (!session_hbox.get_children().empty()) { + session_hbox.remove (**session_hbox.get_children().begin()); + } + + if (session_new_vbox.get_children().empty()) { + + HBox* hbox1 = manage (new HBox); + Label* label1 = manage (new Label); + + hbox1->set_spacing (6); + hbox1->pack_start (*label1, false, false); + hbox1->pack_start (new_name_entry, true, true); + + label1->set_text (_("Session name:")); + + hbox1->show(); + label1->show(); + new_name_entry.show (); + + new_name_entry.signal_changed().connect (mem_fun (*this, &ArdourStartup::new_name_changed)); + + HBox* hbox2 = manage (new HBox); + Label* label2 = manage (new Label); + + hbox2->set_spacing (6); + hbox2->pack_start (*label2, false, false); + hbox2->pack_start (new_folder_chooser, true, true); + + label2->set_text (_("Create session folder in:")); + new_folder_chooser.set_current_folder(getenv ("HOME")); + new_folder_chooser.set_title (_("Select folder for session")); + + hbox2->show(); + label2->show(); + new_folder_chooser.show (); + + if (is_directory (user_template_directory ())) { + session_template_chooser.set_current_folder (user_template_directory().to_string()); + } else if (is_directory (system_template_directory ())) { + session_template_chooser.set_current_folder (system_template_directory().to_string()); + } else { + /* hmm, no templates ... what to do? */ + } + + if (is_directory (system_template_directory ())) { + session_template_chooser.add_shortcut_folder (system_template_directory().to_string()); + } + + HBox* hbox3 = manage (new HBox); + Label* label3 = manage (new Label); + + hbox3->set_spacing (6); + hbox3->pack_start (*label3, false, false); + hbox3->pack_start (session_template_chooser, true, true); + + label3->set_text (_("Use this template:")); + + hbox3->show (); + label3->show (); + session_template_chooser.show (); + + Gtk::FileFilter* template_filter = manage (new (Gtk::FileFilter)); + template_filter->add_pattern(X_("*.template")); + session_template_chooser.set_filter (*template_filter); + session_template_chooser.set_title (_("Select template")); + + + HBox* hbox4 = manage (new HBox); + + hbox4->set_spacing (6); + hbox4->pack_start (more_new_session_options_button, false, false); + + hbox4->show (); + more_new_session_options_button.show (); + more_new_session_options_button.signal_clicked().connect (mem_fun (*this, &ArdourStartup::more_new_session_options_button_clicked)); + session_new_vbox.set_spacing (12); + + session_new_vbox.pack_start (*hbox1, false, false); + session_new_vbox.pack_start (*hbox2, false, false); + session_new_vbox.pack_start (*hbox3, false, false); + session_new_vbox.pack_start (*hbox4, false, false); + } + + session_new_vbox.show (); + session_hbox.pack_start (session_new_vbox, false, false); + set_page_title (session_vbox, _("New Session")); +} + +void +ArdourStartup::new_name_changed () +{ + if (!new_name_entry.get_text().empty()) { + set_page_complete (session_vbox, true); + } else { + set_page_complete (session_vbox, false); + } +} + +void +ArdourStartup::redisplay_recent_sessions () +{ + std::vector<sys::path> session_directories; + RecentSessionsSorter cmp; + + recent_session_display.set_model (Glib::RefPtr<TreeModel>(0)); + recent_session_model->clear (); + + ARDOUR::RecentSessions rs; + ARDOUR::read_recent_sessions (rs); + + if (rs.empty()) { + recent_session_display.set_model (recent_session_model); + return; + } + // + // sort them alphabetically + sort (rs.begin(), rs.end(), cmp); + + for (ARDOUR::RecentSessions::iterator i = rs.begin(); i != rs.end(); ++i) { + session_directories.push_back ((*i).second); + } + + for (vector<sys::path>::const_iterator i = session_directories.begin(); + i != session_directories.end(); ++i) + { + std::vector<sys::path> state_file_paths; + + // now get available states for this session + + get_state_files_in_directory (*i, state_file_paths); + + vector<string*>* states; + vector<const gchar*> item; + string fullpath = (*i).to_string(); + + /* remove any trailing / */ + + if (fullpath[fullpath.length()-1] == '/') { + fullpath = fullpath.substr (0, fullpath.length()-1); + } + + /* check whether session still exists */ + if (!Glib::file_test(fullpath.c_str(), Glib::FILE_TEST_EXISTS)) { + /* session doesn't exist */ + cerr << "skipping non-existent session " << fullpath << endl; + continue; + } + + /* now get available states for this session */ + + if ((states = Session::possible_states (fullpath)) == 0) { + /* no state file? */ + continue; + } + + std::vector<string> state_file_names(get_file_names_no_extension (state_file_paths)); + + Gtk::TreeModel::Row row = *(recent_session_model->append()); + + row[recent_session_columns.visible_name] = Glib::path_get_basename (fullpath); + row[recent_session_columns.fullpath] = fullpath; + + if (state_file_names.size() > 1) { + + // add the children + + for (std::vector<std::string>::iterator i2 = state_file_names.begin(); + i2 != state_file_names.end(); ++i2) + { + + Gtk::TreeModel::Row child_row = *(recent_session_model->append (row.children())); + + child_row[recent_session_columns.visible_name] = *i2; + child_row[recent_session_columns.fullpath] = fullpath; + } + } + } + + recent_session_display.set_model (recent_session_model); +} + +void +ArdourStartup::recent_session_row_selected () +{ + if (recent_session_display.get_selection()->count_selected_rows() > 0) { + set_page_complete (session_vbox, true); + } else { + set_page_complete (session_vbox, false); + } +} + +void +ArdourStartup::setup_existing_session_page () +{ + if (!session_hbox.get_children().empty()) { + session_hbox.remove (**session_hbox.get_children().begin()); + } + + if (recent_scroller.get_children().empty()) { + + recent_session_model = TreeStore::create (recent_session_columns); + recent_session_display.set_model (recent_session_model); + recent_session_display.append_column (_("Recent Sessions"), recent_session_columns.visible_name); + recent_session_display.set_headers_visible (false); + recent_session_display.get_selection()->set_mode (SELECTION_BROWSE); + + recent_session_display.get_selection()->signal_changed().connect (mem_fun (*this, &ArdourStartup::recent_session_row_selected)); + + recent_scroller.add (recent_session_display); + recent_scroller.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC); + + recent_session_display.show(); + } + + recent_scroller.show(); + redisplay_recent_sessions (); + + session_hbox.pack_start (recent_scroller, true, true); + set_page_title (session_vbox, _("Select a session")); + set_page_type (session_vbox, ASSISTANT_PAGE_CONFIRM); +} + +void +ArdourStartup::more_new_session_options_button_clicked () +{ + if (more_new_session_options_button.get_active()) { + more_options_vbox.show (); + } else { + more_options_vbox.hide (); + } +} + +void +ArdourStartup::setup_more_options_page () +{ + Label* foomatic = manage (new Label); + foomatic->set_text (_("Here be more options....")); + foomatic->show (); + + more_options_vbox.set_border_width (12); + more_options_hbox.set_border_width (12); + + more_options_hbox.pack_start (*foomatic, true, true); + more_options_vbox.pack_start (more_options_hbox, true, true); + + more_options_hbox.show (); + + /* note that more_options_vbox is NOT visible by + * default. this is entirely by design - this page + * should be skipped unless explicitly requested. + */ + + append_page (more_options_vbox); + set_page_title (more_options_vbox, _("Advanced Session Options")); + set_page_complete (more_options_vbox, true); +} diff --git a/gtk2_ardour/startup.h b/gtk2_ardour/startup.h new file mode 100644 index 0000000000..1657d4fcd0 --- /dev/null +++ b/gtk2_ardour/startup.h @@ -0,0 +1,115 @@ +#ifndef __gtk2_ardour_startup_h__ +#define __gtk2_ardour_startup_h__ + +#include <string> + +#include <gdkmm/pixbuf.h> +#include <gtkmm/assistant.h> +#include <gtkmm/label.h> +#include <gtkmm/drawingarea.h> +#include <gtkmm/box.h> +#include <gtkmm/radiobutton.h> +#include <gtkmm/filechooserbutton.h> +#include <gtkmm/scrolledwindow.h> +#include <gtkmm/treeview.h> +#include <gtkmm/treestore.h> +#include <gtkmm/checkbutton.h> + +class ArdourStartup : public Gtk::Assistant { + public: + ArdourStartup (); + ~ArdourStartup (); + + private: + bool applying; + + void on_apply (); + void on_cancel (); + void on_close (); + void on_prepare (Gtk::Widget*); + + static ArdourStartup *the_startup; + + Glib::RefPtr<Gdk::Pixbuf> icon_pixbuf; + + void setup_new_user_page (); + Glib::RefPtr<Gdk::Pixbuf> splash_pixbuf; + Gtk::DrawingArea splash_area; + bool splash_expose (GdkEventExpose* ev); + + void setup_first_time_config_page (); + + /* first page */ + void setup_first_page (); + + /* initial choice page */ + + void setup_initial_choice_page (); + Gtk::VBox ic_vbox; + Gtk::RadioButton ic_new_session_button; + Gtk::RadioButton ic_existing_session_button; + + /* session page (could be new or existing) */ + + void setup_session_page (); + Gtk::VBox session_vbox; + Gtk::HBox session_hbox; + + /* recent sessions */ + + void setup_existing_session_page (); + + struct RecentSessionsSorter { + bool operator() (std::pair<std::string,std::string> a, std::pair<std::string,std::string> b) const { + return cmp_nocase(a.first, b.first) == -1; + } + }; + + struct RecentSessionModelColumns : public Gtk::TreeModel::ColumnRecord { + RecentSessionModelColumns() { + add (visible_name); + add (fullpath); + } + Gtk::TreeModelColumn<Glib::ustring> visible_name; + Gtk::TreeModelColumn<Glib::ustring> fullpath; + }; + + RecentSessionModelColumns recent_session_columns; + Gtk::TreeView recent_session_display; + Glib::RefPtr<Gtk::TreeStore> recent_session_model; + Gtk::ScrolledWindow recent_scroller; + void redisplay_recent_sessions (); + void recent_session_row_selected (); + + /* new sessions */ + + void setup_new_session_page (); + Gtk::Entry new_name_entry; + Gtk::FileChooserButton new_folder_chooser; + Gtk::FileChooserButton session_template_chooser; + Gtk::VBox session_new_vbox; + Gtk::CheckButton more_new_session_options_button; + + void more_new_session_options_button_clicked(); + void new_name_changed (); + + /* more options for new sessions */ + + Gtk::VBox more_options_vbox; + Gtk::HBox more_options_hbox; + void setup_more_options_page (); + + /* final page */ + + void setup_final_page (); + Gtk::Label final_page; + + /* always there */ + + Glib::RefPtr<Pango::Layout> layout; + + + +}; + +#endif /* __gtk2_ardour_startup_h__ */ diff --git a/gtk2_ardour/wscript b/gtk2_ardour/wscript index 3db75029ca..3f9d0d0373 100644 --- a/gtk2_ardour/wscript +++ b/gtk2_ardour/wscript @@ -196,6 +196,7 @@ def build(bld): simpleline.cc simplerect.cc splash.cc + startup.cc streamview.cc tape_region_view.cc tempo_dialog.cc |