Lazarus

Programming => Operating Systems => Android => Topic started by: Tomi on April 24, 2021, 03:41:51 pm

Title: Lazarus Android graphics
Post by: Tomi on April 24, 2021, 03:41:51 pm
Hello experts!

I have some problems to start with graphics in Android environment of Lazarus.
I thought, I can use graphical commands as in a normal Lazarus program, but it seems there are some difference and I couldn't find any tutorials on the web for this, therefore I'd like asking here.
First of all, I'd like set a background image in my app and draw a bitmap image on it. Then stretch the background to fit the entire screen - but now Lazarus doesn't know Screen.width and Screen.height commands.
Finally, I tried draw an image - but now Lazarus doesn't know draw command.
Maybe is not possible make things at runtime in Android environment of Lazarus? Does it requires totally different logic than Windows application programming?
Somebody can correct my code or can show me any tutorials?
Here is my small piece of code:
Code: Pascal  [Select][+][-]
  1. (...)
  2. type
  3.  
  4.   { TAndroidModule1 }
  5.  
  6.   TAndroidModule1 = class(jForm)
  7.     myCanvas: jCanvas;
  8.     procedure Drawing(Sender: TObject);
  9.     procedure ProgStart(Sender: TObject);
  10.     procedure ProgEnd(Sender: TObject);
  11.   private
  12.     {private declarations}
  13.   public
  14.     {public declarations}
  15.   end;
  16.  
  17. var
  18.   AndroidModule1: TAndroidModule1;
  19.   backgimage: TBitmap;
  20.  
  21. implementation
  22.  
  23. {$R *.lfm}
  24.  
  25.  
  26. { TAndroidModule1 }
  27.  
  28. procedure TAndroidModule1.Drawing(Sender: TObject);
  29. begin
  30.     myCanvas.draw(0,0,backgimage);
  31. end;
  32.  
  33. procedure TAndroidModule1.ProgStart(Sender: TObject);
  34. begin
  35.   width:=Screen.width;  //Here I try to set the size of my app
  36.   height:=Screen.height;  //to size of screen of device.
  37.   backgimage:=TBitmap.create;
  38.   backgimage.LoadFromFile('pictures\rocks.bmp');
  39.   backgimage.SetSize(width,height);
  40. end;
  41.  
  42. procedure TAndroidModule1.ProgEnd(Sender: TObject);
  43. begin
  44.   backgimage.Free;
  45. end;
  46.  
  47. end.
Title: Re: Lazarus Android graphics
Post by: Handoko on April 24, 2021, 06:03:01 pm
Android's API differs a lot from those in Linux and Windows. Using Lazarus+LAMW only offers you Pascal syntax when developing Android apps, most of the functions and procedures you usually use on Windows and Linux cannot be used on Android.

You may want to try the demo source codes that bundled with your LAMW download. As far as I know the LAMW team is only 2 persons, because of the manpower issue there is no good documentation for LAMW. But the good news is almost all the things you need to know about LAMW Android programming can be found in the demos.
Title: Re: Lazarus Android graphics
Post by: rsu333 on April 25, 2021, 07:46:56 am
Yes ,GREAT job by LAMW team.
Title: Re: Lazarus Android graphics
Post by: Tomi on April 25, 2021, 09:22:09 am
(...)
You may want to try the demo source codes that bundled with your LAMW download.
(...)
Thanks for the idea, Handoko! I forgot that LAMW package contains demo programs, but now I'll see these.
Title: Re: Lazarus Android graphics
Post by: kristof.project on April 27, 2021, 12:16:33 am
if you don't change the suggest target

Under linux

/home/{user}/LAMW/lazandroidmodulewizard/demos/ where {user} is your user name home folder

Under windows

C:LAMW/lazandroidmodulewizard/demos/
Title: Re: Lazarus Android graphics
Post by: Handoko on April 27, 2021, 03:45:19 am
+1 for kistof.project.

