Jump to content
IElite

Help with app

Recommended Posts

When testing it on my android phone, some of the layouts are not resizing when the device orientation changes.  I am using the following code for each form:

 

 

 

 

 

 

window.addEventListener('devicemotion', @Resize, false);

 

 

test here

 

 

 

 

 

NOTE: Not all challenges have completed data, and the GUI needs a lot of tweeking in terms of looks (e.g. fonts)

 

 

 

 

 

Project Source here

 

Share this post


Link to post
Share on other sites

When I try it for the first time it shows OK list of mountains, after going back and selecting it again I've get no items showing (actually only 5px is showing).

What are you using for the control, is it ListBox? Do you have LayoutChildren somewhere in the code, my guess is that you receive resize event for the LisbBox itself but not for the individual items.

Share this post


Link to post
Share on other sites

Yes, a list box

 

the unit  ListBoxItem  holds the class for each item in the listbox

 

The class also has layout functionality

 

I assumed it was all taken care of. Maybe I do have to call it explicitly?

 

Layoutchildren?   Are you saying "layout the children" or are you telling me there is a specific routine named "LayoutChildren"?

 

thanks

Share this post


Link to post
Share on other sites

I tried creating  a public method for my listboxitem class to resize the individual items

 

procedure TListBoxItem.Adjust;
begin
 Resize;
end;

then tried calling it on the forms that have the listboxes. Tried it in both the "InitializeObject" and "OnActivate" using

 

for I:= 0 to lbxMountains.Count-1 do
   TListBoxItem(lbxMountains.Items[I]).Adjust;

 
examples:
procedure TChallenge.InitializeObject;
var
 I: Integer;
begin
  inherited;
  {$I 'Challenge:impl'}
  window.addEventListener('devicemotion', @Resize, false);
  W3Label1.AlignText:= taCenter;


  W3HeaderControl1.StyleClass:= 'TW3HeaderControl2';
  W3HeaderControl1.BackButton.Visible:= False;
  W3HeaderControl1.NextButton.Visible:= False;
  W3HeaderControl1.Title.StyleClass:= 'TW3Label2';
  W3HeaderControl1.Title.Caption:='Mountains';
  W3HeaderControl1.Title.AlignText:= taCenter;


  lbxMountains.ItemClass := TListBoxItem;
  lbxMountains.ItemHeight := 32;
  lbxMountains.Styles.SelectedColor := clSilver;
  lbxMountains.OnSelected := LBItemSelected;


  W3HeaderControl2.StyleClass:= 'TW3HeaderControl2';
  W3HeaderControl2.BackButton.StyleClass:= 'TW3ButtonBack';
  W3HeaderControl2.BackButton.OnClick:= HandleBackButton;
  W3HeaderControl2.NextButton.Visible:= True;
  W3HeaderControl2.NextButton.StyleClass:= 'TW3ButtonBack';
  W3HeaderControl2.NextButton.Caption:= 'Info';
  W3HeaderControl2.NextButton.OnClick:= HandleNextButton;


  FLayout:= Layout.Client(Layout.Margins(5), [
                          Layout.Top(Layout.Height(64), Layout.Center(W3Image1)),
                          Layout.Top(Layout.Height(32), Layout.Client(W3Label1)),
                          Layout.Top(Layout.Height(32), W3HeaderControl1),
                          Layout.Client((lbxMountains)),
                          Layout.Bottom(Layout.Height(32), W3HeaderControl2)
                              ] );
  for I:= 0 to lbxMountains.Count-1 do
   TListBoxItem(lbxMountains.Items[I]).Adjust;
end;
 
 
procedure TChallenge.ChallengeActivate(Sender: TObject);
var
 I: Integer;
begin
      FLayout:= Layout.Client(Layout.Margins(5), [
                          Layout.Top(Layout.Height(64), Layout.Center(W3Image1)),
                          Layout.Top(Layout.Height(32), Layout.Client(W3Label1)),
                          Layout.Top(Layout.Height(32), W3HeaderControl1),
                          Layout.Client((lbxMountains)),
                          Layout.Bottom(Layout.Height(32), W3HeaderControl2)
                              ] );
  for I:= 0 to lbxMountains.Count-1 do
   TListBoxItem(lbxMountains.Items[I]).Adjust;
