www.pudn.com > d4psp31.zip > fmNoteEditor.pas, change:1998-10-05,size:8604b


unit fmNoteEditor; 
 
interface                            
 
uses 
  Windows, Messages, SysUtils, Classes, Graphics, Controls, StdCtrls, Forms, Dialogs, 
  fmBar, cmpPianoRoll, Buttons, ExtCtrls, fmPower, cmpTimerSpeedButton, 
  Menus, cmpKeyboard, cmpBarControl; 
 
type 
  TNoteEditorForm = class(TBarForm) 
    PianoRoll1: TPianoRoll; 
    Bevel1: TBevel; 
    Keys1: TKeys; 
    PopupMenu: TPopupMenu; 
    InsertNote: TMenuItem; 
    EditNote: TMenuItem; 
    DeleteNote: TMenuItem; 
    N1: TMenuItem; 
    SelectTrack1: TMenuItem; 
    stNote: TLabel; 
    stFocusedNote: TLabel; 
    stPosition: TLabel; 
    procedure AdjustHeader; 
    procedure FormShow(Sender: TObject); 
    procedure LStretcherClick(Sender: TObject); 
    procedure RStretcherClick(Sender: TObject); 
    procedure PopupMenuPopup(Sender: TObject); 
    procedure Keys1NoteOn(Sender: TObject; note, velocity: Integer); 
    procedure Keys1NoteOff(Sender: TObject; note, velocity: Integer); 
    procedure PianoRoll1Scroll(Sender: TObject; ScrollCode: TScrollCode; 
      var ScrollPos: Integer); 
    procedure SelectTrack1Click(Sender: TObject); 
    procedure DeleteNoteClick(Sender: TObject); 
    procedure PianoRoll1NoteMoving(sender: TObject; note, 
      startPos, endPos: Integer); 
    procedure PianoRoll1NoteMoved(sender: TObject; note, 
      startPos, endPos: Integer); 
    procedure PianoRoll1StartSelection(sender: TObject; pos: Integer); 
    procedure PianoRoll1EndSelection(sender: TObject; pos: Integer); 
    procedure FormResize(Sender: TObject); 
    procedure PianoRoll1Focus(Sender: TObject); 
    procedure PianoRoll1MouseMoved(sender: TObject; bar, beat, 
      tick: Integer); 
  private 
    MovingNotePlaying : Integer; 
  protected 
  public 
    procedure Notify (tp : TActiveFormNotify); override; 
  end; 
 
implementation 
 
{$R *.DFM} 
 
//{$DEFINE POS_DISPLAY} 
 
uses fmMainForm, unitMidiGlobals, cmpMidiIterator; 
 
procedure TNoteEditorForm.Notify (tp : TactiveFormNotify); 
begin 
  inherited; 
  with PianoRoll1 do 
  begin 
    SetSelStartPos (MainForm.SelStartPos, False); 
    SetSelEndPos (MainForm.SelEndPos, False); 
    ActivePosition := MainForm.CurrentPosition; 
    if tp = ntFullUpdate then Refresh 
  end 
end; 
 
procedure TNoteEditorForm.FormShow(Sender: TObject); 
begin 
  PianoRoll1.Track := MainForm.CurrentTrackNo; 
  inherited; 
  AdjustHeader; 
  MovingNotePlaying := -1; 
  SetCaption ('Note Editor', PianoRoll1.Track); 
end; 
 
procedure TNoteEditorForm.LStretcherClick(Sender: TObject); 
begin 
  inherited; 
  PianoRoll1.QNWidth := PianoRoll1.QNWidth - 1; 
end; 
 
procedure TNoteEditorForm.RStretcherClick(Sender: TObject); 
begin 
  inherited; 
  PianoRoll1.QNWidth := PianoRoll1.QNWidth + 1; 
end; 
 
procedure TNoteEditorForm.AdjustHeader; 
begin 
  Keys1.NoteWidth := PianoRoll1.WhiteNoteHeight; 
  Keys1.top := PianoRoll1.Top - 1; 
  Keys1.height := PianoRoll1.ActiveHeight + 2; 