Almost all the things one needs to know about LAMW - Android programming can be found in those demos.
Title: Re: Lazarus Android graphics
Post by: Tomi on April 27, 2021, 11:29:50 am
I saw some demoss, but my first little application doesn't want show graphics elements. What's wrong with this code?
Code: Pascal  [Select][+][-]
  1.   TElion = class(jForm)
  2.     jButton1: jButton;
  3.     drawcanvas: jCanvas;
  4.     exittimer: JTimer;
  5.     procedure Creating(Sender: TObject);
  6.     procedure ProgEnd(Sender: TObject);
  7.   private
  8.     {private declarations}
  9.   public
  10.     {public declarations}
  11.   end;
  12.  
  13. var
  14.   Elion: TElion;
  15.  
  16.  
  17. implementation
  18.  
  19. {$R *.lfm}
  20.  
  21.  
  22. { TElion }
  23.  
  24. procedure TElion.Creating(Sender: TObject);
  25. begin
  26.   jButton1.Destroy;
  27.   drawcanvas:=JCanvas.create(Elion);
  28.   drawcanvas.PaintColor:=colbrRed;
  29.   drawcanvas.drawcircle(150,150,200);
  30.   exittimer:=JTimer.Create(nil);
  31.   exittimer.interval:=10;
  32.   exittimer.ontimer:=ProgEnd;
  33. end;
When Leapdroid starts, it shows the button correctly, but when I click on that button, it disappearing but the app is not show the circle.
Maybe should I try with Allegro?
Title: Re: Lazarus Android graphics
Post by: loaded on April 27, 2021, 01:01:13 pm
For drawing operations, you should examine the AppDrawingViewDemo1 and AppSurfaceViewDemo1 examples.
They will be very useful. At least it helped me a lot.
After that, the CAD View program I wrote is still in its infancy;
https://youtu.be/J58jgWBupzY (https://youtu.be/J58jgWBupzY)
Also, my recommendation would be to use Surfaceview.
Title: Re: Lazarus Android graphics
Post by: kristof.project on April 27, 2021, 01:05:07 pm
If you want to draw circle on click a button, put your code on the jButton1.onclick

like this

Code: Pascal  [Select][+][-]
  1. procedure jButton1.onclick(Sender: TObject);
  2. begin
  3.   //jButton1.Destroy;
  4.   jButton1.visible:=false; // you can re-use after width  jButton1.visible:=true;
  5.   // drawcanvas:=JCanvas.create(Elion); // don't need in edi mode
  6.   drawcanvas.PaintColor:=colbrRed;
  7.   drawcanvas.drawcircle(150,150,200);
  8.   sleep(10000); // waiting 10 sec
  9.   Elion.close; // close application
  10.   //exittimer:=JTimer.Create(nil);
  11.   //exittimer.interval:=10;
  12.   //exittimer.ontimer:=ProgEnd;
  13. end;
  14.  
Title: Re: Lazarus Android graphics
Post by: Blade on April 27, 2021, 01:28:32 pm
Hello experts!
...Lazarus doesn't know Screen.width and Screen.height commands.
Code: Pascal  [Select][+][-]
  1. (...)
  2. procedure TAndroidModule1.ProgStart(Sender: TObject);
  3. begin
  4.   width:=Screen.width;  //Here I try to set the size of my app
  5.   height:=Screen.height;  //to size of screen of device.
  6.   backgimage:=TBitmap.create;
  7.   backgimage.LoadFromFile('pictures\rocks.bmp');
  8.   backgimage.SetSize(width,height);
  9. end;
  10.  

Passing through and just happen to read... Seems as if nobody answered the OP's question more directly, as in about Screen.Width and Screen.Height...
Title: Re: Lazarus Android graphics
Post by: kristof.project on April 27, 2021, 01:55:10 pm
if this can help you

Code: Pascal  [Select][+][-]
  1. (...)
  2. procedure TAndroidModule1.ProgStart(Sender: TObject);
  3. begin
  4.   width:=TAndroidModule1.width;  // width screen can use
  5.   height:=TAndroidModule1.height; // height screen can use, may be inferior , if application not full screen
  6.  
  7.   backgimage:=TBitmap.create;
  8.   backgimage.LoadFromFile('pictures\rocks.bmp');
  9.   backgimage.SetSize(width,height);
  10. end;
  11.  
