~killian-ebel/seq24/song-editor-editing-capabilities

« back to all changes in this revision

Viewing changes to src/perfroll_input.cpp

  • Committer: Killian
  • Date: 2009-09-29 20:06:11 UTC
  • Revision ID: killian@killian-desktop-20090929200611-jes6fj6ubegtekia
Started to improve code structure and to add selection feature in perfroll (not functionnal yet)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//----------------------------------------------------------------------------
 
2
//
 
3
//  This file is part of seq24.
 
4
//
 
5
//  seq24 is free software; you can redistribute it and/or modify
 
6
//  it under the terms of the GNU General Public License as published by
 
7
//  the Free Software Foundation; either version 2 of the License, or
 
8
//  (at your option) any later version.
 
9
//
 
10
//  seq24 is distributed in the hope that it will be useful,
 
11
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
//  GNU General Public License for more details.
 
14
//
 
15
//  You should have received a copy of the GNU General Public License
 
16
//  along with seq24; if not, write to the Free Software
 
17
//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
18
//
 
19
//-----------------------------------------------------------------------------
 
20
 
1
21
#include "perform.h"
2
22
#include "perfroll_input.h"
3
23
#include "perfroll.h"
4
24
 
 
25
/**
 
26
 * Factory method.
 
27
 * 
 
28
 * Instantiate the correct performance input.
 
29
 * 
 
30
 * @param interaction_method Interaction method to use.
 
31
 * @return PerfInput instance, Seq24PerfInput by default.
 
32
 */
 
33
AbstractPerfInput*
 
34
AbstractPerfInput::get_perf_input(interaction_method_e interaction_method) 
 
35
{
 
36
    switch (global_interactionmethod) 
 
37
    {
 
38
      case e_fruity_interaction:
 
39
        return new FruityPerfInput();
 
40
        break;
 
41
 
 
42
      case e_seq24_interaction:
 
43
      default:
 
44
        return new Seq24PerfInput();
 
45
        break;
 
46
    }
 
47
}
 
48
 
 
49
/**
 
50
 * FruityPerfInput constructor.
 
51
 */
 
52
FruityPerfInput::FruityPerfInput()
 
53
: m_adding_pressed( false )
 
54
, m_current_x( 0 )
 
55
, m_current_y( 0 )
 
56
{
 
57
}
 
58
 
5
59
void FruityPerfInput::updateMousePtr( perfroll& ths )
6
60
{
7
61
    // context sensitive mouse
292
346
}
293
347
 
294
348
 
295
 
/* popup menu calls this */
296
 
void Seq24PerfInput::set_adding( bool a_adding, perfroll& ths )
297
 
{
298
 
    if ( a_adding )
299
 
    {
300
 
        ths.get_window()->set_cursor(  Gdk::Cursor( Gdk::PENCIL ));
301
 
        m_adding = true;
302
 
    }
303
 
    else
304
 
    {
305
 
        ths.get_window()->set_cursor( Gdk::Cursor( Gdk::LEFT_PTR ));
306
 
        m_adding = false;
307
 
    }
308
 
}
309
 
 
310
 
bool Seq24PerfInput::on_button_press_event(GdkEventButton* a_ev, perfroll& ths)
 
349
/**
 
350
 * Seq24PerfInput default constructor.
 
351
 */
 
352
Seq24PerfInput::Seq24PerfInput()
 
353
: m_adding( false )
 
354
, m_adding_pressed( false )
 
355
{
 
356
}
 
357
 
 
358
/**
 
359
 * Defines if we are adding or note.
 
360
 * 
 
361
 * @param a_adding Are we adding ?
 
362
 * @param ths Perfroll instance
 
363
 */
 
364
void 
 
365
Seq24PerfInput::set_adding( bool a_adding, perfroll& ths )
 
366
{
 
367
    ths.get_window()->set_cursor( ( a_adding ) ? Gdk::Cursor( Gdk::PENCIL ) : Gdk::Cursor( Gdk::LEFT_PTR ));
 
368
    m_adding = a_adding;
 
369
}
 
