Lazarus

Programming => Packages and Libraries => Topic started by: Curt Carpenter on September 25, 2024, 01:16:32 am

Title: Any Inputbox alternatives?
Post by: Curt Carpenter on September 25, 2024, 01:16:32 am
I'm using linux and dislike the InputBox widget.  Are there any alternatives to it in the OPM?
Title: Re: Any Inputbox alternatives?
Post by: Aruna on September 25, 2024, 01:42:31 am
I'm using linux and dislike the InputBox widget.  Are there any alternatives to it in the OPM?
Hi @Curt, did you mean a TEdit? You can write your own custom InputBox using a TEdit ? I am just curious, what is your distro and what is it that you do not like about the widget? 
Title: Re: Any Inputbox alternatives?
Post by: dbannon on September 25, 2024, 06:59:48 am
https://wiki.freepascal.org/Dialog_Examples#InputBox

Curt, as Aruna said, you can reasonably easily make your own. Use a TForm and put in there what you want.

But there are other, related things there on the Dialog_Examples wiki page.

Davo
Title: Re: Any Inputbox alternatives?
Post by: Curt Carpenter on September 25, 2024, 06:58:24 pm
Thanks for the inputs.

I'm using the last 32bit Ubuntu system and using InputBox to input a 4 digit number.  The box provided is way too wide, visually inconsistent (to my taste) with the standard Lazarus controls, and I don't know how to set its size.

I can live without the InputBox entirely and just use a TEdit, but was wondering if there were some other OS-independent message dialog components in the OPM.  I suspect there are, and thought I'd ask rather than try and search something out myself.
Title: Re: Any Inputbox alternatives?
Post by: Aruna on September 25, 2024, 08:33:51 pm
I'm using the last 32bit Ubuntu system and using InputBox to input a 4 digit number.  The box provided is way too wide, visually inconsistent (to my taste) with the standard Lazarus controls, and I don't know how to set its size.
I have attached a zip file that has a fully working solution for you. It is heavily commented and I wish 'I' had something similar to learn from when I first started out learning free pascal and the ide.(I cut my teeth on Ubuntu Karmic 32bit and sometimes wish I had never moved on.)

I can live without the InputBox entirely and just use a TEdit, but was wondering if there were some other OS-independent message dialog components in the OPM.  I suspect there are, and thought I'd ask rather than try and search something out myself.
I have nothing against the OPM but I feel someone with 'your' specific analytical capabilities will have little trouble going through my code and understanding what was done. Always better to teach a man how to fish like my friend TRon said to me many moons back :-) Good luck and hope this will help!

PS: Please read those comments
Title: Re: Any Inputbox alternatives?
Post by: Curt Carpenter on September 25, 2024, 10:03:22 pm
I'll take a look.  Thanks.
Title: Re: Any Inputbox alternatives?
Post by: Aruna on September 25, 2024, 10:08:05 pm
I'll take a look.  Thanks.
You are very welcome. I have no clue how experienced (or not) you are with Lazarus and Free Pascal and am going by what I went through initially and if it was me looking at that code I sent your way I would feel a bit overwhelmed and nervous (which is quite normal) I would make a copy/backup first, then start fiddling with the code. Do give us some feedback if you find it useful or have any questions.
Title: Re: Any Inputbox alternatives?
Post by: wp on September 25, 2024, 10:26:15 pm
The box provided is way too wide, visually inconsistent (to my taste) with the standard Lazarus controls, and I don't know how to set its size.
Study the code in the dialogs unit. There are two typed constants:
Code: Pascal  [Select][+][-]
  1. const
  2.   cInputQueryEditSizePixels: Integer = 260; // Edit size in pixels
  3.   cInputQueryEditSizePercents: Integer = 25; // Edit size in % of monitor width

and in the implementation of InputQuery in messagedialogs.inc, there is
Code: Pascal  [Select][+][-]
  1.     NEditWidth:= Max(
  2.       FForm.Scale96ToForm(cInputQueryEditSizePixels),
  3.       _InputQueryActiveMonitor.Width * cInputQueryEditSizePercents div 100);

This means: the width of the edit control and (since the dialog is autosized) the width of the dialog itself is either the (scaled) value of cInputQuerySizePixels (260 px), or the percentage cInputQueryEditSizePercents of the monitor width (25%), whichever is larger. My monitor width is 2560, 25% are 640 which is larger than 260 and thus makes the input box so wide.