Title: Re: Lazarus Android graphics
Post by: Tomi on April 29, 2021, 03:32:43 pm
Why this code draws nothing, just shows a blank screen? In theory, drawing operations happening on a canvas, but is there a main canvas of the application covering my new added one? And what is the size of a canvas? It seems there is no width and height properties of it.
Code: Pascal  [Select][+][-]
  1. procedure TElion.jButton1Click(Sender: TObject);
  2. begin
  3.      jButton1.destroy;
  4.      drawcanvas:=jCanvas.create(Elion);
  5.      drawcanvas.PaintColor:=colbrWhite;
  6.      drawcanvas.drawcircle(10,10,100);
  7. end;
Title: Re: Lazarus Android graphics
Post by: engkin on April 29, 2021, 04:04:18 pm
According to the source code (https://github.com/jmpessoa/lazandroidmodulewizard/blob/master/android_bridges/Laz_And_Controls.pas):
Code: Pascal  [Select][+][-]
  1. procedure jCanvas.drawCircle(_cx: single; _cy: single; _radius: single);
  2. begin
  3.   if FInitialized then
  4.      jCanvas_drawCircle(FjEnv, FjObject , _cx, _cy, _radius);
  5. end;
]

FInitialized turns True in:
Code: Pascal  [Select][+][-]
  1. Procedure jCanvas.Init(refApp: jApp);
  2. begin
  3.   if FInitialized  then Exit;
  4.   inherited Init(refApp);
  5.   FjObject := jCanvas_Create(FjEnv, FjThis, Self);
  6.   jCanvas_setStrokeWidth(FjEnv, FjObject ,FPaintStrokeWidth);
  7.   jCanvas_setStyle(FjEnv, FjObject ,ord(FPaintStyle));
  8.   jCanvas_setColor(FjEnv, FjObject ,GetARGB(FCustomColor, FPaintColor));
  9.   jCanvas_setTextSize(FjEnv, FjObject ,FPaintTextSize);
  10.   FInitialized:= True;
  11. end;

Try calling Init before drawCircle?

Edit:
Whose "canvas" is this?
Digging more in the source code I found:
Code: Pascal  [Select][+][-]
  1. procedure jView.Init(refApp: jApp);
  2. ...
  3.    if  FjCanvas <> nil then
  4.    begin
  5.     FjCanvas.Init(refApp);
  6.     jView_setjCanvas(FjEnv,FjObject ,FjCanvas.JavaObj);
  7.    end;
  8. ...

So it seems you have to "attach" the canvas to some JAVA control.

OR

Simply use a control that has a canvas?
Title: Re: Lazarus Android graphics
Post by: Tomi on April 29, 2021, 04:29:26 pm
Hello Engkin!

I tried initialize after creating, but I don't know what is jApp in this case? What does this parameter mean?
Code: Pascal  [Select][+][-]
  1. drawcanvas:=jCanvas.create(Elion);
  2. drawcanvas.init([b]???[/b]);
  3. drawcanvas.PaintColor:=colbrWhite;
Title: Re: Lazarus Android graphics
Post by: engkin on April 29, 2021, 04:40:36 pm
gApp from unit AndroidWidget?

1st Edit:
I see android_bridges\analogclock.pas is using it:
Code: Pascal  [Select][+][-]
  1. procedure jAnalogClock.UpdateLayout;
  2. begin
  3.   if not FInitialized then exit;
  4.  
  5.   ClearLayout();
  6.  
  7.   inherited UpdateLayout;
  8.  
  9.   init(gApp);
  10. end;

2nd Edit:
I see gApp is used in the Demos as well.
Title: Re: Lazarus Android graphics
Post by: engkin on April 29, 2021, 04:54:09 pm
This demo demos\GUI\AppDrawingInBitmapAndDensity has:
Code: Pascal  [Select][+][-]
  1. library controls;  //[by LAMW: Lazarus Android Module Wizard: 9/26/2019 17:20:36]
  2.  
  3. {$mode delphi}
  4.  
  5. uses
  6. ...
  7.  
  8. begin
  9.   gApp:= jApp.Create(nil);
  10.   gApp.Title:= 'LAMW JNI Android Bridges Library';
  11.   gjAppName:= 'org.lamw.appdrawinginbitmap';
  12.   gjClassName:= 'org/lamw/appdrawinginbitmap/Controls';
  13.   gApp.AppName:=gjAppName;
  14.   gApp.ClassName:=gjClassName;
  15.   gApp.Initialize;
  16.   gApp.CreateForm(TAndroidModule1, AndroidModule1);
  17. end.