370
 
 
371
/**
 
372
 * Seq24 action when clicking with mouse.
 
373
 * 
 
374
 * @param a_ev The Gdk Event
 
375
 * @param ths Perfroll instance
 
376
 * @return True
 
377
 */
 
378
bool 
 
379
Seq24PerfInput::on_button_press_event(GdkEventButton* a_ev, perfroll& ths)
311
380
{
312
381
    ths.grab_focus( );
313
382
 
314
 
 
315
383
    if ( ths.m_mainperf->is_active( ths.m_drop_sequence ))
316
384
    {
317
385
        ths.m_mainperf->get_sequence( ths.m_drop_sequence )->unselect_triggers( );
325
393
 
326
394
    ths.convert_xy( ths.m_drop_x, ths.m_drop_y, &ths.m_drop_tick, &ths.m_drop_sequence );
327
395
 
328
 
    /*      left mouse button     */
329
 
    if ( a_ev->button == 1 ){
330
 
 
 
396
    /* Left mouse button */
 
397
    if ( a_ev->button == 1 )
 
398
    {
331
399
        long tick = ths.m_drop_tick;
332
400
 
333
 
        /* add a new note if we didnt select anything */
334
 
        if (  m_adding ){
335
 
 
 
401
        /* Add a new note if we didnt select anything */
 
402
        if ( m_adding ) 
 
403
        {
336
404
            m_adding_pressed = true;
337
405
 
338
 
            if ( ths.m_mainperf->is_active( ths.m_drop_sequence )){
339
 
 
 
406
            if ( ths.m_mainperf->is_active( ths.m_drop_sequence ))
 
407
            {
340
408
                long seq_length = ths.m_mainperf->get_sequence( ths.m_drop_sequence )->get_length( );
341
 
 
342
409
                bool state = ths.m_mainperf->get_sequence( ths.m_drop_sequence )->get_trigger_state( tick );
343
410
 
344
411
                if ( state )
348
415
                }
349
416
                else
350
417
                {
351
 
 
352
 
                    // snap to length of sequence
 
418
                    // Snap to length of sequence
353
419
                    tick = tick - (tick % seq_length);
354
420
                    //m_adding_pressed_state = true;
355
421
 
363
429
                }
364
430
            }
365
431
        }
366
 
        else {
367
 
 
368
 
            if ( ths.m_mainperf->is_active( ths.m_drop_sequence )){
369
 
 
 
432
        else 
 
433
        {
 
434
            /* Selecting */
 
435
            if ( ths.m_mainperf->is_active( ths.m_drop_sequence ))
 
436
            {
370
437
                ths.m_mainperf->push_trigger_undo();
371
438
                ths.m_mainperf->get_sequence( ths.m_drop_sequence )->select_trigger( tick );
372
439
 
384
451
                        get_selected_trigger_start_tick( );
385
452
                }
386
453
                else
 
454
                {
387
455
                    if ( tick >= end_tick - (c_perfroll_size_box_click_w * c_perf_scale_x) &&
388
456
                            tick <= end_tick &&
389
457
                            (ths.m_drop_y % c_names_y) >= c_names_y - c_perfroll_size_box_click_w - 1 )
397
465
                    else
398
466
                    {
399
467
                        ths.m_moving = true;
 
468
                        ths.m_selecting = true;
400
469
                        ths.m_drop_tick_trigger_offset = ths.m_drop_tick -
401
470
                            ths.m_mainperf->get_sequence( ths.m_drop_sequence )->
402
471
                            get_selected_trigger_start_tick( );
403
472
 
404
473
                    }
 
474
                }
 
475
            }
 
476
            else 
 
477
            {
 
478
                ths.m_selecting = true;
 
479
            }
405
480
 
406
 
                ths.draw_background_on( ths.m_pixmap, ths.m_drop_sequence );
407
 
                ths.draw_sequence_on( ths.m_pixmap, ths.m_drop_sequence );
408
 
                ths.draw_drawable_row( ths.m_window, ths.m_pixmap, ths.m_drop_y);
409
 
            }
 
481
            ths.draw_background_on( ths.m_pixmap, ths.m_drop_sequence );
 
482
            ths.draw_sequence_on( ths.m_pixmap, ths.m_drop_sequence );
 
483
            ths.draw_drawable_row( ths.m_window, ths.m_pixmap, ths.m_drop_y);
410
484
        }
411
485
    }
412
486
 
413
 
    /*     right mouse button      */
414
 
    if ( a_ev->button == 3 ){
 
487
    /* Right mouse button */
 
488
    if ( a_ev->button == 3 )
 
489
    {
415
490
        set_adding( true, ths );
416
491
    }
417
492
 
418
493
    /* middle, split */
419
494
    if ( a_ev->button == 2 )
420
495
    {
421
 
        if ( ths.m_mainperf->is_active( ths.m_drop_sequence )){
422
 
 
 
496
        if ( ths.m_mainperf->is_active( ths.m_drop_sequence ))
 
497
        {
423
498
            bool state = ths.m_mainperf->get_sequence( ths.m_drop_sequence )->get_trigger_state( ths.m_drop_tick );
424
499
 
425
500
            if ( state )
428
503
            }
429
504
        }
430
505
    }
 
506
 
431
507
    return true;
432
508
}
433
509
 
434
 
bool Seq24PerfInput::on_button_release_event(GdkEventButton* a_ev, perfroll& ths)
 
510
/**
 
511
 * Seq24 action when releasing mouse.
 
512
 * 
 
513
 * @param a_ev The Gdk Event
 
514
 * @param ths Perfroll instance
 
515
 * @return True
 
516
 */
 
517
bool 
 
518
Seq24PerfInput::on_button_release_event(GdkEventButton* a_ev, perfroll& ths)
435
519
{
436
 
    if ( a_ev->button == 1 ){
437
 
 
438
 
        if ( m_adding ){
 
520
    /* Left click */
 
521
    if ( a_ev->button == 1 )
 
522
    {
 
523
        if ( m_adding )
 
524
        {
439
525
            m_adding_pressed = false;
440
526
        }
 
527
 
 
528
        /* Force all lines to be redrawn */
 
529
        if ( ths.m_selecting )
 
530
        {
 
531
            ths.fill_background_pixmap();
 
532
            ths.queue_draw();
 
533
        }
441
534
    }
442
535
 
443
 
    if ( a_ev->button == 3 ){
 
536
    /* Right click */
 
537
    if ( a_ev->button == 3 )
 
538
    {
444
539
        m_adding_pressed = false;
445
540
        set_adding( false, ths );
446
541
    }
447
542
 
448
543
    ths.m_moving = false;
449
544
    ths.m_growing = false;
 
545
    ths.m_selecting = false;
 
546
 
450
547
    m_adding_pressed = false;
451
548
 
452
 
    if ( ths.m_mainperf->is_active( ths.m_drop_sequence  )){
453
 
 
 
549
    if ( ths.m_mainperf->is_active( ths.m_drop_sequence  ))
 
550
    {
454
551
        ths.draw_background_on( ths.m_pixmap, ths.m_drop_sequence );
455
552
        ths.draw_sequence_on( ths.m_pixmap, ths.m_drop_sequence );
456
553
        ths.draw_drawable_row( ths.m_window, ths.m_pixmap, ths.m_drop_y );
459
556
    return true;
460
557
}
461
558
 
462
 
bool Seq24PerfInput::on_motion_notify_event(GdkEventMotion* a_ev, perfroll& ths)
 
559
/**
 
560
 * Seq24 action while moving the mouse.
 
561
 * 
 
562
 * @param a_ev The Gdk Event
 
563
 * @param ths Perfroll instance
 
564
 * @return True
 
565
 */
 
566
bool 
 
567
Seq24PerfInput::on_motion_notify_event(GdkEventMotion* a_ev, perfroll& ths)
463
568
{
464
569
    long tick;
465
570
    int x = (int) a_ev->x;
466
571
 
467
 
    if (  m_adding && m_adding_pressed ){
 
572
    ths.m_current_x = (int) (a_ev->x);
 
573
    ths.m_current_y = (int) (a_ev->y);
468
574
 
 
575
    if ( m_adding && m_adding_pressed )
 
576
    {
469
577
        ths.convert_x( x, &tick );
470
578
 
471
 
        if ( ths.m_mainperf->is_active( ths.m_drop_sequence )){
472
 
 
 
579
        if ( ths.m_mainperf->is_active( ths.m_drop_sequence ))
 
580
        {
473
581
            long seq_length = ths.m_mainperf->get_sequence( ths.m_drop_sequence )->get_length( );
474
582
            tick = tick - (tick % seq_length);
475
583
 
476
584
            /*long min_tick = (tick < m_drop_tick) ? tick : m_drop_tick;*/
477
585
            long length = seq_length;
478
586
 
479
 
            ths.m_mainperf->get_sequence( ths.m_drop_sequence )
480
 
                ->grow_trigger( ths.m_drop_tick, tick, length);
 
587
            ths.m_mainperf->get_sequence( ths.m_drop_sequence )->grow_trigger( ths.m_drop_tick, tick, length);
481
588
            ths.draw_background_on( ths.m_pixmap, ths.m_drop_sequence );
482
589
            ths.draw_sequence_on( ths.m_pixmap, ths.m_drop_sequence );
483
590
            ths.draw_drawable_row( ths.m_window, ths.m_pixmap, ths.m_drop_y);
484
591
        }
485
592
    }
486
 
    else if ( ths.m_moving || ths.m_growing ){
487
 
 
488
 
        if ( ths.m_mainperf->is_active( ths.m_drop_sequence)){
489
 
 
 
593
    else if ( ths.m_moving || ths.m_growing || ths.m_selecting )
 
594
    {
 
595
        if ( ths.m_selecting )
 
596
        {
 
597
            ths.draw_selection_on_window();
 
598
            return true;
 
599
        }
 
600
        
 
601
        if ( ths.m_mainperf->is_active( ths.m_drop_sequence))
 
602
        {
490
603
            ths.convert_x( x, &tick );
491
604
            tick -= ths.m_drop_tick_trigger_offset;
492
605
 
494
607
 
495
608
            if ( ths.m_moving )
496
609
            {
497
 
                ths.m_mainperf->get_sequence( ths.m_drop_sequence )
498
 
                    ->move_selected_triggers_to( tick, true );
 
610
                ths.m_mainperf->get_sequence( ths.m_drop_sequence )->move_selected_triggers_to( tick, true );
499
611
            }
 
612
 
500
613
            if ( ths.m_growing )
501
614
            {
502
615
                if ( ths.m_grow_direction )
503
 
                    ths.m_mainperf->get_sequence( ths.m_drop_sequence )
504
 
                        ->move_selected_triggers_to( tick, false, 0 );
 
616
                {
 
617
                    ths.m_mainperf->get_sequence( ths.m_drop_sequence )->move_selected_triggers_to( tick, false, 0 );
 
618
                }
505
619
                else
506
 
                    ths.m_mainperf->get_sequence( ths.m_drop_sequence )
507
 
                        ->move_selected_triggers_to( tick-1, false, 1 );
 
620
                {
 
621
                    ths.m_mainperf->get_sequence( ths.m_drop_sequence )->move_selected_triggers_to( tick-1, false, 1 );
 
622
                }
508
623
            }
509
624
 
510
 
 
511
625
            ths.draw_background_on( ths.m_pixmap, ths.m_drop_sequence );
512
626
            ths.draw_sequence_on( ths.m_pixmap, ths.m_drop_sequence );
513
627
            ths.draw_drawable_row( ths.m_window, ths.m_pixmap, ths.m_drop_y);