end; 
 
procedure TNoteEditorForm.PopupMenuPopup(Sender: TObject); 
begin 
  inherited; 
  DeleteNote.Enabled := PianoRoll1.NoteFocused; 
  EditNote.Enabled := PianoRoll1.NoteFocused; 
 
end; 
 
procedure TNoteEditorForm.Keys1NoteOn(Sender: TObject; note, 
  velocity: Integer); 
begin 
  inherited; 
  with PianoRoll1 do if Assigned (MidiData) then 
    MainForm.TrackOutputs.TrackOutput [Track].Port.NoteOn (MidiData.Tracks [Track].Channel, note, velocity); 
end; 
 
procedure TNoteEditorForm.Keys1NoteOff(Sender: TObject; note, 
  velocity: Integer); 
begin 
  inherited; 
  with PianoRoll1 do 
    MainForm.TrackOutputs.TrackOutput [Track].Port.NoteOff (MidiData.Tracks [Track].Channel, note, velocity); 
end; 
 
procedure TNoteEditorForm.PianoRoll1Scroll(Sender: TObject; 
  ScrollCode: TScrollCode; var ScrollPos: Integer); 
begin 
  inherited; 
  Keys1.BaseOctave := 11 - ScrollPos; 
end; 
 
procedure TNoteEditorForm.SelectTrack1Click(Sender: TObject); 
var 
  trackNo : Integer; 
begin 
  inherited; 
  trackNo := PianoRoll1.Track; 
  if MainForm.SelectTrackDialog (trackNo, False, False) then 
  begin 
    PianoRoll1.Track := trackNo; 
    SetCaption ('Note Editor', PianoRoll1.Track); 
  end 
end; 
 
procedure TNoteEditorForm.DeleteNoteClick(Sender: TObject); 
var 
   startIdx, endIdx : Integer; 
   startNote : PMidiEventData; 
begin 
  inherited; 
  with PianoRoll1 do if NoteFocused then with MidiData.Tracks [Track] do 
  begin 
    GetFocusedNote (startNote); 
    with MidiData.Tracks [Track] do 
    begin 
      startIdx := IndexOf (startNote); 
      endIdx := IndexOf (startNote^.OnOffEvent) 
    end; 
    DeleteEvent (endIdx); 
    DeleteEvent (startIdx); 
    MidiData.Tracks [Track].CalcOnOffPointers; 
    MainForm.NotifyAll 
  end 
end; 
 
procedure TNoteEditorForm.PianoRoll1NoteMoving(sender: TObject; note, startPos, endPos: Integer); 
var 
  velocity : Integer; 
begin 
  inherited; 
  velocity := MainForm.DragNoteVolume; 
  if velocity > 0 then with PianoRoll1 do if Assigned (MidiData) and (note <> MovingNotePlaying) then 
  begin 
    if MovingNotePlaying <> -1 then 
      Keys1.ReleaseNote (MovingNotePlaying, 0, True); 
    MovingNotePlaying := note; 
    Keys1.PressNote (MovingNotePlaying, velocity, True); 
  end 
end; 
 
procedure TNoteEditorForm.PianoRoll1NoteMoved(sender: TObject; note, startPos, endPos: Integer); 
var 
  se, ee : TEventData; 
  sed, eed : PMidiEventData; 
  endIDX, startIDX : Integer; 
begin 
  inherited; 
  with PianoRoll1 do if Assigned (MidiData) then with MidiData.Tracks [Track] do 
  begin 
    if MovingNotePlaying <> -1 then 
    begin 
      Keys1.ReleaseNote (MovingNotePlaying, 0, True); 
      MovingNotePlaying := -1 
    end; 
 
    GetFocusedNote (sed); 
    eed := sed^.OnOffEvent; 
 
    se := sed^.data; 
    ee := eed^.data; 
 
    with MidiData.Tracks [Track] do 
    begin 
      endIdx := IndexOf (eed); 
      startIdx := IndexOf (sed) 
    end; 
 
 
    BeginUpdate; 
    try 
      DeleteEvent (endIdx); 
      DeleteEvent (startIdx); 
 
      se.b2 := Note; 
      ee.b2 := Note; 
      InsertEvent (startPos, se, 0); 
      InsertEvent (endPos, ee, 0) 
    finally 
      EndUpdate 
    end; 
    MainForm.NotifyAll 
  end 
