1 //========================================================= 2 // MusE 3 // Linux Music Editor 4 // scoreedit.h 5 // (C) Copyright 2011 Florian Jung (flo93@users.sourceforge.net) 6 // 7 // This program is free software; you can redistribute it and/or 8 // modify it under the terms of the GNU General Public License 9 // as published by the Free Software Foundation; version 2 of 10 // the License, or (at your option) any later version. 11 // 12 // This program is distributed in the hope that it will be useful, 13 // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 // GNU General Public License for more details. 16 // 17 // You should have received a copy of the GNU General Public License 18 // along with this program; if not, write to the Free Software 19 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 // 21 //========================================================= 22 23 #ifndef __SCOREEDIT_H__ 24 #define __SCOREEDIT_H__ 25 26 #include <limits.h> 27 #include "type_defs.h" 28 #include "cobject.h" 29 #include "event.h" 30 #include "view.h" 31 #include "gconfig.h" 32 #include "keyevent.h" 33 #include "cleftypes.h" 34 #include "helper.h" 35 #include "event_tag_list.h" 36 37 #include <set> 38 #include <map> 39 #include <list> 40 #include <vector> 41 #include <string> 42 43 using std::set; 44 using std::pair; 45 using std::map; 46 using std::list; 47 using std::vector; 48 using std::string; 49 50 51 52 #define TICKS_PER_WHOLE (MusEGlobal::config.division*4) 53 #define SONG_LENGTH (MusEGlobal::song->len()) 54 55 56 57 enum {CMD_COLOR_BLACK, CMD_COLOR_VELO, CMD_COLOR_PART, 58 CMD_SET_NAME, 59 CMD_NOTELEN_1, CMD_NOTELEN_2, CMD_NOTELEN_4, CMD_NOTELEN_8, 60 CMD_NOTELEN_16, CMD_NOTELEN_32, CMD_NOTELEN_LAST, 61 62 CMD_QUANTIZE, CMD_VELOCITY, CMD_CRESCENDO, CMD_NOTELEN, CMD_TRANSPOSE, 63 CMD_ERASE, CMD_MOVE, CMD_FIXED_LEN, CMD_DELETE_OVERLAPS, CMD_LEGATO, 64 CMD_CUT, CMD_COPY, CMD_COPY_RANGE, CMD_PASTE, CMD_PASTE_DIALOG, CMD_DEL, 65 CMD_SELECT_ALL, CMD_SELECT_NONE, CMD_SELECT_INVERT, 66 CMD_SELECT_ILOOP, CMD_SELECT_OLOOP}; 67 68 69 70 71 // Forward declarations: 72 class QCloseEvent; 73 class QResizeEvent; 74 class QKeyEvent; 75 class QPainter; 76 class QPixmap; 77 class QScrollBar; 78 class QComboBox; 79 class QAction; 80 class QActionGroup; 81 class QGridLayout; 82 class QToolButton; 83 84 namespace MusECore { 85 class Part; 86 class StepRec; 87 } 88 89 namespace MusEGui { 90 class EditToolBar; 91 class ScoreCanvas; 92 class MTScaleFlo; 93 class SpinBox; 94 95 //--------------------------------------------------------- 96 // ScoreEdit 97 //--------------------------------------------------------- 98 99 class ScoreEdit : public TopWin 100 { 101 Q_OBJECT 102 private: 103 void closeEvent(QCloseEvent*) override; 104 105 void init_name(); 106 107 QGridLayout* mainGrid; 108 QWidget* mainw; 109 110 MusEGui::EditToolBar* edit_tools; 111 SpinBox* velo_spinbox; 112 SpinBox* velo_off_spinbox; 113 114 QComboBox* quant_combobox; 115 SpinBox* px_per_whole_spinbox; 116 117 QAction* preamble_keysig_action; 118 QAction* preamble_timesig_action; 119 120 QActionGroup* len_actions; 121 QAction* n1_action; 122 QAction* n2_action; 123 QAction* n4_action; 124 QAction* n8_action; 125 QAction* n16_action; 126 QAction* n32_action; 127 QAction* nlast_action; 128 129 QActionGroup* color_actions; 130 QAction* color_black_action; 131 QAction* color_velo_action; 132 QAction* color_part_action; 133 134 QMenu* color_menu; 135 136 QAction* cut_action; 137 QAction* copy_action; 138 QAction* copy_range_action; 139 QAction* paste_action; 140 QAction* paste_dialog_action; 141 QAction* del_action; 142 143 QAction* select_all_action; 144 QAction* select_none_action; 145 QAction* select_invert_action; 146 QAction* select_iloop_action; 147 QAction* select_oloop_action; 148 149 QAction* func_quantize_action; 150 QAction* func_notelen_action; 151 QAction* func_velocity_action; 152 QAction* func_cresc_action; 153 QAction* func_transpose_action; 154 QAction* func_erase_action; 155 QAction* func_move_action; 156 QAction* func_fixed_len_action; 157 QAction* func_del_overlaps_action; 158 QAction* func_legato_action; 159 160 QToolButton* srec; 161 162 QScrollBar* xscroll; 163 QScrollBar* yscroll; 164 ScoreCanvas* score_canvas; 165 MusEGui::MTScaleFlo* time_bar; 166 167 bool apply_velo; 168 169 static set<QString> names; 170 171 QString name; 172 173 bool set_name(QString newname, bool emit_signal=true, bool emergency_name=false); 174 175 void keyPressEvent(QKeyEvent*) override; 176 177 private slots: 178 void menu_command(int); 179 void velo_box_changed(); 180 void velo_off_box_changed(); 181 void quant_combobox_changed(int); 182 void init_shortcuts(); 183 void selection_changed(); 184 void clipboard_changed(); 185 void config_changed(); 186 187 signals: 188 void isDeleting(MusEGui::TopWin*); 189 void name_changed(); 190 void velo_changed(int); 191 void velo_off_changed(int); 192 193 public slots: 194 void canvas_width_changed(int); 195 void viewport_width_changed(int); 196 void canvas_height_changed(int); 197 void viewport_height_changed(int); 198 void song_changed(MusECore::SongChangedStruct_t); 199 void focusCanvas() override; 200 201 public: 202 ScoreEdit(QWidget* parent = nullptr, const char* name = nullptr, unsigned initPos = INT_MAX); 203 ~ScoreEdit() override; 204 205 void writeStatus(int level, MusECore::Xml& xml) const override; 206 void readStatus(MusECore::Xml& xml) override; 207 static void read_configuration(MusECore::Xml&); 208 static void write_configuration(int, MusECore::Xml&); 209 void storeSettings() override; 210 211 void add_parts(MusECore::PartList* pl, bool all_in_one=false); get_name()212 QString get_name() { return name; } get_apply_velo()213 bool get_apply_velo() { return apply_velo; } 214 215 bool itemsAreSelected() const; 216 // Appends given tag list with item objects according to options. Avoids duplicate events or clone events. 217 // Special: We 'abuse' a controller event's length, normally 0, to indicate visual item length. 218 void tagItems(MusECore::TagEventList* tag_list, const MusECore::EventTagOptionsStruct& options) const; 219 void setEditTool(int tool); 220 }; 221 222 223 224 225 226 227 enum stem_t 228 { 229 UPWARDS, 230 DOWNWARDS 231 }; 232 233 enum vorzeichen_t 234 { 235 B=-1, 236 NONE=0, 237 SHARP=1 238 }; 239 240 struct note_pos_t 241 { 242 int height; // 0 means "C-line", 1 "D-line" and so on 243 vorzeichen_t vorzeichen; 244 245 bool operator== (const note_pos_t& that) const 246 { 247 return (this->height==that.height) && (this->vorzeichen == that.vorzeichen); 248 } 249 }; 250 251 bool operator< (const note_pos_t& a, const note_pos_t& b); 252 253 254 255 256 257 258 259 class FloEvent 260 { 261 public: 262 enum typeEnum { NOTE_ON = 30, NOTE_OFF = 10, BAR = 20, KEY_CHANGE=23, TIME_SIG=26 }; //the order matters! 263 typeEnum type; 264 unsigned tick; 265 const MusECore::Part* source_part; 266 const MusECore::Event* source_event; 267 268 int pitch; 269 mutable int vel; 270 mutable int len; 271 272 int num; 273 int denom; 274 275 MusECore::key_enum key; 276 bool minor; 277 278 FloEvent(unsigned ti, int p,int v,int l,typeEnum t, const MusECore::Part* part=nullptr, const MusECore::Event* event=nullptr) 279 { 280 pitch=p; 281 vel=v; 282 len=l; 283 type= t; 284 tick=ti; 285 source_event=event; 286 source_part=part; 287 288 num=denom=0xdeadbeef; //unused, but valgrind complains if uninited 289 key=MusECore::KEY_C; 290 minor = false; 291 } FloEvent(unsigned ti,typeEnum t,int num_,int denom_)292 FloEvent(unsigned ti, typeEnum t, int num_, int denom_) 293 { 294 type=t; 295 num=num_; 296 denom=denom_; 297 tick=ti; 298 source_event=NULL; 299 source_part=NULL; 300 301 len=vel=pitch=0xdeadbeef; //unused, but valgrind complains if uninited 302 key=MusECore::KEY_C; 303 minor = false; 304 } FloEvent(unsigned ti,typeEnum t,MusECore::key_enum k,bool isMinor)305 FloEvent(unsigned ti, typeEnum t, MusECore::key_enum k, bool isMinor) 306 { 307 type=t; 308 key=k; 309 minor = isMinor; 310 tick=ti; 311 source_event=NULL; 312 source_part=NULL; 313 314 pitch=vel=len=num=denom=0xdeadbeef; //unused, but valgrind complains if uninited 315 } 316 }; 317 class FloItem 318 { 319 public: 320 enum typeEnum { NOTE=21, REST=22, NOTE_END=01, REST_END=02, BAR =10, KEY_CHANGE=13, TIME_SIG=16}; //the order matters! 321 typeEnum type; 322 unsigned begin_tick; 323 const MusECore::Event* source_event; 324 const MusECore::Part* source_part; 325 326 note_pos_t pos; 327 int len; 328 int dots; 329 bool tied; 330 bool already_grouped; 331 332 int num; 333 int denom; 334 335 MusECore::key_enum key; 336 bool minor; 337 338 mutable stem_t stem; 339 mutable int shift; 340 mutable bool ausweich; 341 mutable bool is_tie_dest; 342 mutable int tie_from_x; 343 344 mutable int x; 345 mutable int y; 346 mutable int stem_x; 347 mutable QPixmap* pix; 348 349 mutable bool is_active; 350 351 QRect bbox() const; 352 353 354 355 FloItem(typeEnum t, note_pos_t p, int l=0,int d=0, bool ti=false, unsigned beg=0, const MusECore::Part* part=NULL, const MusECore::Event* event=NULL) 356 { 357 pos=p; 358 dots=d; 359 len=l; 360 type=t; 361 already_grouped=false; 362 tied=ti; 363 shift=0; 364 ausweich=false; 365 is_tie_dest=false; 366 begin_tick=beg; 367 source_event=event; 368 source_part=part; 369 is_active=false; 370 } 371 FloItem(typeEnum t,int num_,int denom_)372 FloItem(typeEnum t, int num_, int denom_) 373 { 374 type=t; 375 num=num_; 376 denom=denom_; 377 begin_tick=-1; 378 source_event=NULL; 379 source_part=NULL; 380 } 381 FloItem(typeEnum t,MusECore::key_enum k,bool isMinor)382 FloItem(typeEnum t, MusECore::key_enum k, bool isMinor) 383 { 384 type=t; 385 key=k; 386 minor = isMinor; 387 begin_tick=-1; 388 source_event=NULL; 389 source_part=NULL; 390 } 391 FloItem(typeEnum t)392 FloItem(typeEnum t) 393 { 394 type=t; 395 396 already_grouped=false; 397 tied=false; 398 shift=0; 399 ausweich=false; 400 is_tie_dest=false; 401 begin_tick=-1; 402 source_event=NULL; 403 source_part=NULL; 404 } 405 FloItem()406 FloItem() 407 { 408 already_grouped=false; 409 tied=false; 410 shift=0; 411 ausweich=false; 412 is_tie_dest=false; 413 begin_tick=-1; 414 source_event=NULL; 415 source_part=NULL; 416 } 417 418 bool operator==(const FloItem& that) 419 { 420 if (this->type != that.type) return false; 421 422 switch(type) 423 { 424 case NOTE: 425 case REST: 426 case NOTE_END: 427 case REST_END: 428 return (this->pos == that.pos); 429 430 //the following may only occur once in a set 431 //so we don't search for "the time signature with 4/4 432 //at t=0", but only for "some time signature at t=0" 433 //that's why true is returned, and not some conditional 434 //expression 435 case BAR: 436 case KEY_CHANGE: 437 case TIME_SIG: 438 return true; 439 } 440 } 441 }; 442 struct floComp 443 { operatorfloComp444 bool operator() (const pair<unsigned, FloEvent>& a, const pair<unsigned, FloEvent>& b ) 445 { 446 if (a.first < b.first) return true; 447 if (a.first > b.first) return false; 448 449 if (a.second.type<b.second.type) return true; 450 if (a.second.type>b.second.type) return false; 451 452 return (a.second.pitch<b.second.pitch); 453 } operatorfloComp454 bool operator() (const FloItem& a, const FloItem& b ) 455 { 456 if (a.type < b.type) return true; 457 if (a.type > b.type) return false; 458 459 switch(a.type) 460 { 461 case FloItem::NOTE: 462 case FloItem::REST: 463 case FloItem::NOTE_END: 464 case FloItem::REST_END: 465 return (a.pos < b.pos); 466 467 //the following may only occur once in a set 468 //so we don't search for "the time signature with 4/4 469 //at t=0", but only for "some time signature at t=0" 470 //that's why true is returned, and not some conditional 471 //expression 472 case FloItem::BAR: 473 case FloItem::KEY_CHANGE: 474 case FloItem::TIME_SIG: 475 return false; 476 } 477 return (a.pos < b.pos); 478 } 479 }; 480 481 typedef set< pair<unsigned, FloEvent>, floComp > ScoreEventList; 482 typedef map< unsigned, set<FloItem, floComp> > ScoreItemList; 483 484 enum clef_t 485 { 486 VIOLIN, 487 BASS 488 }; 489 490 491 struct note_len_t 492 { 493 int len; 494 int dots; 495 note_len_tnote_len_t496 note_len_t(int l, int d) 497 { 498 len=l; dots=d; 499 } 500 note_len_tnote_len_t501 note_len_t(int l) 502 { 503 len=l; dots=0; 504 } 505 }; 506 507 508 struct cumulative_t 509 { 510 int count; 511 int cumul; 512 cumulative_tcumulative_t513 cumulative_t() 514 { 515 count=0; 516 cumul=0; 517 } 518 addcumulative_t519 void add(int v) 520 { 521 count++; 522 cumul+=v; 523 } 524 meancumulative_t525 float mean() 526 { 527 return (float)cumul/count; 528 } 529 }; 530 531 #define DEFAULT (NUM_PARTCOLORS) 532 #define HIGHLIGHTED_PIXMAP (NUM_PARTCOLORS + 1) 533 #define SELECTED_PIXMAP (NUM_PARTCOLORS + 2) 534 #define NUM_MYCOLORS (NUM_PARTCOLORS + 3 + 128) 535 #define VELO_PIXMAP_BEGIN (NUM_PARTCOLORS + 3) 536 537 struct timesig_t 538 { 539 int num; 540 int denom; 541 }; 542 543 enum staff_type_t 544 { 545 NORMAL, 546 GRAND_TOP, 547 GRAND_BOTTOM 548 }; 549 550 enum staff_mode_t 551 { 552 MODE_TREBLE, 553 MODE_BASS, 554 MODE_BOTH 555 }; 556 557 struct staff_t 558 { 559 set<const MusECore::Part*> parts; 560 set<int> part_indices; 561 ScoreEventList eventlist; 562 ScoreItemList itemlist; 563 564 int y_top; 565 int y_draw; 566 int y_bottom; 567 568 int min_y_coord; 569 int max_y_coord; 570 571 staff_type_t type; 572 clef_t clef; 573 574 ScoreCanvas* parent; 575 576 void create_appropriate_eventlist(); 577 void create_itemlist(); 578 void process_itemlist(); 579 void calc_item_pos(); 580 581 void apply_lasso(QRect rect, set<const MusECore::Event*>& already_processed); 582 recalculatestaff_t583 void recalculate() 584 { 585 create_appropriate_eventlist(); 586 create_itemlist(); 587 process_itemlist(); 588 calc_item_pos(); 589 } 590 staff_tstaff_t591 staff_t(ScoreCanvas* parent_) 592 { 593 type=NORMAL; 594 clef=VIOLIN; 595 parent=parent_; 596 } 597 staff_tstaff_t598 staff_t (ScoreCanvas* parent_, staff_type_t type_, clef_t clef_, set<const MusECore::Part*> parts_) 599 { 600 type=type_; 601 clef=clef_; 602 parts=parts_; 603 parent=parent_; 604 update_part_indices(); 605 } 606 607 bool cleanup_parts(); 608 609 set<const MusECore::Part*> parts_at_tick(unsigned tick); 610 611 void read_status(MusECore::Xml& xml); 612 void write_status(int level, MusECore::Xml& xml) const; 613 614 void update_parts(); //re-populates the set<MusECore::Part*> from the set<int> 615 void update_part_indices(); //re-populates the set<int> from the set<MusECore::Part*> 616 }; 617 618 list<int> calc_accidentials(MusECore::key_enum key, clef_t clef, MusECore::key_enum next_key=MusECore::KEY_C); 619 note_pos_t note_pos_(int note, MusECore::key_enum key); 620 note_pos_t note_pos (unsigned note, MusECore::key_enum key, clef_t clef); 621 622 int calc_len(int l, int d); 623 list<note_len_t> parse_note_len(int len_ticks, int begin_tick, vector<int>& foo, bool allow_dots=true, bool allow_normal=true); 624 625 int clef_height(clef_t clef); 626 627 628 int calc_timesig_width(int num, int denom); 629 int calc_number_width(int n); 630 631 632 class ScoreCanvas : public MusEGui::View 633 { 634 Q_OBJECT 635 private: 636 void init_pixmaps(); 637 static void draw_pixmap(QPainter& p, int x, int y, const QPixmap& pm); 638 static void draw_tie (QPainter& p, int x1, int x4, int yo, bool up=true, QColor color=Qt::black); 639 static void draw_akkolade (QPainter& p, int x, int y); 640 641 static void draw_accidentials(QPainter& p, int x, int y_offset, const list<int>& acc_list, const QPixmap& pix); 642 643 static void draw_timesig(QPainter& p, int x, int y_offset, int num, int denom); 644 645 static void draw_number(QPainter& p, int x, int y, int n); 646 647 648 649 650 651 static int height_to_pitch(int h, clef_t clef, MusECore::key_enum key); 652 static int height_to_pitch(int h, clef_t clef); 653 static int y_to_height(int y); 654 int y_to_pitch(int y, int t, clef_t clef); 655 656 657 658 659 void draw_note_lines(QPainter& p, int y, bool reserve_akkolade_space=false); 660 void draw_preamble(QPainter& p, int y, clef_t clef, bool reserve_akkolade_space=false, bool with_akkolade=false); 661 void draw_items(QPainter& p, int y, staff_t& staff, ScoreItemList::iterator from_it, ScoreItemList::iterator to_it); 662 void draw_items(QPainter& p, int y, staff_t& staff, int x1, int x2); 663 void draw_items(QPainter& p, int y, staff_t& staff); 664 void calc_pos_add_list(); 665 666 667 void recalc_staff_pos(); 668 list<staff_t>::iterator staff_at_y(int y); 669 670 671 672 bool need_redraw_for_hilighting(ScoreItemList::iterator from_it, ScoreItemList::iterator to_it); 673 bool need_redraw_for_hilighting(ScoreItemList& itemlist, int x1, int x2); 674 bool need_redraw_for_hilighting(ScoreItemList& itemlist); 675 bool need_redraw_for_hilighting(); 676 677 678 void set_staffmode(list<staff_t>::iterator it, staff_mode_t mode); 679 void remove_staff(list<staff_t>::iterator it); 680 void merge_staves(list<staff_t>::iterator dest, list<staff_t>::iterator src); 681 void move_staff_above(list<staff_t>::iterator dest, list<staff_t>::iterator src); 682 void move_staff_below(list<staff_t>::iterator dest, list<staff_t>::iterator src); 683 void cleanup_staves(); 684 void maybe_close_if_empty(); 685 686 QMenu* toolContextMenu(); 687 void callContextMenu(); 688 689 // defaults ---------------------------------------------------------- 690 public: 691 enum coloring_mode_t {COLOR_MODE_BLACK, COLOR_MODE_PART, COLOR_MODE_VELO}; 692 static int _quant_power2_init; 693 static int _pixels_per_whole_init; 694 static int note_velo_init, note_velo_off_init; 695 static int new_len_init; 696 static coloring_mode_t coloring_mode_init; 697 static bool preamble_contains_timesig_init; 698 static bool preamble_contains_keysig_init; 699 700 // member variables --------------------------------------------------- 701 private: 702 int _quant_power2; 703 int _pixels_per_whole; 704 705 int note_velo; 706 int note_velo_off; 707 708 std::map<int,int> pos_add_list; 709 710 list<staff_t> staves; 711 712 MusECore::StepRec* steprec; 713 714 // the drawing area is split into a "preamble" containing clef, 715 // key and time signature, and the "item's area" containing the 716 // actual items (notes, bars, rests, etc.) 717 // x_pos is responsible for scrolling. an item with item->x==x_pos 718 // will be drawn exactly at the left beginning of the item's area 719 // x_left could also be called "preamble's width". it defines 720 // where the item's area begins 721 // when multiple note systems are drawn into one window, the 722 // preamble's length is the same for each system 723 int x_pos; 724 int x_left; 725 726 int y_pos; 727 728 //for mouse-scrolling 729 float x_scroll_speed; 730 float x_scroll_pos; 731 float y_scroll_speed; 732 float y_scroll_pos; 733 734 const MusECore::Part* selected_part; 735 int selected_part_index; 736 737 int last_len; 738 int new_len; //when zero or negative, last_len is used 739 740 Qt::KeyboardModifiers keystate; 741 QPoint mouse_down_pos; 742 bool mouse_down; 743 enum operation_t 744 { 745 NO_OP=0, 746 BEGIN=1, 747 LENGTH=2, 748 PITCH=3 749 }; 750 operation_t mouse_operation; 751 operation_t mouse_x_drag_operation; 752 bool mouse_erases_notes; 753 bool mouse_inserts_notes; 754 755 bool inserting; 756 bool dragging; 757 bool drag_cursor_changed; 758 const MusECore::Part* dragged_event_part; 759 int dragged_event_part_index; 760 MusECore::Event dragged_event; 761 MusECore::Event original_dragged_event; 762 const MusECore::Event* clicked_event_ptr; 763 764 int old_pitch; 765 unsigned old_dest_tick; 766 int old_len; 767 768 bool have_lasso; 769 QPoint lasso_start; 770 QRect lasso; 771 772 bool undo_started; 773 bool temp_undo; 774 775 bool srec; 776 bool held_notes[128]; 777 778 coloring_mode_t coloring_mode; 779 bool preamble_contains_keysig; 780 bool preamble_contains_timesig; 781 782 783 //menu stuff 784 QAction* staffmode_treble_action; 785 QAction* staffmode_bass_action; 786 QAction* staffmode_both_action; 787 QAction* remove_staff_action; 788 789 QMenu* staff_menu; 790 list<staff_t>::iterator current_staff; 791 bool dragging_staff; 792 793 QCursor active_tool_cursor; 794 int active_tool; 795 796 private slots: 797 void staffmode_treble_slot(); 798 void staffmode_bass_slot(); 799 void staffmode_both_slot(); 800 void remove_staff_slot(); 801 802 void play_changed(bool); 803 804 void deselect_all(); 805 void midi_note(int pitch, int velo); 806 807 void add_new_parts(const std::map< const MusECore::Part*, std::set<const MusECore::Part*> >&); 808 809 public slots: 810 void x_scroll_event(int); 811 void y_scroll_event(int); 812 void song_changed(MusECore::SongChangedStruct_t); 813 void fully_recalculate(); 814 void goto_tick(int,bool); 815 void pos_changed(int i, unsigned u, bool b); 816 void heartbeat_timer_event(); 817 void config_changed(); 818 819 void set_tool(int); 820 void set_quant(int); 821 void menu_command(int); 822 void preamble_keysig_slot(bool); 823 void preamble_timesig_slot(bool); 824 void set_pixels_per_whole(int); 825 826 void set_velo(int); 827 void set_velo_off(int); 828 829 void set_steprec(bool); 830 831 void update_parts(); //re-populates the set<MusECore::Part*>s from the set<int>s 832 signals: 833 void xscroll_changed(int); 834 void yscroll_changed(int); 835 void viewport_width_changed(int); 836 void canvas_width_changed(int); 837 void preamble_width_changed(int); 838 void viewport_height_changed(int); 839 void canvas_height_changed(int); 840 void pixels_per_whole_changed(int); 841 void pos_add_changed(); 842 843 protected: 844 virtual void draw(QPainter& p, const QRect& rect, const QRegion& = QRegion()); 845 ScoreEdit* parent; 846 847 virtual void mousePressEvent (QMouseEvent* event); 848 virtual void mouseMoveEvent (QMouseEvent* event); 849 virtual void mouseReleaseEvent (QMouseEvent* event); 850 virtual void resizeEvent(QResizeEvent*); 851 852 public: 853 ScoreCanvas(ScoreEdit*, QWidget*); 854 ~ScoreCanvas(); 855 856 void add_staves(MusECore::PartList* pl, bool all_in_one); push_back_staff(staff_t & staff)857 void push_back_staff(staff_t& staff) { staves.push_back(staff); } //FINDMICH dirty. very dirty. 858 859 int canvas_width(); 860 int canvas_height(); 861 int viewport_width(); 862 int viewport_height(); 863 quant_power2()864 int quant_power2() { return _quant_power2; } quant_len()865 int quant_len() { return (1<<_quant_power2); } quant_ticks()866 int quant_ticks() { return TICKS_PER_WHOLE / (1<<_quant_power2); } pixels_per_whole()867 int pixels_per_whole() { return _pixels_per_whole; } note_x_indent()868 int note_x_indent() { return pixels_per_whole()/quant_len()/2; } 869 get_last_len()870 int get_last_len() {return last_len;} set_last_len(int l)871 void set_last_len(int l) {last_len=l;} 872 get_selected_part()873 const MusECore::Part* get_selected_part() const {return selected_part;} set_selected_part(const MusECore::Part * p)874 void set_selected_part(const MusECore::Part* p) {selected_part=p; if (selected_part) selected_part_index=selected_part->sn();} get_dragged_event_part()875 const MusECore::Part* get_dragged_event_part() const {return dragged_event_part;} set_dragged_event_part(const MusECore::Part * p)876 void set_dragged_event_part(const MusECore::Part* p) {dragged_event_part=p; if (dragged_event_part) dragged_event_part_index=dragged_event_part->sn();} 877 878 set<const MusECore::Part*> get_all_parts(); 879 880 void write_staves(int level, MusECore::Xml& xml) const; 881 882 timesig_t timesig_at_tick(int t); 883 MusECore::KeyEvent key_at_tick(int t); 884 int tick_to_x(int t); 885 int delta_tick_to_delta_x(int t); 886 int x_to_tick(int x); 887 int calc_posadd(int t); 888 889 890 bool itemsAreSelected() const; 891 // Appends given tag list with item objects according to options. Avoids duplicate events or clone events. 892 // Special: We 'abuse' a controller event's length, normally 0, to indicate visual item length. 893 void tagItems(MusECore::TagEventList* tag_list, const MusECore::EventTagOptionsStruct& options) const; 894 }; 895 896 int calc_measure_len(const list<int>& nums, int denom); 897 vector<int> create_emphasize_list(const list<int>& nums, int denom); 898 vector<int> create_emphasize_list(int num, int denom); 899 900 } // namespace MusEGui 901 902 #endif 903 904