Preview Implementation

Discussion forum for C++ and script developers who are using the QCAD development platform or who are looking to contribute to QCAD (translations, documentation, etc).

Moderator: andrew

Forum rules

Always indicate your operating system and QCAD version.

Attach drawing files, scripts and screenshots.

Post one question per topic.

Post Reply
333onlyhalfevil
Junior Member
Posts: 24
Joined: Fri Apr 28, 2023 12:39 pm

Preview Implementation

Post by 333onlyhalfevil » Mon Jul 03, 2023 2:42 pm

Hello:

I'm currently working on a script that draws some things for me. I have it basically working, for the most part, however, the preview portion of it doesn't work at all. I see nothing until I click the last click and the script inputs my drawing elements and terminates. How should I go about getting the preview to work?

Inside of the coordinateEvent function, I have the standard

Code: Select all

if (preview) {this.updatePreview();}
I also tried making my own custom myScript.prototype.updatePreview() {} function but it never gets called (note that I have a qDebug("updatePreview() was called.") to alert me that it was called and it never fires). So, I'm assuming that the updatePreview() function that is being called is the EAction one. Is that a problem? Is it standard to use the EAction updatePreview() function or to override it and make your own?

I also tried making my own custom myScript.prototype.getAuxPreview() {} function as well but it never gets called either. Maybe that's why I see no preview at all because the getAuxPreview in EAction is just empty brackets?

I also noticed, looking through the source code, that certain Draw scripts implement their own getAuxPreview() functions while others do not. The scripts that do implement their own getAuxPreview() seem to only be pushing RLine to the array of shapes. How does the program know to take the RLine and convert it into a circle, or an arc, or whatever? Shouldn't you have to add a circle or an arc or whatever to a custom implementation of getAuxPreview()?

I think that's it. The basic question with this thread is: how do I get previews to work within my script?

Thanks in advance for your time/replies.

User avatar
andrew
Site Admin
Posts: 9063
Joined: Fri Mar 30, 2007 6:07 am

Re: Preview Implementation

Post by andrew » Mon Jul 03, 2023 2:49 pm

Does your script implement getOperation? If so, the preview should simply work if updatePreview is called in preview mode (and applyOperation when the final user input is known).

updatePreview and applyOperation both call getOperation.

CVH
Premier Member
Posts: 3480
Joined: Wed Sep 27, 2017 4:17 pm

Re: Preview Implementation

Post by CVH » Tue Jul 04, 2023 5:57 am