end; 
 
procedure TNoteEditorForm.PianoRoll1StartSelection(sender: TObject; 
  pos: Integer); 
begin 
  inherited; 
  MainForm.SelStartPos := pos; 
  MainForm.SelEndPos := 0; 
  with PianoRoll1 do 
  begin 
    SetSelEndPos (MainForm.SelEndPos, True); 
    SetSelStartPos (MainForm.SelStartPos, True) 
  end 
end; 
 
procedure TNoteEditorForm.PianoRoll1EndSelection(sender: TObject; 
  pos: Integer); 
begin 
  inherited; 
  MainForm.SelEndPos := pos; 
  PianoRoll1.SetSelEndPos (MainForm.SelEndPos, True); 
end; 
 
procedure TNoteEditorForm.FormResize(Sender: TObject); 
const 
  alreadyMaxed : boolean = False; 
begin 
  inherited; 
  AdjustHeader; 
  if WindowState = wsMaximized then 
  begin 
    if not alreadyMaxed then  // Work round maximize bug. 
    begin 
      Application.ProcessMessages; 
      PianoRoll1.Invalidate; 
      alreadyMaxed := True 
    end 
  end 
  else 
    AlreadyMaxed := False 
end; 
 
procedure TNoteEditorForm.PianoRoll1Focus(Sender: TObject); 
var 
 noteOnEvent : PMidiEventData; 
 s : string; 
 x : Integer; 
 bar, beat, tick : Integer; 
begin 
  inherited; 
  with PianoRoll1 do 
    GetFocusedNote (noteOnEvent); 
 
  if Assigned (noteOnEvent) and Assigned (noteOnEvent.OnOffEvent) then 
  begin 
    s := 'Off:'; 
    x := PianoRoll1.CalcPosX (noteOnEvent.OnOffEvent.Pos); 
    PianoRoll1.CalcBarAndBeatFromXY (x, 0, bar, beat, tick); 
    {$IFDEF POS_DISPLAY} 
    stFocusedNote.Caption := IntToStr (noteOnEvent.OnOffEvent.Pos) 
    {$ELSE} 
    stFocusedNote.Caption := Format ('%s %d:%d:%d', [s, bar, beat, tick]) 
    {$ENDIF} 
  end 
  else 
  begin 
    stFocusedNote.Caption := '---'; 
  end 
end; 
 
procedure TNoteEditorForm.PianoRoll1MouseMoved(sender: TObject; bar, 
  beat, tick: Integer); 
var 
  noteOnEvent : PMidiEventData; 
  x : Integer; 
  s : string; 
begin 
  inherited; 
  stNote.Caption := GetNoteName (PianoRoll1.GetNoteNoAtCursor); 
  with PianoRoll1 do 
    GetFocusedNote (noteOnEvent); 
 
  if Assigned (noteOnEvent) then 
  begin 
    s := 'On:'; 
    x := PianoRoll1.CalcPosX (noteOnEvent.Pos); 
    PianoRoll1.CalcBarAndBeatFromXY (x, 0, bar, beat, tick); 
    {$IFDEF POS_DISPLAY} 
    stPosition.Caption := IntToStr (noteOnEvent.pos); 
    {$ELSE} 
    stPosition.Caption := Format ('%s %d:%d:%d', [s, bar, beat, tick]); 
    {$ENDIF} 
  end 
  else 
  begin 
    s := 'Pos'; 
    stPosition.Caption := Format ('%s %d:%d:%d', [s, bar, beat, tick]); 
  end; 
 
end; 
 
end.