Jump to content


Popular Content

Showing content with the highest reputation since 06/20/2018 in all areas

  1. 6 points

    Smart Mobile Studio 3.0 is released!

    One year of hard work, lots of changes, new features and bug fixes. But here it is! Release announcement: https://smartmobilestudio.com/2018/07/20/smart-mobile-studio-3-0-released/ Most of you have already been using beta-versions, that are really, really close to this release. The last bit was to fix the cors-problem in the Images and to add the Smart Desktop source code to the Featured Demos. We've also set up a live demo of the Desktop to showcase what Smart Mobile Studio and JavaScript can do: desktop.smartmobilestudio.com Big thanks to everybody here, who have helped by testing, suggesting improvements and reporting bugs.
  2. 5 points

    Development updates

    New update available: RTL: TW3ListMenu: Add Items-property, so items can created in Object Inspector. Add OnSelected-event. IDE: Bug fix to renaming of units Show form source instead of designer when form is selected from Project Manager
  3. 5 points

    Smart Mobile Studio 3.0.1 is released!

    Smart Mobile Studio 3.0.1 is released This is the first release since 3.0. Biggest new feature is TW3LeafletMap, which lets you use OpenStreetMap. As it does not need API keys (like TW3GoogleMaps), it’s really fast and easy to use: – Create a project – Add a TW3LeafletMap -control on the form – Set AutoCreateMap to true on the map control Changes since 3.0 8.11.2018 RTL: – EventManager: – Add procedure AllowDefaultAction, that can be called from OnClick when the default action should happen. For example: To let the virtual keyboard to pop up from OnTouch. – Bug fixes: – Native scrolling was prevented if scrolling was done from an unknown element. – Prevent an extra OnClick from being fired on mobile devices. – TW3ListView: Bug fix to resizing of items. – Bug fixes to GeoLocation. Also update the Geolocation demo. – Deprecate PhoneGapAPI’s JGeolocation functions. SmartCL.GeoLocation.pas should be used instead. – Fix slider so that OnMouseDown, OnMouseUp and OnMOuseMove can be used. – TW3TabControl Tab’s OnShow was sent twice for the first tab – SmartCL.RegEx moved to System.RegEx. Also fixed TW3RegEx.Exec to return a proper empty array instead of nil. – Bug fix to Chart: TSeriesData.Refresh now also updates the X axis – TW3Grid: – Added TW3ImageColumn – Add Alignment-property to TW3ColumnHeader – Added a new OnCellControlCreated-event, which fires when a button, toggle, progress bar or image is created. Makes it possible to change properties of the control easily. – Added support for OpenStreetMap using the Leaflet library: – New control: TW3LeafletMap – New featured demo: LeafletMap IDE/Compiler: – Fixed search path compilation issues – Relative and absolute paths are working now – Compiler is updated when search path is modified in options – $I will look for include file in the project folder first – $R supports absolute paths, wildcards, folder name extension and ($Libraries) macro – Fix exceptions in Search – Upgrade to UPX 3.95 23.7.2018 – SmartCL.Effects: Properly handle padding and margins while doing effects. 22.7.2018 – Fix to css-files for selected text in TW3Edit and TW3Memo Release notes and installers: https://smartmobilestudio.com/2018/11/08/smart-mobile-studio-3-0-1-released/ Note that you can also use SmartUpdate to keep your portable installation up to date. Instructions on using that are in the link above.
  4. 5 points

    Font Demo

    in project options add a webfont (see https://jonlennartaasenden.wordpress.com/2017/10/04/webfonts-in-smart-mobile-studio/) W3Memo1.Font.Name := 'Tangerine'; W3Memo1.Font.Style := [fsItalic]; W3Memo1.Font.Size := 48; W3Memo1.Font.Weight := 'bold'; In this case I added Font 'Tangerine' (see also https://developers.google.com/fonts/docs/getting_started)
  5. 4 points


    Was looking for an easy to make wysiwyg editor. This one is based on 'document.designMode'. Mozilla: "When an HTML document has been switched to designMode, its document object exposes an execCommand method to run commands that manipulate the current editable region" IFrame's have an innate document element which can be used for that purpose. Have a form with an IFrameHtmlElement and 2 buttons ('bold' and 'italic') : procedure TForm1.InitializeForm; begin inherited; // this is a good place to initialize components W3IframeHtmlElement1.handle.contentDocument.designMode := 'on'; W3IframeHtmlElement1.handle.contentDocument.body.innerHTML := 'this is some text'; W3IframeHtmlElement1.handle.focus(); end; procedure TForm1.W3Button1Click(Sender: TObject); //bold begin W3IframeHtmlElement1.handle.contentDocument.execCommand('bold', false, null); W3IframeHtmlElement1.handle.focus(); end; procedure TForm1.W3Button2Click(Sender: TObject); //italic begin W3IframeHtmlElement1.handle.contentDocument.execCommand('italic', false, null); W3IframeHtmlElement1.handle.focus(); end; Besides 'bold' and 'italic' execCommand supports a host of other edit commands as well. see https://codepen.io/chrisdavidmills/full/gzYjag/
  6. 4 points


    Google has implemented a new service : web.dev Basically this measures some indicators of any url using their LightHouse tool. These indicators are grouped into Performance, Accessibility, Best Practices and SEO I created a minimal SMS project with only a single image on a form and run the test : https://web.dev/measure and url : https://www.lynkfs.com/Experiments/lighthouse/www/ This gives scores of 95 / 27 / 77 / 89 for Performance, Accessibility, Best Practices and SEO respectively There are a couple of really simple things which will up these scores considerably. Scores were upped to 96 / 74 / 92 / 100 when doing this : Best Practices from 77 to 92 : 1) in project options/linker unclick 'generate cache manifest' (deprecated) Performance from 95 to 96 : 1) in project options/linker unclick 'store CSS as a separate file' (95 to 96) 2) add async to <script async src="lib/polyfill.custom.events.js" type="text/javascript"></script> in the index.html template SEO from 89 to 100 : 1) add meta description tag to the head of index.html <meta name="Description" content="Put your description here."> Accessability from 27 to 74 : 1) add alt attribute to images, even if only '' : W3Image1.handle.setAttribute('alt', ''); (27 to 58) 2) add lang="en" to html element in index.html template : <html lang="en"> (58 to 74) 3) tabindex=1 for TW3Display and TW3DisplayView. Should be 0 ? run test again on url : https://www.lynkfs.com/Experiments/lighthouse2/www/ to see these results All of the above could be made part of the standard settings for a new visual project
  7. 4 points

    console override

    redirecting 'console.log' or 'writeln' output proves to be very simple : have a form with a Memo component : procedure TForm1.InitializeObject; begin inherited; {$I 'Form1:impl'} W3Memo1.Text := 'Console.log : ' + #10; browserapi.console.log := procedure(text:variant) begin W3Memo1.Text := W3Memo1.Text + #10 + text; end; writeln('aaa'); browserapi.console.log('bbb'); end; all subsequent calls to writeln and/or console.log are now redirected to the Memo component.
  8. 4 points

    console override

    This mechanism can be used to redefine more built-in functions. Funny. The code below redefines 'ShowMessage' to redirect its contents to a Memo : procedure TForm1.InitializeObject; begin inherited; {$I 'Form1:impl'} W3Memo1.Text := 'ShowMessage : ' + #10; browserapi.window.alert := procedure(text:variant) begin W3Memo1.Text := W3Memo1.Text + #10 + text; end; ShowMessage('ccc'); browserapi.window.alert('ddd'); end; or combine the two and redefine 'ShowMessage' to redirect its contents to the 'Writeln' function, which in its turn is redirected to the Memo : procedure TForm1.InitializeObject; begin inherited; {$I 'Form1:impl'} W3Memo1.Text := 'Console.log : ' + #10; //WriteLn redirects to Memo browserapi.console.log := procedure(text:variant) begin W3Memo1.Text := W3Memo1.Text + #10 + text; end; //ShowMessage redirects to WriteLn browserapi.window.alert := procedure(text:variant) begin writeln(text); end; writeln('aaa'); browserapi.console.log('bbb'); ShowMessage('ccc'); browserapi.window.alert('ddd'); end;
  9. 4 points

    Development updates

    17.11.2018 RTL: Changes to handling of Cursor: Style definitions moved from basic html elements to control styles GetCursor and SetCursor can now be overridden Bug fixes to how many controls handle cursor. Especially TW3Label. Themes: Add missing styles TW3CheckBox, TW3CheckMark, TW3RadioButton, TW3RadioToggle and TW3RadioGroup Two new backgrounds: TW3DecorativeListItemBackground and TW3TransparentBackground RTL optimizations to creation of controls, GetBoundsRect, SetBounds, MoveTo and SetSize. Bug fix to SmartCL.Graphics.pas: Changing of canvas font, size and styles did not work. Bug fix to System.DateUtils.DecodeDate. IDE: Delete key works now Search dialog and other dialogs. Bug fix: Internal Browser Window showed only a white screen if Execute was clicked while it was open. Compiler: Now(), EncodeDate() and EncodeTime() returns now the same values as Delphi and FPC All time/date -functions fixed to work with the new TDateTime-values
  10. 4 points

    DayOf reporting false value

    I dug around and found out that I actually can fix those "buggy" functions in the compiler without having to upgrade to a newer version of DWScript. I only have IncMonth to fix any more. The root cause of the problem is the way javascript dates work. When you build a date from day, month and year, the result depends on your time zone. I guess it builds the date as UTC and then views it from your location. So, while it's 01.12.2018 at 00:00:00 in London, it's still 30.11.2018 in USA. And when you call DayOf on that, you get 30 instead of 1. This affects about 10 other functions as well, including FormatDateTime and DateTimeToStr and TimeToStr. I'll make sure to test this all properly and then release an update. Once it's done, I'm super happy to get rid of these problems.
  11. 4 points


    I'm sad to see Jon leave his baby like this, but I do respect his decision. What I can say is, that SMS is not dying here. I've been waiting a few weeks already to push a new update, but have not been able to get any answers from Jon, if he'd also want to include some changes. I believe things look worse to you guys than they really are. A lot of RTL work and especially bug fixes was done by me during the last year and almost all the IDE improvements and bug fixes by Primoz. Jon did pretty much all the NodeJS work, so we'll miss him most there. If I look at this optimistically, Jon's donating his shares to two young and talented Delphi programmers is a very nice thing and may give them a possibility to spend more time on SMS. But hey, hang on there and lets hope that this divorce will not be too ugly.
  12. 4 points
    I'd rather do it like Delphi and Lazarus: Keycode as a var parameter and setting it to #0 would cancel. However, that would break backwards compatibility of SMS code just as any other new parameters would do. If you guys don't see it as a big problem, we could do it in a future version. Let me know what your thoughts are.
  13. 4 points

    Scroll bar bug

    This was a weird bug that required changes in SynEdit code itself. May be a Delphi bug even. But I got it fixed and it will be in 3.0
  14. 4 points
    @rshotbolt Here are some resources that might help you out. I like the first one as it explains the precedence and how each overrides the others. Playing with the design 03.06.2013 https://smartmobilestudio.com/2013/06/03/playing-with-the-design/ Smart Mobile Studio and CSS: part 1 October 9, 2017 https://jonlennartaasenden.wordpress.com/2017/10/09/smart-mobile-studio-and-css-part-1/ Smart Mobile Studio and CSS: part 2 https://jonlennartaasenden.wordpress.com/2017/10/11/smart-mobile-studio-and-css-part-2/ Smart Mobile Studio and CSS: part 3 https://jonlennartaasenden.wordpress.com/2017/10/12/smart-mobile-studio-and-css-part-3/ Smart Mobile Studio and CSS: part 4 https://jonlennartaasenden.wordpress.com/2017/10/18/smart-mobile-studio-and-css-part-4/ Themes and styles https://smartmobilestudio.com/documentation/getting-started/themes-and-styles/ Working with controls, the boxing model 05.01.2012 https://smartmobilestudio.com/2012/01/05/working-with-controls-the-boxing-model/ Hidden stylesheets with Smart Pascal August 13, 2014 https://jonlennartaasenden.wordpress.com/2014/08/13/hidden-stylesheets-with-smart-pascal/ HTML5 Attributes, learn how to trigger conditional styling with Smart Mobile Studio November 8, 2017 https://jonlennartaasenden.wordpress.com/2017/11/08/html5-attributes-learn-how-to-trigger-conditional-styling-with-smart-mobile-studio/
  15. 3 points

    Smart Mobile Studio 3.0.2 is released!

    Smart Mobile Studio 3.0.2 is released. This version contains all the fixes and improvements from the development-channel. There are lots of bug fixes and improvements to the IDE thanks to all the help from our users here. The Smart Mobile Studio team wants to with everybody a Merry Christmas and Happy New Year. Release notes: https://smartmobilestudio.com/2018/12/21/smart-mobile-studio-3-0-2-released/
  16. 3 points

    inter-tab processing

    Would it be possible to implement a 'client-server' architecture where both the client and the server are executed locally (but in separate spaces). Or just divide an app up in different parts where each part is executed in its own environment and communicates with the other parts as necessary. And all this pure locally. The answer is yes: use separate browser tabs. Surprisingly there are multiple ways of doing this, and the candidate technologies enabling inter-tab communication are : local storage (really) shared web workers broadcast channelling webrtc The demo in this post is based on using localStorage and consists of two separate but standard Smart projects, dubbed 'server' and 'client'. The server-project is just a form with an embedded anchor html element (<a>). When clicked the href-attribute is set to the output of the client-project ('client.html') and the target-attribute to '_blank'. This has the effect of opening up a new browser-tab which runs the client-project. So now there are two browser tabs open, each running its own project. Communication between these tabs is possible using localStorage : mutations in localStorage generate storage-events and these events can be captured and used for communication purposes. This url (https://www.lynkfs.com/Experiments/webrtc/localstorage/server.html) opens up both tabs at once (you might have to allow pop-ups in Chrome or FireFox), and mimics a login process. Server-code and Client-code (native framework but you'll get the idea) Login form : button.OnClick := procedure(sender:TObject) begin //this sends 2 events to the server, which can then validate name and password window.localStorage.setItem('name',name.handle.value); window.localStorage.setItem('pw', pw.handle.value); end; window.onstorage := procedure(e:variant) begin //after validation the server sends a new event with the results console.log(e.key); console.log(e.oldValue); console.log(e.newValue); footer.SetBounds(100,300,200,30); if (e.key = 'result') and (e.newValue = 'ok') then footer.setInnerHTML('login successful'); end; happy holidays
  17. 3 points

    Development updates

    New update available: RTL: TW3TabControl: AnimateTabs-property to control how tabs are changed. TW3ListBox: Prevent an exception if TW3Image is used as a line control and OnShowItem is not set. TW3ListMenu, TW3HeaderControl and TW3SimpleLabel: Don't set default caption to classname during initialization. DWScript: Capitalize day and month names correctly (January instead of january, Sunday instead of sunday) IDE: Improvements to the way the IDE reacts to a changed external file. Use caption while drawing generic controls instead of component name.
  18. 3 points

    New to Node

    Actually, the communication part between a NodeJS server and a Smart client app is pretty easy. Client: You read data from the server using simple http/https get. When you want to write something to the server, you do it with http/https post. Server: You can start with the NodeJS http server example. When your client sends a get or post, it comes to TServer.HandleRequest where you handle the request. You can start by adding some WriteLn to TServer.HandleRequest to print out what the headers and the content is. Then you can send GET and POST requests to it by using a browser (http://localhost:1881/whatever/url/you/want/to/send/it?params=whatever) or curl. With Curl you can easily send post commands. For example: curl -i -X POST -H 'Content-Type: application/json' -d '{"score": "Player": "10000"}' http://localhost:1881 When you can see what's going on in the server, you can also make the client app and start sending those http get/post with TW3HttpRequest (SmartCL.Net.Http) I have done this earlier on the client side with Smart Mobile Studio and it worked nicely. There were hundreds of thousands of users on iOS and Android. The server was in Delphi but it can really be written in any language. I'd probably write my next server in Smart Mobile Studio using NodeJS.
  19. 3 points

    Development updates

    Now it should be possible for everyone to use SmartUpdate with the development-channel.
  20. 3 points

    Smart Mobile Studio 3.0.1 is released!

    Couldn't be easier ?
  21. 3 points
    Recently Microsoft Security Essentials has detected a Trojan:Win32/Azden.B!cl. in Smart Mobile Studio v3.0 smartms.exe binary, and this detection has been removed form malware definitions. Big&Many Thanks to jarto how to submit files to Microsoft in order to remove false malware detection. Report from Microsoft Submission details smartms.exe Submission ID: 43e9c4db-2060-431a-a8d8-17bbddecf3be Status: Completed Submitted by: k**********@gmail.com Submitted: Oct 2, 2018 4:44:50 PM User Opinion: Incorrect detection Analyst comments: Hello Kosta ***, Thank you for your inquiry. We have reviewed the file and we have removed the detection. Please try the following steps to clear cached detections and obtain the latest malware definitions. 1. Open command prompt as administrator and change directory to c:\Program Files\Windows Defender 2. Run “MpCmdRun.exe -removedefinitions -dynamicsignatures” The latest definition is available for download here: https://www.microsoft.com/en-us/wdsi/definitions Best regards, Windows Defender Response Thank you jarto Thank you lennart. Best regards Kosta.
  22. 3 points

    Send an email ?

    This is a 2-step process 1) see this post and follow at least the first steps. Basically establish the link between your app, googles api's and your gmail account. For option 2a(below) you need at least an api-key and clientId, for option 2b you need the full oauth2 gamut including tokens 2) then do one of the following 2a) make use of Googles javascript client library for gmail <!DOCTYPE html> <html> <head> <title>Send email using gmail API</title> <meta charset='utf-8' /> </head> <body> <p>Send email using gmail API.</p> <!--Add buttons to initiate auth sequence and sign out--> <button id="authorize-button" style="display: none;">Authorize</button> <button id="signout-button" style="display: none;">Sign Out</button> <div id="content"></div> <script type="text/javascript"> var apiKey = '********2qOeiRlg2humU4YifLyNqt2TrWR2kGk'; var discoveryDocs = ["https://www.googleapis.com/discovery/v1/apis/gmail/v1/rest"]; var clientId = '********7354-7kp9br0phbsdfkcsilu660u7uq9p6tqs.apps.googleusercontent.com'; var scopes = 'https://www.googleapis.com/auth/gmail.send'; var authorizeButton = document.getElementById('authorize-button'); var signoutButton = document.getElementById('signout-button'); function handleClientLoad() { // Load the API client and auth2 library gapi.load('client:auth2', initClient); } function initClient() { gapi.client.init({ apiKey: apiKey, discoveryDocs: discoveryDocs, clientId: clientId, scope: scopes }).then(function () { // Listen for sign-in state changes. gapi.auth2.getAuthInstance().isSignedIn.listen(updateSigninStatus); // Handle the initial sign-in state. updateSigninStatus(gapi.auth2.getAuthInstance().isSignedIn.get()); authorizeButton.onclick = handleAuthClick; signoutButton.onclick = handleSignoutClick; }); } function updateSigninStatus(isSignedIn) { if (isSignedIn) { authorizeButton.style.display = 'none'; signoutButton.style.display = 'block'; makeApiCall(); } else { authorizeButton.style.display = 'block'; signoutButton.style.display = 'none'; } } function handleAuthClick(event) { gapi.auth2.getAuthInstance().signIn(); } function handleSignoutClick(event) { gapi.auth2.getAuthInstance().signOut(); } // Load the API and make an API call. Display the results function makeApiCall() { const message = "From: lynk@gmail.com\r\n" + "To: nico@hotmail.com\r\n" + "Subject: Subject of this email\r\n\r\n" + "with body text here"; // The body needs to be base64url encoded. const encodedMessage = btoa(message) //but google style, replacing a couple of characters extra const reallyEncodedMessage = encodedMessage.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '') gapi.client.gmail.users.messages.send({ userId: 'me', resource: { raw: reallyEncodedMessage } }).then(function () { console.log("done!")}); } </script> <script async defer src="https://apis.google.com/js/api.js" onload="this.onload=function(){};handleClientLoad()" onreadystatechange="if (this.readyState === 'complete') this.onload()"> </script> </body> </html> 2b) or make an ajax call (post) to https://www.googleapis.com/upload/gmail/v1/users/userId/messages/send and attach a "raw" parameter in the request body with the base64 encoded email as above. I'll "Smart" both of these up a bit when time permits
  23. 3 points
    New update available with SmartUpdate in both alpha- and beta-channels. The update contains lots of bug fixes to the IDE. Some are smaller, but the most important deals with debugging and breakpoints. With this update, breakpoints finally work as they should. The changes to background compilation also makes the IDE a lot smoother to use. We also went through all the demos, fixed and improved a bunch of them and added two new ones. Before updating, please delete the "Featured Demos" -folder to make sure that no old demos will remain after the update. Changelog: 15.7.2018 RTL: - ShowModal: Trigger a cancel if the user clicks on the opaque background. - Bug fixes to Scrollbars - Changed padding in all themes. - Previously all controls had default padding (usually 2px), including div. - Now only known controls have the default padding. - Bug fix to TW3Image.LoadFromStream() IDE: - Bug fixes and improvements to background compilation. - Fixes problems with setting breakpoints in the SMS IDE. - If debugging with breakpoints, code obfuscation and packing is switched off. - If execute was set to a browser, instead of embedded Chrome, closing the debugger window caused an exception. - Fix "code painting bug while scrolling" in SynEdit. - Color picker to work with styled application. Demos: - Added: - https server demo - ThemeView demo - Bug fixes and improvements to many demos.
  24. 3 points
    New update available with SmartUpdate in both alpha- and beta-channels: 1.7.2018 Range checking caused apps not to start due to an error in Base64 lookup tables. Update TW3AceEditor. TW3TabControl: If PrepareTab was called for the visible tab, it was moved to the wrong place. TW3Label: Fix vertical alignment to work with older browsers. TW3ComboBox: Allow values to be set during ObjectReady. Bug fix to TMemoryStream.WriteBuffer. Bug fix to WaitFor.
  25. 3 points
    WebWorkers and Flow Based Programming It has been a while since I got as excited as I was when I read J.Morrison's book "Flow-Based Programming: A New Approach to Application Development - 2nd edition". This post is not meant to give an overview of FBP, but if someone is interested, the first edition of his book is available online for free. FBP utilises independantly running processes which are wired together in an assembly line type of arrangement. The main advantages are that each process runs on demand rather than on availability, components can easily be re-wired to implement changes in requirements and there are possibilities for extensive component re-use. I was in the process of porting this framework to Smart, when I realised that javascript and concurrently running processes is not an easy match. Basically all js code in the browser executes in the same thread, and time-slicing mechanisms like setTimeout (used in the framework I was porting) doesn't enable real concurrent processing. However there are 2 exceptions to escape the single-threadedness : IFrames and webworkers. Both implement runtimes separate from the main thread and have their own heap, stack and message handling mechanism. The similarities between the FBP and shared webworker specs are (more than) striking, so this post is about having a go at implementing FBP using webworkers. Technically - processes (fbp) can be implemented through shared webworkers - connections between processes (fbp) can be implemented using channels (webworker to webworker, buffered) - ports (fbp) can be implemented using ports (webworker) - reading/writing of information packets's (fbp) can be implemented using messaging (webworker) - information packet handling (fbp) can be implemented using the transferable interface (webworker) The demo chosen is a variation of the 'Galaxy Clock' project in the featured-demo's section. The variation being that the 'single motor' driving the 3 hands of the clock (hr, min, sec) is replaced by 3 separate 'motors', each driving one of the hands and each one operating in its own thread. The architecture of this demo : a scheduler webworker receives the current local time when a button is clicked in the main program. It transfers the time-elements to each of the other web-workers through the channels created. These other webworkers in their turn update the main project at appropriate intervals. The result of this rather peculiar architecture. The hr/min/sec displays are purposely not synchronised and are all running at 10x normal clock-speed.