diff -urN ../../denemo-cvs/denemo/include/denemo/denemo_types.h ./include/denemo/denemo_types.h --- ../../denemo-cvs/denemo/include/denemo/denemo_types.h 2007-10-04 19:44:40.000000000 +0100 +++ ./include/denemo/denemo_types.h 2007-10-04 19:58:49.000000000 +0100 @@ -89,11 +89,15 @@ * Enumeration for Denemo's input mode */ typedef enum input_mode { - INPUTNORMAL, - INPUTREST, - INPUTBLANK, - REPLACE, - TRAVERSE +#define MODE_MASK (~(RSM_OFF|RSM_OVERLAY|RSM_RHYTHM)) + RSM_OFF = 0, /* classic mode */ + RSM_OVERLAY = 1<<0, /* edit mode */ + RSM_RHYTHM = 1<<1, /* insert mode */ +#define ENTRY_TYPE_MASK (~(INPUTNORMAL|INPUTREST|INPUTBLANK)) + INPUTNORMAL = 1<<2, /* entry type notes */ + INPUTREST = 1<<3, /* entry type rests */ + INPUTBLANK = 1<<4,/* entry type non-printing rests */ + TRAVERSE = 1<<5 /* read-only */ }input_mode; /** @@ -216,8 +220,8 @@ /* a pair of staffs, used to relate two staffs together */ typedef struct staff_info { - DenemoStaff *main_staff; /**< eg the bass line or the vocal part */ - DenemoStaff *related_staff; /**< eg the figures for the bass or the lyrics*/ + DenemoStaff *main_staff; /* eg the bass line or the vocal part */ + DenemoStaff *related_staff; /* eg the figures for the bass or the lyrics*/ } staff_info; @@ -269,8 +273,8 @@ gboolean lilyentrystyle; gboolean createclones; gboolean articulation_palette; /**< This switch makes the articulation pallete visable */ - gboolean notation_palette; /**< This switch makes the notation pallete visable */ - gboolean rhythm_palette; /**< This option makes the rhythm pallete visable */ + gboolean notation_palette; /**< This switch makes the notation toolbar visable */ + gboolean rhythm_palette; /**< This option makes the rhythm toolbar visable */ gboolean saveparts; /**< Automatically save parts*/ gboolean autosave; /**< Auto save data */ gint autosave_timeout; @@ -312,13 +316,6 @@ }LilypondHeaderInfo; -typedef enum -{ - RSM_OFF = 0, - RSM_OVERLAY = 1<<0, - RSM_RHYTHM = 1<<1 - -} RhythmicSubmode; typedef enum { @@ -464,8 +461,7 @@ * operation */ gint curmeasure_stem_directive; - /* support for INPUTNORMAL sub mode RHYTMIC */ - RhythmicSubmode rhythmicsubmode; + /* support for rhythm patterns */ GList *rhythms;/**< list of RhythmPattern s */ GList *currhythm; /**< currently in use element of rhythms */ GList *rstep; /**< step within RhythmPattern->rsteps, the current element of the current rhythm pattern */ diff -urN ../../denemo-cvs/denemo/src/commandfuncs.c ./src/commandfuncs.c --- ../../denemo-cvs/denemo/src/commandfuncs.c 2007-10-04 19:44:40.000000000 +0100 +++ ./src/commandfuncs.c 2007-10-04 20:01:27.000000000 +0100 @@ -43,7 +43,7 @@ * is easy to alternate rhythms. */ void nextrhythm(DenemoGUI *gui) { - if(!gui->si->rhythmicsubmode) + if(!(gui->mode&(RSM_RHYTHM|RSM_OVERLAY))) return; if(!gui->si->rhythms) return; @@ -456,7 +456,8 @@ gui->si->staffletter_y = note_value; gui->si->cursor_y = jumpcursor (gui->si->cursor_y, oldstaffletter_y, gui->si->staffletter_y); - if((gui->si->rhythmicsubmode & RSM_OVERLAY) && gui->si->currentobject) { + /* in RSM_OVERLAY edit the current note name */ + if((gui->mode & RSM_OVERLAY) && gui->si->currentobject) { DenemoObject *theobj = (DenemoObject *)(gui->si->currentobject->data); if(theobj->type == CHORD && ((chord*)theobj->object)->notes) { DenemoStaff *curstaff = ((DenemoStaff*)gui->si->currentstaff->data); @@ -468,9 +469,9 @@ gui->si->curmeasurekey, gui->si->curmeasureaccs); } } else - /* in rhythmicsubmode we insert a note using the next step of the rhythm pattern */ + /* in INSERT or EDIT mode we insert a note using the next step of the rhythm pattern */ #define g (gui->si->rstep) - if(gui->si->rhythmicsubmode && g) { + if((gui->mode&(RSM_RHYTHM|RSM_OVERLAY)) && g) { GList *start = g; GList *h; do { @@ -495,18 +496,23 @@ #undef g } + void insert_rhythm_pattern(DenemoGUI *gui) { #define g (gui->si->rstep) - if(gui->si->rhythmicsubmode && g) { + if((gui->mode&(RSM_RHYTHM|RSM_OVERLAY)) && g) { GList *start = g; GList *h; do { if(g) { for(h = ((RhythmElement*)g->data)->functions;h;h=h->next) { nextmeasure (gui->si, TRUE); - gui->si->cursoroffend = FALSE; + gui->si->cursoroffend = FALSE; + if(!code_is_a_duration(modifier_code(h->data))) + cursorleft(gui); ((GtkFunction)h->data)(gui); + if(!code_is_a_duration(modifier_code(h->data))) + cursorright(gui); displayhelper(gui); } h = ((RhythmElement*)g->data)->functions; @@ -583,6 +589,12 @@ int prognum; DenemoStaff *curstaffstruct; + if((mode & RSM_OVERLAY) && !si->cursor_appending) { + changeduration(si, duration); + return; + } + + /* First, check to see if the insertion'll cause the cursor to * jump to the next measure. (Denemo will implicitly create it * if it doesn't exist already.) */ @@ -594,13 +606,13 @@ /* Now actually create the chord */ mudela_obj_new = newchord (duration, 0, 0); - if (mode == INPUTBLANK && (rest != TRUE)) + if ( (mode & INPUTBLANK) && (rest != TRUE)) { addtone (mudela_obj_new, si->cursor_y, si->cursoraccs[si->staffletter_y], si->cursorclef); mudela_obj_new->isinvisible = TRUE; } - else if (mode == INPUTNORMAL && (rest != TRUE)) + else if ((mode & INPUTNORMAL) && (rest != TRUE)) addtone (mudela_obj_new, si->cursor_y, si->cursoraccs[si->staffletter_y], si->cursorclef); @@ -714,11 +726,11 @@ } /** - * Change a tone either in a chord or individual note - * alternatively remove it from a chord - * + * If REMOVE delete the note closest to si->cursor_y in a ~si->currentobject + * else add a tone at si->cursor_y to the ~si->currentobject + * FIXME ~si->currentobject in this comment means the thing gotten by the macro declaremudelaobj. This macro is a horrible hack induced by trying to be clever with tuplets - enforcing pairing of begin/end. tonechange * @param si pointer to the scoreinfo structure - * @param remove whether to remove tone or not + * @param remove whether to remove note or not */ void tonechange (DenemoScore * si, gboolean remove) diff -urN ../../denemo-cvs/denemo/src/denemoui.xml ./src/denemoui.xml --- ../../denemo-cvs/denemo/src/denemoui.xml 2007-10-04 19:44:40.000000000 +0100 +++ ./src/denemoui.xml 2007-10-04 20:01:59.000000000 +0100 @@ -49,11 +49,13 @@ - + + + - + @@ -160,7 +162,7 @@ - + diff -urN ../../denemo-cvs/denemo/src/drawcursor.c ./src/drawcursor.c --- ../../denemo-cvs/denemo/src/drawcursor.c 2007-01-24 19:44:26.000000000 +0000 +++ ./src/drawcursor.c 2007-10-04 20:09:17.000000000 +0100 @@ -42,9 +42,9 @@ purplegc = gcs_purplegc (); } - paintgc = (mode == INPUTREST) ? graygc : - (mode == INPUTBLANK) ? bluegc : - (mode == REPLACE) ? purplegc : si->cursoroffend ? redgc : greengc; + paintgc = (mode & INPUTREST) ? graygc : + (mode & INPUTBLANK) ? bluegc : + (mode & RSM_OVERLAY) ? purplegc : si->cursoroffend ? redgc : greengc; gdk_draw_rectangle (pixmap, paintgc, TRUE, xx, height + y - CURSOR_MINUS, CURSOR_WIDTH, CURSOR_HEIGHT); diff -urN ../../denemo-cvs/denemo/src/keyresponses.c ./src/keyresponses.c --- ../../denemo-cvs/denemo/src/keyresponses.c 2007-10-04 19:44:40.000000000 +0100 +++ ./src/keyresponses.c 2007-10-04 20:10:41.000000000 +0100 @@ -37,9 +37,9 @@ event->state))) { - /* in rhythmicsubmode when a duration is entered set up a singleton rhythm pattern that + /* in rhythmic mode when a duration is entered set up a singleton rhythm pattern that is just this one duration */ -#define RSM (gui->si->rhythmicsubmode) +#define RSM (gui->mode) if((RSM & RSM_RHYTHM ) && !(RSM & RSM_OVERLAY)) if( ki->func.nocallback==(gpointer)insert_chord_0key || ki->func.nocallback==(gpointer)insert_chord_1key || @@ -194,10 +194,10 @@ void octave_up_key (DenemoGUI * gui) { - if(gui->si->rhythmicsubmode) + if(gui->mode&(RSM_RHYTHM|RSM_OVERLAY)) tonechange(gui->si, TRUE); gui->si->cursor_y += 7; - if(gui->si->rhythmicsubmode) + if(gui->mode&(RSM_RHYTHM|RSM_OVERLAY)) tonechange(gui->si, FALSE); } @@ -207,10 +207,10 @@ void octave_down_key (DenemoGUI * gui) { - if(gui->si->rhythmicsubmode) + if(gui->mode&(RSM_RHYTHM|RSM_OVERLAY)) tonechange(gui->si, TRUE); gui->si->cursor_y -= 7; - if(gui->si->rhythmicsubmode) + if(gui->mode&(RSM_RHYTHM|RSM_OVERLAY)) tonechange(gui->si, FALSE); } @@ -230,49 +230,11 @@ } -/** - * Change to insert mode - * - */ -void -insert_mode (GtkAction * action, DenemoGUI * gui) -{ - if (gui->mode != INPUTNORMAL) - gui->mode = INPUTNORMAL; - gtk_statusbar_push (GTK_STATUSBAR (gui->statusbar), gui->status_context_id, - "Insert"); - displayhelper (gui); -} -/** - * Change to replace mode - * - */ -void -replace_mode (GtkAction * action, DenemoGUI * gui) -{ - if (gui->mode != REPLACE) - gui->mode = REPLACE; - gtk_statusbar_push (GTK_STATUSBAR (gui->statusbar), gui->status_context_id, - "Replace"); - displayhelper (gui); -} -/** - * Change to blank mode i.e. insert invisible notes - */ -void -blank_mode (GtkAction * action, DenemoGUI * gui) -{ - if (gui->mode != INPUTBLANK) - gui->mode = INPUTBLANK; - gtk_statusbar_push (GTK_STATUSBAR (gui->statusbar), gui->status_context_id, - "Blank"); - displayhelper (gui); -} /** - * Toggle into rest mode + * Toggle into rest mode FIXME bitfields!!!! * */ void @@ -286,7 +248,7 @@ } /** - * Toggle blank mode + * Toggle blank mode FIXME bitfields!!! * */ void @@ -329,9 +291,7 @@ void insert_chord_0key (DenemoGUI * gui) { - if (gui->mode == REPLACE) - change_pitch (gui); - else if (gui->mode == INPUTNORMAL || gui->mode == INPUTREST) + dnm_insertchord (gui->si, 0, gui->mode, FALSE); } @@ -339,54 +299,42 @@ void insert_chord_1key (DenemoGUI * gui) { - if (gui->mode == REPLACE) - change_pitch (gui); - else if (gui->mode == INPUTNORMAL || gui->mode == INPUTREST) + dnm_insertchord (gui->si, 1, gui->mode, FALSE); } void insert_chord_2key (DenemoGUI * gui) { - if (gui->mode == REPLACE) - change_pitch (gui); - else if (gui->mode == INPUTNORMAL || gui->mode == INPUTREST) + dnm_insertchord (gui->si, 2, gui->mode, FALSE); } void insert_chord_3key (DenemoGUI * gui) { - if (gui->mode == REPLACE) - change_pitch (gui); - else if (gui->mode == INPUTNORMAL || gui->mode == INPUTREST) + dnm_insertchord (gui->si, 3, gui->mode, FALSE); } void insert_chord_4key (DenemoGUI * gui) { - if (gui->mode == REPLACE) - change_pitch (gui); - else if (gui->mode == INPUTNORMAL || gui->mode == INPUTREST) + dnm_insertchord (gui->si, 4, gui->mode, FALSE); } void insert_chord_5key (DenemoGUI * gui) { - if (gui->mode == REPLACE) - change_pitch (gui); - else if (gui->mode == INPUTNORMAL || gui->mode == INPUTREST) + dnm_insertchord (gui->si, 5, gui->mode, FALSE); } void insert_chord_6key (DenemoGUI * gui) { - if (gui->mode == REPLACE) - change_pitch (gui); - else if (gui->mode == INPUTNORMAL || gui->mode == INPUTREST) + dnm_insertchord (gui->si, 6, gui->mode, FALSE); } @@ -581,7 +529,7 @@ } /* if you are following a rhythmic pattern then backup the pattern */ #define g (gui->si->rstep) - if(gui->si->rhythmicsubmode && g) + if((gui->mode&(RSM_RHYTHM|RSM_OVERLAY)) && g) { #define CURRP ((RhythmPattern *)gui->si->currhythm->data) g = g->prev; /* list is circular - should we stop at beginning? */ @@ -885,7 +833,7 @@ void change_pitch (DenemoGUI * gui) { - if (gui->mode == REPLACE) + if (gui->mode & RSM_OVERLAY) { //DenemoObject *theobj = // si->currentobject ? (DenemoObject *) si->currentobject->data : NULL; diff -urN ../../denemo-cvs/denemo/src/pitchentry.c ./src/pitchentry.c --- ../../denemo-cvs/denemo/src/pitchentry.c 2007-10-04 19:44:40.000000000 +0100 +++ ./src/pitchentry.c 2007-10-04 20:12:03.000000000 +0100 @@ -302,18 +302,16 @@ store = (curstaff->tone_store); measurenode *curmeasure = curstaff->measures; GList *store_el = NULL; - + // move cursor to start of current measure + si->currentobject = (objnode *) si->currentmeasure->data; + si->cursor_x = 0; + si->cursor_appending = !(gboolean)si->currentobject; + //calcmarkboundaries (si); measurenum = si->currentmeasurenum - 1; curmeasure = si->currentmeasure; if(curmeasure) { store_el = get_tones(store, measurenum); objnode *curobj = curmeasure->data; - - // start at currentobject - while(curobj!=si->currentobject) - curobj = curobj->next; - - while (curobj) { tone* thetone; @@ -333,7 +331,10 @@ ((chord*)theobj->object)->tone_node = store_el; modify_note((chord*)theobj->object, mid_c_offset, thetone->enshift, dclef); tone_stored=TRUE; + if(!si->cursor_appending) + cursorright(PR_gui); store_el = store_el->next; + }// tone available }// note available /* skip over non notes */ @@ -341,15 +342,10 @@ curobj = curobj->next; if(curobj) theobj = (DenemoObject *) curobj->data; - } - while(curobj && (theobj->type != CHORD || ((chord*)theobj->object)->notes==NULL)); - - + } while(curobj && + (theobj->type != CHORD || ((chord*)theobj->object)->notes==NULL)); if(tone_stored && curobj==NULL && curmeasure->next) ret = TRUE; - - - }// while objects in measure if(store_el && !PR_continuous) sound_click();//extra tones in measure @@ -403,19 +399,13 @@ thetone->octave = octave; thetone->valid = TRUE; #define store (((DenemoStaff*)gui->si->currentstaff->data)->tone_store) - /* if this measure has tones, but not on the currentobject then clear the tones, otherwise - the one being stored will not apply to the currentobject */ - if(gui->si->currentobject && !((chord*)((DenemoObject *)gui->si->currentobject->data)->object)->tone_node && store && g_list_nth(store,gui->si->currentmeasurenum - 1) && g_list_nth(store,gui->si->currentmeasurenum - 1)->data) - clear_tones_currentmeasure(NULL, gui); store = put_tone(store, gui->si->currentmeasurenum - 1, thetone); nextmeasure = apply_tones(gui->si); displayhelper (gui); if(PR_continuous && nextmeasure) { sound_click(); measureright(gui); - } - - /* gtk_widget_draw(gui->scorearea, NULL); */ + } #undef store } @@ -425,7 +415,6 @@ static void clear_tone_nodes(DenemoGUI *gui ) { DenemoScore *si = gui->si; DenemoStaff* curstaff = ((DenemoStaff*)si->currentstaff->data); - measurenode *curmeasure; for (curmeasure = curstaff->measures;curmeasure; curmeasure = curmeasure->next) { objnode *curobj = curmeasure->data; @@ -455,6 +444,7 @@ store = NULL; #undef store displayhelper(gui); + switch_back_to_main_window(); } /* @@ -489,23 +479,16 @@ GList *tone_node = thechord->tone_node; if(tone_node) { ((tone*)tone_node->data)->valid = FALSE; - thechord->tone_node = NULL; - /* move cursor back to where tone overlay starts, so that the overlay is placed on the same notes as before */ - gint leftshifts = 0; - while(si->currentobject->prev) { - cursorleft(PR_gui); - leftshifts++; - DenemoObject *theobj = (DenemoObject *)si->currentobject->data; - if((theobj->type == CHORD) && (((chord*)theobj->object)->notes!=NULL) && (((chord*)theobj->object)->tone_node == NULL)) { - cursorright(PR_gui); - leftshifts--; - break; - } - } + objnode *keep = si->currentobject; + gint keepx = si->cursor_x; + gboolean keepa = si->cursor_appending; apply_tones(si); /*restore the position of the cursor before the delete of the tone */ - while(leftshifts--) - cursorright(PR_gui); + si->currentobject = keep; + si->cursor_x = keepx; + si->cursor_appending = keepa; + calcmarkboundaries (si); + displayhelper (PR_gui); return TRUE; } else { @@ -726,10 +709,11 @@ switch_back_to_main_window(); } - -static void toggle_insert(GtkButton *button) { - // switch the button to read Collect Notes/Insert Notes - // toggle PR_insert to show where the notes detected should go + // toggle PR_insert to show where the notes detected should go, and start correct entry mode +static void toggle_insert(GtkButton *button, DenemoGUI *gui) { + GtkAction *action; + action = gtk_ui_manager_get_action (gui->ui_manager, PR_insert?"/MainMenu/EntryMenu/TogglePitchless": "/MainMenu/EntryMenu/Replace"); + gtk_action_activate(action); PR_insert = !PR_insert; switch_back_to_main_window(); } @@ -773,7 +757,7 @@ gtk_box_pack_start (GTK_BOX (hbox2), radio_button, TRUE, TRUE, 0); g_signal_connect (G_OBJECT (radio_button), "toggled", - G_CALLBACK (toggle_insert), NULL); + G_CALLBACK (toggle_insert), gui); button = gtk_button_new_with_label("Clear"); gtk_box_pack_start (GTK_BOX (hbox2), button, @@ -801,10 +785,6 @@ gtk_box_pack_start (GTK_BOX (hbox2), spinner, TRUE, TRUE, 0); g_signal_connect (G_OBJECT (spinner), "value-changed", G_CALLBACK (change_click_volume), NULL); - - - - button = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(radio_button), "Insert Notes"); gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);/* no need for callback */ diff -urN ../../denemo-cvs/denemo/src/prefdialog.c ./src/prefdialog.c --- ../../denemo-cvs/denemo/src/prefdialog.c 2007-01-24 19:44:26.000000000 +0000 +++ ./src/prefdialog.c 2007-10-04 20:02:44.000000000 +0100 @@ -30,6 +30,7 @@ GtkWidget *checkclone; GtkWidget *checkautosave; GtkWidget *checknotationpalette; + GtkWidget *checkrhythmpalette; GtkWidget *checkarticulationpalette; GtkWidget *autosaveentry; GtkWidget *browserentry; @@ -133,6 +134,9 @@ prefs->notation_palette = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (cbdata->checknotationpalette)); + prefs->rhythm_palette = + gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON + (cbdata->checkrhythmpalette)); prefs->saveparts = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (cbdata->checkautosaveparts)); @@ -161,6 +165,7 @@ GtkWidget *texteditor; GtkWidget *denemopath; GtkWidget *checknotationpalette; + GtkWidget *checkrhythmpalette; GtkWidget *checkarticulationpalette; GtkWidget *notebook; GtkWidget *hbox; @@ -191,7 +196,7 @@ /* * Note entry settings */ - table = gtk_table_new (9, 2, FALSE); + table = gtk_table_new (13, 2, FALSE); gtk_container_set_border_width (GTK_CONTAINER (table), 12); gtk_table_set_row_spacings (GTK_TABLE (table), 8); gtk_table_set_col_spacings (GTK_TABLE (table), 8); @@ -230,7 +235,7 @@ (GtkAttachOptions) (0), 0, 0); checknotationpalette = - gtk_check_button_new_with_label (_("Display notataion toolbar")); + gtk_check_button_new_with_label (_("Display durations toolbar")); gtk_widget_set_sensitive (checknotationpalette, TRUE); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (checknotationpalette), gui->prefs->notation_palette); @@ -247,8 +252,22 @@ (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0); + + checkrhythmpalette = + gtk_check_button_new_with_label (_("Display rhythm pattern toolbar")); + gtk_widget_set_sensitive (checkrhythmpalette, TRUE); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (checkrhythmpalette), + gui->prefs->rhythm_palette); + gtk_table_attach (GTK_TABLE (table), checkrhythmpalette, 0, 2, 8, 9, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + + + + + hbox = gtk_hbox_new (FALSE, 8); - gtk_table_attach (GTK_TABLE (table), hbox, 0, 2, 7, 8, + gtk_table_attach (GTK_TABLE (table), hbox, 0, 2, 10, 11, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0); @@ -273,7 +292,7 @@ gtk_widget_set_sensitive (checkarticulationpalette, FALSE); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (checkautosaveparts), gui->prefs->saveparts); - gtk_table_attach(GTK_TABLE(table), checkautosaveparts, 0,2, 8,9, + gtk_table_attach(GTK_TABLE(table), checkautosaveparts, 0,2, 11,12, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0,0); /* @@ -440,6 +459,7 @@ cbdata.checkautosaveparts = checkautosaveparts; cbdata.checkarticulationpalette = checkarticulationpalette; cbdata.checknotationpalette = checknotationpalette; + cbdata.checkrhythmpalette = checkrhythmpalette; cbdata.checkclone = checkclone; cbdata.checkautosave = checkautosave; cbdata.autosaveentry = autosaveentry; diff -urN ../../denemo-cvs/denemo/src/prefops.c ./src/prefops.c --- ../../denemo-cvs/denemo/src/prefops.c 2007-08-22 10:50:05.000000000 +0100 +++ ./src/prefops.c 2007-10-04 20:03:13.000000000 +0100 @@ -111,8 +111,9 @@ ret->createclones = FALSE; ret->autosave = TRUE; ret->autosave_timeout = 5; - ret->notation_palette = FALSE; - ret->articulation_palette = FALSE; + ret->notation_palette = TRUE; + ret->articulation_palette = TRUE; + ret->rhythm_palette = TRUE; ret->history = g_queue_new (); /* Read values from systemwide preferences file */ @@ -332,6 +333,16 @@ xmlFree (tmp); } } + else if (0 == + xmlStrcmp (cur->name, (const xmlChar *) "rhythmpalette")) + { + xmlChar *tmp = xmlNodeListGetString (doc, cur->xmlChildrenNode, 1); + if(tmp) + { + prefs->rhythm_palette = atoi ((gchar *) tmp); + xmlFree (tmp); + } + } else if (0 == xmlStrcmp (cur->name, (const xmlChar *) "lilyversion")) { xmlChar *tmp = xmlNodeListGetString (doc, cur->xmlChildrenNode, 1); @@ -556,6 +567,8 @@ prefs->notation_palette); newXMLIntChild (child, (xmlChar *) "articulationpalette", prefs->articulation_palette); + newXMLIntChild (child, (xmlChar *) "rhythmpalette", + prefs->rhythm_palette); if (prefs->browser) xmlNewChild (child, NULL, (xmlChar *) "browser", (xmlChar *) prefs->browser->str); diff -urN ../../denemo-cvs/denemo/src/view.c ./src/view.c --- ../../denemo-cvs/denemo/src/view.c 2007-10-04 19:44:40.000000000 +0100 +++ ./src/view.c 2007-10-04 20:08:18.000000000 +0100 @@ -92,7 +92,7 @@ { GList *display = NULL; - + stop_pitch_recognition(); DenemoScore *si = gui->si; //Iterate through the views list if more than one is open if (g_list_length (displays) > 1) @@ -336,7 +336,7 @@ r->gui->si->currhythm = g_list_find(r->gui->si->rhythms, r); r->gui->si->rstep = r->rsteps; #define g (r->gui->si->rstep) -#define RSM (r->gui->si->rhythmicsubmode) +#define RSM (r->gui->mode) if(((RhythmElement*)g->data)->icon) { GtkWidget *label = LABEL(CURRP->button); gtk_label_set_markup(GTK_LABEL(label),((RhythmElement*)g->data)->icon); @@ -368,7 +368,7 @@ * return an ascii code to indicate what modifier (if any) function gives. * '0x0' means not a valid modifier for a rhythmic duration * char '.' means a dotted note, '(' and ')' mean start and end slur - * r to x are rests + * r to z are rests * others to be defined * */ @@ -387,6 +387,9 @@ fn==(gpointer)insert_rest_6key ? 'x':0; } +gboolean code_is_a_duration(gchar code) { + return code==0 || (code>='r' && code<='z'); +} /** * Callback to translate keypresses into rhythm elements @@ -618,7 +621,7 @@ delete_rhythm_cb (GtkAction * action, DenemoGUI * gui) { - if(gui->si->rhythmicsubmode == RSM_OFF) + if(gui->mode&(RSM_RHYTHM|RSM_OVERLAY) == 0) return; if(gui->si->currhythm==NULL) return; @@ -713,13 +716,11 @@ "List Available Plugins", G_CALLBACK (list_available_plugins)}, {"ViewMenu", NULL, N_("_View")}, {"EntryMenu", NULL, N_("Mo_de")}, - {"Insert", NULL, N_("_Insert"), "Insert", "Insert Mode", - G_CALLBACK (insert_mode)}, - {"Replace", NULL, N_("_Replace"), NULL, "Replace Mode", - G_CALLBACK (replace_mode)}, - {"Blank", NULL, N_("_Blank"), NULL, "Blank Mode", G_CALLBACK (blank_mode)}, - {"Rest", NULL, N_("_Rest"), "r", "Rest Mode", G_CALLBACK (rest_toggle_key)}, - {"Default", NULL, N_("_Default"), "Escape", "Default Mode", + + + + + {"ReadOnly", NULL, N_("Read Only"), NULL, "Read only Mode", G_CALLBACK (default_mode)}, {"StaffMenu", NULL, N_("_Staff")}, {"AddBefore", NULL, N_("Add _Before Current Staff..."), NULL, NULL, @@ -886,13 +887,53 @@ } /** - * Function to toggle entry of rhythms without pitches + * callback changing mode gui->mode + * + */ +static void +change_mode (GtkRadioAction * action, GtkRadioAction * current, DenemoGUI * gui) { +gint val = gtk_radio_action_get_current_value (action); + switch(val) { +#define SET_MODE(m) (gui->mode=((gui->mode&MODE_MASK)|m)) + case RSM_OFF: + SET_MODE(RSM_OFF); + break; + case RSM_RHYTHM: + SET_MODE(RSM_RHYTHM); + break; + case RSM_OVERLAY: + SET_MODE(RSM_RHYTHM|RSM_OVERLAY); + break; +#undef SET_MODE + } + //g_print("Mode is %x for val=%x for %p %p other is %x\n", gui->mode, val, action, current, gtk_radio_action_get_current_value (current)); +} + + +/** + * callback changing type of entry * */ static void -toggle_pitchless (GtkAction * dummy, DenemoGUI * gui) { - gui->si->rhythmicsubmode ^= RSM_OVERLAY; +change_entry_type (GtkRadioAction * action, GtkRadioAction * current, DenemoGUI * gui) { +gint val = gtk_radio_action_get_current_value (action); + switch(val) { +#define SET_MODE(m) (gui->mode=((gui->mode&ENTRY_TYPE_MASK)|m)) + case INPUTREST: + SET_MODE(INPUTREST); + break; + case INPUTNORMAL: + SET_MODE(INPUTNORMAL); + break; + case INPUTBLANK: + SET_MODE(INPUTBLANK); + break; + } +#undef SET_MODE + //g_print("Mode is %x masks %x %x\n",ENTRY_TYPE_MASK, MODE_MASK, gui->mode); } + + /** * Function to toggle entry of notes by pitch recognition off/on * @@ -914,27 +955,31 @@ } } /* then turn on/off */ + if(gui->pitch_recognition) { stop_pitch_recognition(); } else { start_pitch_recognition(gui);// FIXME different guis + + } gui->pitch_recognition = !gui->pitch_recognition; /* always turn rhythm mode on with pitch recognition, since otherwise the cursor just bobs about uselessly, while the accidentals in the notes affect the previous note */ - - GtkWidget *widget = gtk_ui_manager_get_widget (gui->ui_manager, "/MainMenu/EntryMenu/ToggleRhythmToolbar"); - GtkWidget *toolbar = gtk_ui_manager_get_widget (gui->ui_manager, "/RhythmToolBar"); - if (!GTK_WIDGET_VISIBLE (toolbar)) - g_signal_emit_by_name(widget, "activate", action, gui); - + GtkAction *mode = gtk_ui_manager_get_action (gui->ui_manager, gui->pitch_recognition?"/MainMenu/EntryMenu/Replace": "/MainMenu/EntryMenu/TogglePitchless"); + //g_print("PRIOR The %s action is %p is sen\n",gui->pitch_recognition?"/MainMenu/EntryMenu/Replace": "/MainMenu/EntryMenu/TogglePitchless", mode, gtk_action_get_sensitive(mode) ); + gtk_action_activate(mode); + // g_print("The %s action is %p \n",gui->pitch_recognition?"/MainMenu/EntryMenu/Replace": "/MainMenu/EntryMenu/TogglePitchless", mode); +mode = gtk_ui_manager_get_action (gui->ui_manager, "/MainMenu/EntryMenu/Note"); + gtk_action_activate(mode); + // g_print("Note action is %p is sensitive %x\n", mode, gtk_action_get_sensitive(mode)); } /** * Function to toggle whether rhythm toolbar is visible - * Sets the rhythmic submode, and turns off pitchless entry if it is being hidden. + * switches keymap to Rhythm.keymaprc when toolbar is on back to standard when off. * */ static void @@ -943,28 +988,27 @@ static keymap *rhythm_keymap;// special keymap in rhythm submode GtkWidget *widget; widget = gtk_ui_manager_get_widget (gui->ui_manager, "/RhythmToolBar"); + // g_print("Callback for %s\n", g_type_name(G_TYPE_FROM_INSTANCE(widget))); if (GTK_WIDGET_VISIBLE (widget)) { - if(gui->si->rhythmicsubmode & RSM_OVERLAY) { - GtkAction *tog = gtk_ui_manager_get_action (gui->ui_manager, "/RhythmToolBar/TogglePitchless"); -/* g_print("type is %s\n", g_type_name(G_TYPE_FROM_INSTANCE(tog))); */ - g_signal_emit_by_name(tog, "activate", NULL, gui); - } if(gui->prefs->standard_keymap) gui->prefs->the_keymap = gui->prefs->standard_keymap; - gui->si->rhythmicsubmode = RSM_OFF; gtk_widget_hide (widget); } else { if(rhythm_keymap==NULL){ - rhythm_keymap = create_keymap ("Rhythm.keymaprc"); //printf("CREATED keymap\n"); } gui->prefs->the_keymap = rhythm_keymap; gtk_widget_show (widget); - gui->si->rhythmicsubmode |= (RSM_RHYTHM); +#if 0 + GtkAction *mode = gtk_ui_manager_get_action (gui->ui_manager, "/MainMenu/EntryMenu/Replace"); +#else + GtkAction *mode = gtk_ui_manager_get_action (gui->ui_manager, "/MainMenu/EntryMenu/Note"); +#endif + gtk_action_activate(mode);//FIXME does not work } } @@ -975,7 +1019,7 @@ {"ToggleNotationToolbar", NULL, N_("_Durations Toolbar"), NULL, N_("Enter single notes/rests of a given duration"), G_CALLBACK (toggle_notation_toolbar), FALSE} , - {"ToggleRhythmToolbar", NULL, N_("_Rhythmic & Overlays"), NULL, N_("Enter notes using a prevailing rhythm\nOverlay with pitches"), + {"ToggleRhythmToolbar", NULL, N_("Rhythms & Overlays"), NULL, N_("Enter notes using a prevailing rhythm\nOverlay with pitches"), G_CALLBACK (toggle_rhythm_toolbar), FALSE} , {"TogglePitchRecognition", NULL, N_("_Microphone"), NULL, N_("Enable pitch entry from microphone"), @@ -983,12 +1027,29 @@ , {"ToggleArticulationPalette", NULL, N_("_Articulation Palette"), NULL, NULL, G_CALLBACK (toggle_articulation_palette), FALSE} - , - {"TogglePitchless", NULL, N_("_Overlay"), NULL, N_("Pure rhythm entry\nAnd overlay notes with pitches"), - G_CALLBACK (toggle_pitchless), FALSE} + }; +/** + * Radio entries for the menus + */ +static GtkRadioActionEntry radio_menu_entries[] = { + {"Classic", NULL, N_("Classic"), NULL, "Denemo Classic note entry mode", + RSM_OFF}, + {"Replace", NULL, N_("Insert"), NULL, N_("Insert notes"), + RSM_RHYTHM}, + {"TogglePitchless", NULL, N_("Edit"), NULL, N_("Edit notes/Enter pure rhythms"), + RSM_OVERLAY} + +}; + + +static GtkRadioActionEntry type_menu_entries[] = { + {"Note", NULL, N_("Note"), NULL, N_("Normal Mode"), INPUTNORMAL}, + {"Rest", NULL, N_("Rest"), NULL, N_("Rest Mode"), INPUTREST}, + {"Blank", NULL, N_("Non printing rests"), NULL, N_("Ghost rests"), INPUTBLANK} +}; struct cbdata { @@ -1004,7 +1065,7 @@ openrecent (GtkWidget * widget, gpointer data) { struct cbdata *cdata = (struct cbdata *) data; - g_print ("actioned\n"); + // g_print ("actioned\n"); open_for_real (cdata->filename, cdata->gui); } @@ -1112,6 +1173,22 @@ toggle_menu_entries, G_N_ELEMENTS (toggle_menu_entries), gui); + gtk_action_group_add_radio_actions (action_group, + radio_menu_entries, + G_N_ELEMENTS (radio_menu_entries), + RSM_RHYTHM/* initial value */, + G_CALLBACK(change_mode), gui); + + + gtk_action_group_add_radio_actions (action_group, + type_menu_entries, + G_N_ELEMENTS (type_menu_entries), + INPUTNORMAL/* initial value */, + G_CALLBACK(change_entry_type), gui); + + + + ui_manager = gtk_ui_manager_new (); gui->ui_manager = ui_manager; gtk_ui_manager_insert_action_group (ui_manager, action_group, 0); @@ -1119,7 +1196,7 @@ gtk_window_add_accel_group (GTK_WINDOW (gui->window), accel_group); data_dir = g_build_filename ( -#ifndef USE_LOCAL_DENEMOUI +#ifdef USE_LOCAL_DENEMOUI get_data_dir (), #endif "denemoui.xml", NULL); @@ -1147,7 +1224,7 @@ GTK_WIDGET_UNSET_FLAGS(toolbar, GTK_CAN_FOCUS); gtk_widget_show (toolbar); toolbar = gtk_ui_manager_get_widget (ui_manager, "/EntryToolBar"); - g_print("EntryToolbar is %p\n", toolbar); + //g_print("EntryToolbar is %p\n", toolbar); gtk_toolbar_set_style (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_ICONS); gtk_box_pack_start (GTK_BOX (main_vbox), toolbar, FALSE, TRUE, 0); GTK_WIDGET_UNSET_FLAGS(toolbar, GTK_CAN_FOCUS); @@ -1230,24 +1307,37 @@ /* Now that the window's shown, initialize the gcs */ gcs_init (gui->window->window); - if (gui->prefs->articulation_palette) - toggle_articulation_palette (NULL, gui); - toggle_rhythm_toolbar (NULL, gui); - if (!gui->prefs->notation_palette) - { - g_print ("Notation palette %d\n", gui->prefs->notation_palette); - toggle_notation_toolbar (NULL, gui); - } /* Similarly, the keymap should be initialized after the only once si->window is shown, as it may pop up an advisory dialog. */ gui->prefs->standard_keymap = gui->prefs->the_keymap = init_keymap (); displays = g_list_append (displays, gui); - g_print ("No of Displays %d\n", g_list_length (displays)); + //g_print ("No of Displays %d\n", g_list_length (displays)); if (gui->prefs->autosave) g_timeout_add (gui->prefs->autosave_timeout * 1000 * 60, (GSourceFunc) auto_save_document_timeout, gui->si); + if (gui->prefs->articulation_palette) + toggle_articulation_palette (NULL, gui); + + /* we have to do this properly, because it introduces a keymap */ + if (gui->prefs->rhythm_palette) { + GtkWidget *widget = gtk_ui_manager_get_widget (gui->ui_manager, "/RhythmToolBar"); + if (GTK_WIDGET_VISIBLE (widget)) + g_print("hiding tool bar\n"), gtk_widget_hide(widget);// I do not understand why this is visible - there is no gtk_widget_show(all) in the hierarchy + widget = gtk_ui_manager_get_widget (gui->ui_manager, "/MainMenu/EntryMenu/ToggleRhythmToolbar"); + g_signal_emit_by_name(widget, "activate", NULL, gui); + g_print("type is %s\n", g_type_name(G_TYPE_FROM_INSTANCE(widget))); + } + // A cheap way of doing activating this toolbar, note it is called variously notation toolbar, duration toolbar and EntryToolBar FIXME + if (!gui->prefs->notation_palette) + { + //g_print ("Notation palette %d\n", gui->prefs->notation_palette); + toggle_notation_toolbar (NULL, gui); + } + g_print("Turning on the modes\n"); + + gui->mode = RSM_RHYTHM | INPUTNORMAL; g_free (error);