Jump to content


  • Content Count

  • Joined

  • Last visited

  • Days Won


Everything posted by lennart

  1. I would need to see exactly what you tried to inject into the stylesheet. The stylesheet's innerhtml would contain exactly what you would use in an external file. The other variation of add takes a name + rule (look at the code and you will see).
  2. lennart

    TryStrToInt bug

    I have tracked the bug down, and its actually not about TryStrToInt. The bug happens even if you remove calls to that function. It is the codegen that has made a mistake with regards to how values are stored inside SMS. The {}.v thing is the only way to emulate VAR params, and for some odd reason that is not dealt with properly. But I have registered the bug with the guy doing the codegen. Hopefully that will be resolves quickly.
  3. lennart

    TryStrToInt bug

        I had a closer look at now I was able to reproduce the problem. Yes, it seems that this combination was not implemented by the codegen. The way compilers work is that there has to be a unified way to deal with source/target symbols. In this case the combination of a global variable mixed with a class-context call to a unit procedure somehow returned the whole var object rather than just the value. Not a huge bug but indeed enough to cause frustration. I will pass this along to Eric and see what we can do. The codegen has a test-pass rate of 95% which is actually very high (Delphi XE6 had a rate of 70+ before the updates), but like all living software things can break. And ofcourse, we are very sorry that we didnt pick up on these before. The Smart Mobile Studio codebase is a massive undertaking, and there are bound to be glitches and mistakes. Smart has remained somewhat in the shadows for a couple of years, and we have finally started to get the wheels turning again. So while there will be bugs (especially now in the Alpha phase) - we are here to remove them. So keep on reporting things like this and we will fix them one by one. In a perfect world we would have caught this sooner, but like I mentioned earlier - a lot of this tech doesnt exist in JavaScript. So we have had to work miles off the beaten track. No body has done anything like this before, so there will be odd workarounds here and there. Best regards Jon L. Aasenden
  4. There are quite a few things to talk about here, but lets start with the basics. First, you never create instances of TW3CustomControl. This is meant for inheritance only. So in your case you would start by defining your spinner-class: type TSpinner = class(TW3CustomControl) // Override stuff here end; Next we come to css, and I think what you need is to create your own stylesheet in code.While its perfectly ok to use the theme sheet, I think in your case it would be easier to create a stylesheet in memory to deal with things like this. So add the unit "SmartCL.Css.Stylesheet" to your uses clause and have a look there. The class TW3StyleSheet have 4 class functions for adding, removing or checking is a class has been added to a control handle -- but I think you want to create an instance of TW3StyleSheet. type TSpinner = class(TW3CustomControl) private FSheet: TW3StyleSheet; protected procedure InitializeObject; override; procedure FinalizeObject; override; end; procedure TSpinner.InitializeObject; begin inherited; FSheet := TW3StyleSheet.Create; end; procedure FinalizeObject; begin FSheet.free; inherited; end; Next you want to inject the style-code by calling the overloaded version of "Add", like this: procedure TSpinner.InitializeObject; begin inherited; FSheet := TW3StyleSheet.Create; FSheet.Add(#" long css multi-line code here "); end; OK, with that done your css is now in memory and you can use the styles as you want. Next, when it comes to child div's -- that is ultimately something you need to read up on with normal CSS documentation. But here are a few pointers: .MyStyle { } /* This applies a style to all child elements of MyStyle. So if you assign MyStyle to a panel, then the code inside here will be forced on whatever child controls you add to that panel */ .MyStyle > * { } /* Same as above, but here it will only affect a child control named "MyButton" */ .MyStyle > #MyButton { } I will also urge you to get rid of the hardcoded -Webkit- stuff. If you look at SmartCL.System there is a driver system you can use to get the prefix for whatever browser you are running in. Its available as a function: var Text := BrowserAPI.PrefixDef("anim"); // Text is now "-webkit-anim" if you are using webkit var Text := BrowserAPI.Prefix("anim"); // Text is now "-webkitAnim" (or -fsAnim, or msAnim depending) And last but not least -- a solution! Add the unit "SmartCL.Effects" to your mainform's uses clause. When you do this, all controls gains around 15 effect methods. Rotate is not one of them sadly (yet). But there is a class called "TW3NamedAnimation". This class allows you to execute any named CSS animation on any visual control. And if you look in the stylesheet (the standard stylesheet) there is an animation named "rotate forever". Set the name and call Execute() and that should be a much cleaner solution. Well, I hope some of this helped! The CSS stuff you need is essentially things you must read up on, it's way outside the scope of our product. CSS is a large and complex media definition standard that needs to be properly studied. But you are well on your way, and some of the clues here should help you do what you want in several ways.
  5. lennart

    TryStrToInt bug

    This is not a bug, but rather a missunderstanding of how JSVM deals with inline values. Variables that are created inline (ex: var a := 10) exist only in local scope (so in your case they die when you pass them as a var param). What happens here is that you are pushing a value out of scope, at which point the garbage collector eats it, and you get zero in return. I know this is quite confusing, but that's JavaScript for you. The best way to ensure "delphi like" results is to avoid using "JS like" features. Inline variables etc. is great for fast calculations and temporary values that doesnt leave the scope - or where you directly assign the value to a class field. But using them with var-param based procedures is a throw of the dice. Define the variables "the old way" and it should be ok
  6. lennart

    Game Demo

    First, awesome post! Inspiring and cool (and love the graphics man!) About the keyboard stuff, this is very simple in the new RTL (that you use here). If you look in the unit SmartCL.Components, there is a type called "TW3CreationFlags". You might remember from Delphi that forms have something called CreateParams? In Delphi it looks like this: procedure CreateParams(var Params: TCreateParams); override; We might adopt a similar approach later, but right now our version looks like this: class function CreationFlags: TW3CreationFlags; virtual; If you override this function you can set some low-level stuff to control things like input. In HTML5 a value needs to be set for a DIV to catch keyboard events. So to make your control(s) get input events, simply add the "cfKeyCapture" set-value. Here are the values you can use on any control: Note: These flags drastically alters the behavior of a control, please make sure you study and understand these before altering them. *) TW3CreationFlags = set of ( cfIgnoreReadyState, // Ignore waiting for readystate cfSupportAdjustment, // Controls requires boxing adjustment (default!) cfReportChildAddition, // Dont call ChildAdded() on element insertion cfReportChildRemoval, // Dont call ChildRemoved() on element removal cfReportMovement, // Report movements? Managed call to Moved() cfReportResize, // Report resize? Manages call to Resize() cfAllowSelection, // Allow for text selection cfKeyCapture // assign tabindex, causing the control to issue key and focus events ); Simply override the function for your class like this: Class function TMyContainer.CreationFlags: TW3CreationFlags; begin result := inherited CreationFlags(); Include(result, cfKeyCapture); end; And now you the OnKey-xyz events will fire. The reason its isolated like this is because we didnt want to activate it everywhere. Under HTML5 it can cause some confusion if every single element has it -- also events behave different (propagation).. Well, hope it helps!
  7. No i didnt mean that you somehow blamed anything - just tend to be people that think it has to be a mistake. When it in fact is how JS works rather than how the pascal implementation is done on top of js. >>- Am i interpreting it correctly as you saying i should define all my styles in a Pascal-style through "procedure ObjectReady; override;" rather than in the custom style sheet? ObjectReady() is what the name says, a method that fires when the element is successfully created and injected into the dom. Personally im a fan of having matching css-styles and pascal classes, but if you must adjust something "safely" (not just styles) then this is a nice place to do just that. InitializeObject() is the constructor in SMS, so depending on what you do - that can also be a good, just keep in mind that the prototype may still be building when this fires. But! We also have a procedure just for CSS stuff, namely StyleTagObject(). This was made exactly for what you want. It is defined as such: (* This gives you the ability to set basic styles straight after the element has been created *) procedure StyleTagObject; virtual; So if we are going by the book - that is the procedure you want to override when messing with styles manually. But try to inherit out the things you need to change, give it a unique name and then write a css style for it. The style and the class will find each other automatically so you dont have to think about it. And yes, I wish we had proper docs for this. It sort of takes for granted that you know a bit JS, a bit css and a bit html -- and then a lot of object pascal. But if you look at TW3CustomControl there is a lot of commenting in the code - an you can follow how an element is created, various mechanisms and events are hooked up etc. by reading the code there. Also about resize. Only IE has an actual onResize() event.. none of the other browser have that. So we figure out how to do resize through Width/Height changes. If you do a lot of them, call Obj.BeginUpdate; first -- then Obj.EndUpdate when you are done -- that way you just get one resize rather than 100 of them.. (* Scheduled update mechanism: Before performing changes to multiple styles or properties, wrap them in BeginUpdate() and EndUpdate() calls. You combine this with calls to AddToComponentState() and RemoveFromComponentState() to inform the control what has changed. Note: Internally, you can have multiple nested BeginUpdate/Endupdate. It makes no difference since the control uses a counter to keep track of simulanious updates Example: BeginUpdate; try MoveTo(10,10); SetSize(100,100); Background.fromColor(clRed); finally AddToComponentState([csMoved,csSized]); EndUpdate; end; *) procedure BeginUpdate; procedure EndUpdate; virtual; Well, hope it helps! When im finally done with the RTL i will be focusing on docs, fixing all the examples to run under the new RTL and naturally -- make sure the CSS and visual controls all follow the rules.
  8. The biggest challenge for me, is that CSS makes it almost impossible to create code that looks the same everywhere. A simple "margin: 2px" is enough to break the design between one stylesheet and another - and everyone thinks its the codebase fault. The codebase works fine, but some composite controls have different default css values depending on the browser. And if the rules are broken, like assigning values to a control still being created in the background -- results will be sporadic. Under linux the standard checkmark has a padding of 2px by default in the Origyn browser, and the other browsers have varying degree of accuracy. Its the same for Windows -- even between versions of the same bloody browser. There is also two stylesheets: the one you provide, and the one the browser calculates as a reasonable faximilee of the result. This is why we write to handle.style["somevalue"] but read from the calculated stylesheet. So its pretty complex stuff. But as long as some rules are followed, like inheriting out controls you need to closely manage, always override the objectReady() method when doing safe changes, and making full use of callbacks -- then there is rarely any problem. I do 90% of my code by hand (old school, never really bothered with designers) -- and as long as you follow the rules of JS and HTML, it works fine. Check this out for instance. And naturally I had to write the css for each element i wanted to use. Its like writing a make-file for C/C+++. http://quartexhq.myasustor.com/ We could make things more uniform by generating the CSS using classes. A bit like what Delphi does -- but it would be very time consuming with little gains. But when the creation-chain is understood, then writing complex application is easy and fun.
  9. There are quite a few things that must be understood about the way HTML works vs how delphi works. First of all, when you create a control -- it is never ready when the constructor finishes. Javascript is a single threaded event driven beast - meaning that it can take several milliseconds after the constructor is done -- before you can safely do anything with controls. This is why its so important to create controls in one place, adjust them in another and position them in yet another procedure. Some things you can get away with, but ultimately it will become a mess if you just create things all over the place. Its not how the DOM works and will only lead to frustration. Secondly, composite controls like TW3Checkbox requires a bit more time to ready. It will set it's csReady flag in ComponentState ONLY when all its children report that they have finished creating too. If this takes too long it will exit the wait loop to not slow down the system. But just like you would check csCreating, csDestroying etc. in Delphi -- so you must do here, but on pre-defined junctions in the creation process. This is why the old RTL had a Handle.readyExecute() mechanism, which would call you when the element was ready to be used. First thing i would do would be this: TMyCheckbox = class(TW3Checkbox) protected procedure ObjectReady; override; end; And set the styles there, rather than the way you are doing it now. Also remember that a control will always map its style to a css-style with the same name. So TMyCheckbox will automatically map to ".TMyCheckBox {}" in the stylesheet. And then you can do the same for the child elements ".TMyCheckBox > .TCheckMark" to set the style for the sub elements. Then there is the layout -- you are remaking the layout for every single call to resize (!) A layout should only be created once -- in either the InitializeForm or ObjectReady() method, and then simply updated in the resize method.. it will take care of itself. You should also check if the instance is actually created in the resize() method before setting values, because ASYNC programming is nothing like synchronized programming. And once in a while, a call to ReSize() is needed manually here and there. TW3Dispatch.Execute(Resize, 50); // call resize in 50ms just to be sure The whole point of making a new RTL was to create a system more in sync with how the browser and node.js works. But that means we have to follow the rules. As for differences between server and design -- im guessing you have compiled with a cache manifest, so the server will always keep giving you the same css (from its cache) regardless. Hence the changes never occur until you either delete the manifest file or replace it As to using a alpha rtl that was shared only between 3-4 people -- it shouldnt even be available. And its now months behind the present evolution. But if you look at the new methods and remember that everything in javascript is async, you can make some knockout stuff with this. But the components is the last thing i update, because the real work is in the core of the rtl. So in the Alpha things like checkbox will be utterly useless until i go over them. Anyways, here is a preferences form from the Smart desktop using the layout control. Its fairly straight forward: unit wb.desktop.window.prefs; interface uses W3C.DOM, System.Types, System.Types.Convert, System.Types.Graphics, System.Colors, System.Time, System.Streams, System.Reader, System.Stream.Reader, System.Writer, System.Stream.Writer, System.Structure, System.Structure.Json, System.Memory, System.Memory.Allocation, System.Memory.Buffer, System.Widget, wb.desktop.types, wb.desktop.window, wb.desktop.preferences, SmartCL.Layout, SmartCL.System, SmartCL.Storage, SmartCL.Storage.Cookie, SmartCL.Storage.Local, SmartCL.Storage.Session, SmartCL.Time, SmartCL.Controls.Elements, SmartCL.Graphics, SmartCL.Components, SmartCL.MouseTouch, SmartCL.Effects, SmartCL.Fonts, SmartCL.Borders, SmartCL.CSS.Classes, SmartCL.CSS.StyleSheet, SmartCL.Controls.Image, SmartCL.Controls.Label, SmartCL.Controls.Panel, SmartCL.Controls.Button, SMartCL.Controls.ToggleSwitch, SMartCL.Controls.CheckBox, SmartCL.Controls.Toolbar ; type TWbPreferencesWindow = class(TWbWindow) private FEffectsOpen: TW3ToggleSwitch; FEffectsOpenLabel: TW3Label; FEffectsClose: TW3ToggleSwitch; FEffectsCloseLabel: TW3Label; FEffectsMaximize: TW3ToggleSwitch; FEffectsMaximizeLabel: TW3Label; FEffectsMinimize: TW3ToggleSwitch; FEffectsMinimizeLabel: TW3Label; FShowDocking: TW3CheckBox; FLayout: TLayout; FButtonLayout: TLayout; FCancel: TW3Button; FApply: TW3Button; FSave: Tw3Button; FPanel: TW3Panel; FFooter: TW3Panel; protected procedure HandleApply(Sender: TObject); procedure HandleSave(Sender: TObject); procedure HandleCancel(Sender: TObject); procedure StoreCurrentValues; protected procedure InitializeObject; override; procedure FinalizeObject; override; procedure ObjectReady; override; procedure Resize; override; end; implementation uses SmartCL.FileUtils; //############################################################################# // TWbPreferencesWindow //############################################################################# {$DEFINE HOOKTEST} procedure TWbPreferencesWindow.InitializeObject; var LAccess: IWbDesktop; LReader: IW3StructureReadAccess; begin inherited; Header.Title.Caption := 'Preferences'; FEffectsOpenLabel := TW3Label.Create(Content); FEffectsOpenLabel.Name :='lbEffectsOpen'; FEffectsOpenLabel.SetBounds(10,10, 200 ,32); FEffectsOpenLabel.Caption := "Effect Window Open"; FEffectsOpenLabel.AlignText := TTextAlign.taRight; FEffectsOpen := TW3ToggleSwitch.Create(Content); FEffectsOpen.Name :='btnEffectsOpen'; FEffectsOpen.SetBounds(220,10,120,32); // --------------------- FEffectsCloseLabel := TW3Label.Create(Content); FEffectsOpenLabel.Name :='lbEffectsClose'; FEffectsCloseLabel.SetBounds(10,52, 200 ,32); FEffectsCloseLabel.Caption := "Effect Window Close"; FEffectsCloseLabel.AlignText := TTextAlign.taRight; FEffectsClose := TW3ToggleSwitch.Create(Content); FEffectsClose.Name :='btnEffectsClose'; FEffectsClose.SetBounds(220,52,120,32); // --------------------- FEffectsMaximizeLabel := TW3Label.Create(Content); FEffectsMaximizeLabel.Name :='lbEffectsMaximize'; FEffectsMaximizeLabel.SetBounds(10,94, 200 ,32); FEffectsMaximizeLabel.Caption := "Effect Window Maximize"; FEffectsMaximizeLabel.AlignText := TTextAlign.taRight; FEffectsMaximize := TW3ToggleSwitch.Create(Content); FEffectsMaximize.Name :='btnEffectsMaximize'; FEffectsMaximize.SetBounds(220,94,120,32); // --------------------- FEffectsMinimizeLabel := TW3Label.Create(Content); FEffectsMinimizeLabel.Name :='lbEffectsMinimize'; FEffectsMinimizeLabel.SetBounds(10,136, 200 ,32); FEffectsMinimizeLabel.Caption := "Effect Window Minimize"; FEffectsMinimizeLabel.AlignText := TTextAlign.taRight; FEffectsMinimize := TW3ToggleSwitch.Create(Content); FEffectsMaximize.Name :='btnEffectsMinimize'; FEffectsMinimize.SetBounds(220,136,120,32); // --------------------- LAccess := GetDesktop() as IWbDesktop; LReader := LAccess.GetPreferences.GetPreferencesReader(); FPanel := TW3Panel.Create(Content); FPanel.Name :='PnlPrefs'; FShowDocking := TW3CheckBox.Create(FPanel); FShowDocking.Font.Size := 14; FShowDocking.Caption := 'Show workbench dock'; FShowDocking.SetBounds(10,10, 300,16); FFooter := TW3Panel.Create(Content); FPanel.Name :='PnlPrefsFooter'; FFooter.StyleClass := ''; FFooter.Height:=32; FCancel := TW3Button.Create(FFooter); FCancel.Name :='btnCancel'; FCancel.Caption := 'Cancel'; FCancel.OnClick := procedure (Sender: TObject) begin CloseWindow(); end; FApply := TW3Button.Create(FFooter); FApply.Name :='btnApply'; FApply.Caption :='Apply'; FApply.OnClick := @HandleApply; FSave :=Tw3Button.Create(FFooter); FSave.Name :='btnSave'; FSave.Caption := 'Save'; FSave.OnClick := @HandleSave; var LOwner: TW3CustomControl := TW3CustomControl(Parent); var wd := 400; var hd := 500; var dx :=(LOwner.width div 2) - (wd div 2); var dy :=(LOwner.height div 2) - (hd div 2); SetBounds(dx, dy, wd, hd); end; procedure TWbPreferencesWindow.FinalizeObject; begin FEffectsOpen.free; FEffectsOpenLabel.free; FEffectsClose.free; FEffectsCloseLabel.free; FEffectsMaximize.free; FEffectsMaximizeLabel.free; FEffectsMinimize.free; FEffectsMinimizeLabel.free; inherited; end; procedure TWbPreferencesWindow.ObjectReady; var LAccess: IWbDesktop; LReader: IW3StructureReadAccess; begin inherited; FButtonLayout := Layout.Client(Layout.Margins(2).Spacing(10), [ Layout.left(FSave), Layout.client(FApply), Layout.Right(FCancel) ]); FLayout := Layout.Client(Layout.Margins(4).Spacing(4), [ Layout.top( [ Layout.top(Layout.Stretch.Spacing(8).Margins(2), [ Layout.client(FEffectsOpenLabel), Layout.right(FEffectsOpen) ]), Layout.top(Layout.Stretch.Spacing(8).Margins(2), [ Layout.client(FEffectsCloseLabel), Layout.right(FEffectsClose) ]), Layout.top(Layout.Stretch.Spacing(8).Margins(2), [ Layout.client(FEffectsMinimizeLabel), Layout.right(FEffectsMinimize) ]), Layout.top(Layout.Stretch.Spacing(8).Margins(2), [ Layout.client(FEffectsMaximizeLabel), Layout.right(FEffectsMaximize) ]) ]), Layout.Client(FPanel), Layout.Bottom(Layout.Height(36), FFooter) ] ); LAccess := GetDesktop() as IWbDesktop; LReader := LAccess.GetPreferences.GetPreferencesReader(); FEffectsOpen.Checked := LReader.ReadBool(PREFS_WINDOW_EFFECTS_OPEN); FEffectsClose.Checked := LReader.ReadBool(PREFS_WINDOW_EFFECTS_CLOSE); FEffectsMinimize.Checked := LReader.ReadBool(PREFS_WINDOW_EFFECTS_MIN); FEffectsMaximize.Checked := LReader.ReadBool(PREFS_WINDOW_EFFECTS_MAX); TW3Dispatch.Execute(Invalidate, 200); end; procedure TWbPreferencesWindow.StoreCurrentValues; var LAccess: IWbDesktop; LWriter: IW3StructureWriteAccess; begin LAccess := GetDesktop() as IWbDesktop; LWriter := LAccess.GetPreferences.GetPreferencesWriter(); // Apply to preferences LWriter.WriteBool(PREFS_WINDOW_EFFECTS_OPEN, FEffectsOpen.Checked); LWriter.WriteBool(PREFS_WINDOW_EFFECTS_CLOSE, FEffectsClose.Checked); LWriter.WriteBool(PREFS_WINDOW_EFFECTS_MIN, FEffectsMinimize.Checked); LWriter.WriteBool(PREFS_WINDOW_EFFECTS_MAX, FEffectsMaximize.Checked); end; procedure TWbPreferencesWindow.HandleApply(Sender: TObject); begin try // Apply to preferences StoreCurrentValues(); finally // Exit, dont save prefs permanently (!) CloseWindow(); end; end; procedure TWbPreferencesWindow.HandleSave(Sender: TObject); var LAccess: IWbDesktop; begin LAccess := GetDesktop() as IWbDesktop; try // Apply to preferences StoreCurrentValues(); // Store values permanently try LAccess.SavePreferences(); except on e: exception do showmessage(e.message); end; finally CloseWindow(); end; end; procedure TWbPreferencesWindow.HandleCancel(Sender: TObject); begin end; procedure TWbPreferencesWindow.Resize; begin inherited; if FLayout <> nil then begin try FLayout.Resize(Content); except on e: exception do; end; end; if FButtonLayout<>nil then begin try FButtonLayout.Resize(FFooter); except on e: exception do; end; end; {$IFNDEF HOOKTEST} if assigned(FEditor) then FEditor.SetBounds(10,64, Content.Clientwidth - 20, Content.ClientHeight - 80); {$ENDIF} end; end.
  10. I so want to post the code I have made for this, but I cannot without the board's backing. But I will make some calls today and see if we at least can get the units/changes that are finished out. We are low on manpower, and right now im the only one coding on the RTL. But if people are ok with many small updates, and that we issue 1 by 1 unit as I finish them - then that's ok by me. Hopefully that would help?
  11. lennart


    As Igor notes, the procedure FormActivated() and FormDeActivated() kick in to inform you of exactly that. However these procedures should be superseded by these events firing. As for WayleyX's comment "a review of the whole RTL is very welcomed". That is exactly what is taking place. The old RTL model has a good and solid foundation, for example the inheritance chain and how more and more complex behavior is incrementally built up. However, there is still much to be desired when it comes to depth, order and "the little things". Now that I think about it, are you hooking into these events on the first form? If this is the default form, I think i know they dont fire. These methods and events are invoked basically via the GotoForm() methods and the process they represent. I dont have access to my VMWare test machines right now, and my primary installation is used for writing the next RTL. So I am unable to check. But it can be easily checked: 1. Add a second form. 2. Place a button on form1 3. In the OnClick event for the button, call GotoForm and navigate to the second form If the events fire on the second form, then try the same in reverse: 1. Add a button on the second form 2. In the OnClick event for that button, use GotoForm() and navigate back to the first form If the events fire in Form1, then we have solved the question. I simply have to alter the startup code so that these methods are called regardless.
  12. Hm. That is odd. It could be that our Remobjects codegen is due for an overhaul. There have probably been some changed to the RODL format that cause this. The ";" in the parameter-list points to the codegen trying to read a parameter, but failing - leaving only a separator before it continued with the next. Secondly, it seem odd that the codegen would perform an "indexof" something, and return the index rather than using the index to return the item in question. I would guess (without having looked at the RODL) that the code should look like something along these lines: result := TAccessRight(enumvalues[enumvalues.indexof(self.value)]); What version of Remobjects SDK are you using? It may be prudent to create a test-server and slowly add features to establish what is actually broken? From the looks of it, the error here seems to affect complex types -- so i would imagine that the format of complex types in the RODL file has changed between versions. We will ofcourse take note of this and give it some attention, but if we could pinpoint what exactly fails that would make things easier. For instance, does functions and procedures using only intrinsic datatypes work fine? Does TAccessRight contain other datatypes other than intrinsic, or are there collections/arrays defined there?
  13. Hi Well, glad we got to annoy you one more time David I could tell you a long story of how and why, but ultimately you are right: documentation was probably the biggest mistake we made. The initial design was based on a class browser, where we also had editing capabilities. This model worked well for Mono and C#, but sadly due to an accident I had 5 years ago where I broke my back in two places - that part faded away in my absence. Thankfully people like iElite and Warlayex have guru status and have helped the community tremendously. Either way -- you are completely right that we botched that aspect of the system. We have no investors behind us, and the little we make from SMS is used to pay for hosting and cloud services. So SMS is a project of love for the language and what we can do. To remedy the documentation situation --you will be glad to know that the book "Smart Mobile Studio Unleashed" will be free to all that have supported and bought SMS. And we are making headway on the update! It cleans up the RTL (to begin with) and then the IDE is going to get a complete overhaul. But we will have to do this in incremental steps. Rather than 2 large updates a year, we are aiming at many updates which each focus on a particular topic, solution or technical issue. Some of the more obvious bugs, like CTRL+Click etc. have already been fixed. There are plenty of such little bugs that we have in our list for the update. And hopefully we might make it between xmas and new-years, but I cant make any promises. But we are 3 people working on this each week, so its progressing a lot faster this time! Part of our motivation for the next year is to establish proper funding, which means that myself and the others can work full time on SMS. Which is really what is needed to get this to the next level. But the update is going to make SMS a much more enjoyable experience! And more logical as well since things are being organized into namespaces, classes and helpers. There is a lot of legacy code that we quite frankly dont need any more. So a cleanup was more than overdue.
  14. My account was out of order in the database, so I have been unable to respond or do much on the forum for a while. Im not going to bore people with the details. Either way, I contacted iElite, a member of this forum, asking for his aid. He kindly accepted and has done a great job while our webmaster sorted out the mess. So I want to personally thank iElite for his help. Thank you so much, it really means a lot! I am humbled when I see how many people are pitching in, and iElite has been with us since the beginning. I also want to apologize deeply for the neglect since this summer. We have had to completely re-structure the company and establish a new team. This is not an excuse, but it may serve as an explanation to why things have been quiet. We are learning from our mistakes. But thank you iElite for keeping an eye on things and for your support. It will not be forgotten. Sincerly Jon Lennart Aasenden A.K.A - Cipher Diaz of Quartex (my old hacker group on the Amiga computer he he)
  15. The reason is that SMS class-code operate with a SELF parameter. Which naturally means nothing to cordova. Hence you should use a vanilla in-place anonymous procedure there and then call out to ordinary object pascal from that (or in this case, into cordova's API). w3_AddEvent(BrowserAPI.document,'deviceready', procedure () begin // call init here end, false);
  16. Again a nice idea! Ill talk to the webmaster if he can get that going! Cant guarante anything, but i do like the idea. Kinda like what Blitzbasic used to have.
  17. One of our team members, Primoz, made a fantastic layout library en-par with Linux GTK and C#'s GTK#. You will find this under $RTL\SmartCL\SmartCL.Layout.pas. Sadly he has been unable to document it, so I cant even tell you how to use it properly. But there are a couple of demos in the demo folder demonstrating it. This really is a library we want to create a designer for. It will make creating display agnostic layouts so easy. It will automatically scale and position controls according to size, no need for anchors or anything as such. You can regard it as horizontal panels that always fit to the total width, but who in turn have cells (like a spreadsheet) that can be set to an absolute size or a percentage. Inside each cell you can have components and they are always stretched to fit the cell size. Its a brilliant piece of enginering and primoz deserves praise for his work on this. Shame that we havent had time/resources to really create an easy to use editor for it. It makes perfect sense for mobile and web design, much more than absolute positioning like we are traditionally used to. Well worth looking into!
  18. Yes this is something we are dealing with right now. There was a series of unfortunate sircumstances that affected the initial momentum of Smart Mobile Studio. Most notably that I broke my spine in two places and was unable to work for nearly two years. This naturally had an impact on the tech and other members had to pick up my payload, leaving docs as a lower priority than fixing bugs and getting new tech into the releases. But yes. When the new RTL which we are working on right now (as I type actually) is finalized, then the book will be finished and released as well. At the same time we are looking at completing our wiki which will be en-par with other systems, such as mono etc. So we are indeed not blind to these facts
  19. The problem with IE and M$ browsers is that they all have peculiar behavior not easily made uniform. But the tests im running now, although with an RTL that wont be released quite yet, it scrolls fine on both my high-end Microsoft Lumia and IE 11 on my PC. And indeed you are right, the CSS must be adapted for multi-target projects In the beginning we shipped the "standard" css files and components only as Examples. Like Samarin did for their monoTouch framework. Like mono the user were expected to tailor and work with the css and code at a much lower-level than Delphi. But, as time as passed we have changed our ideas a bit - and I am presently re-writing every control we have (with the exception of third party packages). The reason the RTL im working on now will have to wait, is because we need to establish more visual tools in the IDE. Take something simple, like TAction. We are so used to this in Delphi that we dont stop and think just how much it involves from a javascript perspective. Having support for TAction without visually being able to connect them to buttons etc. would be sad. Although I have been doing that for ages myself (im used to writing everything from scratch in SMS). Then there is the DB layer and also the effect stack. Right now you can use SmartCL.Effects.pas to instantly add 20-30 special effects to all TW3Movablecontrol based components. Thats the power of partial classes. Just include it and everything gets a ton of fxEffect methods. But in order to move forward and take SMS to the next level, the entire codebase is being re-organized, polished and abstracted. When writing an application in SMS, including the version you have, you should always do some research on the target. IE is lacking a ton of methods that are common in other browsers, so you MUST include shims to patch those holes. We have not bolted those in by default because, well, if you target iOS then you dont want a megabyte extra of IE patches slowing things down. Then there is the concept of "same behavior". I am right now writing scroll-controller classes, basically isolating the code that performs scrolling, as separate TW3Widget (non visual component) classes. This gives you finer control over what "scroller" to use. You can do testing in your code to pick the best mechanism. This also means that "normal" scrolling (or built in overflow=scroll) can be isolated as a scroll-controller widget. Making the whole system orderly, abstracted just enough and allows for easy adaptation for the future. Im also doing optimization based on iScroll, which picks the best scrolling method depending on the platform. So the overflow scrolling will no doubt be used where the browser allows it. But I would really give iScroll a go if I was you. It has six years of testing and perfection behind it -- and using it is a piece of cake. Just download the JS file, copy it to your libraries folder, then include it with {$R "iscroll5.js"} Once included, you can attach it to a container quite easily. Here is an older article I wrote on the subject. It may have to be updated since iScroll has grown since I did this code. https://jonlennartaasenden.wordpress.com/2014/08/05/iscroll-for-smart-mobile-studio-part-2/ iScroll is not only more smoth than "native" scrolling (believe it or not), but it also gives you functions that are better than the original. And it also very, very platform independent.
  20. The biggest change is basically organization. We need better separation between DOM and non-DOM code (nodejs, io and embedded), so the RTL has been divided into more distinct namespaces. Universal and abstract classes are moved into the system namespace, SmartCL should contain DOM only code, and nodeJS will naturally have its own high-level interface. We have also set a standard when it comes to files and filesystem. So you have an abstract filesystem defined in system, which is then implemented for each target. So if you use phonegap, then the filesystem will use those functions, if you use node then you get the native versions there -- and so on. As a user you dont have to care about that, just use the FileSystem classes and the linker will pick the correct version depending on your target. So there is a lot of over-due "cleanup" of classes, concepts and units. I am also going over every component we have, re-writing a lot of the code from scratch. Then you have stuff like TAction's which we have in Delphi, that is already done. And finally a unified DB API. It takes time because we are dealing with 3 platforms and multiple targets. NodeWebkit for instance is a bit of a freak since it allows both node-level access to the system AND full DOM access. Up until now we have basically provided pascal access (or implementations) of JS functionality. This has caused some confusion for many people, who expect object pascal standards to be in place. So thats what I am going for now - setting some standards (like filesystem being a standard abstract class, which is implemented for each target) that delivers the same behavior regardless of platform. The scroll stuff is a good example. When possible I try to write it in object pascal to avoid differences in behavior. But for best performance i will probably have to optimize for each browser type. Scrolling with CSS3 has worse performance in IE than using an animation with a matrix ease function -- so "smarting up" some of the controls is important. Non visual components is also in the RTL now, which should simplify things considerably. At the same time im writing a book, Smart Mobile Studio Unleashed, that teaches hard-core SMS coding - with focus on control writing, nodejs clustering and services. So its quite a job.
  21. This shim should make most of IE's problems go away. IE has a ton of missing functions, especially in IE 1-9. Adding this shim to your application (just keep it in the shims folder and include it with {$R "shimname.js"}) should SMS run even in older browsers: https://github.com/es-shims/es5-shim/blob/master/es5-shim.js
  22. The "bug" if we can call it that was quite simple: Both IE 10, 11 and Edge expose wildly different markers in the user-agent vendor information. In short: w3_getIsInternetExplorer was unable to recognize the browser as variations of Internet Explorer. If the browser-driver is completely unable to recognize a vendor (this is the first time that has happened in 4 years), it defaults to the Mozilla behavior. Anyways, here is the fix. Simply replace the existing w3_getIsInternetExplorer() function (SmartCL.System.pas) with this one: function w3_getIsInternetExplorer: Boolean; var ua, msie, trident, edge: variant; function IE_10_Or_Older: boolean; begin asm @ua = window.navigator.userAgent; @msie = (@ua).indexOf('MSIE '); @result = (@msie > 0); end; end; function IE_11: boolean; begin asm @ua = window.navigator.userAgent; @trident = (@ua).indexOf('Trident/'); @result = (@trident > 0); end; end; function IE_Edge: boolean; begin asm @ua = window.navigator.userAgent; @edge = (@ua).indexOf('Edge/'); @result = (@edge > 0); end; end; begin result := IE_Edge or IE_11 or IE_10_Or_Older; {$IFDEF DEBUG} asm if (@result === true) console.log("Internet Explorer detected"); end; {$ENDIF} end; I did however notice that the scrolling was not as smooth under IE as it is under webkit. It's probably falling back to the requestAnimationFrame() shim, so that will have to be dealt with next.
  23. Did a quick debug session and found the error: For some reason the Mozilla driver is created for later IE. They changed the identifier (!) -- which explains a lot. Good that you brought this up, I actually did not know this (IE is not our primary target. Mobile devices typically run webkit, and our main API target is phonegap). I'll post a quick fix soon! https://www.dropbox.com/sh/e2ya5g8b0pj6s8r/AADuRo8p9f2fXUcTo7gR_7sIa?dl=0 As for the DB grid, that was an early prototype written in a couple of hours. The scroll code has been completely re-written and the GPU is used as much as possible everywhere. It goes without saying that "low level" procedural JS and using the browsers built-in scrolling functionality is faster -- there is always a small speed penalty when using OOP based code like SMS generates, but when done right it is hardly noticable. I remember people went nuts when Delphi 1 came out, they were used to Turbo pascal speed and owning the CPU 100% -- and many hated delphi for being slightly "slower" than Turbo. But after Delphi's RTL got more and more refactored, that speed penalty eventually was gone. In the VCL today, only the drawing mechanism is slow (the constant allocating of a full bitmap, draw form, then dispose of the bitmap again). There is a lot of cool stuff in the new RTL that makes scrolling, styling (skinning) and animation easier and faster. Much, much faster. I have also re-written parts of the framework in pure JS to avoid those extra calls (every call comes with a cost). If i have time, I might do a pascal port of iScroll, re-writing it in pure pascal just like we did with Sprite3d.
  24. This should do the trick for event dispatching, ill look into the scroll part. if (typeof Element.prototype.addEventListener === 'undefined') { Element.prototype.addEventListener = function (e, callback) { e = 'on' + e; return this.attachEvent(e, callback); }; } Where Firefox, webkit, opera and everyone else in the world uses "eventname" for addEventListner, Microsoft requires the "on" prefix, which in normal browsers made by sane human beings should only be used on element event attributes (e.g: Self.Handle.onSomeEvent := SomeHandler).
  25. In most cases you want scrolling inside a container, like a list, so doing a recursive "fixup" of scrolling content is not the best idea. Simply create a TW3Customcontrol decendant, override StyleTagObject() and change the value there. You should also add a style-rule for your class in the stylesheet (the CSS name should always match the classname). Scrolling (or auto scrolling) works fine on android, but since iOS requires 2 fingers for momentum scrolling - which is something they added just to make it harder to use, I went for a solution that would work identical on all platforms. As for Windows10, i have yet to update the codebase with their headers. I know they deal with touch differently (microsoft just cant stick to standards), so special care has to be added for that. As for IE, anything below IE9 should not be supported. But IE10 etc. have only a minor difference in scroll functionality and I will test it when that task is due. I usually test on iOS, Android and MS mobile devices. Either way, all of this is being dealt with in the new RTL. Things will be easier to maintain and also to deal with differences. As for iScroll, that is by far the best solution -- and the only reason it doesnt work on IE is a simple shim. Most notably the lack of [object].indexOf() and various other tidbits. You must always make sure you have the latest IE shims if you target that. Officially IE is not something we support, its outdated and people still using it should be forced to update -- Spartan should be considered a bare minimum. Do a debug session (if that is even possible in IE) and see what it says -- much easier to track down the culprit code.
  • Create New...