bool
FruityPerfInput::on_button_press_event (GdkEventButton * ev, perfroll & roll)
{
    bool result = false;
    perform & p = roll.perf();
    roll.grab_focus();
    int & dropseq = roll.m_drop_sequence;       /* reference needed         */
    sequence * seq = p.get_sequence(dropseq);
    if (p.is_active(dropseq))
    {
        seq->unselect_triggers();
        roll.draw_all();
    }
    else
    {
        return false;
    }
    roll.m_drop_x = int(ev->x);
    roll.m_drop_y = int(ev->y);
    m_current_x = int(ev->x);
    m_current_y = int(ev->y);
    roll.convert_xy                             /* side-effects             */
    (
        roll.m_drop_x, roll.m_drop_y, roll.m_drop_tick, dropseq
    );
    if (SEQ64_CLICK_LEFT(ev->button))
    {
        result = on_left_button_pressed(ev, roll);
    }
    else if (SEQ64_CLICK_RIGHT(ev->button))
    {
        result = on_right_button_pressed(ev, roll);
    }
    else if (SEQ64_CLICK_MIDDLE(ev->button))   /* left-ctrl???, middle    */
    {
        /*
         * Implements some Stazed fixes now.
         */

        if (p.is_active(dropseq))
        {
            midipulse droptick = roll.m_drop_tick;
            droptick -= droptick % roll.m_snap; /* stazed fix: grid snap    */
            bool state = seq->get_trigger_state(droptick);
            if (state)                          /* trigger click, split it  */
            {
                roll.split_trigger(dropseq, droptick);
                result = true;
            }
            else                                /* track click, paste trig  */
            {
                p.push_trigger_undo(dropseq);
                seq->paste_trigger(droptick);
            }
        }
    }
    update_mouse_pointer(roll);
    return result;
}
Ejemplo n.º 2
0
bool
Seq24PerfInput::handle_motion_key (bool is_left, perfroll & roll)
{
    bool result = false;
    bool ok = roll.m_drop_sequence > 0;
    if (ok)
    {
        perform & p = roll.perf();
        int dropseq = roll.m_drop_sequence;
        midipulse droptick = roll.m_drop_tick;
        if (m_effective_tick == 0)
            m_effective_tick = droptick;

        if (is_left)
        {
            /*
             * This needlessly prevents a selection from moving leftward
             * from its original position.  We'll just put up with the
             * annoyance of absorbed decrements and document it in
             * sequencer64-doc.
             *
             * if (m_effective_tick < droptick)
             *     m_effective_tick = droptick;
             */

            midipulse tick = m_effective_tick;
            m_effective_tick -= roll.m_snap;
            if (m_effective_tick <= 0)
                m_effective_tick += roll.m_snap;    /* retrench */

            if (m_effective_tick != tick)
                result = true;
        }
        else
        {
            m_effective_tick += roll.m_snap;
            result = true;

            /*
             * What is the upper boundary here?
             */
        }

        midipulse tick = m_effective_tick - roll.m_drop_tick_trigger_offset;
        tick -= tick % roll.m_snap;

        /*
         * Hmmmm, this overrides any result setting above.  Due to issues with
         * triggers::move_selected(), this always returns true.  Let's ignore
         * the return value for now.
         */

        (void) p.get_sequence(dropseq)->move_selected_triggers_to(tick, true);
    }
    return result;
}
bool
FruityPerfInput::on_button_release_event (GdkEventButton * ev, perfroll & roll)
{
    bool result = false;
    m_current_x = int(ev->x);
    m_current_y = int(ev->y);

    perform & p = roll.perf();
    roll.m_moving = false;
    roll.m_growing = false;
    set_adding_pressed(false);
    if (p.is_active(roll.m_drop_sequence))
        roll.draw_all();

    update_mouse_pointer(roll);
    return result;
}
bool
FruityPerfInput::on_right_button_pressed (GdkEventButton * ev, perfroll & roll)
{
    bool result = false;
    perform & p = roll.perf();
    midipulse droptick = roll.m_drop_tick;
    int dropseq = roll.m_drop_sequence;
    if (p.is_active(dropseq))
    {
        sequence * seq = p.get_sequence(dropseq);
        bool state = seq->get_trigger_state(droptick);
        if (state)
        {
            p.push_trigger_undo(dropseq);       /* stazed fix */
            seq->del_trigger(droptick);
            result = true;
        }
    }
    return result;
}
Ejemplo n.º 5
0
bool
Seq24PerfInput::on_button_release_event (GdkEventButton * ev, perfroll & roll)
{
    bool result = false;
    if (SEQ64_CLICK_LEFT(ev->button))
    {
        if (is_adding())
            set_adding_pressed(false);
    }
    else if (SEQ64_CLICK_RIGHT(ev->button))
    {
        /*
         * Minor new feature.  If the Super (Mod4, Windows) key is
         * pressed when release, keep the adding-state in force.  One
         * can then use the unadorned left-click key to add material.  Right
         * click to reset the adding mode.  This feature is enabled only
         * if allowed by Options / Mouse  (but is true by default).
         * See the same code in seq24seqroll.cpp.
         */

        bool addmode_exit = ! rc().allow_mod4_mode();
        if (! addmode_exit)
            addmode_exit = ! is_super_key(ev);              /* Mod4 held? */

        if (addmode_exit)
        {
            set_adding_pressed(false);
            activate_adding(false, roll);
        }
    }

    perform & p = roll.perf();
    roll.m_moving = roll.m_growing = false;
    set_adding_pressed(false);
    m_effective_tick = 0;
    if (p.is_active(roll.m_drop_sequence))
    {
        roll.draw_all();
    }
    return result;
}
void
FruityPerfInput::update_mouse_pointer (perfroll & roll)
{
    perform & p = roll.perf();
    midipulse droptick;
    int dropseq;
    roll.convert_xy(m_current_x, m_current_y, droptick, dropseq);
    sequence * seq = p.get_sequence(dropseq);
    if (p.is_active(dropseq))
    {
        midipulse start;
        midipulse end;
        if (seq->intersect_triggers(droptick, start, end))
        {
            int wscalex = s_perfroll_size_box_click_w * c_perf_scale_x;
            int ymod = m_current_y % c_names_y;
            if
            (
                start <= droptick && droptick <= (start + wscalex) &&
                (ymod <= s_perfroll_size_box_click_w + 1)
            )
            {
                roll.get_window()->set_cursor(Gdk::Cursor(Gdk::RIGHT_PTR));
            }
            else if
            (
                droptick <= end && (end - wscalex) <= droptick &&
                ymod >= (c_names_y - s_perfroll_size_box_click_w - 1)
            )
            {
                roll.get_window()->set_cursor(Gdk::Cursor(Gdk::LEFT_PTR));
            }
            else
                roll.get_window()->set_cursor(Gdk::Cursor(Gdk::CENTER_PTR));
        }
        else
            roll.get_window()->set_cursor(Gdk::Cursor(Gdk::PENCIL));
    }
    else
        roll.get_window()->set_cursor(Gdk::Cursor(Gdk::CROSSHAIR));
}
Ejemplo n.º 7
0
bool
Seq24PerfInput::on_button_press_event (GdkEventButton * ev, perfroll & roll)
{
    bool result = false;
    perform & p = roll.perf();
    int & dropseq = roll.m_drop_sequence;
    sequence * seq = p.get_sequence(dropseq);
    bool dropseq_active = p.is_active(dropseq);
    roll.grab_focus();
    if (dropseq_active)
    {
        seq->unselect_triggers();
        roll.draw_all();
    }
    roll.m_drop_x = int(ev->x);
    roll.m_drop_y = int(ev->y);
    roll.convert_drop_xy();                             /* affects dropseq  */
    seq = p.get_sequence(dropseq);
    dropseq_active = p.is_active(dropseq);
    if (! dropseq_active)
        return false;

    /*
     * EXPERIMENTAL.
     *  Let's make better use of the Ctrl key here.  First, let Ctrl-Left be
     *  handled exactly like the Middle click, then bug out.
     *
     *  Note that this middle-click code ought to be folded into a function.
     */

    if (is_ctrl_key(ev))
    {
        if (SEQ64_CLICK_LEFT(ev->button))
        {
            bool state = seq->get_trigger_state(roll.m_drop_tick);
            if (state)
            {
                roll.split_trigger(dropseq, roll.m_drop_tick);
            }
            else
            {
                p.push_trigger_undo(dropseq);
                seq->paste_trigger(roll.m_drop_tick);
            }
        }
        return true;
    }

    if (SEQ64_CLICK_LEFT(ev->button))
    {
        midipulse droptick = roll.m_drop_tick;
        if (is_adding())                /* add new note if nothing selected */
        {
            set_adding_pressed(true);
            midipulse seqlength = seq->get_length();
            bool state = seq->get_trigger_state(droptick);
            if (state)
            {
                p.push_trigger_undo(dropseq);           /* stazed fix   */
                seq->del_trigger(droptick);
            }
            else
            {
                droptick -= (droptick % seqlength);     /* snap         */
                p.push_trigger_undo(dropseq);           /* stazed fix   */
                seq->add_trigger(droptick, seqlength);
                roll.draw_all();
            }
            result = true;
        }
        else
        {
            /*
             * Set this flag to tell on_motion_notify() to call
             * p.push_trigger_undo().
             */

            roll.m_have_button_press = seq->select_trigger(droptick);

            midipulse tick0 = seq->selected_trigger_start();
            midipulse tick1 = seq->selected_trigger_end();
            int wscalex = s_perfroll_size_box_click_w * c_perf_scale_x;
            int ydrop = roll.m_drop_y % c_names_y;
            if
            (
                droptick >= tick0 && droptick <= (tick0 + wscalex) &&
                ydrop <= s_perfroll_size_box_click_w + 1
            )
            {
                roll.m_growing = true;
                roll.m_grow_direction = true;
                roll.m_drop_tick_trigger_offset = droptick -
                                                  seq->selected_trigger_start();
            }
            else if
            (
                droptick >= (tick1 - wscalex) && droptick <= tick1 &&
                ydrop >= c_names_y - s_perfroll_size_box_click_w - 1
            )
            {
                roll.m_growing = true;
                roll.m_grow_direction = false;
                roll.m_drop_tick_trigger_offset = droptick -
                                                  seq->selected_trigger_end();
            }
            else
            {
                roll.m_moving = true;
                roll.m_drop_tick_trigger_offset = droptick -
                                                  seq->selected_trigger_start();
            }
            roll.draw_all();
        }
    }
    else if (SEQ64_CLICK_RIGHT(ev->button))
    {
        activate_adding(true, roll);
        // Should we add this?
        // result = true;
    }
    else if (SEQ64_CLICK_MIDDLE(ev->button))                   /* split    */
    {
        /*
         * The middle click in seq24 interaction mode is either for splitting
         * the triggers or for setting the paste location of copy/paste.
         */

        bool state = seq->get_trigger_state(roll.m_drop_tick);
        if (state)
        {
            roll.split_trigger(dropseq, roll.m_drop_tick);
            result = true;
        }
        else
        {
            p.push_trigger_undo(dropseq);
            seq->paste_trigger(roll.m_drop_tick);
            // Should we add this?
            // result = true;
        }
    }
    return result;
}
Ejemplo n.º 8
0
bool
Seq24PerfInput::on_motion_notify_event (GdkEventMotion * ev, perfroll & roll)
{
    bool result = false;
    int x = int(ev->x);
    perform & p = roll.perf();
    int dropseq = roll.m_drop_sequence;
    sequence * seq = p.get_sequence(dropseq);
    if (! p.is_active(dropseq))
    {
        return false;
    }
    if (is_adding() && is_adding_pressed())
    {
        midipulse seqlength = seq->get_length();
        midipulse tick;
        roll.convert_x(x, tick);
        tick -= (tick % seqlength);

        midipulse length = seqlength;
        seq->grow_trigger(roll.m_drop_tick, tick, length);
        roll.draw_all();
        result = true;
    }
    else if (roll.m_moving || roll.m_growing)
    {
        /*
         * This code is necessary to insure that there is no push unless
         * we have a motion notification.
         */

        if (roll.m_have_button_press)
        {
            p.push_trigger_undo(dropseq);
            roll.m_have_button_press = false;
        }

        midipulse tick;
        roll.convert_x(x, tick);
        tick -= roll.m_drop_tick_trigger_offset;
        tick -= tick % roll.m_snap;
        if (roll.m_moving)
        {
            seq->move_selected_triggers_to(tick, true);
            result = true;
        }
        if (roll.m_growing)
        {
            if (roll.m_grow_direction)
            {
                seq->move_selected_triggers_to
                (
                    tick, false, triggers::GROW_START
                );
            }
            else
            {
                seq->move_selected_triggers_to
                (
                    tick - 1, false, triggers::GROW_END);
            }
            result = true;
        }
        roll.draw_all();
    }
    return result;
}
bool
FruityPerfInput::on_left_button_pressed (GdkEventButton * ev, perfroll & roll)
{
    bool result = false;
    perform & p = roll.perf();
    int dropseq = roll.m_drop_sequence;
    sequence * seq = p.get_sequence(dropseq);
    if (is_ctrl_key(ev))
    {
        if (p.is_active(dropseq))
        {
            midipulse droptick = roll.m_drop_tick;
            droptick -= droptick % roll.m_snap;     /* stazed: grid snap    */
            bool state = seq->get_trigger_state(droptick);
            if (state)
            {
                roll.split_trigger(dropseq, droptick);
                result = true;
            }
            else                                /* track click, paste trig  */
            {
                p.push_trigger_undo(dropseq);
                seq->paste_trigger(droptick);
            }
        }
    }
    else                    /* add a new note if we didn't select anything  */
    {
        midipulse droptick = roll.m_drop_tick;
        set_adding_pressed(true);
        if (p.is_active(dropseq))
        {
            midipulse seqlength = seq->get_length();
            bool state = seq->get_trigger_state(droptick);
            if (state)      /* resize or move event based on where clicked  */
            {
                set_adding_pressed(false);

                /*
                 * Set the flag that tells the motion-notify callback to call
                 * push_trigger_undo().
                 */

                roll.m_have_button_press = seq->select_trigger(droptick);

                midipulse starttick = seq->selected_trigger_start();
                midipulse endtick = seq->selected_trigger_end();
                int wscalex = s_perfroll_size_box_click_w * c_perf_scale_x;
                int ydrop = roll.m_drop_y % c_names_y;
                if
                (
                    droptick >= starttick && droptick <= (starttick + wscalex) &&
                    ydrop <= (s_perfroll_size_box_click_w + 1)
                )
                {           /* clicked left side: grow/shrink left side     */
                    roll.m_growing = true;
                    roll.m_grow_direction = true;
                    roll.m_drop_tick_trigger_offset = roll.m_drop_tick -
                        seq->selected_trigger_start();
                }
                else if
                (
                    droptick >= (endtick - wscalex) && droptick <= endtick &&
                    ydrop >= (c_names_y - s_perfroll_size_box_click_w - 1)
                )
                {           /* clicked right side: grow/shrink right side   */
                    roll.m_growing = true;
                    roll.m_grow_direction = false;
                    roll.m_drop_tick_trigger_offset = roll.m_drop_tick -
                        seq->selected_trigger_end();
                }
                else        /* clicked in the middle - move it              */
                {
                    roll.m_moving = true;
                    roll.m_drop_tick_trigger_offset = roll.m_drop_tick -
                         seq->selected_trigger_start();
                }
                roll.draw_all();
            }
            else                                    /* add a trigger        */
            {
                droptick -= (droptick % seqlength); /* snap to seqlength    */
                p.push_trigger_undo();
                seq->add_trigger(droptick, seqlength);
                result = true;
                roll.draw_all();
            }
        }
    }
    return result;
}