So, all you have to do is to set the percentage value to 0, which gives priority to the decent 260 pixels of cInputQuerySizePixels (or any value that you prefer). Do this, for example, in the project unit, and all InputBox or InputQuery forms will have the nicer width:
Code: Pascal  [Select][+][-]
  1. program Project1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. uses
  6.   ...
  7.   Dialogs;
  8.  
  9. {$R *.res}
  10.  
  11. begin
  12.   cInputQueryEditSizePercents := 0;
  13.   RequireDerivedFormResource := True;
  14.   Application.Scaled := True;
  15.   Application.{%H-}MainFormOnTaskbar := True;
  16.   Application.Initialize;
  17.   Application.CreateForm(TForm1,Form1);
  18.   Application.Run;
  19. end.                    
Title: Re: Any Inputbox alternatives?
Post by: Curt Carpenter on September 26, 2024, 01:56:29 am
Thank you wp.  It never occurred to me to check the dialogs unit source, but I will do so now.    (I've overlooked checking source before, with other issues.  Seems to be a blind spot for me that needs fixing.)

Thanks again.
Title: Re: Any Inputbox alternatives?
Post by: Curt Carpenter on September 26, 2024, 03:46:51 am
wp:

Changing that constant in the project source works like magic and I appreciate it.  But frankly I would never have come across your solution on my own without your help -- it is way beyond my skill level and knowledge. 

I wonder if you could recommend a study guide or any organized approach that would lead me toward this level of understanding of Lazarus project organization?  Where should one start to develop the level of knowledge that would let me do this sort of magic on my own?   How did you learn about that constant (which is buried around line 753 (!!!) of the dialogs unit source code?

(I confess that I'm still not sure where to find the dialogs.pp file in my lazarus/fpc installation, although I was able to study it with the help of the IDE without knowing where it was on my drive.  I did finally find messagedialogs.inc). 

Not a whine.  I would like to study and work on my understanding, but just don't really know where to start! Any pointers would be much appreciated. 

Meanwhile -- thanks again.  Worked like a charm.
Title: Re: Any Inputbox alternatives?
Post by: LV on September 26, 2024, 07:36:17 am
Worked like a charm.
I sometimes look at this forum, and I am also delighted with the level of experts.  Is it like, a gift from God or something? :)
Title: Re: Any Inputbox alternatives?
Post by: wp on September 26, 2024, 12:38:46 pm
I wonder if you could recommend a study guide or any organized approach that would lead me toward this level of understanding of Lazarus project organization?  Where should one start to develop the level of knowledge that would let me do this sort of magic on my own?   How did you learn about that constant (which is buried around line 753 (!!!) of the dialogs unit source code?
The main point is that there is a simple trick how to navigate though any source code: Hold the CTRL key down and click on an identifier, and the IDE will open the unit in which this identifier is declared. Then press CTR:+SHIFT+Up/Down arrow to jump between interface and implementation sections of this unit.

Example: You have in your code somewhere the word "InputQuery(...)" because you want to call this function. Do the CTRL-click trick on this word and the IDE jumps to its declaration in the dialogs unit. CTRL+SHIFT+Down jumps to the implementation. Scroll down a bit and you'll find the section which I had cited:
Code: Pascal  [Select][+][-]
  1.     NEditWidth:= Max(
  2.       FForm.Scale96ToForm(cInputQueryEditSizePixels),
  3.       _InputQueryActiveMonitor.Width * cInputQueryEditSizePercents div 100);
Here you see these constants already. Now repeat the CTRL+click on cInputQueryEditSizePixels, and the IDE jumps to
Code: Pascal  [Select][+][-]
  1. const
  2.   cInputQueryEditSizePixels: Integer = 260; // Edit size in pixels
  3.   cInputQueryEditSizePercents: Integer = 25; // Edit size in % of monitor width
Title: Re: Any Inputbox alternatives?
Post by: Curt Carpenter on September 27, 2024, 10:18:00 pm
WP:  As you pointed out for me, the dialogs unit contains
Code: Pascal  [Select][+][-]
  1.     const
  2.       cInputQueryEditSizePixels: Integer = 260; // Edit size in pixels
  3.       cInputQueryEditSizePercents: Integer = 25; // Edit size in % of monitor width

and I understand that typed constants can be assigned different values at runtime.  But could you tell me why they aren't simply defined as variables in the unit in this instance?  Do all typed constants have global scope?
Title: Re: Any Inputbox alternatives?
Post by: wp on September 27, 2024, 10:51:39 pm
I understand that typed constants can be assigned different values at runtime.  But could you tell me why they aren't simply defined as variables in the unit in this instance?
You mean var without an initial value?
Code: Pascal  [Select][+][-]
  1. var
  2.   cInputQueryEditSizePixels: Integer;
  3.   cInputQueryEditSizePercents: Integer;
  4.  
Then the initial values would have to be assigned somewhere in the code (cInputQueryEditSizePixels := 260), and this is much more difficult to find. What's confusing is that this kind of variables is declared as "const". It would have been possible also to replace the "const" by "var". I don't know why this options was not chosen.
Code: Pascal  [Select][+][-]
  1.         var
  2.           cInputQueryEditSizePixels: Integer = 260; // Edit size in pixels
  3.           cInputQueryEditSizePercents: Integer = 25; // Edit size in % of monitor width
  4.  

Do all typed constants have global scope?
Not 100% sure, but I think this is true. The "var" solution in the previous code section, however, would be possible to be used locally in procedures/functions. I do this often to avoid a "non-initialized variable" warning.
Title: Re: Any Inputbox alternatives?
Post by: Curt Carpenter on September 27, 2024, 11:56:39 pm
Thanks.  I guess it's a matter of style (although it would be more if all typed constants were somehow global at compile time?).

In my own code style (by no means elegant) I would have defined the two typed constants here as variables, and then assigned them initial values in the unit initialization section. But I suspect whoever wrote the dialogs unit had a good reason for his/her approach.

Anyway, with the inputbox now a thing of beauty I can turn to other obsessions  :)
Title: Re: Any Inputbox alternatives?
Post by: dseligo on September 28, 2024, 02:01:45 am
Do all typed constants have global scope?

No.

Try this ('Counter' is limited to procedure TestScope):
Code: Pascal  [Select][+][-]
  1. procedure TestScope;
  2. const Counter: Integer = 0;
  3. begin
  4.   inc(Counter);
  5.   WriteLn('Pass: ', Counter);
  6. end;
  7.  
  8. begin
  9.   TestScope;
  10.   TestScope;
  11.   TestScope;
  12.   inc(Counter); // Error: Identifier not found "Counter"
  13. end.
Title: Re: Any Inputbox alternatives?
Post by: PascalDragon on September 28, 2024, 04:01:19 pm
Do all typed constants have global scope?

Typed constants can also be declared inside classes and records (the later if $ModeSwitch AdvancedRecords or $Mode Delphi is used).

If they are declared inside functions/methods as dseligo showed, then they are essentially static variables and they'll keep their assigned variables from invocation to invocation.
Title: Re: Any Inputbox alternatives?
Post by: wp on September 28, 2024, 04:13:21 pm
Modifying dseligo's sample it can be shown that locally declared "const counter: Integer = 0" and "var counter: Integer = 0" behave differently. The former one ("const") essentially is a global variable which however can be accessed from the procedure where it is declared. Therefore, with every call of the procedure the value is incremented. The latter one ("var"), however, is a truely local variable which returns to the initial value whenever the procedure is called:
Code: Pascal  [Select][+][-]
  1. program Project1;
  2.  
  3. procedure TestConstScope;
  4. const
  5.   Counter: Integer = 0;
  6. begin
  7.   inc(Counter);
  8.   WriteLn('Pass: ', Counter);
  9. end;
  10.  
  11. procedure TestVarScope;
  12. var
  13.   Counter: Integer = 0;
  14. begin
  15.   inc(Counter);
  16.   WriteLn('Pass: ', Counter);
  17. end;
  18.  
  19. begin
  20.   WriteLn('var counter: Integer = 0');
  21.   TestVarScope;
  22.   TestVarScope;
  23.   TestVarScope;
  24.   WriteLn;
  25.   WriteLn('const Counter: Integer = 0');
  26.   TestConstScope;
  27.   TestConstScope;
  28.   TestConstScope;
  29.   WriteLn;
  30.   WriteLn('var counter: Integer = 0');
  31.   TestVarScope;
  32.  
  33.   ReadLn;
  34. end.
  35.  
  36. { Output:
  37. var counter: Integer = 0
  38. Pass: 1
  39. Pass: 1
  40. Pass: 1
  41.  
  42. const Counter: Integer = 0
  43. Pass: 1
  44. Pass: 2
  45. Pass: 3
  46.  
  47. var counter: Integer = 0
  48. Pass: 1
  49. }
Title: Re: Any Inputbox alternatives?
Post by: Curt Carpenter on September 28, 2024, 05:09:41 pm
I did not know that -- very interesting.  So a typed constant is sort of a "zombie" global variable that scope-wise is neither alive or dead :).   Using that as a feature seems totally counter to the spirit of Pascal -- but cool in its own way. 

Thanks again.
Title: Re: Any Inputbox alternatives?
Post by: wp on September 28, 2024, 06:55:32 pm
I did not know that
Me not either...
TinyPortal © 2005-2018