end;

Doesn't seem to make a difference

 

 

Share this post


Link to post
Share on other sites

> the unit  ListBoxItem  holds the class for each item in the listbox

 

I've used custom form for items, haven't tried with custom control but I assume it should work the same.

 

> I assumed it was all taken care of. Maybe I do have to call it explicitly?

> Layoutchildren?   Are you saying "layout the children" or are you telling me there is a specific routine named "LayoutChildren"?

 

Yes, you need to call it from Resize method of form where list box is. For example:

 

 

procedure TfrmClientDetails.Resize;
begin
  inherited;

  if not (Handle.Valid and (csReady in ComponentState)) {or (glbApp.CurrentForm <> Self)} then
    Exit;

  if Assigned(FLayout) then
  begin
    FLayout.Resize(Self);    // To position listbox itself
    lbMain.LayoutChildren;  // To position items
  end;
end;

Share this post


Link to post
Share on other sites

I encountered troubles with the LayoutManager if it dependce on other elements, too. In my case I had to create a new Layout instance on every resize call. Try to place the FLayout := into the overridden Resize method.

 

It seems that the LayoutManager caches some size properties from child contols for better performance, but didn't think of other use cases.

Share this post


Link to post
Share on other sites

I've looked around your code, and can't find an answer to this issue.

Actually, you're trying to format the JSON to look pretty and render it to the page, you're updating a DIV content from a JSON response with innerHTML, this means the string needs to be re-parsed and used to construct the rendering tree that will cause page reflow or repaint. When you move forward/backwards, the heavy layout manager uses this DIV, to calculate the layout, I think it can cause some page reflow, and could collapse in some time. Other thing, the layout manager does not like the inner TW3Label component, but this component is used everywhere in others components in the SmartCL controls such as headers, lists, etc.

 

I'd use a totally different approach: dynamic templates. You can declare a template markup ahead of time, have the browser parse it into DOM, and reuse it over and over again. I think it's lightweight.

And use "datastores" to feed the templates, you retrieve JSON data from datastores. The collection datastores (DM) will take care of populating the data according to the array of JSON objects. It helps to work with nested JSON data.

Share this post


Link to post
Share on other sites

thanks, i will experiment with that next

 

I've looked around your code, and can't find an answer to this issue.

Actually, you're trying to format the JSON to look pretty and render it to the page, you're updating a DIV content from a JSON response with innerHTML, this means the string needs to be re-parsed and used to construct the rendering tree that will cause page reflow or repaint. When you move forward/backwards, the heavy layout manager uses this DIV, to calculate the layout, I think it can cause some page reflow, and could collapse in some time. Other thing, the layout manager does not like the inner TW3Label component, but this component is used everywhere in others components in the SmartCL controls such as headers, lists, etc.

 

I'd use a totally different approach: dynamic templates. You can declare a template markup ahead of time, have the browser parse it into DOM, and reuse it over and over again. I think it's lightweight.

And use "datastores" to feed the templates, you retrieve JSON data from datastores. The collection datastores (DM) will take care of populating the data according to the array of JSON objects. It helps to work with nested JSON data.

Share this post


Link to post
Share on other sites

I have updated the code and project test

 

issues I am having now

 

Testing in web browser, the list boxes can't distinguish between mouse click (to select item) and a mouse click and drag (to scroll).

 

Packages it up in Phonegap and then testing it on my mobile device,  the listboxes can't distinguish between touch (to select item) and a touch and hold / drag (to scroll).

Share this post


Link to post
Share on other sites

> Testing in web browser, the list boxes can't distinguish between mouse click (to select item) and a mouse click and drag (to scroll).

> Packages it up in Phonegap and then testing it on my mobile device,  the listboxes can't distinguish between touch (to select item) and a

> touch and hold / drag (to scroll).

 

That's issue with listbox control itself, you can try to fix it youself (catching mouse and touch events before reaches control) or wait for update, hopefully that'll be fixed in changes.

