Jump to content

Daniel Eiszele

  • Content Count

  • Joined

  • Last visited

  • Days Won


Reputation Activity

  1. Like
    Daniel Eiszele got a reaction from Tim Koscielski in JSON.parse on String Variable   
    Hi @COMFIED, I'm not sure if the following answers your question or not.
    Add System.JSON to your uses clause and run the following. Some follow up questions would be, is the object you are passing always a single key/value pair and is the name of the key known or not known? There are many ways to do this; some type safe, others not - just depends on your use case really.
    var aString : String; anObject : variant; begin aString := '{"v" : "this is sample text"}'; anObject := TJSON.parse(aString); Showmessage(anObject.v); end;  
  2. Like
    Daniel Eiszele reacted to jarto in Smart Mobile Studio 3.9.1 (1st Alpha release) is available   
    A new update is available:
    Fix compilation without saving, when SMS is run from Program Files Change embedded browser to always use localhost This lets us use Chrome's Powerful Features through http RTL:
    Add RemoteUrl as a property for TNJWebSocketServer Bug fixes and improvements to TW3Slider Works now with mobile devices Set default max value to 100
  3. Like
    Daniel Eiszele reacted to jarto in Smart Mobile Studio 3.9.1 (1st Alpha release) is available   
    A new update is available. This one contains two new controls:
        TW3GoogleLogin     TW3FacebookLogin Both are non-visual components, but they are available in the Designer under the Cloud-tab.
    These two controls let you add Single-Sign-On via Google and Facebook to your web page. To use them,
    Add the control to the form Set the AppId- or ClientId-properties You need to register at Google or Facebook to get these ids You also need to copy the app to the registered URI that you specify during registration Set the OnLogin and OnLogout -events Finally, set Enabled to True Copy the compiled app to your web server and test Documentation:
    Note! When writing this, there is a problem with Facebook's API and Firefox browser. This problem is not related to Smart Mobile Studio at all, but affects any Facebook logins in Firefox. Refer to these URLs for more information:
  4. Like
    Daniel Eiszele reacted to jarto in Facebook or Google OAuth   
    @lynkfs Oh, that helped so much! I've struggled at the concept of calling these external js apis when class references don't exists and also had no experience with using promises. But you helped me get going and now I'm making very good progress 🙂
    Now I have TW3FacebookLogin- and TW3GoogleLogin-classes that both work. I'll have to read up a bit to add the necessary parameters (besides ClientId of the app), but I should be able to get them into alpha and component palette next week.
  5. Like
    Daniel Eiszele reacted to lynkfs in Facebook or Google OAuth   
    Works from server only, the one specified in the credentials page
    var document external 'document': variant; var console  external 'console':  variant; var gapi     external 'gapi':     variant; implementation { TForm1 } procedure TForm1.InitializeForm; begin   inherited;   // this is a good place to initialize components   var Script := document.createElement('script');   Script.src := 'https://apis.google.com/js/api.js';   Script.setAttribute('async','');   Script.setAttribute('defer','');   document.head.appendChild(Script);   Script.onload := procedure   begin     writeln('loaded');     //     // Load the API client and auth2 library     gapi.load('auth2', procedure     begin       var mypromise : variant;       mypromise := gapi.auth2.init(class         clientId = '..........s0m9qrp8u2m6dcivi8p09tu5se.apps.googleusercontent.com';       end); mypromise.then(procedure begin console.log(mypromise.isSignedIn.get()); end, procedure begin console.log('error'); end);     end);   end; end; logs 'loaded' and 'true'
    your other link does specify useful functions which can be added to the above
  6. Like
    Daniel Eiszele reacted to jarto in Facebook or Google OAuth   
    Yep, got it working nicely. I'm in the process of writing this into a non-visual component, which can be added to the component palette.
  7. Like
    Daniel Eiszele reacted to jarto in Smart Mobile Studio 3.9.1 (1st Alpha release) is available   
    A new update is available:
    IDE: When a property is changed, the IDE adds the required unit into uses clauses. RTL: Bug fix to TRESTCall: Call OnRemove only if it is assigned.
  8. Like
    Daniel Eiszele 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.
  9. Like
    Daniel Eiszele got a reaction from lynkfs in the future of coding   
    With great power comes great responsibility!
  10. Like
    Daniel Eiszele 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)
  11. Like
    Daniel Eiszele reacted to jarto in Smart Mobile Studio 3.9.1 (1st Alpha release) is available   
    A new update is available:
    Fix character set that was sent from the internal server RTL:
    Bug fix to handling resizes when anchor gaps are locked. Improvements to TW3ScrollBox Scrollbars -property can now be changed in Object Inspector The ScrollBox waits properly until it's subcontrols are ready ScrollBars and indicators did not work properly if ForceParent was true Fix bugs in resizing the scrollbox
  12. Like
    Daniel Eiszele reacted to lynkfs in Scroll form   
    I'm not a js guru , or maybe
    Anyway, logically it's either the form or the memo which reacts to scrolling/swiping.
    If you want both, you need to be able to distinguish in which situations you want either to happen.
    There are various ways to do this, one of them this : as soon as the form scrolls, disable scrolling on the memo altogether. Then you need to determine under which condition you want to re-enable scrolling the memo. One way would be to have a simple onclick handler
    procedure TForm1.InitializeForm; begin   inherited;   // this is a good place to initialize components   self.NativeScrolling := true;   self.onscroll := lambda W3Memo1.NativeScrolling := false; end;   W3Memo1.OnClick := lambda W3Memo1.NativeScrolling := true; end; demo here 
    Instead of having to click the memo, it would be better to do this automatically when form-scrolling has ended. There is no such thing as a scroll-end event, but you could simulate one by using a timer of say 1000 ms. Reset the timer continuously during form scrolling and re-enable memo scrolling after the timer fires.
    This may work for you, but it is hooking into some finely tuned browser actions, so look out for surprises.
  13. Like
    Daniel Eiszele reacted to lynkfs in styling   
    Styling of visual elements.
    There are some 280 separate css properties which can be used to style each and every visual dom element. The following statement produces such a list
    var styles := browserapi.window.getComputedStyle(Panel.handle); (280 entries) If we disregard the properties which have a vendor prefix (-webkit, -moz etc) we still end up with some 230 properties for each visual element. 
    And although many of these have default property values, the complexity is just too great to do styling on this level.
    Each and every css framework (including Smart) tries to reduce the complexity by a number of measures
    group css properties into meaningful categories,  give these groups meaningful names and  possibly also rename individual properties connect groups to visual components making sure that all groups adhere to application wide values (i.e. primaryBlue is set to "#ebf8ff" in all groups) eliminate annoying differences in how browsers interpret universal css do this either static and/or dynamic in code The way the above is implemented varies wildly across frameworks.
    Two examples :
    Smart does its standard styling mainly by grouping classes on the level of components (1), giving them component names like .TW3Button (2,4). Every visual component gets this class on creation with 2 additional classes for background and border (4).
    So the resulting styling of a button gets defined by <button class="TW3Button TW3ButtonBackground TW3ButtonBorder" ...
    The supplied css templates in the Templates directory have a feature which implements application wide setting (5), so f.i. const 'EdgeRounding' will be set to "4px" in all components which use 'EdgeRounding (3)'. 
    There also some settings which standardise browser behaviour (6)
    Furthermore the rtl has methods to manipulate all classes, groups, properties and stylesheets in code (SmartCL.Css.Classes, SmartCL.Css.Stylesheet (7)
    Tailwind CCS. 
    This framework is sort of on the other side of the spectrum. It groups css properties in a large numer of very small groups (1,2,3). These groups are almost atomic in nature, so f.i. the 'm-0' class is specified as { margin: 0 }.
    It basically does not do any of 4,5,6 or 7
    So implementing a button using Tailwind involves many classes :
    <button class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded" which gives a light blue button with rounded corners, becomes a bit darker on hover, has its caption in bold white and has specific values for top/bottom and left/right padding. 
    Nevertheless people build beautifully styled apps and websites using Tailwind. And it is readily accessible through code (7)

    Thinking about how to merge the best features of the above into a styling design mechanism, I would look at doing this :
    1- define a (limited) number of atomic groups. An atomic group combines and names simple css properties which can be used in more complex structures. Candidates are : colors, borders, backgrounds and fonts to start off with. The font-category f.i could be sub-grouped in 'families', 'sizes', 'weights', 'letterSpacings' and 'lineHeights'.  As an example the 'lineSpacings' subgroup could then be specified as
      "letterSpacings": {     "tighter": "-0.05em",     "tight": "-0.025em",     "normal": "0",     "wide": "0.025em",     "wider": "0.05em",     "widest": "0.1em"   }  
    2- define generic building blocks or component groups, i.e a generic button, using as many of the atomic groupings from 1) as possible
    "button": {      "cursor": "pointer",      "fontSize": "100%",      "lineHeight": "inherit",      "backgroundColor": { "colors" : "primary" },      "border": "none",      "color": "white",      "fontWeight": "bold",      "borderRadius": { "radii" : "default" },      ":hover": {        "backgroundColor": { "colors" : "primaryHover"},     } This uses the atomic 'colors' group, which will have entries like
        "primary": "#2b6cb0",     "primaryHover": "#2c5282" which then will be substituted in the above, so f.i. the 'backgroundColor' entry will become "backgroundColor": "#2b6cb0"
    This way all groups who use 'colors:primary' will have the same colour value, application-wide.
    3- define descendants from the component groups from 2), f.i. a rounded pill button, which only has those properties different from its parent
      "buttons": {
          "pill": {
            "borderRadius": "full",
    So far the above examples boil down to something like this after substitution (2) and child creation (3) 
    theme01.colors.primary: #2b6cb0 theme01.colors.primaryHover: #2c5282 theme01.buttons.generic.cursor: pointer theme01.buttons.generic.fontSize: 100% theme01.buttons.generic.lineHeight: inherit theme01.buttons.generic.backgroundColor: #2b6cb0 theme01.buttons.generic.border: none theme01.buttons.generic.color: white theme01.buttons.generic.fontWeight: bold theme01.buttons.generic.borderRadius: 0.25rem theme01.buttons.generic.hover.backgroundColor: #2c5282 theme01.buttons.generic.pill.borderRadius: 9999px and a class invocation like <button class="buttonPill ..."  (or even TW3Button)

    4- generate this into a regular css template and include the modernize.css entries to harmonize across browsers as well.
    5- integrate this in the visual designer
    Actually the style generation should closely follow the hierarchy in the visual designer. So if there is a rounded-button on a panel on a form on the <body> element, then the css property values should reflect the #body, #form, #panel, #generic-button and #rounded-button properties (and nothing more).
    just an idea, but doable
  14. Like
    Daniel Eiszele reacted to jarto in Smart Mobile Studio 3.9.1 (1st Alpha release) is available   
    Another important fix to handling of aligns is available.
  15. Like
    Daniel Eiszele reacted to jarto in Radiogroup add function   
    Fixed now in the alpha. Thank you @lynkfs for finding an important bug. This affected way more than just the radiogroup.
  16. Like
    Daniel Eiszele reacted to lynkfs in Radiogroup add function   
    Composing a Radiogroup in the designer works fine
    For objects created in code however the add function doesn't work
    //creating in code var RadioGroup1 : TW3RadioGroup := TW3RadioGroup.Create(self);   RadioGroup1.setbounds (200,200,200,200);   RadioGroup1.Add('bbb'); <==== no results //created in the designer   W3RadioGroup1.Add('aaaa'); <==== correct results (probably to do with the difference between TStringlist and TStrArray)
  17. Like
    Daniel Eiszele reacted to jarto in Smart Mobile Studio 3.9.1 (1st Alpha release) is available   
    An important fix is now available in the alpha channel:
    Bug fix to handling calls for resize when component is not ready
  18. Like
    Daniel Eiszele got a reaction from Tim Koscielski in Managing Tab Order in a Form   
    I vote for remove. As far as my understanding goes it does not follow the html "standard". I too was trying to work out why it was being set to 0 as a "default"? 
  19. Like
    Daniel Eiszele got a reaction from jarto in Bug in LocalDateTimeToUTC   
    Sorry, you are correct with 1. Being locked inside for 3 weeks with my kids is getting to me the new amendments look good.
  20. Like
    Daniel Eiszele reacted to jarto in Bug in LocalDateTimeToUTC   
    In TDateTime the integer part is the number of days since Dec 30th 1899. If the TDateTime contains just a time with no date, then it's a number that is bigger than 0 and smaller than 1. In that case it makes sense to use the current TZ. Maybe like this:
    function DateTimeToLocal(const UTCTime: TDateTime): TDateTime; begin var JD:=new JDate(); if Abs(UTCTime)>=1 then JD:=DateTimeToJDate(UTCTime); result:=UTCTime+JDateToLocalDateTime(JD)-JDateToDateTime(JD); end; function LocalDateTimeToUTC(const LocalTime: TDateTime): TDateTime; begin var JD:=new JDate(); if Abs(LocalTime)>=1 then JD:=DateTimeToJDate(LocalTime); result:=LocalTime+JDateToDateTime(JD)-JDateToLocalDateTime(JD); end;  
  21. Like
    Daniel Eiszele got a reaction from jarto in Managing Tab Order in a Form   
    I vote for remove. As far as my understanding goes it does not follow the html "standard". I too was trying to work out why it was being set to 0 as a "default"? 
  22. Like
    Daniel Eiszele reacted to DavidRM in Managing Tab Order in a Form   
    I manually set the tabIndex for the controls. And use the key down event to handle pressing ENTER to move to the next control.
    I set it using the Handle property.
    FLoginHandleLabel := TW3Label.Create(FPanel); FLoginHandleLabel.AutoSize := True; FLoginHandleLabel.TextNode.style.setProperty('font-weight', 'bold'); FLoginHandleLabel.Caption := 'Handle (or email address)'; FLoginHandleEdit := TW3EditBox.Create(FPanel); FLoginHandleEdit.PlaceHolder := '...handle'; FLoginHandleEdit.OnGotFocus := LoginHandleEditGetFocus; FLoginHandleEdit.OnKeyDown := LoginHandleEditKeyDown; FLoginHandleEdit.Handle.tabIndex := 1; FLoginPasswordLabel := TW3Label.Create(FPanel); FLoginPasswordLabel.AutoSize := True; FLoginPasswordLabel.TextNode.style.setProperty('font-weight', 'bold'); FLoginPasswordLabel.Caption := 'Password'; FLoginPasswordEdit := TW3EditBox.Create(FPanel); FLoginPasswordEdit.PlaceHolder := '...password'; FLoginPasswordEdit.InputType := itPassword; FLoginPasswordEdit.OnGotFocus := LoginPasswordGetFocus; FLoginPasswordEdit.OnKeyDown := LoginPasswordEditKeyDown; FLoginPasswordEdit.Handle.tabIndex := 2; I'm still using the latest real release, not the alpha. So I create my UI controls manually. It might be easier with the latest alpha.
    Also, I've become very accustomed to mixing Javascript in with my Object Pascal to handle situations like this.
  23. Thanks
    Daniel Eiszele reacted to IgorSavkic in Nodejs.Path Unit   
    That needs fix from dev team, but as a workaround try to write class helper (untested) and hopefully it will take precedence over default declaration.
    JPathExportHelper = class helper for JPath_Exports
       function Join(Paths: string): string;
    and implementation as:
    asm @Result = join(@Paths); end
    Result := Variant(Self).join(Paths);
  24. Like
    Daniel Eiszele 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);
  25. Like
    Daniel Eiszele 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
  • Create New...