Jump to content

Ron

uniGUI Subscriber
  • Posts

    374
  • Joined

  • Last visited

  • Days Won

    31

Ron last won the day on July 29 2023

Ron had the most liked content!

Profile Information

  • Gender
    Male
  • Location
    Norway

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

Ron's Achievements

Advanced Member

Advanced Member (4/4)

111

Reputation

  1. You use a JS function to call the server, to set some session data? Why not do that directly in the code? Anyway, attached is your example, with the JS file and mainForm code modified to use the ajaxRequest function. test javascript.zip
  2. Attached is an example, in MainForm.script you may have: function myFunction() { var num = 2 + 3; ajaxRequest(MainForm.form, ['callback'], { res: num} ); } And in MainForm: procedure TMainForm.UniButton1Click(Sender: TObject); begin uniSession.addJS('myFunction()'); end; procedure TMainForm.UniFormAjaxEvent(Sender: TComponent; EventName: string; Params: TUniStrings); begin if sameText(eventname,'callback') then begin showMessage('Result: '+Params.Values['res']); end; end; ajaxtest.zip
  3. Ron

    Intercept URI

    I see, then you could probably use a simple proxy server with only url rewriting capabilities, like EZProxy: https://help.oclc.org/Library_Management/EZproxy/Get_started/About_URL_rewriting Edit: I did not notice that EZProxy costs money, but there are probably other free proxy servers out there, or you could even build your own using Indy components. It is basically two http servers and two clients, feeding data from each server to each client in a cross pattern, being on different ports or IPs.* And then just add a url rewrite function, to convert the last part of the url to a parameter format.
  4. If you have both the start and stop commands in the batch file, as mentioned, it will wait for the service to stop, before it starts it. In other words, the "net stop" command is "blocking", and will not return until the service stops, and then the next batch command (net start) is executed.. If you use the hyperserver, it is of course the webserver service that runs the ISAPI modules that has to be stopped and started, aka restarted. I am not sure, however, if this will work from an Unigui app, when I think about it, as you may need administrator privileges. In that case, you may have to create a desktop app, which you run as admin at startup, and communicates with the Ungui app, to run the batch file.
  5. Ron

    Intercept URI

    I guess you can solve this using hyperserver and aliases in the web server setup, running two separate instances of the app, one in each directory: <Directory "C:/myapp1> Options FollowSymLinks ExecCGI AllowOverride None Order allow,deny Allow from all DirectoryIndex myapp.dll?q=param1 </Directory> Alias /option1 "C:/myapp1" <Directory "C:/myapp2> Options FollowSymLinks ExecCGI AllowOverride None Order allow,deny Allow from all DirectoryIndex myapp.dll?q=param2 </Directory> Alias /option2 "C:/myapp2" So the URL would be https//mydomain.com/option1 or 2, as the dll is specified as the folder index. You may skip using a parameter, by just checking startup directory to determine which alias was used. Using a URL Rewrite function in the web server setup is another option, to translate part of a URL to a parameter.
  6. You could have a batch file, e.g. "restart.bat", which restarts the service: net stop uniguiService net start uniguiService The batch file may be executed in a click event handler, or you could use an incoming email or an SMS from a specific phone number, with a code word in the text, triggering a PHP file on a webserver. Using SMS, you specify which file to run at incoming messages to the the virtual SMS number, at the provider. The following PHP extracts message data from the HTTP Post call from the provider and runs the batch file, this assumes you have a running webserver set up with PHP to handle incoming calls: <?php $Sid = $_POST['MessageSid']; $From = $_POST['From']; $To = $_POST['To']; $Body = $_POST['Body']; $From = substr($From,3,8); if(($From==='12345678')&&(strtolower ($Body)==='restart')){ $output = shell_exec('c:\restart.bat'); $message = "Web Server Restart: " . $output; $response = '<?xml version="1.0" encoding="UTF-8"?><Response><Message>' . $message . '</Message></Response>'; echo $response; } ?>
  7. If you wake up one day, and suddenly conclude that coding is the work of the devil, you may want to delete all of your contributions. There may be a million more reasons to turn away from coding, so who knows the motivation - or lack thereof. Some may be addicted to coding, and would do better staying away from it. Especially if it ruins their health. Or what if your IQ doubles overnight, and you are suddenly ashamed of your old code, which now looks terrible.
  8. Make sure your image file reference is correct, like <img src="files/myimage.jpg"> if your image is located in /files. You can also use the complete URL, like https://mydomain.com/files/myimage.jpg if you run it on a server, or localhost/files/myimage.jpg if running locally. Not sure if you have to use UniHTMLFrame for the local references to work, but if you are only serving local files, that should do it. If you run the app on a non-standard (non-80) port, then of course the port has to be specified if not using a local reference.
  9. It is possible to access local files (at the client), but not directly due to security reasons. Only indirectly, through a server installed on the client computer - it could be a TCP server, FTP or HTTP. In such a case, one needs to create and install the server, and make a custom directory listing routine. Using HTTP, you can use CORS calls, that is call a local resource from the client, like a webserver on port 80 on localhost/127.0.0.1, using Javascript. You can also run the call from the server, but then you have to go through the firewall at the client network.
  10. I guess you can store the script in a text file, load it into a stringlist as the application starts, and then run the script using AddJS when you need it, like in the event handler of a button. In mainForm.Create: sl:=TStringList.Create; sl.loadFromFile('myjs.js'); In onClick event handler: AddJS(sl.text);
  11. Last update, with one more class to internalize variables, for cleaner code. It seems like p5 works pretty well with Unigui. Movable polygons with movable vertices. Edit: Using literal object for polygons, for a bit more efficient code. Edit 2: Added function for deleting selected polygon. Edit 3: Added function for inserting and deleting vertices. JS code: <div id='cnvCont'></div> <script type="text/javascript"> new p5(); let bgImg; let imgLoaded = false; const px = 8; const minimumVx = 3; const vxFillCol = 'white'; const selVxCol = 'red'; const vxCol = 'rgb(0,0,0)'; const hoverPolyCol = 'green'; const drawPolyCol = 'red'; const polyCol = 'blue'; const selPolyCol = 'black'; const polyStrokeW = 2; let Vertex = function(ix, iy) { this.x = ix; this.y = iy; this.drawVx = function(selected) { if (selected) { stroke(selVxCol); strokeWeight(2); } else { stroke(vxCol); strokeWeight(1); } fill(vxFillCol); rect(this.x-round(px/2), this.y-round(px/2), px); }; this.move = function(dX, dY) { this.x += dX; this.y += dY; }; this.hit = function(mX, mY) { return (collidePointRect(mX, mY, this.x-px, this.y-px, px*2, px*2)); }; }; class Polygon { constructor(x, y) { this.isSelected = false; this.closed = false; this.hover = false; this.moveLock = false; this.vxhover = false; this.vxMoveLock = false; this.vxi = -1; this.vx = []; this.vx.push(new Vertex(x,y)); } addVx(x,y) { this.vx.push(new Vertex(x,y)); } doClose() { this.closed = true; this.isSelected = true; } move(dX, dY) { this.vx.forEach( v => { v.x += dX; v.y += dY; }); } drawPoly(len, mX, mY) { if (this.hover) { cursor(MOVE); stroke(hoverPolyCol); } else if (!this.closed) stroke(drawPolyCol); else stroke(polyCol); if (this.isSelected) stroke(selPolyCol); strokeWeight(polyStrokeW); noFill(); if (len>1) this.vx.slice(0, len-1).forEach( (vx, i) => { line(vx.x, vx.y, this.vx[i+1].x, this.vx[i+1].y); }); let lastVx = this.vx[len-1], startVx = this.vx[0]; (!this.closed) ? line(lastVx.x, lastVx.y, mX, mY) : line(lastVx.x, lastVx.y, startVx.x, startVx.y); } displayVx(len, mX, mY) { this.vxhover = false; this.vx.forEach((v, i) => { v.drawVx(i===this.vxi); if (!this.vxMoveLock) if (v.hit(mX, mY)) { this.vxi = i; this.vxhover = true; } }); } moveVx(dX, dY) { if (!this.moveLock && (this.vxhover || this.vxMoveLock)) { cursor(HAND); if (mouseIsPressed) { this.vxMoveLock = true; this.vx[this.vxi].move(dX, dY); } else this.vxMoveLock = false; } else this.vxhover = false; } movePoly(dX, dY) { if (!this.vxMoveLock && (!this.vxhover) && (this.hover || this.moveLock)) { if (mouseIsPressed) { this.moveLock = true; this.move(dX, dY); this.vxi = -1; this.vxhover = false; } else this.moveLock = false; } } delVx() { if (this.vxi < 0) return; this.vx.splice(this.vxi, 1); this.vxMoveLock = false; } insertVx() { if (this.vxi < 0) return; let vxn = this.vxi - 1; if (vxn < 0) vxn = this.vx.length - 1; let ix = (round(this.vx[this.vxi].x + this.vx[vxn].x)/2); let iy = (round(this.vx[this.vxi].y + this.vx[vxn].y)/2); this.vx.splice(this.vxi, -1, new Vertex(ix,iy)); } duplicate() { if (this.vxi < 0) return; let vi = this.vx[this.vxi]; return this.vx.some( (vx, i) => { return (((abs(vx.x-vi.x))<10) && ((abs(vx.y-vi.y))<10) && (i!=this.vxi)); }); } display(mX, mY, dX, dY) { this.hover = (collidePointPoly(mX, mY, this.vx) && (!polys.vxMoveLocked()) && (!(polys.moveLocked() && !this.isSelected)) && (!polys.drawing())); let len = this.vx.length; this.drawPoly(len, mX, mY); if (this.isSelected) { this.displayVx(len, mX, mY); this.movePoly(dX, dY); this.moveVx(dX, dY); } } } let polys = { started: false, closed: false, pArray: [], selIndex: -1, count: 0, ready: function() { return (!this.started); }, drawing: function() { return ((this.started)&&(!this.closed)); }, moveLocked: function() { return this.pArray.some( poly => { return (poly.moveLock===true); }); }, vxMoveLocked: function() { return this.pArray.some( poly => { return (poly.vxMoveLock===true); }); }, clear: function() { this.started = false; this.closed = false; this.pArray = []; this.selIndex = -1; this.count = 0; }, newPoly: function(mX, mY) { if ((mX<0) || (mY<0) || (mX>bgImg.width) || (mY>bgImg.height)) return; this.clearSelected(); this.pArray.push(new Polygon(mX, mY)); this.started = true; this.closed = false; this.count = this.pArray.length; this.selIndex = this.count - 1; }, addVx: function(mX, mY) { if ((mX<0) || (mY<0) || (mX>bgImg.width) || (mY>bgImg.height)) return; if (this.pArray.every( (poly, i) => { return (poly.hover && (i!=this.selIndex)); })) return; this.selected().addVx(mX,mY); }, canClose: function(mX, mY) { return ((Math.abs(mX-this.getX())<10) && (Math.abs(mY-this.getY())<10)); }, doClose: function() { this.selected().doClose(); this.started = false; this.closed = true; }, delSelected: function() { if (this.selIndex < 0) return false; if (this.started) { this.pArray.pop(); this.started = false; } else this.pArray.splice(this.selIndex, 1); this.count = this.pArray.length; this.selIndex = -1; return true; }, clearSelected: function() { this.pArray.forEach( poly => { poly.isSelected = false; }); this.selIndex = -1; }, doSelect: function() { return this.pArray.some( (poly, i) => { if (poly.hover || poly.vxhover) { this.clearSelected(); this.selIndex = i; poly.isSelected = true; return true; } }); }, selected: function() { if (polys.selIndex>-1) return this.pArray[this.selIndex]; }, isSelected: function() { return (polys.selIndex>-1); }, isEmpty: function() { return (this.count===0); }, isClosed: function() { return (this.closed); }, vxLen: function() { return this.selected().vx.length; }, getVx: function() { return this.selected().vx; }, getX: function() { return this.selected().vx[0].x; }, getY: function() { return this.selected().vx[0].y; }, dupCheck: function() { if ((this.count>0) && (this.selIndex>-1)) return this.selected().duplicate(); }, delVxDup: function() { if ((this.vxLen() > minimumVx) && (this.dupCheck())) this.selected().delVx(); }, delVx: function() { if (this.vxLen() > minimumVx) this.selected().delVx(); }, hover: function() { this.pArray.forEach( poly => { if (poly.hover) return true; }); }, insertVx: function() { this.selected().insertVx(); }, display: function(mX, mY, dX, dY) { if (this.isEmpty()) return; cursor(ARROW); this.pArray.forEach( poly => { poly.display(mX, mY, dX, dY); }); } } function setup() { loadImage('files/city.jpg', regImg); } function regImg(img) { bgImg = img; let cnv = createCanvas(bgImg.width,bgImg.height); cnv.parent('cnvCont'); imgLoaded = true; } function draw() { if (imgLoaded) background(bgImg); polys.display(mouseX, mouseY, mouseX-pmouseX, mouseY-pmouseY); } function pushData() { ajaxRequest(MainForm.HTMLFrame, ['getCoords'], { data : JSON.stringify(polys.getVx()) }); } function mousePressed() { if (polys.doSelect()) return else if (polys.ready()) polys.newPoly(mouseX, mouseY); else if (polys.drawing()) { if (polys.canClose(mouseX, mouseY)) { polys.doClose(); pushData(); } else polys.addVx(mouseX, mouseY); } } function mouseReleased() { if (!polys.isClosed()) return; polys.delVxDup(); } function doubleClicked() { if (polys.isEmpty()) return; if (polys.isSelected()) polys.insertVx(); } function keyPressed() { if (polys.isEmpty()) return; if ((key = ESCAPE) && (polys.vxLen() > (minimumVx - 1))) { polys.doClose(); pushData(); } else if ((key = ESCAPE) && (polys.vxLen() <= (minimumVx - 1)) && polys.drawing()) polys.delSelected(); } function delVertex() { if (polys.isEmpty()) return; if (!polys.isClosed()) return; polys.delVx(); } function insertVertex() { if (polys.isEmpty()) return; if (polys.isSelected()) polys.insertVx(); } function delSelected() { if (polys.isEmpty()) { ajaxRequest(MainForm.HTMLFrame, ['delete'], { status : 'no polygons to delete' }); return; } if (polys.delSelected()) ajaxRequest(MainForm.HTMLFrame, ['delete'], { status : 'polygon deleted ok' }); else ajaxRequest(MainForm.HTMLFrame, ['delete'], { status : 'no polygon selected' }); } function resetCnv() { polys.clear(); } </script> Testprog.zip
  12. Last update, moved some code into an object, so each polygon will do the hit testing itself. <div id='cnvCont'></div> <script type="text/javascript"> new p5(); let pStarted, pClosed = false; let pArray = []; let bg; let imgLoaded = false; let selP = -1; class Coords { constructor(ix, iy) { this.x = ix; this.y = iy; this.selected = false; } } class MPoly { constructor(x, y) { this.selected = false; this.closed = false; this.hover = false; this.vx = []; this.vx.push(new Coords(x,y)); pStarted = true; pClosed = false; } addVx(x,y) { this.vx.push(new Coords(x,y)); } close(doPop) { if(doPop)this.vx.pop(); this.closed = true; pClosed = true; pStarted = false; } move(dx, dy) { for (let i=0;i<this.vx.length;i++) { this.vx[i].x += dx; this.vx[i].y += dy; } } display() { let hit = collidePointPoly(mouseX, mouseY, this.vx); if(hit && this.closed) { cursor(MOVE); this.hover = true; } else this.hover = false; if ((mouseIsPressed === true) && hit && this.closed) this.move(mouseX - pmouseX, mouseY - pmouseY); if(hit && this.closed) { stroke(0, 255, 0); } else if (!this.closed) stroke(255, 0, 0); else stroke(0, 0, 255); let len = this.vx.length; if (len>1) for(let i=0;i<len-1;i++) line(this.vx[i].x, this.vx[i].y, this.vx[i+1].x, this.vx[i+1].y); if (!this.closed) line(this.vx[len-1].x, this.vx[len-1].y, mouseX, mouseY); else line(this.vx[len-1].x, this.vx[len-1].y, this.vx[0].x, this.vx[0].y); } } function setup() { loadImage('files/city.jpg', regImg); } function regImg(img) { bg = img; let cnv = createCanvas(bg.width,bg.height); cnv.parent('cnvCont'); strokeWeight(2); imgLoaded = true; } function draw() { if (imgLoaded) background(bg); let len = pArray.length; if (len == 0) return; cursor(ARROW); for(let i=0;i<len;i++) { pArray[i].display(); } } function mouseClicked() { let len = pArray.length; for(let i=0;i<len;i++) if (pArray[i].hover) { selP = i; return; } if ((pStarted)&&(!pClosed)) pArray[selP].addVx(mouseX, mouseY); if (!pStarted) { pArray.push(new MPoly(mouseX, mouseY)); selP = pArray.length - 1; } else if ((!pClosed) && ((Math.abs(mouseX-pArray[selP].vx[0].x)<10) && (Math.abs(mouseY-pArray[selP].vx[0].y)<10))) { pArray[selP].close(true); ajaxRequest(MainForm.HTMLFrame, ['getCoords'], { data : JSON.stringify(pArray[selP].vx) }); } } function keyPressed() { let len = pArray.length; if (len == 0) return; len = pArray[selP].vx.length; if ((key = ESCAPE) && (len > 2)) { pArray[selP].close(false); ajaxRequest(MainForm.HTMLFrame, ['getCoords'], { data : JSON.stringify(pArray[selP].vx) }); } } function resetCnv() { pStarted = false; pClosed = false; pArray = []; } </script> Testprog.zip
  13. Attached is another version, using p5.js, from p5js.org p5() had to be initiated in on-demand global mode at the beginning, see https://github.com/processing/p5.js/wiki/p5.js-overview The canvas is created within a div container, set up via a callback function with loadImage(), and the function draw() runs a continous loop. <div id='cnvCont'></div> <script type="text/javascript"> new p5(); let pStarted, pClosed = false; let cArray = []; let bg; let imgLoaded = false; class Coords { constructor(ix, iy) { this.x = ix; this.y = iy; } } function setup() { loadImage('files/city.jpg', regImg); } function regImg(img) { bg = img; let cnv = createCanvas(bg.width,bg.height); cnv.parent('cnvCont'); strokeWeight(2); imgLoaded = true; } function draw() { if (imgLoaded) background(bg); if (!pStarted) return; if (!pClosed) stroke(255, 0, 0); else stroke(0, 0, 255); let len = cArray.length; if (len>1) for(i=0;i<len-1;i++) line(cArray[i].x, cArray[i].y, cArray[i+1].x, cArray[i+1].y); if (!pClosed) line(cArray[len-1].x, cArray[len-1].y, mouseX, mouseY); else line(cArray[len-1].x, cArray[len-1].y, cArray[0].x, cArray[0].y); } function mouseClicked() { if (!pClosed) cArray.push(new Coords(mouseX, mouseY)); if (!pStarted) pStarted = true; else if ((!pClosed) && ((Math.abs(mouseX-cArray[0].x)<10) && (Math.abs(mouseY-cArray[0].y)<10))) { cArray.pop(); pClosed = true; ajaxRequest(MainForm.HTMLFrame, ['getCoords'], { data : JSON.stringify(cArray) }); } } function resetCnv() { pStarted = false; pClosed = false; cArray = []; } </script> Testprog.zip
  14. When I put your code into https://pynative.com/online-python-code-editor-to-execute-python-code/ it works fine. Only had to replace the : with a ; at the end of this line: sum+=i; Result: Enter the number:The sum up to 3 is 6
  15. We are happy users of Delphi, so unfortunately we don't care very much about Python not working. Python - even the name of the game tells one to stay away. Who knows, if it bites?
×
×
  • Create New...