333onlyhalfevil wrote:
Mon Jul 03, 2023 2:42 pm
I also noticed, looking through the source code, that certain Draw scripts implement their own getAuxPreview() functions while others do not.
...
How does the program know to take the RLine and convert it into a circle, or an arc, or whatever?
getAuxPreview() is intended to preview extra auxiliary shapes.
These are displayed dashed in a kind of violet color (#7976c5) in standard installations.
A good example is the spline tool, activate SP and start indicating control points.
The auxiliary line shapes connect the control points ... AKA the spline polygon in degree 1.

Usually only auxiliary construction lines are required but one can include any RShape in the return array.
Remark that these are not cast as entities on the drawing with getOperation(false).
Only REntities ("circle, or an arc, or whatever") included in the operation created by getOperation() are actually cast to the document.

updatePreview() is called on regular base when a tool is running to update the display depending the user actions.
It automatically calls getOperation(true), getAuxPreview() and getHighlightedEntities().
It handles fault conditions and repaint views.
I see no reason to override that.

Regards,
CVH
Last edited by CVH on Tue Jul 04, 2023 7:06 pm, edited 1 time in total.

333onlyhalfevil
Junior Member
Posts: 24
Joined: Fri Apr 28, 2023 12:39 pm

Re: Preview Implementation

Post by 333onlyhalfevil » Tue Jul 04, 2023 4:50 pm

It appears that updatePreview() within the if (preview) {} block never gets called because preview is always false. I'm still trying to figure out what I'm doing wrong. To figure it out (and make it as simple as possible) I tried to edit the ExThreePoints.js code to include a preview of the three points and am having the same problem. Here is the code:

Code: Select all

//! [include]
include("scripts/EAction.js");
//! [include]
 
//! [constructor]
/**
 * \class ExThreePoints
 * \ingroup ecma_misc_examples_draw
 */
function ExThreePointsWithPreview(guiAction) {
    EAction.call(this, guiAction);
    this.point1 = undefined;
}
//! [constructor]
 
//! [State]
ExThreePointsWithPreview.State = {
    SettingPosition : 0
};
//! [State]
 
//! [inheritance]
ExThreePointsWithPreview.prototype = new EAction();
//! [inheritance]
 
//! [setState]
ExThreePointsWithPreview.prototype.setState = function(state) {
    EAction.prototype.setState.call(this, state);
 
    // set crosshair cursor for choosing the coordinate:
    this.setCrosshairCursor();
 
    // we are interested in coordinates the user clicks 
    // (as opposed to entities):
    this.getDocumentInterface().setClickMode(RAction.PickCoordinate);
 
    // status bar user information:
    var appWin = RMainWindowQt.getMainWindow();
    var tr = qsTr("Position");
    this.setLeftMouseTip(tr);
    this.setCommandPrompt(tr);
    this.setRightMouseTip(EAction.trCancel);
 
    // show the snap toolbar, so the user can choose an alternative 
    // snap tool if desired:
    EAction.showSnapTools();
};
//! [setState]
 
//! [beginEvent]
ExThreePointsWithPreview.prototype.beginEvent = function() {
    EAction.prototype.beginEvent.call(this);
 
    this.setState(ExThreePointsWithPreview.State.SettingPosition);
};
//! [beginEvent]
 
//! [coordinateEvent]
ExThreePointsWithPreview.prototype.coordinateEvent = function(event, preview) {
    // the exact position that was clicked or 
    // entered by the user:
    this.point1 = event.getModelPosition();
    if (preview) {
        qDebug("updatePreview if statement was fired");
        this.updatePreview();
    }
 
    // move relative zero point to that position:
    this.getDocumentInterface().setRelativeZero(this.point1);
 
    this.applyOperation();
};
//! [coordinateEvent]
 
ExThreePointsWithPreview.prototype.applyOperation = function (preview) {
    if (!isVector(this.point1)) {
        return undefined;
    }
    // create an operation for adding objects:
    var op = new RAddObjectsOperation();
    for (var i=0; i<3; i++) {
        // create a point entity and add it to the operation:
        var point = new RPointEntity(
            this.getDocument(),
            new RPointData(new RVector(this.point1.x + i, this.point1.y))
        );
        op.addObject(point);
    }
 
    // apply the operation to the current drawing:
    this.getDocumentInterface().applyOperation(op);
    this.terminate();
};

ExThreePointsWithPreview.prototype.getOperation = function(preview) {
    var doc = this.getDocument();

    var op = new RAddObjectsOperation();
    for (var i=0; i<3; i++) {
        // create a point entity and add it to the operation:
        var point = new RPointEntity(
            doc,
            new RPointData(new RVector(this.point1.x + i, this.point1.y))
        );
        op.addObject(point);
    }
    return op;
};

//! [init]
ExThreePointsWithPreview.init = function(basePath) {
    var action = new RGuiAction(qsTr("Three Points With Preview"), RMainWindowQt.getMainWindow());
    action.setRequiresDocument(true);
    action.setScriptFile(basePath + "/ExThreePointsWithPreview.js");
    //action.setIcon(basePath + "/ExThreePointsWithPreview.svg");
    action.setStatusTip(qsTr("Draw three points"));
    action.setDefaultShortcut(new QKeySequence("p,3"));
    action.setDefaultCommands(["point3"]);
    action.setGroupSortOrder(73100);
    action.setSortOrder(400);
    action.setWidgetNames(["MiscMenu"]);
};
//! [init]
Basically I just copy/pasted the ExThreePoints.js code from the first tutorial of the developer documentation and then tried to add in a preview that shows the three points before the user clicks to insert them similarly to how I'm doing it with my script.

What's wrong? Why is preview always false and updatePreview() never gets fired? What do you think?

@CVH: Thank you for the getAuxPreview() clarification.

User avatar
andrew
Site Admin
Posts: 9063
Joined: Fri Mar 30, 2007 6:07 am

Re: Preview Implementation

Post by andrew » Tue Jul 04, 2023 5:01 pm

coordinateEvent does not have a preview parameter.

You can either implement coordinateEvent and coordinateEventPreview respectively or (easier) change "coordinateEvent" to the higher level "pickCoordinate" which has parameters event and preview:

Code: Select all

ExThreePointsWithPreview.prototype.pickCoordinate = function(event, preview) {
    // same content as previously "coordinateEvent"
    ...
};

333onlyhalfevil
Junior Member
Posts: 24
Joined: Fri Apr 28, 2023 12:39 pm

Re: Preview Implementation

Post by 333onlyhalfevil » Thu Jul 06, 2023 2:08 pm

Ah. It seems to be working as expected with that change. Thank you very much for your time/help.

Post Reply

Return to “QCAD Programming, Script Programming and Contributing”