Lazarus Android graphics lazarus / 43-Android ---------------------------------------------------------------------- Tomi · 2021-04-24 13:41 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][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i (...)type   { TAndroidModule1 }   TAndroidModule1 = class(jForm)    myCanvas: jCanvas;    procedure Drawing(Sender: TObject);    procedure ProgStart(Sender: TObject);    procedure ProgEnd(Sender: TObject);  private    {private declarations}  public    {public declarations}  end; var  AndroidModule1: TAndroidModule1;  backgimage: TBitmap; implementation  {$R *.lfm}   { TAndroidModule1 } procedure TAndroidModule1.Drawing(Sender: TObject);begin    myCanvas.draw(0,0,backgimage);end; procedure TAndroidModule1.ProgStart(Sender: TObject);begin  width:=Screen.width;  //Here I try to set the size of my app  height:=Screen.height;  //to size of screen of device.  backgimage:=TBitmap.create;  backgimage.LoadFromFile('pictures\rocks.bmp');  backgimage.SetSize(width,height);end; procedure TAndroidModule1.ProgEnd(Sender: TObject);begin  backgimage.Free;end; end. ---------------------------------------------------------------------- Handoko · 2021-04-24 16:03 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. ---------------------------------------------------------------------- rsu333 · 2021-04-25 05:46 Yes ,GREAT job by LAMW team. ---------------------------------------------------------------------- Tomi · 2021-04-25 07:22 Quote from: Handoko on April 24, 2021, 06:03:01 pm(...) 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. ---------------------------------------------------------------------- kristof.project · 2021-04-26 22:16 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/ ---------------------------------------------------------------------- Handoko · 2021-04-27 01:45 +1 for kistof.project. Almost all the things one needs to know about LAMW - Android programming can be found in those demos. ---------------------------------------------------------------------- Tomi · 2021-04-27 09:29 I saw some demoss, but my first little application doesn't want show graphics elements. What's wrong with this code? Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i   TElion = class(jForm)    jButton1: jButton;    drawcanvas: jCanvas;    exittimer: JTimer;    procedure Creating(Sender: TObject);    procedure ProgEnd(Sender: TObject);  private    {private declarations}  public    {public declarations}  end; var  Elion: TElion;  implementation  {$R *.lfm}   { TElion } procedure TElion.Creating(Sender: TObject);begin  jButton1.Destroy;  drawcanvas:=JCanvas.create(Elion);  drawcanvas.PaintColor:=colbrRed;  drawcanvas.drawcircle(150,150,200);  exittimer:=JTimer.Create(nil);  exittimer.interval:=10;  exittimer.ontimer:=ProgEnd;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? ---------------------------------------------------------------------- loaded · 2021-04-27 11:01 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 Also, my recommendation would be to use Surfaceview. ---------------------------------------------------------------------- kristof.project · 2021-04-27 11:05 If you want to draw circle on click a button, put your code on the jButton1.onclick like this Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure jButton1.onclick(Sender: TObject);begin  //jButton1.Destroy;  jButton1.visible:=false; // you can re-use after width  jButton1.visible:=true;  // drawcanvas:=JCanvas.create(Elion); // don't need in edi mode  drawcanvas.PaintColor:=colbrRed;  drawcanvas.drawcircle(150,150,200);  sleep(10000); // waiting 10 sec Elion.close; // close application  //exittimer:=JTimer.Create(nil);  //exittimer.interval:=10;  //exittimer.ontimer:=ProgEnd;end; ---------------------------------------------------------------------- Blade · 2021-04-27 11:28 Quote from: Tomi on April 24, 2021, 03:41:51 pmHello experts! ...Lazarus doesn't know Screen.width and Screen.height commands. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i (...)procedure TAndroidModule1.ProgStart(Sender: TObject);begin  width:=Screen.width;  //Here I try to set the size of my app  height:=Screen.height;  //to size of screen of device.  backgimage:=TBitmap.create;  backgimage.LoadFromFile('pictures\rocks.bmp');  backgimage.SetSize(width,height);end;  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... ---------------------------------------------------------------------- kristof.project · 2021-04-27 11:55 if this can help you Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i (...)procedure TAndroidModule1.ProgStart(Sender: TObject);begin  width:=TAndroidModule1.width;  // width screen can use  height:=TAndroidModule1.height; // height screen can use, may be inferior , if application not full screen    backgimage:=TBitmap.create;  backgimage.LoadFromFile('pictures\rocks.bmp');  backgimage.SetSize(width,height);end; ---------------------------------------------------------------------- Tomi · 2021-04-29 13:32 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][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure TElion.jButton1Click(Sender: TObject);begin     jButton1.destroy;     drawcanvas:=jCanvas.create(Elion);     drawcanvas.PaintColor:=colbrWhite;     drawcanvas.drawcircle(10,10,100);end; ---------------------------------------------------------------------- engkin · 2021-04-29 14:04 According to the source code: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure jCanvas.drawCircle(_cx: single; _cy: single; _radius: single);begin  if FInitialized then     jCanvas_drawCircle(FjEnv, FjObject , _cx, _cy, _radius);end;] FInitialized turns True in: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i Procedure jCanvas.Init(refApp: jApp);begin  if FInitialized  then Exit;  inherited Init(refApp);  FjObject := jCanvas_Create(FjEnv, FjThis, Self);  jCanvas_setStrokeWidth(FjEnv, FjObject ,FPaintStrokeWidth);  jCanvas_setStyle(FjEnv, FjObject ,ord(FPaintStyle));  jCanvas_setColor(FjEnv, FjObject ,GetARGB(FCustomColor, FPaintColor));  jCanvas_setTextSize(FjEnv, FjObject ,FPaintTextSize);  FInitialized:= True;end; Try calling Init before drawCircle? Edit: Whose "canvas" is this? Digging more in the source code I found: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure jView.Init(refApp: jApp);...   if  FjCanvas <> nil then   begin    FjCanvas.Init(refApp);    jView_setjCanvas(FjEnv,FjObject ,FjCanvas.JavaObj);   end;... So it seems you have to "attach" the canvas to some JAVA control. OR Simply use a control that has a canvas? ---------------------------------------------------------------------- Tomi · 2021-04-29 14:29 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][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i drawcanvas: =jCanvas.create(Elion);drawcanvas.init([b]???[/b]);drawcanvas.PaintCol or:=colbrWhite; ---------------------------------------------------------------------- engkin · 2021-04-29 14:40 gApp from unit AndroidWidget? 1st Edit: I see android_bridges\analogclock.pas is using it: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure jAnalogClock.UpdateLayout;begin  if not FInitialized then exit;   ClearLayout();   inherited UpdateLayout;   init(gApp);end; 2nd Edit: I see gApp is used in the Demos as well. ---------------------------------------------------------------------- engkin · 2021-04-29 14:54 This demo demos\GUI\AppDrawingInBitmapAndDensity has: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i library controls;  //[by LAMW: Lazarus Android Module Wizard: 9/26/2019 17:20:36]  {$mode delphi}  uses... begin  gApp:= jApp.Create(nil);  gApp.Title:= 'LAMW JNI Android Bridges Library';  gjAppName:= 'org.lamw.appdrawinginbitmap';  gjClassName:= 'org/lamw/appdrawinginbitmap/Controls';  gApp.AppName:=gjAppName;  gApp.ClassName:=gjClassName;  gApp.Initialize;  gApp.CreateForm(TAndroidModule1, AndroidModule1);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][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure TAndroidModule1.jButton1Click(Sender: TObject);...   //show on screen   ivLow.SetImage(canvasLow.GetBitmap()); ---------------------------------------------------------------------- jmpessoa · 2021-04-29 15:56 About jCanvas component : jCanvas can take a "real" java canvas from other component: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure TAndroidModule2.jButton1BeforeDispatchDraw(Sender: TObject; canvas: JObject; tag: integer);begin   jCanvas1. SetCanvas(canvas);   //now you can draw:   //jCanvas1.DrawCircle(30, 30, 15);    //etc...end; You can get the real java canvas object, too: function GetJInstance(): jObject;  //return the "real" java Canvas.... ---------------------------------------------------------------------- Tomi · 2021-05-01 09:28 Quote from: jmpessoa on April 29, 2021, 05:56:57 pmYou 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][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i btn2:=jButton.create(Elion);     btn2.parent:=Elion;     btn2.init(gApp);     btn2.text:='A new button';     btn2.left:=Elion.left+200; //The button position is always at 0,0     btn2.top:=Elion.top+200;     btn2.width:=50; //The button will larger than this value     btn2.height:=50;     btn2.enabled:=true; ---------------------------------------------------------------------- jmpessoa · 2021-05-01 14:18 On android this code don't work! Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i      btn2.left:=Elion.left+200; //The button position is always at 0,0     btn2.top:=Elion.top+200;     btn2.width:=50; //The button will larger than this value     btn2.height:=50;  From here: https://github.com/jmpessoa/lazandroidmodulewizard/blob/master/LAMW_Ge tting_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".