Share this post


Link to post
Share on other sites
Hey, you're using static challenge.json

 

I've been thinking this JSON object could be coming from any API. Can you inform the API?

 

Just proof of concept, I created a wrapper class to use templates with SMS. I'd like to create agnostic datastores, I think I will use promises to call async, and I didn't test with remote JSON, 

 


To style the templates, I'm using the lightweight http://phonon.quarkdev.com/ - phonon.css (34kb) 

Share this post


Link to post
Share on other sites

challenges.json is static because the file will never change until there is an update in the app or the static json data.

 

However, what will be dynamic is the user data (i.e. the dates the user completed each challenge and mountains)

 

I haven't even begun to work on that

 

initially i will just do local storage, but at some point I would like to make it save to the cloud

 

 

 

 

Hey, you're using static challenge.json
 
I've been thinking this JSON object could be coming from any API. Can you inform the API?
 
Just proof of concept, I created a wrapper class to use templates with SMS. I'd like to create agnostic datastores, I think I will use promises to call async, and I didn't test with remote JSON, 
 
To style the templates, I'm using the lightweight http://phonon.quarkdev.com/ - phonon.css (34kb) 

 

Share this post


Link to post
Share on other sites

> I wouldn't even know where to begin

> How do I catch them and do my own thing?

 

Use addEventListener on ListBox.Handle, have in mind it won't be easy. You'll have to distuingish when mouse click is a click and when scroll request and then do appropriate actions. I would start from scrolling code that's already implemented inside ListBox, perhaps it would be easier to fix there than to write from scratch. In similiar situation I've let browser handle scrolling, just added Handle.style['overflow-y'] := 'auto';

On desktop browser you'll get a standard scrollbar and on mobile none but momentum scroll should work.

Share this post


Link to post
Share on other sites

How would you make a call to navigate to another form  (e.g.   Application.GotoForm('Challenge', feToLeft);)

How can this be done from within innerHTML ?

 

 

 

 

I've looked around your code, and can't find an answer to this issue.

Actually, you're trying to format the JSON to look pretty and render it to the page, you're updating a DIV content from a JSON response with innerHTML, this means the string needs to be re-parsed and used to construct the rendering tree that will cause page reflow or repaint. When you move forward/backwards, the heavy layout manager uses this DIV, to calculate the layout, I think it can cause some page reflow, and could collapse in some time. Other thing, the layout manager does not like the inner TW3Label component, but this component is used everywhere in others components in the SmartCL controls such as headers, lists, etc.

 

I'd use a totally different approach: dynamic templates. You can declare a template markup ahead of time, have the browser parse it into DOM, and reuse it over and over again. I think it's lightweight.

And use "datastores" to feed the templates, you retrieve JSON data from datastores. The collection datastores (DM) will take care of populating the data according to the array of JSON objects. It helps to work with nested JSON data.

Share this post


Link to post
Share on other sites

Since SmartMobileStudio doesn't have a built-in template engine, I just created one, it's a wrapper around the lightweight (1KB minified) Template7

 

Another missing feature is the Data module with datastores. I hope in the next release they implement such feature.

 

Here is a clone of ProjBike using templates.

 

DOWNLOAD

PREVIEW 

 

Share this post


Link to post
Share on other sites

That looks great. I download the project, but it will not run for me.  Keeps kicking up the browser and saying page not found

 

I will study the code and see how these template7 templates work

 

thanks

 

Since SmartMobileStudio doesn't have a built-in template engine, I just created one, it's a wrapper around the lightweight (1KB minified) Template7

 

Another missing feature is the Data module with datastores. I hope in the next release they implement such feature.

 

Here is a clone of ProjBike using templates.

 

DOWNLOAD

PREVIEW 

Share this post


Link to post
Share on other sites

I meant that I could not compile and run it from the IDE

 

I have no idea what you talking about. For me, it works fine both in Chrome and firefox.

 

Ensure you have this files:

lib\template7.min.js

lib\sms.core.min.js

lib\phonon.css

res\bike.jpg

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×