Logo Search packages:      
Sourcecode: cadencii version File versions  Download package

void org::kbinani::cadencii::FormMain::pictPianoRoll_MouseUp ( Object  sender,
BMouseEventArgs  e 
) [inline]

ピアノロールからマウスボタンが離れたときの処理

Parameters:
sender
e

Definition at line 9323 of file FormMain.cs.

References org::kbinani::cadencii::AppManager::clockFromXCoord(), org::kbinani::vsq::VsqEvent::clone(), org::kbinani::cadencii::VsqFileEx::clone(), org::kbinani::vsq::VsqID::clone(), org::kbinani::vsq::VsqTrack::clone(), org::kbinani::vsq::VsqBPList::clone(), org::kbinani::cadencii::AppManager::editHistory, org::kbinani::cadencii::SelectedEventEntry::editing, org::kbinani::cadencii::Utility::editLengthOfVsqEvent(), org::kbinani::vsq::VsqCommand::generateCommandEventChangeClockAndIDContaintsRange(), org::kbinani::vsq::VsqCommand::generateCommandEventChangeIDContaints(), org::kbinani::vsq::VsqTrack::getCurve(), org::kbinani::vsq::VsqBPList::getDefault(), org::kbinani::cadencii::AppManager::getEditMode(), org::kbinani::vsq::VsqBPList::getMaximum(), org::kbinani::vsq::VsqBPList::getMinimum(), org::kbinani::vsq::VsqTrack::getNoteEventIterator(), org::kbinani::vsq::VsqFile::getPreMeasureClocks(), org::kbinani::cadencii::AppManager::getSelected(), org::kbinani::cadencii::AppManager::getVsqFile(), org::kbinani::vsq::VsqEvent::InternalID, org::kbinani::cadencii::AppManager::itemSelection, org::kbinani::cadencii::AppManager::mAddingEvent, org::kbinani::cadencii::AppManager::mDrawObjects, org::kbinani::cadencii::AppManager::mIsPointerDowned, org::kbinani::cadencii::AppManager::mWholeSelectedInterval, org::kbinani::cadencii::AppManager::mWholeSelectedIntervalStartForMoving, org::kbinani::cadencii::AppManager::noteFromYCoordDoublePrecision(), org::kbinani::cadencii::SelectedEventEntry::original, org::kbinani::vsq::VsqTrack::reflectDynamics(), org::kbinani::cadencii::EditHistoryModel::register(), org::kbinani::cadencii::AppManager::setEditMode(), org::kbinani::vsq::VsqFile::Track, org::kbinani::cadencii::ItemSelectionModel::updateSelectedEventInstance(), org::kbinani::cadencii::AppManager::vibratoLengthEditingRule, and org::kbinani::cadencii::AppManager::xCoordFromClocks().

        {
#if DEBUG
            AppManager.debugWriteLine( "pictureBox1_MouseUp" );
            AppManager.debugWriteLine( "    m_config.EditMode=" + AppManager.getEditMode() );
#endif
            AppManager.mIsPointerDowned = false;
            mMouseDowned = false;

            int modefiers = PortUtil.getCurrentModifierKey();

            EditMode edit_mode = AppManager.getEditMode();
            VsqFileEx vsq = AppManager.getVsqFile();
            int selected = AppManager.getSelected();
            VsqTrack vsq_track = vsq.Track.get( selected );
            CurveType selected_curve = trackSelector.getSelectedCurve();
            int stdx = controller.getStartToDrawX();
            int stdy = controller.getStartToDrawY();
            double d2_13 = 8192; // = 2^13
            int track_height = (int)(100 * controller.getScaleY());
            int half_track_height = track_height / 2;

            if ( edit_mode == EditMode.CURVE_ON_PIANOROLL ) {
                if ( pictPianoRoll.mMouseTracer.size() > 1 ) {
                    // マウスの軌跡の左右端(px)
                    int px_start = pictPianoRoll.mMouseTracer.firstKey();
                    int px_end = pictPianoRoll.mMouseTracer.lastKey();

                    // マウスの軌跡の左右端(クロック)
                    int cl_start = AppManager.clockFromXCoord( px_start - stdx );
                    int cl_end = AppManager.clockFromXCoord( px_end - stdx );

                    // 編集が行われたかどうか
                    boolean edited = false;
                    // 作業用のPITカーブのコピー
                    VsqBPList pit = (VsqBPList)vsq_track.getCurve( "pit" ).clone();
                    VsqBPList pbs = (VsqBPList)vsq_track.getCurve( "pbs" ); // こっちはクローンしないよ

                    // トラック内の全音符に対して、マウス軌跡と被っている部分のPITを編集する
                    for ( Iterator<VsqEvent> itr = vsq_track.getNoteEventIterator(); itr.hasNext(); ) {
                        VsqEvent item = itr.next();
                        int cl_item_start = item.Clock;
                        if ( cl_end < cl_item_start ) {
                            break;
                        }
                        int cl_item_end = cl_item_start + item.ID.getLength();
                        if ( cl_item_end < cl_start ) {
                            continue;
                        }

                        // ここに到達するってことは、pitに編集が加えられるってこと。
                        edited = true;

                        // マウス軌跡と被っている部分のPITを削除
                        int cl_remove_start = Math.Max( cl_item_start, cl_start );
                        int cl_remove_end = Math.Min( cl_item_end, cl_end );
                        int value_at_remove_end = pit.getValue( cl_remove_end );
                        int value_at_remove_start = pit.getValue( cl_remove_start );
                        Vector<Integer> remove = new Vector<Integer>();
                        for ( Iterator<Integer> itr2 = pit.keyClockIterator(); itr2.hasNext(); ) {
                            int clock = itr2.next();
                            if ( cl_remove_start <= clock && clock <= cl_remove_end ) {
                                remove.add( clock );
                            }
                        }
                        for ( Iterator<Integer> itr2 = remove.iterator(); itr2.hasNext(); ) {
                            int clock = itr2.next();
                            pit.remove( clock );
                        }
                        remove = null;

                        int px_item_start = AppManager.xCoordFromClocks( cl_item_start ) + stdx;
                        int px_item_end = AppManager.xCoordFromClocks( cl_item_end ) + stdx;

                        int lastv = value_at_remove_start;
                        boolean cl_item_end_added = false;
                        boolean cl_item_start_added = false;
                        int last_px = 0, last_py = 0;
                        for ( Iterator<Point> itr2 = pictPianoRoll.mMouseTracer.iterator(); itr2.hasNext(); ) {
                            Point p = itr2.next();
                            if ( p.x < px_item_start ) {
                                last_px = p.x;
                                last_py = p.y;
                                continue;
                            }
                            if ( px_item_end < p.x ) {
                                break;
                            }

                            int clock = AppManager.clockFromXCoord( p.x - stdx );
                            if ( clock < cl_item_start ) {
                                last_px = p.x;
                                last_py = p.y;
                                continue;
                            } else if ( cl_item_end < clock ) {
                                break;
                            }
                            double note = AppManager.noteFromYCoordDoublePrecision( p.y - stdy - half_track_height );
                            int v_pit = (int)(d2_13 / (double)pbs.getValue( clock ) * (note - item.ID.Note));

                            // 正規化
                            if ( v_pit < pit.getMinimum() ) {
                                v_pit = pit.getMinimum();
                            } else if ( pit.getMaximum() < v_pit ) {
                                v_pit = pit.getMaximum();
                            }

                            if ( cl_item_start < clock && !cl_item_start_added &&
                                 cl_start <= cl_item_start && cl_item_start < cl_end ) {
                                // これから追加しようとしているデータ点の時刻が、音符の開始時刻よりも後なんだけれど、
                                // 音符の開始時刻におけるデータをまだ書き込んでない場合
                                double a = (p.y - last_py) / (double)(p.x - last_px);
                                double x_at_clock = AppManager.xCoordFromClocks( cl_item_start ) + stdx;
                                double ext_y = last_py + a * (x_at_clock - last_px);
                                double tnote = AppManager.noteFromYCoordDoublePrecision( (int)(ext_y - stdy - half_track_height) );
                                int t_vpit = (int)(d2_13 / (double)pbs.getValue( cl_item_start ) * (tnote - item.ID.Note));
                                pit.add( cl_item_start, t_vpit );
                                lastv = t_vpit;
                                cl_item_start_added = true;
                            }

                            // 直前の値と違っている場合にのみ追加
                            if ( v_pit != lastv ) {
                                pit.add( clock, v_pit );
                                lastv = v_pit;
                                if ( clock == cl_item_end ) {
                                    cl_item_end_added = true;
                                } else if ( clock == cl_item_start ) {
                                    cl_item_start_added = true;
                                }
                            }
                        }

                        if ( !cl_item_end_added &&
                             cl_start <= cl_item_end && cl_item_end <= cl_end ) {
                            pit.add( cl_item_end, lastv );
                        }

                        pit.add( cl_remove_end, value_at_remove_end );
                    }

                    // 編集操作が行われた場合のみ、コマンドを発行
                    if ( edited ) {
                        CadenciiCommand run = new CadenciiCommand(
                            VsqCommand.generateCommandTrackCurveReplace( selected, "PIT", pit ) );
                        AppManager.editHistory.register( vsq.executeCommand( run ) );
                        setEdited( true );
                    }
                }
                pictPianoRoll.mMouseTracer.clear();
                AppManager.setEditMode( EditMode.NONE );
                return;
            }

            if ( edit_mode == EditMode.MIDDLE_DRAG ) {
                setCursor( new Cursor( java.awt.Cursor.DEFAULT_CURSOR ) );
            } else if ( edit_mode == EditMode.ADD_ENTRY || edit_mode == EditMode.ADD_FIXED_LENGTH_ENTRY ) {
                #region AddEntry || AddFixedLengthEntry
                if ( AppManager.getSelected() >= 0 ) {
                    if ( (edit_mode == EditMode.ADD_FIXED_LENGTH_ENTRY) ||
                         (edit_mode == EditMode.ADD_ENTRY && (mButtonInitial.x != e.X || mButtonInitial.y != e.Y) && AppManager.mAddingEvent.ID.getLength() > 0) ) {
                        if ( AppManager.mAddingEvent.Clock < vsq.getPreMeasureClocks() ) {
#if !JAVA
                            SystemSounds.Asterisk.Play();
#endif
                        } else {
                            fixAddingEvent();
                        }
                    }
                }
                #endregion
            } else if ( edit_mode == EditMode.MOVE_ENTRY ) {
                #region MoveEntry
#if DEBUG
                sout.println( "FormMain#pictPianoRoll_MouseUp; edit_mode is MOVE_ENTRY" );
#endif
                if ( AppManager.itemSelection.getEventCount() > 0 ) {
                    SelectedEventEntry last_selected_event = AppManager.itemSelection.getLastEvent();
#if DEBUG
                    sout.println( "FormMain#pictPianoRoll_MouseUp; last_selected_event.original.InternalID=" + last_selected_event.original.InternalID );
#endif
                    VsqEvent original = last_selected_event.original;
                    if ( original.Clock != last_selected_event.editing.Clock ||
                         original.ID.Note != last_selected_event.editing.ID.Note ) {
                        boolean out_of_range = false; // プリメジャーにめり込んでないかどうか
                        boolean contains_dynamics = false; // Dynaff, Crescend, Desrecendが含まれているかどうか
                        VsqTrack copied = (VsqTrack)vsq_track.clone();
                        int clockAtPremeasure = vsq.getPreMeasureClocks();
                        for ( Iterator<SelectedEventEntry> itr = AppManager.itemSelection.getEventIterator(); itr.hasNext(); ) {
                            SelectedEventEntry ev = itr.next();
                            int internal_id = ev.original.InternalID;
                            if ( ev.editing.Clock < clockAtPremeasure ) {
                                out_of_range = true;
                                break;
                            }
                            if ( ev.editing.ID.Note < 0 || 128 < ev.editing.ID.Note ) {
                                out_of_range = true;
                                break;
                            }
                            for ( Iterator<VsqEvent> itr2 = copied.getEventIterator(); itr2.hasNext(); ) {
                                VsqEvent item = itr2.next();
                                if ( item.InternalID == internal_id ) {
                                    item.Clock = ev.editing.Clock;
                                    item.ID = (VsqID)ev.editing.ID.clone();
                                    break;
                                }
                            }
                            if ( ev.original.ID.type == VsqIDType.Aicon ) {
                                contains_dynamics = true;
                            }
                        }
                        if ( out_of_range ) {
#if !JAVA
                            SystemSounds.Asterisk.Play();
#endif
                        } else {
                            if ( contains_dynamics ) {
                                copied.reflectDynamics();
                            }
                            CadenciiCommand run = VsqFileEx.generateCommandTrackReplace( selected,
                                                                                         copied,
                                                                                         vsq.AttachedCurves.get( selected - 1 ) );
                            AppManager.editHistory.register( vsq.executeCommand( run ) );
                            AppManager.itemSelection.updateSelectedEventInstance();
                            setEdited( true );
                        }
                    } else {
                        /*if ( (modefier & Keys.Shift) == Keys.Shift || (modefier & Keys.Control) == Keys.Control ) {
                            Rectangle rc;
                            VsqEvent select = IdOfClickedPosition( e.Location, out rc );
                            if ( select != null ) {
                                m_config.addSelectedEvent( item.InternalID );
                            }
                        }*/
                    }
                    lock ( AppManager.mDrawObjects ) {
                        Collections.sort( AppManager.mDrawObjects.get( selected - 1 ) );
                    }
                }
                #endregion
            } else if ( edit_mode == EditMode.EDIT_LEFT_EDGE || edit_mode == EditMode.EDIT_RIGHT_EDGE ) {
                #region EDIT_LEFT_EDGE | EDIT_RIGHT_EDGE
                if ( mMouseMoved ) {
                    VsqEvent original = AppManager.itemSelection.getLastEvent().original;
                    int count = AppManager.itemSelection.getEventCount();
                    int[] ids = new int[count];
                    int[] clocks = new int[count];
                    VsqID[] values = new VsqID[count];
                    int i = -1;
                    boolean contains_aicon = false; // dynaff, crescend, decrescendが含まれていればtrue
                    for ( Iterator<SelectedEventEntry> itr = AppManager.itemSelection.getEventIterator(); itr.hasNext(); ) {
                        SelectedEventEntry ev = itr.next();
                        if ( ev.original.ID.type == VsqIDType.Aicon ) {
                            contains_aicon = true;
                        }
                        i++;

                        Utility.editLengthOfVsqEvent( ev.editing, ev.editing.ID.getLength(), AppManager.vibratoLengthEditingRule );
                        ids[i] = ev.original.InternalID;
                        clocks[i] = ev.editing.Clock;
                        values[i] = ev.editing.ID;
                    }

                    CadenciiCommand run = null;
                    if ( contains_aicon ) {
                        VsqFileEx copied_vsq = (VsqFileEx)vsq.clone();
                        VsqCommand vsq_command =
                            VsqCommand.generateCommandEventChangeClockAndIDContaintsRange( selected,
                                                                                           ids,
                                                                                           clocks,
                                                                                           values );
                        copied_vsq.executeCommand( vsq_command );
                        VsqTrack copied = (VsqTrack)copied_vsq.Track.get( selected ).clone();
                        copied.reflectDynamics();
                        run = VsqFileEx.generateCommandTrackReplace( selected,
                                                                     copied,
                                                                     vsq.AttachedCurves.get( selected - 1 ) );
                    } else {
                        run = new CadenciiCommand(
                            VsqCommand.generateCommandEventChangeClockAndIDContaintsRange( selected,
                                                                                 ids,
                                                                                 clocks,
                                                                                 values ) );
                    }
                    AppManager.editHistory.register( vsq.executeCommand( run ) );
                    setEdited( true );
                }
                #endregion
            } else if ( edit_mode == EditMode.EDIT_VIBRATO_DELAY ) {
                #region EditVibratoDelay
                if ( mMouseMoved ) {
                    double max_length = AppManager.mAddingEventLength - _PX_ACCENT_HEADER * controller.getScaleXInv();
                    double rate = AppManager.mAddingEvent.ID.getLength() / max_length;
                    if ( rate > 0.99 ) {
                        rate = 1.0;
                    }
                    int vibrato_length = (int)(AppManager.mAddingEventLength * rate);
                    VsqEvent item = null;
                    for ( Iterator<VsqEvent> itr = vsq_track.getNoteEventIterator(); itr.hasNext(); ) {
                        VsqEvent ve = itr.next();
                        if ( ve.InternalID == mVibratoEditingId ) {
                            item = (VsqEvent)ve.clone();
                            break;
                        }
                    }
                    if ( item != null ) {
                        if ( vibrato_length <= 0 ) {
                            item.ID.VibratoHandle = null;
                            item.ID.VibratoDelay = item.ID.getLength();
                        } else {
                            item.ID.VibratoHandle.setLength( vibrato_length );
                            item.ID.VibratoDelay = item.ID.getLength() - vibrato_length;
                        }
                        CadenciiCommand run = new CadenciiCommand(
                            VsqCommand.generateCommandEventChangeIDContaints( selected, mVibratoEditingId, item.ID ) );
                        AppManager.editHistory.register( vsq.executeCommand( run ) );
                        setEdited( true );
                    }
                }
                #endregion
            } else if ( edit_mode == EditMode.MOVE_ENTRY_WHOLE ) {
#if DEBUG
                sout.println( "FormMain#pictPianoRoll_MouseUp; EditMode.MOVE_ENTRY_WHOLE" );
#endif
                #region MOVE_ENTRY_WHOLE
                int src_clock_start = AppManager.mWholeSelectedInterval.getStart();
                int src_clock_end = AppManager.mWholeSelectedInterval.getEnd();
                int dst_clock_start = AppManager.mWholeSelectedIntervalStartForMoving;
                int dst_clock_end = dst_clock_start + (src_clock_end - src_clock_start);
                int dclock = dst_clock_start - src_clock_start;

                int num = AppManager.itemSelection.getEventCount();
                int[] selected_ids = new int[num]; // 後段での再選択用のInternalIDのリスト
                int last_selected_id = AppManager.itemSelection.getLastEvent().original.InternalID;

                // 音符イベントを移動
                VsqTrack work = (VsqTrack)vsq_track.clone();
                int k = 0;
                for ( Iterator<SelectedEventEntry> itr = AppManager.itemSelection.getEventIterator(); itr.hasNext(); ) {
                    SelectedEventEntry item = itr.next();
                    int internal_id = item.original.InternalID;
                    selected_ids[k] = internal_id;
                    k++;
#if DEBUG
                    sout.println( "FormMain#pictPianoRoll_MouseUp; internal_id=" + internal_id );
#endif
                    for ( Iterator<VsqEvent> itr2 = work.getNoteEventIterator(); itr2.hasNext(); ) {
                        VsqEvent vsq_event = itr2.next();
                        if ( internal_id == vsq_event.InternalID ) {
#if DEBUG
                            sout.println( "FormMain#pictPianoRoll_MouseUp; before: clock=" + vsq_event.Clock + "; after: clock=" + item.editing.Clock );
#endif
                            vsq_event.Clock = item.editing.Clock;
                            break;
                        }
                    }
                }

                // 全てのコントロールカーブのデータ点を移動
                for ( int i = 0; i < Utility.CURVE_USAGE.Length; i++ ) {
                    CurveType curve_type = Utility.CURVE_USAGE[i];
                    VsqBPList bplist = work.getCurve( curve_type.getName() );
                    if ( bplist == null ) {
                        continue;
                    }

                    // src_clock_startからsrc_clock_endの範囲にあるデータ点をコピー&削除
                    VsqBPList copied = new VsqBPList( bplist.getName(), bplist.getDefault(), bplist.getMinimum(), bplist.getMaximum() );
                    int size = bplist.size();
                    for ( int j = size - 1; j >= 0; j-- ) {
                        int clock = bplist.getKeyClock( j );
                        if ( src_clock_start <= clock && clock <= src_clock_end ) {
                            VsqBPPair bppair = bplist.getElementB( j );
                            copied.add( clock, bppair.value );
                            bplist.removeElementAt( j );
                        }
                    }

                    // dst_clock_startからdst_clock_endの範囲にあるコントロールカーブのデータ点をすべて削除
                    size = bplist.size();
                    for ( int j = size - 1; j >= 0; j-- ) {
                        int clock = bplist.getKeyClock( j );
                        if ( dst_clock_start <= clock && clock <= dst_clock_end ) {
                            bplist.removeElementAt( j );
                        }
                    }

                    // コピーしたデータを、クロックをずらしながら追加
                    size = copied.size();
                    for ( int j = 0; j < size; j++ ) {
                        int clock = copied.getKeyClock( j );
                        VsqBPPair bppair = copied.getElementB( j );
                        bplist.add( clock + dclock, bppair.value );
                    }
                }

                // コマンドを作成&実行
                CadenciiCommand run = VsqFileEx.generateCommandTrackReplace( selected,
                                                                             work,
                                                                             vsq.AttachedCurves.get( selected - 1 ) );
                AppManager.editHistory.register( vsq.executeCommand( run ) );

                // 選択範囲を更新
                AppManager.mWholeSelectedInterval = new SelectedRegion( dst_clock_start );
                AppManager.mWholeSelectedInterval.setEnd( dst_clock_end );
                AppManager.mWholeSelectedIntervalStartForMoving = dst_clock_start;

                // 音符の再選択
                AppManager.itemSelection.clearEvent();
                Vector<Integer> list_selected_ids = new Vector<Integer>();
                for ( int i = 0; i < num; i++ ) {
                    list_selected_ids.add( selected_ids[i] );
                }
                AppManager.itemSelection.addEventAll( list_selected_ids );
                AppManager.itemSelection.addEvent( last_selected_id );

                setEdited( true );
                #endregion
            } else if ( AppManager.isWholeSelectedIntervalEnabled() ) {
                int start = AppManager.mWholeSelectedInterval.getStart();
                int end = AppManager.mWholeSelectedInterval.getEnd();
#if DEBUG
                sout.println( "FormMain#pictPianoRoll_MouseUp; WholeSelectedInterval; (start,end)=" + start + ", " + end );
#endif
                AppManager.itemSelection.clearEvent();

                // 音符の選択状態を更新
                Vector<Integer> add_required_event = new Vector<Integer>();
                for ( Iterator<VsqEvent> itr = vsq_track.getEventIterator(); itr.hasNext(); ) {
                    VsqEvent ve = itr.next();
                    if ( start <= ve.Clock && ve.Clock + ve.ID.getLength() <= end ) {
                        add_required_event.add( ve.InternalID );
                    }
                }
                AppManager.itemSelection.addEventAll( add_required_event );

                // コントロールカーブ点の選択状態を更新
                Vector<Long> add_required_point = new Vector<Long>();
                VsqBPList list = vsq_track.getCurve( selected_curve.getName() );
                if ( list != null ) {
                    int count = list.size();
                    for ( int i = 0; i < count; i++ ) {
                        int clock = list.getKeyClock( i );
                        if ( clock < start ) {
                            continue;
                        } else if ( end < clock ) {
                            break;
                        } else {
                            VsqBPPair v = list.getElementB( i );
                            add_required_point.add( v.id );
                        }
                    }
                }
                if ( add_required_point.size() > 0 ) {
                    AppManager.itemSelection.addPointAll( selected_curve,
                                                    PortUtil.convertLongArray( add_required_point.toArray( new Long[] { } ) ) );
                }
            }
        heaven:
            AppManager.setEditMode( EditMode.NONE );
            refreshScreen( true );
        }

Here is the call graph for this function:


Generated by  Doxygen 1.6.0   Back to index