Jump to content


  • Content Count

  • Joined

  • Last visited

  • Days Won


Reputation Activity

  1. Like
    Czar reacted to lynkfs in panel.zoom and firefox   
    zoom is not supported in firefox (https://caniuse.com/#search=zoom) and opera
    The workaround is to use the "transform" css function
    W3Panel1.handle.style.transform := "scale(1.5)"; You can scale to different values for x and y as in "scale(2, 3)"
  2. Like
    Czar reacted to jarto in Update   
    Hi all,
    as you probably have noticed, I've been very quiet lately. When COVID-19 spread around the world, the restrictions hit my personal life pretty hard. In UAE, all the schools were closed very early and remained closed all the way to the end of the semester. There was also a strict lock down and lots of restrictions. Doing a lock down with three small children and having to home school them basically meant that my chances of spending many hours of time on development went to nil.
    Luckily it seems like the schools will open in 3 weeks, which should give me a possibility to concentrate on development again. My plan is to get 3.0 out then.
  3. Like
    Czar reacted to lynkfs in the future of coding   
    Read this article , at least till the paragraph "and now for the fun part". 
    Then, after that, have a look at this 
  4. Like
    Czar reacted to lynkfs in styling   
    Off topic : there is an interesting effect when putting images on top of images.
    Take an image and give it a large width and height. Take the same image (same src) and place it on top of the first image, give it same height but say 25% of width and center it. Both images should have object-fit set to 'cover' and reduce opacity of the first one to about 65%.
    Depending on the image, about 1 in 5 give a passable interesting result doing this, 1 in 50 look amazing.
    Some examples here. 
    (not optimised for size, so slow loading)
  5. Like
    Czar reacted to lynkfs in percentage based positioning   
    Percentage based positioning has the advantage of having a 'responsive' page layout with little effort.
    Responsive in this respect means that page layouts will scale seamlessly on devices which may have slightly different pixel dimensions horizontally and/or vertically.
    So instead of having an editbox on absolute positioning 100,100,400,35 in pixel terms, it is sometimes easier to define all or some of these in percentages. Conveniently 10%-left is interpreted by the browser as starting on 10% of the viewport width, 10%-top starts at 10% of the viewport height etc.
    Mixing pixels and percentages works fine too
    MyEditBox.handle.style.left := '10%'; MyEditBox.handle.style.top := '12px'; //MyEditBox.left := 12; This is all still based on absolute positioning, which is the default in Smart.
    An alternative approach, with the same outcome, is to define dimensions at runtime based on a formula.
    MyEditBox.handle.style.left := 'calc(10vw - 20px)'  resolves in a left positioning of 10% of the viewport-width minus 20 pixels : 28 pixels on a 480 pixels wide phone
    Note that the minus sign needs to be enclosed in spaces or this won't work
    This can be also used to scale f.i. font size depending on device capabilities :
    MyEditBox.handle.style['font-size'] := 'calc(16px + 1vw)'  which has the effect of a font size which grows by 1 pixel for every 100 pixels of viewport width. 
    It can get a bit funny on orientation change
    an all-percentage example page with some random text and images, based on these principles, looks like this , which scales nicely from mobile to desktop (resize browser window).
  6. Like
    Czar reacted to lynkfs in ionic   
    Usually I try to steer away from external frameworks. They seldom provide exactly what is needed and are difficult to modify.
    An exception may be the ionic framework. It is an open source ui toolkit with some nice elements in it. The good thing is that their components subtly change depending on which platform they are used on.
    The following code uses 2 Ionic components : a button and an extremely elegant selector
      var iobutton : TIonicButton := TIonicButton.Create(self);   iobutton.setbounds(100,100,100,35);   iobutton.color := 'primary';   iobutton.fill := 'outline';   iobutton.caption := 'mybutton';   iobutton.onclick := procedure(sender:TObject)     begin       showmessage((sender as TIonicButton).caption);     end;   end); and the selector
      var iofab : TIonicFab := TIonicFab.Create(self);   iofab.setbounds(400,200,56,56);   iofab.mainIcon   := 'share';   iofab.topIcon    := 'logo-vimeo';   iofab.bottomIcon := 'logo-facebook';   iofab.leftIcon   := 'logo-instagram';   iofab.rightIcon  := 'logo-twitter';   iofab.right.button.onclick := lambda showmessage('twitter'); end; See demo here
    The code for both the button and the selector component in unit2/3 of this project
  7. Like
    Czar reacted to lynkfs in styling   
    Looking into this idea a bit further.
    So the ultimate styler program needs to do this :
    - read in a theme file
      - discover the visual components in the theme
      - and populate them for use
    - have a canvas where these components can be dropped on
      - and can be manipulated qua size and position
      - and have a preview for how it looks in real life
    Basically this is an exercise in elevating css to its maximum capabilites, without using js (pascal) or html at all in the styling process.
    A first draft of such a program :
    The demo theme file contains components for buttons and images, and thus these are displayed on top.
    These can be dragged onto the canvas and positioned at will. The coordinates are displayed on the right, either in absolute or relative values. 
    The preview icon on the canvas opens up a new live browser window.
    So far so good.
    The huge number of atomic css properties per visual component (280) now has been subdivided in 3 chunks :
    A- those css properties to do with visual design : x (left), y (top), width and height
       These are displayed on the right
    B- those css properties which are part of the theme file for this component
       so if for instance the theme file has a line like this: "theme01.buttons.generic.fontWeight: bold", then this will result in a modifier on the screen, where 'bold' can be changed.  <to do>
    C- the remainder of the 280 css properties (280 minus A minus B). 
       Those are either not important, have passable default values or are only seldomly important for styling of the particular component. <to do>
    Using components ultimately translates into html. 
    Taking this example : 
    <img class="img" id="Component38" src="images/buttons.jpg" name="button" style="visibility: visible; display: inline-block; position: absolute; overflow: auto; left: 350px; top: 10px; width: 82px; height: 34px; cursor: pointer;"> Styling through css results in modifying the style attribute (.. style="visibility: etc...)
    Still debating whether the other attributes should be part of the styling process.
    In the demo above for instance I've assigned the 'src' attribute of images to a random unsplash picture, instead of making it directly editable. Its not a css property after all.
    Demo here (alpha version)
  8. Thanks
    Czar reacted to lynkfs in https://peerjs.com/ - is this feasible?   
    just as a proof of concept :
    tutor initiates conversation with student : https://lynkfs.com/Experiments/peer/receive/www
    and on another machine : https://lynkfs.com/Experiments/peer/send/www (must be on another machine)
    student sends a text by copying tutor id into the edit box and pressing buttons 1, 2 and 3
    this text then arrives at the tutors project
    The user interface of these projects is really bad, sorry, just proof-of-concept. 
    This demo is basically a simple chap app, but since it is using webrtc (and webrtc handles not only text but also other media), I feel that extending this to a full-fledged channel between parties should be feasible and reasonably straightforward
  9. Like
    Czar reacted to lynkfs in https://peerjs.com/ - is this feasible?   
    Just going through the first bit of their docs, it looks fairly straightforward
    procedure TForm1.W3Button1Click(Sender: TObject); begin //   var Script := browserapi.document.createElement('script');   Script.src := 'https://cdn.jsdelivr.net/npm/peerjs@0.3.20/dist/peer.min.js';   browserapi.document.head.appendChild(Script);   Script.onload := procedure   begin     writeln('peer.js loaded');     asm @mypeer = new Peer({key: 'lwjd5qra8257b9'}); end; //demo key     mypeer.on('open', procedure(id:string) begin writeln('New peer ID : ' + id); end);   end; end; the remainder doesn't look too cumbersome, i'll have a look later
  10. Like
    Czar reacted to lynkfs in https://peerjs.com/ - is this feasible?   
    webrtc I think has come of age, so it's worthwhile exploring
    I'll be happy to have a look
  11. Like
    Czar reacted to lynkfs in app   
    I usually don't publish commercial apps on the forum.
    Here is the exception : a retail shopping experience - made with Smart
  12. Like
    Czar reacted to lynkfs in design templates   
    I'm sharing some links below to app-demo's, based on design templates.
    I'm a big fan of these types of templates as they provide essential design guidance on navigation, styling and the use of animation. And since I'm not a graphic designer, that all helps tremendously.
    The demo's below are recreated in Smart, using elements of the 'famous' design templates (https://famous.co)
    Retail shop demo couple of slides of a business presentation  demo's optimised for laptop only
    (also the background video's on the first forms may take a couple of seconds to load)
    On the animation side : the animation framework in these demo's is based on waapi (web animation api) and consists of an extension of the standard form handling. Basically every form and every component on a form can enable web-animation events. These events are triggered by the phase a form is in : coming into focus going forward, going out of focus going forward, coming into focus going backwards and going out of focus going backwards. These phases not only trigger screen events, but also all component animation events
    Procedure Traverse(phase: string; screen: string; direction: string); begin   var z : variant := new JObject;   z := browserapi.document.getElementById('Component2').getElementsByTagName("*");  //all children of TDisplayView   for var i := 0 to z.length-1 do begin     if z[i].dataset.screen then begin       if (phase = 'init') and (screen = z[i].dataset.screen) then begin         if (direction = 'forward') then begin           if z[i].dataset.initforwardanim then             z[i].animate(json.parse(z[i].dataset.initforwardanim),z[i].dataset.initforwardtime);         end;         if (direction = 'reverse') then begin           if z[i].dataset.initreverseanim then             z[i].animate(json.parse(z[i].dataset.initreverseanim),z[i].dataset.initreversetime);         end;       end;       if (phase = 'exit') and (screen = z[i].dataset.screen) then begin         if (direction = 'forward') then begin           if z[i].dataset.exitforwardanim then             z[i].animate(json.parse(z[i].dataset.exitforwardanim),z[i].dataset.exitforwardtime);         end;         if (direction = 'reverse') then begin           if z[i].dataset.exitreverseanim then             z[i].animate(json.parse(z[i].dataset.exitreverseanim),z[i].dataset.exitreversetime);         end;       end;     end;   end; end;
  13. Like
    Czar reacted to jarto in Parsing unknown JSON (into TW3StringGrid)   
    procedure TForm1.AnalyzeJSON(jsontxt: String); var jroot: TJSONObject; begin jroot:=TJSONObject.Create; jroot.FromJson(jsontxt); writeln('Items: '+IntToStr(jroot.Count)); jroot.ForEach(function (Name: string; Data: variant): TEnumState begin var jobj:=TJSONObject.Create(Data); var k:=jobj.Keys; writeln('Keys: '+IntToStr(Length(k))); for var a:=0 to Length(k)-1 do begin var key:=k[a]; Writeln(Format('Key %s has value %s',[key,jobj.Values[key]])); end; result:=esContinue; end); end;  
  14. Like
    Czar reacted to jarto in Smart Mobile Studio 3.9.1 (1st Alpha release) is available   
    New update is available. This is probably the last alpha release.
    Add TabOrder-property Make TW3Label, TW3Display and TW3DisplayView not focusable Set TabOrder for these if you want to override this TW3CheckBox and TW3RadioButton: Value can be changed with keyboard Allow changing of HRange and VRange in TW3SwipeController Improvements to DateTimeToLocal and LocalDateTimeToUTC IDE:
    Fix exception in code that monitors changes to RTL files. Prevent exception during startup if IDE's internal port is already in use.  
  15. Like
    Czar reacted to warleyalex in TIPOFDAY#10 - Using Promises in SMS   
    Promises in Smart Mobile Studio
    Example: Run Promises in Sequential
    Note: you have to return next promise from success callback!
    function getURI(url: string): variant; begin // Create new promise with the Promise() constructor; // This has as its argument a function // with two parameters, resolve and reject Result := JPromise.create( procedure(resolve: TCallback; reject: TCallback) // Standard XHR to load an image var request: JXMLHttpRequest; begin request := new JXMLHttpRequest(); request.open('GET', url); // When the request loads, check whether it was successful request.onload := lambda begin // This is called even on 404 etc // so check the status if (request.status = 200) then begin // If successful, resolve the promise by passing back the request response resolve(request.response); end else begin // Otherwise reject with the status text // which will hopefully be a meaningful error reject(Error("File didn't load successfully; error code: " + request.statusText)); end; end; end; // Handle network errors request.onerror := lambda // Also deal with the case when the entire request fails to begin with // This is probably a network error, so reject the promise with an appropriate message reject(Error('There was a network error.')); end; // Send the request request.send(); end); end; getURI('data/step1.json') .then(lambda(): variant exit getURI('data/step2.json'); end) .then(lambda(): variant exit getURI('data/doesnt-exist.json'); end) .then(lambda(): variant exit getURI('data/step3.json'); end) .then(lambda(response: variant) console.log(response); end) .catch(lambda(error: variant) console.log(':('+ error); end);
  16. Like
    Czar reacted to jarto in Smart Mobile Studio 3.9.1 (1st Alpha release) is available   
    A new update is available. This one contains improvements for aligning TW3CheckBox and TW3Radiobutton, when word wrap is used. Huge thanks to @lynkfs and @Daniel Eiszele for their help with this!
    Change horizontal alignment to be done using flexbox styles. This affects mostly TW3CheckBox and TW3RadioButton, but also other controls that are using lbxcontent -styles. Improve right alignment of TW3CheckBox and TW3RadioButton
  17. Like
    Czar reacted to jarto in Checkbox Wordwrap   
    That property doesn't seem to work. Let me have a quick look.
    Yep, confirmed. There are issues with other properties as well. On it...
  18. Like
    Czar reacted to jarto in open external link in new tab of browser   
    I need to have a look at the code completion/code insight. It's been on my bug list for quite some time. Have to see what I can do to that internal browser shutdown issue as well :-)
  19. Like
    Czar reacted to Daniel Eiszele in open external link in new tab of browser   
    Try using BrowserApi.Windowobject.open( ) instead. Note that "window" is of type THandle which means you can utilise any valid javascript method/property on it, but code completion will not work. "Windowobject" on the other hand is of type Jwindow and is built with code completion in mind. 
  20. Like
    Czar reacted to lynkfs in open external link in new tab of browser   
    The other possible downside of using window.open is that it depends on the users browser setting whether it opens a new tab or a new window.
    This behaviour cannot be determined by js, it is dependent on the user.
    While chrome seems to favour using the tab-mechanism, other browsers don't. I've tested a couple which resulted in 'pop-up blocked' messages
    Also mobile browsers don't have tabs, so they will spawn a new window at best.
    (There is something called the tab-api, which gives granular tab processing under program control. This is used for developing browser extensions, which I have never done. It may or may not be possible to use that api in SMS, although I suspect that even if it does, it will have ramifications)
    Another possible option is of course using an iFrame element on the form. Depends on your requirements
  21. Like
    Czar reacted to jarto in open external link in new tab of browser   
    procedure TForm1.W3Button1Click(Sender: TObject); begin BrowserAPI.Window.open('https://www.google.com', '_blank'); end;  
  22. Like
    Czar reacted to Daniel Eiszele in open external link in new tab of browser   
    Would something like this work?
  23. Like
    Czar reacted to lynkfs in Performance due to compiler optimisation   
    The other thing I noticed when comparing the same project generated by SMS3.0.0 and the latest alpha is a marked speed increase.
    I did some tests on the training phase of a neural network, with these results :
    SMS 3.0.0 : Training took 30810 milliseconds.
    SMS 3.1.9 : Training took 18937 milliseconds.
    SMS 3.0.0 : Training took 32611 milliseconds.
    SMS 3.1.9 : Training took 47272 milliseconds.
    SMS 3.0.0 : Training took 34233 milliseconds.
    SMS 3.1.9 : Training took 16627 milliseconds.
    SMS 3.0.0 : Training took 33177 milliseconds.
    SMS 3.1.9 : Training took 18275 milliseconds.
    SMS 3.0.0 : Training took 30762 milliseconds.
    SMS 3.1.9 : Training took 16734 milliseconds.
    SMS 3.0.0 : Training took ... milliseconds. 
    SMS 3.1.9 : Training took 16062 milliseconds.
    Except for 1 outlier, the speed difference of the latest alpha is about on average 1.6 - 1.8 times faster
    This can only be due to compiler optimisation
  24. Like
    Czar reacted to jarto in Smart Mobile Studio 3.9.1 (1st Alpha release) is available   
    New update available:
    Move setting of Align higher up in generated form sfm Take port for welcome page and form designer from IDE settings. RTL:
    Improvements to how forms are built from form sfm: Minimize resizes and alignments during construction Do not hide a form too early Add TVariant.Values (Thank you Daniel Eiszele) Bug fix to TVariant.ForEachProperty Compiler:
    Bug fix to Randomize in DWScript
  25. Like
    Czar reacted to IgorSavkic in Form designer improvements   
    Right now form and control definitions, properties and events are stored inside .sfm files. 
    In new SMS IDE designer uses Chrome so there's a nice opportunity to update that part, my idea is to store control definitions inside regular html files and have events and SMS specific properties stored inside .sfm file. That would probably be a major upgrade but it would bring so much benefits, for example separation of UI design from code, UI would be handed to designer and I could focus on programming logic. It would also allow to reuse available online templates and libraries, which would shorten development time.
    Alternative (perhaps easier to implement) would be build html importer, when you need a new form, select external .html file and IDE recreates it as standard .sfm file, unsupported controls could be mapped to neareast SMS equivalent (for example UL/OL lists would be mapped to ListBox) or to standard div/panel.
  • Create New...