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;
}
Exemple #2
0
/* gfx_gdi_move_mouse:
 */
static void gfx_gdi_move_mouse(int x, int y)
{
   if (!mouse_on)
      return;

   x -= mouse_xfocus;
   y -= mouse_yfocus;

   if ((mouse_xpos == x) && (mouse_ypos == y))
      return;

   update_mouse_pointer(x, y, TRUE);
} 
Exemple #3
0
/* gfx_gdi_show_mouse:
 */
static int gfx_gdi_show_mouse(struct BITMAP *bmp, int x, int y)
{
   /* handle only the screen */
   if (bmp != gdi_screen)
      return -1;

   mouse_on = TRUE;

   x -= mouse_xfocus;
   y -= mouse_yfocus;

   update_mouse_pointer(x, y, FALSE);

   return 0;
} 
bool
FruitySeqEventInput::on_motion_notify_event
(
    GdkEventMotion * ev,
    seqevent & seqev
)
{
    bool result = false;
    midipulse tick = 0;
    seqev.m_current_x = (int) ev->x  + seqev.m_scroll_offset_x;
    if (seqev.m_moving_init)
    {
        seqev.m_moving_init = false;
        seqev.m_moving = true;
    }
    update_mouse_pointer(seqev);      /* context sensitive mouse pointer... */

    /*
     * Ctrl-left click drag on selected note(s) starts a copy/unselect/paste.
     */

    if (m_is_drag_pasting_start)
    {
        seqev.m_seq.copy_selected();
        seqev.m_seq.unselect();
        seqev.start_paste();
        m_is_drag_pasting_start = false;
        m_is_drag_pasting = true;
    }
    if (seqev.m_selecting || seqev.m_moving || seqev.m_paste)
    {
        if (seqev.m_moving || seqev.m_paste)
            seqev.snap_x(seqev.m_current_x);

        seqev.draw_selection_on_window();
    }
    if (seqev.m_painting)
    {
        seqev.m_current_x = int(ev->x)  + seqev.m_scroll_offset_x;
        seqev.snap_x(seqev.m_current_x);
        seqev.convert_x(seqev.m_current_x, tick);
        seqev.drop_event(tick);             // Why no push_undo()?
        result = 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
FruitySeqEventInput::on_button_release_event
(
    GdkEventButton * ev,
    seqevent & seqev
)
{
    bool result = false;
    midipulse tick_s;
    midipulse tick_f;
    seqev.grab_focus();
    seqev.m_current_x = int(ev->x) + seqev.m_scroll_offset_x;;
    if (seqev.m_moving || m_is_drag_pasting)
        seqev.snap_x(seqev.m_current_x);

    int delta_x = seqev.m_current_x - seqev.m_drop_x;
    midipulse delta_tick;
    if (SEQ64_CLICK_LEFT(ev->button))
    {
        int current_x = seqev.m_current_x;
        midipulse t_s, t_f;
        seqev.snap_x(current_x);
        seqev.convert_x(current_x, t_s);
        t_f = t_s + (seqev.m_zoom);                 /* shift back a few ticks */
        if (t_s < 0)
            t_s = 0;

        /*
         * Use the ctrl-left click button up for select/drag copy/paste;
         * use the left click button up for ending a move of selected notes.
         */

        if (m_is_drag_pasting)
        {
            m_is_drag_pasting = false;
            m_is_drag_pasting_start = false;
            seqev.m_paste = false; /* convert deltas into screen coordinates */
            seqev.m_seq.paste_selected(t_s, 0);
            result = true;
        }

        /* ctrl-left click but without movement - select a note */

        if (m_is_drag_pasting_start)
        {
            m_is_drag_pasting_start = false;

            /*
             * If a ctrl-left click without movement and if the note under
             * cursor is selected, and ctrl is held and button-down,
             * just select one.
             */

            if                                  /* deselect the event? */
            (
                is_ctrl_key(ev) &&
                ! m_justselected_one &&
                seqev.m_seq.select_events
                (
                    t_s, t_f, seqev.m_status, seqev.m_cc, sequence::e_is_selected
                ) 
            )
            {
                (void) seqev.m_seq.select_events
                (
                    t_s, t_f, seqev.m_status, seqev.m_cc, sequence::e_deselect
                );
            }
        }
        m_justselected_one = false;         /* clear flag on left button up */
        if (seqev.m_moving)
        {
            delta_x -= seqev.m_move_snap_offset_x; /* adjust for snap         */
            seqev.convert_x(delta_x, delta_tick);  /* deltas to screen coords */
            seqev.m_seq.move_selected_notes(delta_tick, 0);
            result = true;
        }
    }

    /*
     * Yet another stazed fix.  :-)
     */

    bool right = SEQ64_CLICK_RIGHT(ev->button);
    if (! right)
        right = is_ctrl_key(ev) && SEQ64_CLICK_LEFT(ev->button);

    if (right)
    {
        if (seqev.m_selecting)
        {
            int x, w;
            seqev.x_to_w(seqev.m_drop_x, seqev.m_current_x, x, w);
            seqev.convert_x(x, tick_s);
            seqev.convert_x(x + w, tick_f);
            (void) seqev.m_seq.select_events
            (
                tick_s, tick_f,
                seqev.m_status, seqev.m_cc, sequence::e_toggle_selection
            );

#ifdef USE_STAZED_SELECTION_EXTENSIONS

            /*
             * Stazed fix
             */

            if (event::is_strict_note_msg(seqev.m_status))
                seqev.m_seq.select_linked(tick_s, tick_f, seqev.m_status);
#endif

            /*
             * To update the select or unselect of notes by this action.
             * Not sure this makes sense, though.  How does selection dirty
             * anything?
             */

            seqev.m_seq.set_dirty();
        }
    }
    seqev.m_selecting = false;          /* turn it all off */
    seqev.m_moving = false;
    seqev.m_growing = false;
    seqev.m_moving_init = false;
    seqev.m_painting = false;
    seqev.m_seq.unpaint_all();
    seqev.update_pixmap();              /* if they clicked, something changed */
    seqev.draw_pixmap_on_window();
    update_mouse_pointer(seqev);
    return result;                      // true;
}
bool
FruitySeqEventInput::on_button_press_event
(
    GdkEventButton * ev,
    seqevent & seqev
)
{
    bool result = false;
    midipulse tick_s, tick_w;
    seqev.grab_focus();                 // NEW: I think this would be helpful
    seqev.convert_x(c_eventevent_x, tick_w);
    seqev.m_drop_x = seqev.m_current_x = int(ev->x) + seqev.m_scroll_offset_x;
    seqev.m_old.x = seqev.m_old.y = seqev.m_old.width = seqev.m_old.height = 0;
    if (seqev.m_paste)
    {
        seqev.snap_x(seqev.m_current_x);
        seqev.convert_x(seqev.m_current_x, tick_s);
        seqev.m_paste = false;
        seqev.m_seq.paste_selected(tick_s, 0);          /* does undo/mod    */
        seqev.m_seq.set_dirty();                        /* a stazed fix     */
        result = true;
    }
    else
    {
        int x, w;
        midipulse tick_f;
        if (SEQ64_CLICK_LEFT(ev->button))               /* Note 1   */
        {
            seqev.convert_x(seqev.m_drop_x, tick_s); /* x,y into tick/note    */
            tick_f = tick_s + seqev.m_zoom;          /* shift back some ticks */
            tick_s -= tick_w;
            if (tick_s < 0)
                tick_s = 0;

            int eventcount = seqev.m_seq.select_events
            (
                tick_s, tick_f, seqev.m_status, seqev.m_cc,
                sequence::e_would_select
            );
            if (! is_ctrl_key(ev) && eventcount == 0)
            {
                seqev.m_painting = true;
                seqev.snap_x(seqev.m_drop_x);
                seqev.convert_x(seqev.m_drop_x, tick_s); /* x,y-->tick/note  */
                eventcount = seqev.m_seq.select_events
                (
                    tick_s, tick_f, seqev.m_status, seqev.m_cc,
                    sequence::e_would_select
                );
                if (eventcount == 0)
                {
                    seqev.m_seq.push_undo();            /* add to add_event? */
                    seqev.drop_event(tick_s);           /* m_seq.add_event() */
                    result = true;
                }
            }
            else                                        /* selecting         */
            {
                eventcount = seqev.m_seq.select_events
                (
                    tick_s, tick_f, seqev.m_status, seqev.m_cc,
                    sequence::e_is_selected
                );
                if (eventcount == 0)
                {
                    eventcount = seqev.m_seq.select_events
                    (
                        tick_s, tick_f, seqev.m_status, seqev.m_cc,
                        sequence::e_would_select
                    );
                    if (eventcount > 0)                 /* if clicking event */
                    {
                        if (! is_ctrl_key(ev))
                            seqev.m_seq.unselect();
                    }
                    else    /* clickempty space, unselect all if no Ctrl-Sh  */
                    {
                        if (! is_ctrl_shift_key(ev))
                            seqev.m_seq.unselect();
                    }

                    /* on direct click select only one event */

                    eventcount = seqev.m_seq.select_events
                    (
                        tick_s, tick_f, seqev.m_status,
                        seqev.m_cc, sequence::e_select_one
                    );

                    /*
                     * Stazed fix:
                     */

#ifdef USE_STAZED_SELECTION_EXTENSIONS
                    if (event::is_strict_note_msg(seqev.m_status))
                    {
                        seqev.m_seq.select_linked(tick_s, tick_f, seqev.m_status);
                        seqev.m_seq.set_dirty();
                    }
#endif

                    if (eventcount)
                        m_justselected_one = true;  /* stop deselect on release */

                    /* if nothing selected, start the selection box */

                    if (is_ctrl_key(ev) && eventcount == 0)
                        seqev.m_selecting = true;
                }
                eventcount = seqev.m_seq.select_events
                (
                    tick_s, tick_f, seqev.m_status, seqev.m_cc,
                    sequence::e_is_selected
                );
                if (eventcount > 0)         /* if event under cursor selected */
                {
                    if (! is_ctrl_key(ev))          /* grab/move note       */
                    {
                        seqev.m_moving_init = true;
                        int note;
                        seqev.m_seq.get_selected_box(tick_s, note, tick_f, note);
                        tick_f += tick_w;
                        seqev.convert_t(tick_s, x); /* convert to X,Y values */
                        seqev.convert_t(tick_f, w);
                        w -= x;                     /* w is coordinates now  */

                        /* set the m_selected rectangle for x,y,w,h */

                        seqev.m_selected.x = x;
                        seqev.m_selected.width = w;
                        seqev.m_selected.y = (c_eventarea_y-c_eventevent_y) / 2;
                        seqev.m_selected.height = c_eventevent_y;

                        /* save offset that we get from the snap above */

                        int adjusted_selected_x = seqev.m_selected.x;
                        seqev.snap_x(adjusted_selected_x);
                        seqev.m_move_snap_offset_x =
                            seqev.m_selected.x - adjusted_selected_x;

                        /* align selection for drawing */

                        seqev.snap_x(seqev.m_selected.x);
                        seqev.snap_x(seqev.m_current_x);
                        seqev.snap_x(seqev.m_drop_x);
                    }
                    else if   /* Ctrl-Left-click when stuff already selected */
                    (
                        is_ctrl_key(ev) &&
                        seqev.m_seq.select_events(tick_s, tick_f,
                           seqev. m_status, seqev.m_cc, sequence::e_is_selected)
                    )
                    {
                        m_is_drag_pasting_start = true;
                    }
                }
            }

        }
        if (SEQ64_CLICK_RIGHT(ev->button))
        {
            seqev.convert_x(seqev.m_drop_x, tick_s); /* x,y in to tick/note   */
            tick_f = tick_s + seqev.m_zoom;          /* shift back some ticks */
            tick_s -= (tick_w);
            if (tick_s < 0)
                tick_s = 0;

            /*
             * Stazed fix: don't allow individual deletion of Note On/Off
             * events.  Should we do the same for AfterTouch events?  No, they
             * are not linked to Note On or Note Off events.
             */

            if (event::is_strict_note_msg(seqev.m_status))
                return true;

            int eventcount = seqev.m_seq.select_events
            (
                tick_s, tick_f, seqev.m_status, seqev.m_cc,
                sequence::e_would_select
            );
            if (eventcount > 0)   /* erase event under cursor if there is one */
            {
                /* remove only note under cursor, leave selection intact */

                (void) seqev.m_seq.select_events
                (
                    tick_s, tick_f,
                    seqev.m_status, seqev.m_cc, sequence::e_remove_one
                );
                seqev.redraw();
                seqev.m_seq.set_dirty();                /* take note!       */
                result = true;
            }
            else                                        /* selecting        */
            {
                if (! is_ctrl_key(ev))
                    seqev.m_seq.unselect();             /* nothing selected   */

                seqev.m_selecting = true;               /* start select-box   */
            }
        }
    }
    seqev.update_pixmap();              /* if they clicked, something changed */
    seqev.draw_pixmap_on_window();
    update_mouse_pointer(seqev);
    return result;                      // true;
}
bool
FruityPerfInput::on_motion_notify_event (GdkEventMotion * ev, perfroll & roll)
{
    bool result = false;
    perform & p = roll.perf();
    int dropseq = roll.m_drop_sequence;
    sequence * seq = p.get_sequence(dropseq);
    int x = int(ev->x);
    midipulse tick = 0;
    m_current_x = int(ev->x);
    m_current_y = int(ev->y);
    if (is_adding_pressed())
    {
        roll.convert_x(x, tick);        /* side-effect */
        if (p.is_active(dropseq))
        {
            midipulse seqlength = seq->get_length();
            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)
    {
        if (p.is_active(dropseq))
        {
            /*
             * 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;
            }
            roll.convert_x(x, tick);                    /* side-effect  */
            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)
            {
                result = true;
                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
                    );
                }
            }
            roll.draw_all();
        }
    }
    update_mouse_pointer(roll);
    return result;
}
Exemple #9
0
/* render_proc:
 *  Timer proc that updates the window.
 */