So gApp is similar to Application.

The demo itself is bothering me because I see three canvases being used, but I don't see where they get created. Anyway I noticed these two lines:
Code: Pascal  [Select][+][-]
  1. procedure TAndroidModule1.jButton1Click(Sender: TObject);
  2. ...
  3.    //show on screen
  4.    ivLow.SetImage(canvasLow.GetBitmap());
Title: Re: Lazarus Android graphics
Post by: jmpessoa on April 29, 2021, 05:56:57 pm

About jCanvas component :

jCanvas can take a "real" java canvas from other component:
Code: Pascal  [Select][+][-]
  1. procedure TAndroidModule2.jButton1BeforeDispatchDraw(Sender: TObject; canvas: JObject; tag: integer);
  2. begin
  3.    jCanvas1. SetCanvas(canvas);
  4.    //now you can draw:
  5.    //jCanvas1.DrawCircle(30, 30, 15);
  6.    //etc...
  7. end;  
  8.  


You can get the real java canvas object, too:

function GetJInstance(): jObject;  //return the "real" java Canvas....

Title: Re: Lazarus Android graphics
Post by: Tomi on May 01, 2021, 11:28:58 am
You can get the real java canvas object, too:

function GetJInstance(): jObject;  //return the "real" java Canvas....
It sounds good. Can you explain me using of this? For example: maincanvas:=GetJInstance(); or how?
And:
why can't I resize a button? The app in the emulator always shows the same size button, however I resized it:
Code: Pascal  [Select][+][-]
  1. btn2:=jButton.create(Elion);
  2.      btn2.parent:=Elion;
  3.      btn2.init(gApp);
  4.      btn2.text:='A new button';
  5.      btn2.left:=Elion.left+200; //The button position is always at 0,0
  6.      btn2.top:=Elion.top+200;
  7.      btn2.width:=50; //The button will larger than this value
  8.      btn2.height:=50;
  9.      btn2.enabled:=true;
Title: Re: Lazarus Android graphics
Post by: jmpessoa on May 01, 2021, 04:18:19 pm

On android this code don't work!

Code: Pascal  [Select][+][-]
  1.      btn2.left:=Elion.left+200; //The button position is always at 0,0
  2.      btn2.top:=Elion.top+200;
  3.      btn2.width:=50; //The button will larger than this value
  4.      btn2.height:=50;
  5.  

From here:
https://github.com/jmpessoa/lazandroidmodulewizard/blob/master/LAMW_Getting_Started.txt

Quote
[FAQ 2]: [Thanks to Ahmad Bohloolbandi (a.k.a. @developing) ]

#Question: How do we can design a layout that shown same in real device?

[Answer]: You should use the component properties:

      "Anchor",
      "PosRelativeToParent",
      "PosRelativeToAnchor",
      "LayoutParamHeight",
      "LayoutParamWhidth"
         
Example:

1-Put a "jTextView" component on your AndroidModule form:

   Set "PosRelativeToParent"
      "rpCenterHorizontal" [True]
      "rpTop" [True]

2-Put a "jButton" component on AndroidModule form:

   Set "Anchor" to "jTextView" (Because you should set position relative with "jTextView")
   set "PosRelativeToAnchor"
      "raBelow" [True]

3-Put a "jEditText" component on form:

   Set "Anchor" to "jButton".
   Set "PosRelativeToAnchor"
      "raBelow" [True]

NOTE: Anchor setting is most important section of this design,
   because your component position depends on this property.
   And for change width and/or height of each components you should
   change/configure "LayoutParamWhidth" and/or "LayoutParamHeight".



TinyPortal © 2005-2018