Exemple #1
0
void GraphicsWindow::MouseRightUp(double x, double y) {
    SS.extraLine.draw = false;
    InvalidateGraphics();

    // Don't show a context menu if the user is right-clicking the toolbar,
    // or if they are finishing a pan.
    if(ToolbarMouseMoved((int)x, (int)y)) return;
    if(orig.startedMoving) return;

    if(context.active) return;

    if(pending.operation == DRAGGING_NEW_LINE_POINT ||
       pending.operation == DRAGGING_NEW_CUBIC_POINT)
    {
        // Special case; use a right click to stop drawing lines, since
        // a left click would draw another one. This is quicker and more
        // intuitive than hitting escape. Likewise for new cubic segments.
        ClearPending();
        return;
    }

    context.active = true;

    if(!hover.IsEmpty()) {
        MakeSelected(&hover);
        SS.ScheduleShowTW();
    }
    GroupSelection();

    bool itemsSelected = (gs.n > 0 || gs.constraints > 0);

    if(itemsSelected) {
        if(gs.stylables > 0) {
            ContextMenuListStyles();
            AddContextMenuItem("Assign to Style", CONTEXT_SUBMENU);
        }
        if(gs.n + gs.constraints == 1) {
            AddContextMenuItem("Group Info", CMNU_GROUP_INFO);
        }
        if(gs.n + gs.constraints == 1 && gs.stylables == 1) {
            AddContextMenuItem("Style Info", CMNU_STYLE_INFO);
        }
        if(gs.withEndpoints > 0) {
            AddContextMenuItem("Select Edge Chain", CMNU_SELECT_CHAIN);
        }
        if(gs.constraints == 1 && gs.n == 0) {
            Constraint *c = SK.GetConstraint(gs.constraint[0]);
            if(c->HasLabel() && c->type != Constraint::COMMENT) {
                AddContextMenuItem("Toggle Reference Dimension",
                    CMNU_REFERENCE_DIM);
            }
            if(c->type == Constraint::ANGLE ||
               c->type == Constraint::EQUAL_ANGLE)
            {
                AddContextMenuItem("Other Supplementary Angle",
                    CMNU_OTHER_ANGLE);
            }
        }
        if(gs.comments > 0 || gs.points > 0) {
            AddContextMenuItem("Snap to Grid", CMNU_SNAP_TO_GRID);
        }

        if(gs.points == 1) {
            Entity *p = SK.GetEntity(gs.point[0]);
            Constraint *c;
            IdList<Constraint,hConstraint> *lc = &(SK.constraint);
            for(c = lc->First(); c; c = lc->NextAfter(c)) {
                if(c->type != Constraint::POINTS_COINCIDENT) continue;
                if(c->ptA.v == p->h.v || c->ptB.v == p->h.v) {
                    break;
                }
            }
            if(c) {
                AddContextMenuItem("Delete Point-Coincident Constraint",
                                   CMNU_DEL_COINCIDENT);
            }
        }
        AddContextMenuItem(NULL, CONTEXT_SEPARATOR);
        if(LockedInWorkplane()) {
            AddContextMenuItem("Cut",  CMNU_CUT_SEL);
            AddContextMenuItem("Copy", CMNU_COPY_SEL);
        }
    }

    if(SS.clipboard.r.n > 0 && LockedInWorkplane()) {
        AddContextMenuItem("Paste", CMNU_PASTE_SEL);
    }

    if(itemsSelected) {
        AddContextMenuItem("Delete", CMNU_DELETE_SEL);
        AddContextMenuItem(NULL, CONTEXT_SEPARATOR);
        AddContextMenuItem("Unselect All", CMNU_UNSELECT_ALL);
    }
    // If only one item is selected, then it must be the one that we just
    // selected from the hovered item; in which case unselect all and hovered
    // are equivalent.
    if(!hover.IsEmpty() && selection.n > 1) {
        AddContextMenuItem("Unselect Hovered", CMNU_UNSELECT_HOVERED);
    }

    int ret = ShowContextMenu();
    switch(ret) {
        case CMNU_UNSELECT_ALL:
            MenuEdit(MNU_UNSELECT_ALL);
            break;

        case CMNU_UNSELECT_HOVERED:
            if(!hover.IsEmpty()) {
                MakeUnselected(&hover, true);
            }
            break;

        case CMNU_SELECT_CHAIN:
            MenuEdit(MNU_SELECT_CHAIN);
            break;

        case CMNU_CUT_SEL:
            MenuClipboard(MNU_CUT);
            break;

        case CMNU_COPY_SEL:
            MenuClipboard(MNU_COPY);
            break;

        case CMNU_PASTE_SEL:
            MenuClipboard(MNU_PASTE);
            break;

        case CMNU_DELETE_SEL:
            MenuClipboard(MNU_DELETE);
            break;

        case CMNU_REFERENCE_DIM:
            Constraint::MenuConstrain(MNU_REFERENCE);
            break;

        case CMNU_OTHER_ANGLE:
            Constraint::MenuConstrain(MNU_OTHER_ANGLE);
            break;

        case CMNU_DEL_COINCIDENT: {
            SS.UndoRemember();
            if(!gs.point[0].v) break;
            Entity *p = SK.GetEntity(gs.point[0]);
            if(!p->IsPoint()) break;

            SK.constraint.ClearTags();
            Constraint *c;
            for(c = SK.constraint.First(); c; c = SK.constraint.NextAfter(c)) {
                if(c->type != Constraint::POINTS_COINCIDENT) continue;
                if(c->ptA.v == p->h.v || c->ptB.v == p->h.v) {
                    c->tag = 1;
                }
            }
            SK.constraint.RemoveTagged();
            ClearSelection();
            break;
        }

        case CMNU_SNAP_TO_GRID:
            MenuEdit(MNU_SNAP_TO_GRID);
            break;

        case CMNU_GROUP_INFO: {
            hGroup hg;
            if(gs.entities == 1) {
                hg = SK.GetEntity(gs.entity[0])->group;
            } else if(gs.points == 1) {
                hg = SK.GetEntity(gs.point[0])->group;
            } else if(gs.constraints == 1) {
                hg = SK.GetConstraint(gs.constraint[0])->group;
            } else {
                break;
            }
            ClearSelection();

            SS.TW.GoToScreen(TextWindow::SCREEN_GROUP_INFO);
            SS.TW.shown.group = hg;
            SS.ScheduleShowTW();
            break;
        }

        case CMNU_STYLE_INFO: {
            hStyle hs;
            if(gs.entities == 1) {
                hs = Style::ForEntity(gs.entity[0]);
            } else if(gs.points == 1) {
                hs = Style::ForEntity(gs.point[0]);
            } else if(gs.constraints == 1) {
                hs = SK.GetConstraint(gs.constraint[0])->disp.style;
                if(!hs.v) hs.v = Style::CONSTRAINT;
            } else {
                break;
            }
            ClearSelection();

            SS.TW.GoToScreen(TextWindow::SCREEN_STYLE_INFO);
            SS.TW.shown.style = hs;
            SS.ScheduleShowTW();
            break;
        }

        case CMNU_NEW_CUSTOM_STYLE: {
            uint32_t v = Style::CreateCustomStyle();
            Style::AssignSelectionToStyle(v);
            break;
        }

        case CMNU_NO_STYLE:
            Style::AssignSelectionToStyle(0);
            break;

        default:
            if(ret >= CMNU_FIRST_STYLE) {
                Style::AssignSelectionToStyle(ret - CMNU_FIRST_STYLE);
            } else {
                // otherwise it was cancelled, so do nothing
                contextMenuCancelTime = GetMilliseconds();
            }
            break;
    }

    context.active = false;
    SS.ScheduleShowTW();
}