static void render_proc(void)
{
   int top_line, bottom_line;
   HDC hdc = NULL;
   HWND allegro_wnd = win_get_window();

   /* to prevent reentrant calls */
   if (render_semaphore)
      return;

   render_semaphore = TRUE;

   /* to prevent the drawing threads and the rendering proc
    * from concurrently accessing the dirty lines array.
    */
   _enter_gfx_critical();

   if (!gdi_screen) {
      _exit_gfx_critical();
      render_semaphore = FALSE;
      return;
   }

   /* pseudo dirty rectangles mechanism:
    *  at most only one GDI call is performed for each frame,
    *  a true dirty rectangles mechanism makes the demo game
    *  unplayable in 640x480 on my system.
    */

   /* find the first dirty line */
   top_line = 0;

   while (!gdi_dirty_lines[top_line])
      top_line++;

   if (top_line < gfx_gdi.h) {
      /* find the last dirty line */
      bottom_line = gfx_gdi.h-1;

      while (!gdi_dirty_lines[bottom_line])
         bottom_line--;

      hdc = GetDC(allegro_wnd);

      if (_color_depth == 8)
         set_palette_to_hdc(hdc, palette);

      blit_to_hdc(gdi_screen, hdc, 0, top_line, 0, top_line,
                  gfx_gdi.w, bottom_line - top_line + 1);

      /* update mouse pointer if needed */
      if (mouse_on) {
         if ((mouse_ypos+wgdi_mouse_sprite->h > top_line) && (mouse_ypos <= bottom_line)) {
            blit(gdi_screen, mouse_backbuffer, mouse_xpos, mouse_ypos, 0, 0,
                 mouse_backbuffer->w, mouse_backbuffer->h);

            update_mouse_pointer(mouse_xpos, mouse_ypos, TRUE);
         }
      }
      
      /* clean up the dirty lines */
      while (top_line <= bottom_line)
         gdi_dirty_lines[top_line++] = 0;

      ReleaseDC(allegro_wnd, hdc);
   }

   _exit_gfx_critical();

   /* simulate vertical retrace */
   PulseEvent(vsync_event);

   render_semaphore = FALSE;
}