diff options
author | Thomas White <taw@physics.org> | 2020-08-25 15:53:34 +0200 |
---|---|---|
committer | Thomas White <taw@physics.org> | 2020-08-25 15:56:25 +0200 |
commit | c783ee20a9c3297f097429ac02595628981e1555 (patch) | |
tree | 4edb0adce674e16f76fc7dd856c4738fe70d1072 | |
parent | 0f96cae079fe8b278819c572dc56b4d40dc47c06 (diff) |
Create a progress bar for each running job
-rw-r--r-- | src/crystfel_gui.c | 60 | ||||
-rw-r--r-- | src/crystfel_gui.h | 39 | ||||
-rw-r--r-- | src/gui_backend_local.c | 16 | ||||
-rw-r--r-- | src/gui_backend_slurm.c | 8 | ||||
-rw-r--r-- | src/gui_index.c | 6 | ||||
-rw-r--r-- | src/gui_project.c | 2 | ||||
-rw-r--r-- | src/gui_project.h | 15 |
7 files changed, 93 insertions, 53 deletions
diff --git a/src/crystfel_gui.c b/src/crystfel_gui.c index 48c0777a..fd79e9da 100644 --- a/src/crystfel_gui.c +++ b/src/crystfel_gui.c @@ -1002,64 +1002,52 @@ int main(int argc, char *argv[]) static void infobar_response_sig(GtkInfoBar *infobar, gint resp, gpointer data) { - //struct crystfelproject *proj = data; + struct gui_task *task = data; if ( resp == GTK_RESPONSE_CANCEL ) { + task->backend->cancel_task(task->job_priv); /* FIXME: Cancel processing */ } else { ERROR("Unrecognised infobar response!\n"); - } } -void remove_infobar(struct crystfelproject *proj) +void add_running_task(struct crystfelproject *proj, + const char *task_desc, + struct crystfel_backend *backend, + void *job_priv) { - gtk_widget_destroy(proj->info_bar); - proj->info_bar = NULL; -} - - -GtkWidget *create_infobar(struct crystfelproject *proj, const char *task, - const char *extra_button, - void (*cbfunc)(struct crystfelproject *proj)) -{ - GtkWidget *info_bar; + struct gui_task *task; GtkWidget *bar_area; - if ( proj->info_bar != NULL ) { - STATUS("Can't create info bar - task already running\n"); - return NULL; - } + task = &proj->tasks[proj->n_running_tasks++]; + task->job_priv = job_priv; + task->backend = backend; /* Progress info bar */ - info_bar = gtk_info_bar_new_with_buttons(GTK_STOCK_CANCEL, - GTK_RESPONSE_CANCEL, - extra_button, - GTK_RESPONSE_OK, - NULL); - gtk_box_pack_end(GTK_BOX(proj->main_vbox), GTK_WIDGET(info_bar), + task->info_bar = gtk_info_bar_new_with_buttons(GTK_STOCK_CANCEL, + GTK_RESPONSE_CANCEL, + NULL); + gtk_box_pack_end(GTK_BOX(proj->main_vbox), GTK_WIDGET(task->info_bar), FALSE, FALSE, 0.0); - proj->info_bar = info_bar; - bar_area = gtk_info_bar_get_content_area(GTK_INFO_BAR(info_bar)); + bar_area = gtk_info_bar_get_content_area(GTK_INFO_BAR(task->info_bar)); /* Create progress bar */ - proj->progressbar = gtk_progress_bar_new(); + task->progress_bar = gtk_progress_bar_new(); gtk_box_pack_start(GTK_BOX(bar_area), - GTK_WIDGET(proj->progressbar), + GTK_WIDGET(task->progress_bar), TRUE, TRUE, 0.0); - gtk_progress_bar_set_text(GTK_PROGRESS_BAR(proj->progressbar), - task); - gtk_progress_bar_set_show_text(GTK_PROGRESS_BAR(proj->progressbar), + gtk_progress_bar_set_text(GTK_PROGRESS_BAR(task->progress_bar), + task_desc); + gtk_progress_bar_set_show_text(GTK_PROGRESS_BAR(task->progress_bar), TRUE); - g_signal_connect(G_OBJECT(info_bar), "response", - G_CALLBACK(infobar_response_sig), proj); - - gtk_widget_show_all(info_bar); - gtk_info_bar_set_revealed(GTK_INFO_BAR(info_bar), TRUE); + g_signal_connect(G_OBJECT(task->info_bar), "response", + G_CALLBACK(infobar_response_sig), task); - return info_bar; + gtk_widget_show_all(task->info_bar); + gtk_info_bar_set_revealed(GTK_INFO_BAR(task->info_bar), TRUE); } diff --git a/src/crystfel_gui.h b/src/crystfel_gui.h new file mode 100644 index 00000000..d0a4efcb --- /dev/null +++ b/src/crystfel_gui.h @@ -0,0 +1,39 @@ +/* + * crystfel_gui.h + * + * CrystFEL's main graphical user interface + * + * Copyright © 2020 Deutsches Elektronen-Synchrotron DESY, + * a research centre of the Helmholtz Association. + * + * Authors: + * 2020 Thomas White <taw@physics.org> + * + * This file is part of CrystFEL. + * + * CrystFEL 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 3 of the License, or + * (at your option) any later version. + * + * CrystFEL 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 CrystFEL. If not, see <http://www.gnu.org/licenses/>. + * + */ + +#ifndef CRYSTFEL_GUI_H +#define CRYSTFEL_GUI_H + +#include "gui_project.h" + +extern void add_running_task(struct crystfelproject *proj, + const char *task_desc, + struct crystfel_backend *backend, + void *job_priv); + +#endif diff --git a/src/gui_backend_local.c b/src/gui_backend_local.c index dfa208b6..b6d475cf 100644 --- a/src/gui_backend_local.c +++ b/src/gui_backend_local.c @@ -42,7 +42,7 @@ struct local_indexing_opts }; -struct local_indexing_job +struct local_job { double frac_complete; int n_frames; @@ -60,7 +60,7 @@ struct local_indexing_job static void watch_indexamajig(GPid pid, gint status, gpointer vp) { - struct local_indexing_job *job = vp; + struct local_job *job = vp; STATUS("Indexamajig exited with status %i\n", status); job->indexamajig_running = 0; g_spawn_close_pid(job->indexamajig_pid); @@ -72,7 +72,7 @@ static gboolean index_readable(GIOChannel *source, GIOCondition cond, { GIOStatus r; GError *err = NULL; - struct local_indexing_job *job = vp; + struct local_job *job = vp; gchar *line; r = g_io_channel_read_line(source, &line, NULL, NULL, &err); @@ -168,9 +168,9 @@ static void *run_indexing(char **filenames, int r; int ch_stderr; GError *error; - struct local_indexing_job *job; + struct local_job *job; - job = malloc(sizeof(struct local_indexing_job)); + job = malloc(sizeof(struct local_job)); if ( job == NULL ) return NULL; if ( write_file_list(filenames, events, n_frames) ) { @@ -263,9 +263,9 @@ static void *run_indexing(char **filenames, } -static void cancel_indexing(void *job_priv) +static void cancel_task(void *job_priv) { - struct local_indexing_job *job = job_priv; + struct local_job *job = job_priv; if ( !job->indexamajig_running ) return; @@ -353,7 +353,7 @@ int make_local_backend(struct crystfel_backend *be) be->make_indexing_parameters_widget = make_indexing_parameters_widget; be->run_indexing = run_indexing; - be->cancel_indexing = cancel_indexing; + be->cancel_task = cancel_task; be->indexing_opts_priv = make_default_local_opts(); if ( be->indexing_opts_priv == NULL ) return 1; be->write_indexing_opts = write_indexing_opts; diff --git a/src/gui_backend_slurm.c b/src/gui_backend_slurm.c index 281472a3..434c9302 100644 --- a/src/gui_backend_slurm.c +++ b/src/gui_backend_slurm.c @@ -44,16 +44,16 @@ struct slurm_indexing_opts }; -struct slurm_indexing_job +struct slurm_job { double frac_complete; /* FIXME: List of SLURM job numbers to track */ }; -static void cancel_indexing(void *job_priv) +static void cancel_task(void *job_priv) { - //struct slurm_indexing_job *job = job_priv; + //struct slurm_job *job = job_priv; } @@ -220,9 +220,9 @@ int make_slurm_backend(struct crystfel_backend *be) be->make_indexing_parameters_widget = make_indexing_parameters_widget; be->run_indexing = run_indexing; - be->cancel_indexing = cancel_indexing; be->write_indexing_opts = write_indexing_opts; be->read_indexing_opt = read_indexing_opt; + be->cancel_task = cancel_task; be->indexing_opts_priv = make_default_slurm_opts(); if ( be->indexing_opts_priv == NULL ) return 1; diff --git a/src/gui_index.c b/src/gui_index.c index 278bbf9c..7d672ccd 100644 --- a/src/gui_index.c +++ b/src/gui_index.c @@ -49,6 +49,7 @@ #include "crystfelimageview.h" #include "crystfelindexingopts.h" #include "gui_project.h" +#include "crystfel_gui.h" void cell_explorer_sig(struct crystfelproject *proj) { @@ -110,7 +111,10 @@ static void run_indexing_all(struct crystfelproject *proj) &proj->indexing_params, be->indexing_opts_priv); - STATUS("Started job %p\n", job_priv); + if ( job_priv != NULL ) { + add_running_task(proj, "Indexing all frames", + be, job_priv); + } } diff --git a/src/gui_project.c b/src/gui_project.c index 7d124a5c..39f45f5d 100644 --- a/src/gui_project.c +++ b/src/gui_project.c @@ -538,7 +538,6 @@ void default_project(struct crystfelproject *proj) proj->filenames = NULL; proj->events = NULL; proj->peak_params = NULL; - proj->info_bar = NULL; proj->data_top_folder = NULL; proj->data_search_pattern = 0; proj->stream_filename = NULL; @@ -546,6 +545,7 @@ void default_project(struct crystfelproject *proj) proj->dtempl = NULL; proj->cur_image = NULL; proj->indexing_opts = NULL; + proj->n_running_tasks = 0; /* FIXME: Crappy error handling */ proj->n_backends = 2; diff --git a/src/gui_project.h b/src/gui_project.h index e3066b5f..d2a78079 100644 --- a/src/gui_project.h +++ b/src/gui_project.h @@ -34,6 +34,7 @@ #include <peaks.h> #include <stream.h> +#define MAX_RUNNING_TASKS (16) enum match_type_id { @@ -103,7 +104,7 @@ struct crystfel_backend { void *opts_priv); /* Called to ask the backend to cancel the job */ - void (*cancel_indexing)(void *job_priv); + void (*cancel_task)(void *job_priv); /* Called to ask the backend to write its indexing options */ void (*write_indexing_opts)(void *opts_priv, FILE *fh); @@ -118,6 +119,14 @@ struct crystfel_backend { }; +struct gui_task +{ + GtkWidget *info_bar; + GtkWidget *progress_bar; + struct crystfel_backend *backend; + void *job_priv; +}; + struct crystfelproject { GtkWidget *window; @@ -168,8 +177,8 @@ struct crystfelproject { struct crystfel_backend *backends; int n_backends; - GtkWidget *info_bar; - GtkWidget *progressbar; + struct gui_task tasks[MAX_RUNNING_TASKS]; + int n_running_tasks; }; extern enum match_type_id decode_matchtype(const char *type_id); |