//--------------------------------------------------------------------------------------- void TopLevelCaretPositioner::layout_caret(Caret* pCaret, DocCursor* pCursor) { m_pCursor = pCursor; m_state = m_pCursor->get_state(); ImoId id = m_state.get_parent_level_id(); GmoBox* pBox = m_pGModel->get_box_for_imo(id); URect pos; if (pBox) pos = pBox->get_bounds(); else { //at end of document pBox = get_box_for_last_element(); if (pBox) { pos.set_top_left( UPoint(pBox->get_left(), pBox->get_bottom()) ); pos.set_height(1000.0f); pos.set_width(1000.0f); } else { //empty document pos = URect(0.0f, 0.0f, 1000.0f, 1000.0f); } } pCaret->set_type(Caret::k_top_level); pCaret->set_top_level_box(pos); pCaret->set_position( pos.get_top_left() ); pCaret->set_size( USize(pos.get_width(), pos.get_height()) ); }
//--------------------------------------------------------------------------------------- UPoint ClefEngraver::get_drag_offset() { //return center of clef URect bounds = m_pClefShape->get_bounds(); return UPoint(bounds.get_width() / 2.0, bounds.get_height() / 2.0 ); }
//--------------------------------------------------------------------------------------- int GmoCompositeShape::add(GmoShape* pShape) { m_components.push_back(pShape); if (m_components.size() == 1) { //copy bounds m_origin = pShape->get_origin(); m_size = pShape->get_size(); } else { //TODO: Note from LenMus: // lmCompositeShape: the selection rectangle should not be the boundling rectangle // but each rectangle of each component shape. This will save the need to define // specific shapes just to override selection rectangle. i.i. metronome marks //compute new selection rectangle by union of individual selection rectangles URect bbox = get_bounds(); bbox.Union(pShape->get_bounds()); m_origin = bbox.get_top_left(); m_size.width = bbox.get_width(); m_size.height = bbox.get_height(); } //return index to added shape return (int)m_components.size() - 1; }
//--------------------------------------------------------------------------------------- void ScoreCaretPositioner::caret_on_pointed_object(Caret* pCaret) { URect bounds = get_bounds_for_imo( m_spState->id(), m_spState->staff() ); bounds.x -= tenths_to_logical(1); set_caret_y_pos_and_height(&bounds, m_spState->id(), m_spState->staff()); pCaret->set_type(Caret::k_line); pCaret->set_position( bounds.get_top_left() ); pCaret->set_size( USize(bounds.get_width(), bounds.get_height()) ); set_caret_timecode(pCaret); }
//--------------------------------------------------------------------------------------- void GmoCompositeShape::recompute_bounds() { URect bbox; std::list<GmoShape*>::iterator it; for (it = m_components.begin(); it != m_components.end(); ++it) bbox.Union((*it)->get_bounds()); m_origin = bbox.get_top_left(); m_size.width = bbox.get_width(); m_size.height = bbox.get_height(); }
//--------------------------------------------------------------------------------------- void ScoreCaretPositioner::caret_on_empty_timepos(Caret* pCaret) { //cursor is between two staffobjs, on a free time position. //Place caret between both staffobjs. Interpolate position based on cursor time //get info for current ref. object ImoId refId = m_pScoreCursor->staffobj_id_internal(); int refStaff = m_pScoreCursor->ref_obj_staff(); //get info for prev object SpElementCursorState spState = m_pScoreCursor->get_state(); m_pScoreCursor->move_prev(); ImoId prevId = m_pScoreCursor->id(); int prevStaff = m_pScoreCursor->staff(); TimeUnits prevTime = m_pScoreCursor->time(); m_pScoreCursor->restore_state(spState); URect boundsPrev = get_bounds_for_imo(prevId, prevStaff); URect bounds = get_bounds_for_imo(refId, refStaff); #if 1 //interpolate position //TODO: linear interpolation is wrong. This has to be changed to use time-grid TimeUnits time1 = prevTime; TimeUnits time2 = m_spState->time(); TimeUnits time3 = m_spState->ref_obj_time(); LUnits xIncr = bounds.x - boundsPrev.x; // Ax = x3-x1 bounds.x = boundsPrev.x + (xIncr * float((time2 - time1) / (time3 - time1)) ); #else //determine x position based on TimeGridTable TimeUnits time = m_pScoreCursor->time(); int iSystem = m_pGModel->get_system_for(m_pScore->get_id(), m_pScoreCursor->instrument(), m_pScoreCursor->measure(), time); m_pBoxSystem = m_pGModel->get_system_box(iSystem); TimeGridTable* pTimeGrid = m_pBoxSystem->get_time_grid_table(); bounds.x = pTimeGrid->get_x_for_time(time); #endif //set caret set_caret_y_pos_and_height(&bounds, prevId, prevStaff); pCaret->set_type(Caret::k_line); pCaret->set_position( bounds.get_top_left() ); pCaret->set_size( USize(bounds.get_width(), bounds.get_height()) ); set_caret_timecode(pCaret); }
//--------------------------------------------------------------------------------------- void ArticulationEngraver::center_on_parent() { if (!m_pParentShape) return; LUnits uCenterPos; if (m_pParentShape->is_shape_note()) { //it is a note. Center articulation on notehead shape GmoShapeNote* pNote = dynamic_cast<GmoShapeNote*>(m_pParentShape); uCenterPos = pNote->get_notehead_left() + pNote->get_notehead_width() / 2.0f; } else { //it is not a note (normally it would be a rest). //Center articulation on parent shape uCenterPos = m_pParentShape->get_left() + m_pParentShape->get_width() / 2.0f; } LUnits xShift = uCenterPos - (m_pArticulationShape->get_left() + m_pArticulationShape->get_width() / 2.0f); if (xShift != 0.0f) { USize shift(xShift, 0.0f); m_pArticulationShape->shift_origin(shift); } //ensure that articulation does not collides with parent shape URect overlap = m_pParentShape->get_bounds(); overlap.intersection( m_pArticulationShape->get_bounds() ); LUnits yShift = overlap.get_height(); if (yShift != 0.0f) { yShift += tenths_to_logical(5.0f); yShift = m_fAbove ? - yShift : yShift; USize shift(0.0f, yShift); m_pArticulationShape->shift_origin(shift); } }
//--------------------------------------------------------------------------------------- void ScoreCaretPositioner::caret_at_end_of_staff(Caret* pCaret) { //cursor is at end of a staff or end of score. Score is not empty. //No current staffobj but a previous one must exist. //Place cursor 0.8 lines (8 tenths) at the right of last staffobj //get info for prev object SpElementCursorState spState = m_pScoreCursor->get_state(); m_pScoreCursor->move_prev(); ImoId id = m_pScoreCursor->id(); int staff = m_pScoreCursor->staff(); m_pScoreCursor->restore_state(spState); URect bounds = get_bounds_for_imo(id, staff); bounds.x += tenths_to_logical(8); set_caret_y_pos_and_height(&bounds, id, staff); pCaret->set_type(Caret::k_line); pCaret->set_position( UPoint(bounds.right(), bounds.top()) ); pCaret->set_size( USize(bounds.get_width(), bounds.get_height()) ); set_caret_timecode(pCaret); }
//--------------------------------------------------------------------------------------- void ScoreCaretPositioner::caret_at_start_of_score(Caret* pCaret) { //Cursor is at end of score but score is empty. //Place cursor at start of first system //get shape for first system DocCursorState state = m_pDocCursor->get_state(); ImoId scoreId = state.get_parent_level_id(); //GmoShapeStaff* pShape = m_pGModel->get_shape_for_first_staff_in_first_system(scoreId); GmoBoxScorePage* pBSP = static_cast<GmoBoxScorePage*>( m_pGModel->get_box_for_imo(scoreId) ); m_pBoxSystem = dynamic_cast<GmoBoxSystem*>(pBSP->get_child_box(0)); GmoShapeStaff* pShape = (m_pBoxSystem ? m_pBoxSystem->get_staff_shape(0) : NULL); URect bounds; if (pShape) { bounds = pShape->get_bounds(); bounds.x += m_pMeter->tenths_to_logical(20, 0, 0); } else { //score totally empty. No staff displayed! Position cursors at start of page //TODO bounds = URect(0.0f, 0.0f, 20.0f, 700.0f); // uPos.y = pBPage->GetYTop(); // uPos.x = pBPage->GetXLeft() + pScore->tenths_to_logical(20); } set_caret_y_pos_and_height(&bounds, k_no_imoid, 0); pCaret->set_type(Caret::k_line); pCaret->set_position( bounds.get_top_left() ); pCaret->set_size( USize(bounds.get_width(), bounds.get_height()) ); set_caret_timecode(pCaret); }
//--------------------------------------------------------------------------------------- UPoint BarlineEngraver::get_drag_offset() { //return left side, vertical center URect bounds = m_pBarlineShape->get_bounds(); return UPoint(0.0, bounds.get_height() / 2.0); }