Esempio n. 1
0
void
ags_note_edit_draw_notation(AgsNoteEdit *note_edit, cairo_t *cr)
{
  AgsMachine *machine;
  AgsEditor *editor;
  GtkWidget *widget;
  AgsNote *note;
  GList *list_notation, *list_note;
  guint x_offset;
  guint control_height;
  guint x, y, width, height;
  gint selected_channel;
  gint i;

  editor = (AgsEditor *) gtk_widget_get_ancestor(GTK_WIDGET(note_edit),
						 AGS_TYPE_EDITOR);

  if(editor->selected_machine == NULL ||
     (machine = editor->selected_machine) == NULL ||
     machine->audio->notation == NULL)
    return;

  widget = (GtkWidget *) note_edit->drawing_area;

  cairo_set_source_rgb(cr, 1.0, 1.0, 1.0);

  i = 0;

  while((selected_channel = ags_notebook_next_active_tab(editor->notebook,
							 i)) != -1){
    list_notation = g_list_nth(machine->audio->notation,
			       selected_channel);
    list_note = AGS_NOTATION(list_notation->data)->notes;

    control_height = note_edit->control_height - 2 * note_edit->control_margin_y;

    x_offset = (guint) GTK_RANGE(note_edit->hscrollbar)->adjustment->value;

    /* draw controls smaller than note_edit->nth_x */
    while(list_note != NULL && (note = (AgsNote *) list_note->data)->x[0] < note_edit->control_unit.nth_x){
      if(note->x[1] >= note_edit->control_unit.nth_x){
	if(note->y >= note_edit->nth_y && note->y <= note_edit->stop_y){
	  x = 0;
	  y = (note->y - note_edit->nth_y) * note_edit->control_height + note_edit->y0 + note_edit->control_margin_y;

	  width = (guint) ((double) note->x[1] * note_edit->control_unit.control_width - (double) x_offset);

	  if(width > widget->allocation.width)
	    width = widget->allocation.width;

	  height = control_height;

	  /* draw note */
	  cairo_rectangle(cr, (double) x, (double) y, (double) width, (double) height);
	  cairo_fill(cr);

	  /* check if note is selected */
	  if((AGS_NOTE_IS_SELECTED & (note->flags)) != 0){
	    cairo_set_source_rgba(cr, 1.0, 0.0, 0.0, 0.7);

	    cairo_rectangle(cr, (double) x, (double) y, (double) width, (double) height);
	    cairo_stroke(cr);

	    cairo_set_source_rgb(cr, 1.0, 1.0, 1.0);
	  }
	}else if(note->y == (note_edit->nth_y - 1) && note_edit->y0 != 0){
	  if(note_edit->y0 > note_edit->control_margin_y){
	    x = 0;
	    width = (guint) ((double) note->x[1] * (double) note_edit->control_unit.control_width - x_offset);

	    if(width > widget->allocation.width)
	      width = widget->allocation.width;

	    if(note_edit->y0 > control_height + note_edit->control_margin_y){
	      y = note_edit->y0 - (control_height + note_edit->control_margin_y);
	      height = control_height;
	    }else{
	      y = 0;
	      height = note_edit->y0 - note_edit->control_margin_y;
	    }

	    /* draw note */
	    cairo_rectangle(cr, (double) x, (double) y, (double) width, (double) height);
	    cairo_fill(cr);

	    /* check if note is selected */
	    if((AGS_NOTE_IS_SELECTED & (note->flags)) != 0){
	      cairo_set_source_rgba(cr, 1.0, 0.0, 0.0, 0.7);
	    
	      cairo_rectangle(cr, (double) x, (double) y, (double) width, (double) height);
	      cairo_stroke(cr);
	    
	      cairo_set_source_rgb(cr, 1.0, 1.0, 1.0);
	    }
	  }
	}else if(note->y == (note_edit->stop_y + 1) && note_edit->y1 != 0){
	  if(note_edit->y1 > note_edit->control_margin_y){
	    x = 0;
	    width = note->x[1] * note_edit->control_unit.control_width - x_offset;

	    if(width > widget->allocation.width)
	      width = widget->allocation.width;

	    y = (note->y - note_edit->nth_y) * note_edit->control_height + note_edit->control_margin_y;

	    if(note_edit->y1 > control_height + note_edit->control_margin_y){
	      height = control_height;
	    }else{
	      height = note_edit->y1 - note_edit->control_margin_y;
	    }

	    /* draw note */
	    cairo_rectangle(cr, (double) x, (double) y, (double) width, (double) height);
	    cairo_fill(cr);
	  
	    /* check if note is selected */
	    if((AGS_NOTE_IS_SELECTED & (note->flags)) != 0){
	      cairo_set_source_rgba(cr, 1.0, 0.0, 0.0, 0.7);
	    
	      cairo_rectangle(cr, (double) x, (double) y, (double) width, (double) height);
	      cairo_stroke(cr);
	    
	      cairo_set_source_rgb(cr, 1.0, 1.0, 1.0);
	    }
	  }
	}
      }

      list_note = list_note->next;
    }

    /* draw controls equal or greater than note_edit->nth_x */
    while(list_note != NULL && (note = (AgsNote *) list_note->data)->x[0] <= note_edit->control_unit.stop_x){
      if(note->y >= note_edit->nth_y && note->y <= note_edit->stop_y){
	x = (guint) note->x[0] * note_edit->control_unit.control_width;
	y = (note->y - note_edit->nth_y) * note_edit->control_height +
	  note_edit->y0 +
	  note_edit->control_margin_y;

	width = note->x[1] * note_edit->control_unit.control_width - x;
	x -= x_offset;

	if(x + width > widget->allocation.width)
	  width = widget->allocation.width - x;

	height = control_height;

	/* draw note*/
	cairo_rectangle(cr, (double) x, (double) y, (double) width, (double) height);
	cairo_fill(cr);

	/* check if note is selected */
	if((AGS_NOTE_IS_SELECTED & (note->flags)) != 0){
	  cairo_set_source_rgba(cr, 1.0, 0.0, 0.0, 0.7);
	
	  cairo_rectangle(cr, (double) x, (double) y, (double) width, (double) height);
	  cairo_stroke(cr);
	
	  cairo_set_source_rgb(cr, 1.0, 1.0, 1.0);
	}
      }else if(note->y == (note_edit->nth_y - 1) && note_edit->y0 != 0){
	if(note_edit->y0 > note_edit->control_margin_y){
	  x = note->x[0] * note_edit->control_unit.control_width - x_offset;
	  width = note->x[1] * note_edit->control_unit.control_width - x_offset - x;
      
	  if(x + width > widget->allocation.width)
	    width = widget->allocation.width - x;

	  if(note_edit->y0 > control_height + note_edit->control_margin_y){
	    y = note_edit->y0 - (control_height + note_edit->control_margin_y);
	    height = control_height;
	  }else{
	    y = 0;
	    height = note_edit->y0 - note_edit->control_margin_y;
	  }

	  /* draw note */
	  cairo_rectangle(cr, (double) x, (double) y, (double) width, (double) height);
	  cairo_fill(cr);

	  /* check if note is selected */
	  if((AGS_NOTE_IS_SELECTED & (note->flags)) != 0){
	    cairo_set_source_rgba(cr, 1.0, 0.0, 0.0, 0.7);

	    cairo_rectangle(cr, (double) x, (double) y, (double) width, (double) height);
	    cairo_stroke(cr);

	    cairo_set_source_rgb(cr, 1.0, 1.0, 1.0);
	  }
	}
      }else if(note->y == (note_edit->stop_y + 1) && note_edit->y1 != 0){
	if(note_edit->y1 > note_edit->control_margin_y){
	  x = note->x[0] * note_edit->control_unit.control_width - x_offset;
	  width = note->x[1] * note_edit->control_unit.control_width - x_offset - x;
      
	  if(x + width > widget->allocation.width)
	    width = widget->allocation.width - x;

	  y = (note->y - note_edit->nth_y) * note_edit->control_height + note_edit->control_margin_y;

	  if(note_edit->y1 > control_height + note_edit->control_margin_y){
	    height = control_height;
	  }else{
	    height = note_edit->y1 - note_edit->control_margin_y;
	  }

	  /* draw note */
	  cairo_rectangle(cr, (double) x, (double) y, (double) width, (double) height);
	  cairo_fill(cr);

	  /* check if note is selected */
	  if((AGS_NOTE_IS_SELECTED & (note->flags)) != 0){
	    cairo_set_source_rgba(cr, 1.0, 0.0, 0.0, 0.7);

	    cairo_rectangle(cr, (double) x, (double) y, (double) width, (double) height);
	    cairo_stroke(cr);

	    cairo_set_source_rgb(cr, 1.0, 1.0, 1.0);
	  }
	}
      }

      list_note = list_note->next;
    }

    i++;
  }
}
void
ags_select_acceleration_dialog_apply(AgsApplicable *applicable)
{
  AgsSelectAccelerationDialog *select_acceleration_dialog;
  AgsWindow *window;
  AgsAutomationEditor *automation_editor;
  AgsMachine *machine;
  AgsNotebook *notebook;

  AgsAudio *audio;

  xmlDoc *clipboard;
  xmlNode *audio_node, *automation_node;

  GList *start_list_automation, *list_automation;
  GList *port, *port_start;
  GList *list;
  
  gchar **specifier;
  xmlChar *buffer;
  gchar *str;
  
  GType channel_type;

  gdouble gui_y;
  
  gdouble c_y0, c_y1;
  gdouble val;
  gdouble upper, lower, range, step;
  gdouble c_upper, c_lower, c_range;

  int size;
  guint x0, y0;
  guint x1, y1;
  guint i;
  gint line;
  
  gboolean copy_selection;
    
  select_acceleration_dialog = AGS_SELECT_ACCELERATION_DIALOG(applicable);

  window = (AgsWindow *) select_acceleration_dialog->main_window;
  automation_editor = window->automation_window->automation_editor;

  machine = automation_editor->selected_machine;

  if(machine == NULL ||
     automation_editor->focused_automation_edit == NULL){
    return;
  }

  notebook = NULL;

  if(automation_editor->focused_automation_edit->channel_type == G_TYPE_NONE){
    notebook = NULL;
    channel_type = G_TYPE_NONE;
  }else if(automation_editor->focused_automation_edit->channel_type == AGS_TYPE_OUTPUT){
    notebook = automation_editor->output_notebook;
    channel_type = AGS_TYPE_OUTPUT;
  }else if(automation_editor->focused_automation_edit->channel_type == AGS_TYPE_INPUT){
    notebook = automation_editor->input_notebook;
    channel_type = AGS_TYPE_INPUT;
  }
  
  audio = machine->audio;

  g_object_get(audio,
	       "automation", &start_list_automation,
	       NULL);

  /* get some values */
  copy_selection = gtk_toggle_button_get_active((GtkToggleButton *) select_acceleration_dialog->copy_selection);

  x0 = (AGS_SELECT_ACCELERATION_DEFAULT_WIDTH / 16) * gtk_spin_button_get_value_as_int(select_acceleration_dialog->select_x0);

  x1 = (AGS_SELECT_ACCELERATION_DEFAULT_WIDTH / 16) * gtk_spin_button_get_value_as_int(select_acceleration_dialog->select_x1);
  
  /* select acceleration */
  port =
    port_start = gtk_container_get_children((GtkContainer *) select_acceleration_dialog->port);
  
  specifier = NULL;

  if(copy_selection){
    /* create document */
    clipboard = xmlNewDoc(BAD_CAST XML_DEFAULT_VERSION);
  
    /* create root node */
    audio_node = xmlNewNode(NULL, BAD_CAST "audio");
    xmlDocSetRootElement(clipboard, audio_node);
  }

  for(i = 0; port != NULL;){
    list = gtk_container_get_children((GtkContainer *) port->data);
    str = gtk_combo_box_text_get_active_text(list->data);

    g_list_free(list);
    
    if(specifier != NULL &&
       g_strv_contains(specifier,
		       str)){
      port = port->next;

      continue;
    }

    if(specifier == NULL){
      specifier = (gchar **) malloc(2 * sizeof(gchar *));
    }else{
      specifier = (gchar **) realloc(specifier,
				     (i + 2) * sizeof(gchar *));
    }
    
    specifier[i] = str;
    specifier[i + 1] = NULL;
    
    line = 0;
    
    while((line = ags_notebook_next_active_tab(notebook,
					       line)) != -1){
      list_automation = start_list_automation;

      while((list_automation = ags_automation_find_specifier_with_type_and_line(list_automation,
										specifier[i],
										channel_type,
										line)) != NULL){
	AgsAutomation *current_automation;
	AgsPort *current_port;

	AgsConversion *conversion;
	
	AgsTimestamp *timestamp;
	
	current_automation = list_automation->data;

	g_object_get(current_automation,
		     "timestamp", &timestamp,
		     NULL);

	g_object_unref(timestamp);
	
	if(ags_timestamp_get_ags_offset(timestamp) + AGS_AUTOMATION_DEFAULT_OFFSET < x0){
	  list_automation = list_automation->next;
	  
	  continue;
	}

	if(ags_timestamp_get_ags_offset(timestamp) > x1){
	  break;
	}

	g_object_get(current_automation,
		     "port", &current_port,
		     "upper", &upper,
		     "lower", &lower,
		     NULL);

	g_object_get(current_port,
		     "conversion", &conversion,
		     NULL);
	
	range = upper - lower;

	if(conversion != NULL){
	  c_upper = ags_conversion_convert(conversion,
					   upper,
					   FALSE);
	  c_lower = ags_conversion_convert(conversion,
					   lower,
					   FALSE);
	  c_range = c_upper - c_lower;

	  g_object_unref(conversion);
	}else{
	  c_upper = upper;
	  c_lower = lower;
	  
	  c_range = range;
	}

	g_object_unref(current_port);
	
	if(range == 0.0){
	  list_automation = list_automation->next;
	  g_warning("ags_select_acceleration_dialog.c - range = 0.0");
	  
	  continue;
	}
	
	/* check steps */
	g_object_get(current_automation,
		     "steps", &gui_y,
		     NULL);

	val = c_lower + (gui_y * (c_range / gui_y));
	c_y0 = val;

	/* conversion */
	if(conversion != NULL){
	  c_y0 = ags_conversion_convert(conversion,
					c_y0,
					TRUE);
	}

	/* check steps */
	gui_y = 0;

	val = c_lower + (gui_y * (c_range / gui_y));
	c_y1 = val;

	/* conversion */
	if(conversion != NULL){
	  c_y1 = ags_conversion_convert(conversion,
					c_y1,
					TRUE);
	}
	    
	/* select */
	ags_automation_add_region_to_selection(current_automation,
					       x0 * AGS_SELECT_ACCELERATION_DEFAULT_WIDTH, c_y0,
					       x1 * AGS_SELECT_ACCELERATION_DEFAULT_WIDTH, c_y1,
					       TRUE);


	if(copy_selection){
	  automation_node = ags_automation_copy_selection(list_automation->data);
	  xmlAddChild(audio_node, automation_node);      
	}

	list_automation = list_automation->next;
      }

      line++;
    }

    port = port->next;
    i++;
  }

  g_strfreev(specifier);
  
  g_list_free_full(start_list_automation,
		   g_object_unref);
  g_list_free(port_start);

  /* write to clipboard */
  if(copy_selection){
    xmlDocDumpFormatMemoryEnc(clipboard, &buffer, &size, "UTF-8", TRUE);
    gtk_clipboard_set_text(gtk_clipboard_get(GDK_SELECTION_CLIPBOARD),
			   buffer, size);
    gtk_clipboard_store(gtk_clipboard_get(GDK_SELECTION_CLIPBOARD));
    
    xmlFreeDoc(clipboard);
  }  
}