Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation since 04/27/23 in all areas

  1. Completely unnecessary this question about the future of Unigui If the Unigui team doesn't create anything new and just improve what already exists, giving more stability bug fixes it's already great everything we need in terms of components we have with Unigui For me Unigui is perfect. I managed to migrate all my ERP of 520.000 thousand lines of code to Unigui Instead of complaining let's help the team by always renewing our licenses. Hug to everyone.
    7 points
  2. I compiled all above in program wich create a Self Signed Certificate in 3 secondes. Best Regards... See the updated program here : http://forums.unigui.com/index.php?/topic/18951-help-with-ssl-intranet/&do=findComment&comment=141667 Prg.7z
    7 points
  3. Dears, You have chosen to be a developer. For what ? the answer is simple: It's because you love everything that is: - Beautiful - TRUE - and Fair it makes you lights in this dark world. but...you are forgetting something very important: your health. guys, we develop too much, we stay too long in front of our screens and we end up with hypertension, heart palpitations, loss of visual acuity, and other nasty syndromes... I wanted to launch this alert, because I myself am concerned. Fortunately, there is a solution: Do SPORT and drink lots of water. it's funny, isn't it! try it and you will see: it will be beneficial for you and your family and moreover, you will develop twice as fast. Have a good day
    6 points
  4. Dears, I was finally able to do something: If one day, you will have to develop an Unigui app: - Under local network, - Without Internet, - Which requires an SSL (example Scann Camera) Then read the following: I thought, wrongly to create "Self Signed Certificate". Today, most of browsers reject them. So, after 3 days search, I understood that it was necessary to use another technic : Create a localhost Certificate by mkcert This is inspired by (thx to the Author) : https://technixleo.com/create-locally-trusted-ssl-certificates-with-mkcert-on-windows OK...Step by Step : 1. Installing mkcert on Windows 1.1 mkcert can be installed by Chocolatey To install Chocolatey, you must first ensure the Policy AllSigned Open PowerShell as Admin Get-ExecutionPolicy if Restricted then : Set-ExecutionPolicy AllSigned 1.2 To install Chocolatey see https://chocolatey.org/install In PowerSehlle type (in a single line): Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1')) 1.3 install mkcert In PowerSehlle type: choco install mkcert The mkCert Directory (by default) is: C:\Users\...\AppData\Local\mkcert 2. Generate my 2 pem files In PowerSehlle type: mkcert -install This will generate 2 files in C:\Users\...\AppData\Local\mkcert: rootCA.pem rootCA-key.pem 3. Generate a localhost.p12 Certificate In PowerSehlle type: mkcert -pkcs12 localhost This will generate localhost.p12 certificate which will be in the PowerShell directory, ie: ..\System32 4. Import the localhost Certificate Touche Win + R key: mmc File > Add > Certificates > Add Computer account local computer OK Right click / on WEB Hosting Certificates > All Tasks Machine Room Select localhost.p12 Certificate Next specify the password (default): changeit Check: Key Exportable Place of the Certificate on : Web Hosting (dépend on your windows langage : example for french : Hébergement Web) This will create 2 Certificates (in Web Hosting): - localhost - mkcert myDESKTOP-xxx 5. Project Unigui Requires 3 files: cert.pem key.pem root.pem Do not use root.pem = rootCA.pem ( C:\Users\...\AppData\Local\mkcert ) key.pem = rootCA-key.pem ( C:\Users\...\AppData\Local\mkcert ) wich are generated by mkcert. Use instead the new 3 files, obtained online (by converting the p12 file in a new global pem file) 5.1 Split localhost.p12 into 3 Files You can obtain the 3 files via a conversion of the Certificate: localhost.p12 Use Online: https://www.sslshopper.com/ssl-converter.html - Upload the Certificate File: localhost.p12 - indicate the type: PFX/PCKC#12 - Convert To: Standard PEM - Password: changeit You will get global File, containing 3 blocks : start ...end Separate them with Notebook, and save them into 3 files: The first = cert.pem The second = root.pem The third = key.pem 5.2 Compile your project and run it : https://localhost:8077/ is Secure Have fun... ___________________ PS: if you are interesting by an easy way to scan BareCode via your Android device (wich requires an SSL url) you can use Falcon Store - Components Delphi from our Friend Marlon. Very fast and light ! http://forums.unigui.com/index.php?/topic/11359-falcon-store-components-delphi-httpsstorefalconsistemascombr/#comment-60260
    6 points
  5. News https://store.falconsistemas.com.br Added 4 additional months of subscription for all components for all users. From now on all components have 1 year for fixes, new components and improvements for all users 🚀🚀🚀.
    5 points
  6. uniGUI Floating Buttons (simple but useful) This is a very simple project that shows how to use floating buttons anchored to the main browser window or your form. I already left the JS code calling ajaxrequest to select the correct buttons for your UI. So, just choose the icons, the best model and see in the CSS where you change it to leave it in one format or another. I already commented on where to change the CSS code. project411-floatingbutton.rar FloatingButtons2.mp4 FloatingButtons.mp4
    5 points
  7. uniGUI/VCL Face Recognition based on Luxand FaceSDK library.Recognition/Face Features/Expressions and more.. Projects For Sale Download Demos With examples ported/adapted and updated to Delphi VCL and uniGUI. Brief Introduction Luxand is one of the oldest and well tailored libs for facial recognition for different programming languages and development environments (Windows, Web (python and .net), Android and iOS). Since 2010, I have been following this material and used it for several simpler projects and tests, just curiosity. It has evolved a lot over the years, going from just a simple comparison of images to very sophisticated things like easy recognition in a video feed, real-time tracking of people in a video feed, facial expressions, facial features and much more. However, its best examples were never properly adapted to Delphi/Pascal after the String/Ansi/unicode changes introduced in version 2010 onwards. Even the examples you can download today from the official website will not work correctly or will have pascal code primitive errors. You can test it ! Some of them won't even work for Delphi/Pascal at all. Despite being a very cheap and practical lib, they now seem to only focus on their online Cloud API service and, in the last version, they didn't even update or make exampled for Delphi/Pascal. So you will find new examples for other languages but not for Delphi/Pascal since 2010 in their own package. I spent weeks studying and correcting the examples shown here and adapting them when possible to uniGUI and code to Pascal. All the basic functions of the lib I managed to adapt to VCL and uniGUI completely. The examples prove this! Watch the video demos. I highly recommend this lib for facial recognition and many other features it has. Even more so, it is the only one that does not require an hardcore dedicated video card or suffer from the slowdowns that OpenCV has. Features and Characteristics Detects Age, Gender, Facial expressions such as smile, closed eyes, angle of the face in relation to the photo. Detects facial elements such as eyes, mouth, entire face, face position, face angle in relation to the photo plane. Easily detects and identifies multiple faces in the same image with all the elements described above (see Face_SDK Mega demo). Detects people (up to 256 on-the-fly) in a video feed (webcam or IPCam), with support for identification tracking (See the LiveRecognition demo). Detects people in live video feed and their elements such as Age, Gender, Facial expression etc. (for unigui too) see example uniGUIFaceDetectionCircle. Compare images by template (one image in relation to another) or group of images against one. Good for security authorization/access walls. See LookAlike Example.ce Command example show how to integrate with a lot os commands. Easy to modify and adapt to your needs No third party components. All fonts included for Delphi/Pascal. No hidden costs or fees. Yes, we offer advice on adapting any of these examples to your systems. Contact us to receive a quote. Try before buy it 1- Download functional Demos Examples List of Examples with Source Code Adapted/Updated by me for Delphi/uniGUI: -AgeGenderRecognition - VCL - Find Age and Gender on Live feed from Webcam and subtitle on-the-fly the subject (the person detected) with that information. -ExpressionRecognition - VCL - Find if subject is Smiling and its age on Live Feed from Webcam -FaceSDK- VCL - Detects Face(s), Extracts Face and Facial Features, Face Expressions (smile, Eyes Open), Age and Gender from image, One Face only (the first detect) or Muultiple Faces (ALL detected in a image). Extract faces to files. This is a mega demo with all the basics image features I made. You don't have this in the original package. See demo video ou download demo package. You can adapt this to uniGUI easy. This code is completly compatible with uniGUI since is just replace all components. -FaceTracking - VCL - Tracking face from a Live feed from Webcam (plot rectangle over face) -FacialFeatures - VCL - Plot face features from an image (face, eyes, mouth, eyes etc) -LiveFacialFeatures - VCL Tracking face from a Live feed from Webcam (plot retangle over face and face elements: face, eyes, mouth etc) Live Recognition from feed LiveRecognition - VCL - Tracking face from a Live feed from Webcam , identify subjects and add to tracket table to future track. Support 256 face tracking and identificiation at the same time. IPCamera - VCL - Tracking face from a Live feed from Webcam , identify subjects and add to tracket table to future track. Support 256 face tracking and identificiation at the same time. uniGUIFaceDetection - uniGUI - MegaDemo for uniGUI: Tracking face from a Live feed from Webcam. Upon face detection, Get elements, facial expression and facial features with discritive text (gender, age, facial expression etc). This is a mega demos I made to unigui with all basic features. 2- Video Samples Live Feed Face Recognition with ID track (aka name of subject) Live Feed Face Expressions Live Feed Face Reecognition Gender, Age and Facial Expressions detection Photo LookAlike (batch)
    4 points
  8. uniGUI - Module Notification This notification lib is different since it injects the notification inside a module container. So, is perfect for a non intrusive like dashboards and works perfectly with native uniGUI controls. Module-Noty.mp4 Download project below. Only for uniGUI subscribers. Project19-ModuleNotification.rar
    4 points
  9. Hello this is my solution for my customers to change the colors - it works in your existing unigui-application. If you will used it -and make it better 😉 - please post your work here HowTo: Please set Theme "triton.modified" in UniMainModule you need public vars in UniMainModule: my_text_under_highlite, texthintergrund, texthintergrund_focus, my_color, hintergrundfarbe, randfarbe, textfarbe : String; you need a hidden "UniHTMLFrame2" in Mainform ..and the Form in the zip 😉 unigui_UI.webm colors.zip
    4 points
  10. I have the same opinion. nothing is perfect but out of all the frameworks I tested to create Radcore, Unigui was my best choice. 4 years after Radcore was created, I am proud to have collaborated with the sale of new licenses in Brazil, as I explain to my users the importance of this and they, how it has results, licensing and/or renewing their licenses.
    4 points
  11. PDF document generation library for server-side and client-side usage in pure JavaScript. https://pdfmake.github.io/docs/0.1/ http://pdfmake.org/playground.html
    4 points
  12. I'd like to add: - Spend time with the family - Meditate twice a day - Go to bed with a good book, preferably fiction Any other tips?
    4 points
  13. A release without uSesamoBase.Json (internal test) Demo Responsive2.zip
    4 points
  14. 52 years old.. used Turbo Pascal since 1991 and Delphi since 1995.
    3 points
  15. 1. UniSpeedButton.ClientEvent.LayoutConfig.Cls = customSpBtn 2. CustomCSS -> .customSpBtn.x-btn.x-btn-pressed, .customSpBtn.x-btn:hover { border-color: none; background-image: none; background-color: green; background-image: linear-gradient(yellowgreen 50%, green); }
    3 points
  16. Indeed, that's an excellent idea! I actually went ahead and converted the chm file using an online converter and have attached the PDF here for others to benefit from. uniGUI.pdf
    3 points
  17. Someday, when I got my farm and retire, I'll rise two pigs and will name them: AJAX and REQUEST ! Just to see the mess they will do when I call.
    3 points
  18. With a few code you can attach popups to any uniGUI control. But to make works exactly as Windows, you must walk a little more. Here is a simple example to attach context menu (mouse right-click) to any uniGUI control and create as you wish 'on- the-fly'. Very simple to use and customize. Features: * Tiny library. Only dependency is jQuery. * Simple API. * Looks good out of the box, with no additional tweaking. * Designed to look and behave like a standard Windows context menu. * There's so little code, it should be easy to add your own custom features. ContextMenu2uniGUI.mp4 Silver Package - 89 Projects Just $99,00 USD https://www.unigui.com.br/democetera/ This project/source-code is free to uniGUI subscriber and will be available here to download for the next few days. After that, only for sale. Link below. Don't DM me about it ! Visite http://www.unigui.com.br/ Nosso grupo no Telegram: Livros, packs de projetos, cursos, serviços, consultoria e tudo sobre unigui ! https://t.me/uniguiBrazil - Conteúdo em português ou/or See more and get this pack at http://www.unigui.com.br/democetera Our group at Telegram: https://t.me/uniguiexpress Content in English Project420-ContextMenu.rar
    3 points
  19. Hi, I have always ask for a Combobox or Lookup with a list of display values and and corresponding values to be assigned in the field below. Now I can with dataset lookups; I need also a simple editor with a list of display values and a list of corrispondent keys. I add the request (made many times) for a well-formatted and multi-column table in the popup (with headers and separation lines). If it already exists tell me where I can find it 🙂 Good job!
    3 points
  20. News Compatible with the latest version of uniGui 1.95.0.1575 and ExtJS 7.5.1. Delphi 2007 to Delphi 12.0 Athens UniClientEventsPropEditor.zip
    3 points
  21. Hi Abaksoft, Thanx for your PERFECT work .. i tried a lot! of things and found a solution for the Android Problem 😉 The maion problem is the "-extensions v3_req" 1. change in delphi: //A.2.2 root.pem stDays:=intToStr(365 * upYrears.Position); param:='req -x509 -days ' + stDays + ' -new -nodes -key root.key -out root.pem -config san.cnf -extensions v3_req'; ShellExecute(Application.Handle ,PChar('RunAs'),PChar(Fichier),PChar(param),PChar(Dossier),SW_HIDE); sleep(300); //A.2.3 cert.pem param:='req -x509 -nodes -days ' + stDays + ' -newkey rsa:2048 -keyout key.pem -out cert.pem -config san.cnf -extensions v3_req'; ShellExecute(Application.Handle ,PChar('RunAs'),PChar(Fichier),PChar(param),PChar(Dossier),SW_HIDE); sleep(300); 2. change in san.cnf [req] default_bits = 2048 distinguished_name = req_distinguished_name req_extensions = v3_req x509_extensions = v3_req prompt = no [req_distinguished_name] countryName = XX stateOrProvinceName = N/A localityName = N/A organizationName = Self-signed certificate commonName = Self-signed certificate [req_ext] subjectAltName = @alt_names [v3_req] subjectAltName = @alt_names basicConstraints = critical,CA:true [alt_names] IP.1 =10.0.0.10 3. Export CA in Windows - and import it as CA in Android .. Works 🙂
    3 points
  22. JSInterface.JSConfig('cls', ['x-fa fa-sync fa-spin']); JSInterface.JSAddListener('afterrender', 'function(me){me.setStyle("color", "red"); me.setStyle("line-height", "'+ Height.ToString() +'px"); me.setStyle("font-size", "'+ Height.ToString() +'px")}');
    3 points
  23. This is an update to this example below in Chinese. I made some correction and soon I'll be providing a whole project and with English support. See other projects, examples and resources from us at https://unigui.com.br/ SourceOriginal.rar
    3 points
  24. dgAllowSelfUpdate - Normally when you edit a grid row directly, the entire row won't be refreshed until all changes in row are committed to the related dataset. Sometimes when row contains calculated fields you may want to refresh the row before all changed are committed. By enabling this option the related grid row will be refreshed each time a field is edited. This option is disabled by default. You can enable it if your dataset contains calculated fields and you want to update the row before it is committed. http://unigui.com/doc/online_help/api/uniGUITypes_TUniDBGridOption.html
    3 points
  25. My first computers! I Still have them.
    3 points
  26. And finaly for this you can use this function + Unitimer function TDMT.Ping2(const AHost: string): Integer; var ICMP: TIdICMPClient; Started: Tdatetime; begin Result:=-1; Started := Now; ICMP := TIdICMPClient.Create(nil); try ICMP.Host := AHost; ICMP.ReceiveTimeout := 2000; ICMP.Ping(); If (ICMP.ReplyStatus.ReplyStatusType = rsEcho) Then Result:=MilliSecondsBetween(TDateTime.Now, Started); finally ICMP.Free; end; end; in timer procedure TMainForm.UniTimer1Timer(Sender: TObject); Var T : Integer; begin T:=Ping2('1.1.1.1'); if T>=0 then LPing.Caption:=T.ToString+ ' ms' Else LPing.Caption:= ' Error'; end; and for program server as @Sherzod guide me we can use this code Function UniServer(Var RetParams : Tstringlist):Integer; begin With RetParams Do Begin Add('Memory Used:'+UniServerModule.ServerResources.MemoryUsed.ToString+'/'+UniServerModule.ServerResources.PeakMemoryUsed.ToString); Add('Process Memory Used:'+UniServerModule.ServerResources.ProcessMemoryUsed.ToString+'/'+UniServerModule.ServerResources.PeakProcessMemoryUsed.ToString); Add('USER Objects:'+UniServerModule.ServerResources.USERObjects.ToString+'/'+UniServerModule.ServerResources.PeakUSERObjects.ToString); Add('GDI Objects:'+UniServerModule.ServerResources.GDIObjects.ToString+'/'+UniServerModule.ServerResources.PeakGDIObjects.ToString); Add('CPU Usage:'+FloatToStr(UniServerModule.ServerResources.CPUUsage)+'/'+FloatToStr(UniServerModule.ServerResources.PeakCPUUsage)); Add('Handles:'+UniServerModule.ServerResources.Handles.ToString+'/'+UniServerModule.ServerResources.PeakHandles.ToString); End; end;
    3 points
  27. Hi, yes is not a problem. I add my own procedure to save image to file. DrawInCanvas_Mousemove_ex.7z
    3 points
  28. Integração com a Ntfy no Delphi. Ntfy é um serviço simples de… | by Samuel R. O. | Medium GitHub - hazzelnuts/ntfy-for-delphi: Biblioteca amigável para enviar e receber notificações instantâneas usando servidores ntfy.sh em Delphi
    3 points
  29. Good afternoon, the reason it doesn't work is that it requires on mobile https example https://192.168.1.xxx:8077
    2 points
  30. Finally ..My code completed. function beforeInit(sender, config) { config.listeners = { keyup: function(textarea) { var inputEl = textarea.inputElement; textHeight = inputEl.dom.scrollHeight; if (textarea.getValue() == '') { textHeight=35; } if (textHeight != textarea.getHeight()) { var H1 = textHeight; var H2 = textarea.getHeight(); if (H1<=35*4) { textarea.setHeight(textHeight); } ajaxRequest(sender,'_resize',{newH: H1, oldH: H2}); } } } }
    2 points
  31. Добрый день,
    2 points
  32. Hi, You can try to use html into SQL script. I use it on my Desktop. like this (H1, H2, H3 are set in CSS file): SELECT ('<H2>'+ Products."PrdName" + '</H2>' + '<ul>' + Groups."gName" + '</ul>' + CASE WHEN CONVERT (varchar (250) , STUFF ( (SELECT CHAR (10) + '|||' + REPLACE ([PName],'-','') + CHAR (10) + [PValue] FROM OtherTable1 WHERE OtherTable1."ID" = Products."ID" FOR XML Path ('')),1,1,'')) <> '' THEN '<h3>' + REPLACE (CONVERT (varchar (250) , STUFF ( (SELECT CHAR (10) + '|||' + REPLACE ([PName],'-','') + CHAR (10) + [PValue] FROM OtherTable1 WHERE OtherTable1."ID" = Products."ID" FOR XML Path ('')),1,1,'')) ,'|||','</br>') + '</h3>' ELSE '' END + '<ul><ul><h3 align="right">Price: ' + CAST (ROUND (Products."Price",2) as varchar (20)) + ', ' + lower (Products."V") + '</h3></ul></ul>' ............. ) as Opisanie FROM TableName WHERE .... css file: html,body,h1,h2,h3,h4,h5,h6 { font-family: "Segoe Script", cursive, sans-serif; line-height: 1.2; }
    2 points
  33. All post that are irrelevant to this topic have been deleted. Please stay on topic. Cheers
    2 points
  34. Towards the end of the year, I remember this post ❄️ 🙂
    2 points
  35. Thanks for the feedback 🤝. It is already being resolved by email suporte@falconsistemas.com.br
    2 points
  36. last actual manual on PDF
    2 points
  37. This is not a simple stuff. Very sophisticated and works way better than the native Bootstrap Toast. I tried all the toast and notifiers I could find. Got all that was good and what is missing. So... that is it !
    2 points
  38. copyright by QQ:48391810
    2 points
  39. 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
    2 points
  40. @Sherzod@Hayri ASLAN@Farshad Mohajeri I see that there are several posts related to "showmask". I'm also having problems using synchronize and I see that it's better not to use it, but when should it really be used? Because there are some situations where some things only work with it. Ex: I click on the menu to call a form/frame but immediately click on another option. This sometimes works but sometimes generates an error with something called "tabconfig" that I've seen other related posts about this with no response. This seems like the wrong thing to do, but we develop systems for other users, and these users do unimaginable things and we need to try to create solutions to avoid this. Another situation is to keep a mask active until I actually order it to stop (hide), for example: - I click on unitreemainmenu - mask is displayed; - open a form/frame; - process some queries; - I hide the mask; This doesn't work, because when activating the mask of a UniDBGrid, for example, which is linked to one of the queries, the first mask (referring to the menu click) is already interrupted. I don't know if I managed to make myself understood, but basically, it's the same thing I've seen in other posts, but there was also no continuity. PS: It's not just me with this question and of course, I could be doing something wrong but I can't find the solution and that's why I'm asking for help.
    2 points
  41. Solved 😀 procedure TDMT.ShowListStart(TTl: STring); Var F : TUniForm; RollingStone : TUniHTMLFrame; Begin F := TUniForm(UniApplication.FindComponent('MyShowListName')); if Assigned(F) then FreeAndNil(F); F := TUniForm.Create(UniApplication); With F Do Begin AlignmentControl:=uniAlignmentServer; ClientHeight := 512 ; ClientWidth := 1248; OldCreateOrder := False ; Width:=Round(Screen.Width/4); Height:=Round(Screen.Height/2); Left:=Screen.Width-Round(Screen.Width/8); Top:=Screen.Height-Round(Screen.Height/4); Position:=poScreenCenter; BorderStyle:=bsSingle; BorderIcons:=[biMaximize,biSystemMenu]; Name:='MyShowListName'; KeyPreview:=True; Rtl:=False; Caption:=''; CaptionAlign:=taCenter; FormStyle:=fsStayOnTop; OnKeyDown:= KeyDownConfig; Caption:=TTl; FreeOnClose:=True; End; RollingStone:=TUniHTMLFrame.Create(F); With RollingStone Do Begin Parent:=F; AlignWithMargins := True; RTL := True; Align:=alClient; AutoScroll := True; Name:='MyShowListRollingStoneName'; end; F.Show; End;
    2 points
  42. I'm using it for my mobile/desktop app for computer service and/or auto service businesses to have customers hand sign some documents through the app
    2 points
  43. answering to myself , may be useful for others I have to set Content-Type: application/pdf in HTML headers , at the s3 object during upload or change it if it was alwready uploaded by others... Thanks.
    2 points
  44. Unfortunately you can only have 1 mainform. I suggest create UniFrameA and UniFrameB. Load them into mainform based on user
    2 points
  45. 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
    2 points
  46. Dear Friends, Here is in attachment a good way to memorize centering text on touch Mobile. Enjoy... Mobile_Lecons.7z
    2 points
×
×
  • Create New...