Recent

Author Topic: Vertical show form  (Read 5739 times)

xinyiman

  • Hero Member
  • *****
  • Posts: 2259
    • Lazarus and Free Pascal italian community
Vertical show form
« on: April 08, 2016, 08:25:42 am »
Hello guys, I have to build software that runs in the background and simply alert the user if there are any updates. Here comes my problem. I wish that aesthetically appear a pop-up in the lower right, with a show effect is gradual upward. Like opening a vertical panel. Who tells me how to do?
Win10, Ubuntu and Mac
Lazarus: 2.1.0
FPC: 3.3.1

balazsszekely

  • Guest
Re: Vertical show form
« Reply #1 on: April 08, 2016, 08:39:56 am »
Under windows there is a nice api: AnimateWindow(https://msdn.microsoft.com/en-us/library/windows/desktop/ms632669%28v=vs.85%29.aspx)
When you want to show a form:
1. Set position to the lower right corner of the screen. Use Screen.Width, Screen.Height to determine the exact position.
2.
Code: Pascal  [Select][+][-]
  1.   Form2.BorderStyle := bsNone;
  2.   AnimateWindow(Form2.Handle, 3000, AW_ACTIVATE or AW_VER_NEGATIVE);
  3.   Form2.Show;        
  4.  
3. Feel free to play with the extra parameters
« Last Edit: April 08, 2016, 08:54:50 am by GetMem »

xinyiman

  • Hero Member
  • *****
  • Posts: 2259
    • Lazarus and Free Pascal italian community
Re: Vertical show form
« Reply #2 on: April 08, 2016, 04:18:33 pm »
Thank you. But exist a cross-platform solution?
Win10, Ubuntu and Mac
Lazarus: 2.1.0
FPC: 3.3.1

balazsszekely

  • Guest
Re: Vertical show form
« Reply #3 on: April 08, 2016, 06:11:45 pm »
Quote
@xinyiman
But exist a cross-platform solution?
Not that I'm aware of, unless you write your own. Unfortunately window animation doesn't look too good under GTK2, Carbon(at least in my experience)!

xinyiman

  • Hero Member
  • *****
  • Posts: 2259
    • Lazarus and Free Pascal italian community
Re: Vertical show form
« Reply #4 on: April 08, 2016, 06:25:20 pm »
Thanks for the suggestion
Win10, Ubuntu and Mac
Lazarus: 2.1.0
FPC: 3.3.1

balazsszekely

  • Guest
Re: Vertical show form
« Reply #5 on: April 08, 2016, 09:05:01 pm »
This is the best solution I could came up with(attachment)! All that crappy support code only needed for GTK2 and Carbon. Under windows you can do it with a few lines of code. Feel free to play with the AlphaBlend value. Tested under win7/ubuntu 14. I wonder if there is a better way, to achieve this?

PS: Screenshot in the next post.
« Last Edit: April 08, 2016, 09:16:51 pm by GetMem »

balazsszekely

  • Guest
Re: Vertical show form
« Reply #6 on: April 08, 2016, 09:09:50 pm »
This is how it looks(I must attach the picture in a separate post because is too large):

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: Vertical show form
« Reply #7 on: April 09, 2016, 12:06:29 am »
Another possibly cross-platform way would be something like the following function, called for instance as
WindowPopup(['first line','second line','third line','fourth line']);
or with additional parameters. An AlphaBlend parameter could be added if needed.

Code: Pascal  [Select][+][-]
  1. unit popWindow;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, Forms, Graphics, Controls, ExtCtrls;
  9.  
  10. type
  11.  
  12.   { TPopNotifier }
  13.  
  14.   TPopNotifier = class(TForm)
  15.   private
  16.     FMargin: integer;
  17.     FTimer: TTimer;
  18.     FTimeout: integer;
  19.     FTimeoutStarted: boolean;
  20.     FStrArray: array of string;
  21.     FLineHeight: integer;
  22.     FMaxHite: integer;
  23.     FTimerStart: QWord;
  24.     FDrawStrings: boolean;
  25.     procedure popShow(Sender: TObject);
  26.     procedure timerOnTimer(Sender: TObject);
  27.   public
  28.     constructor {%H-}Create(aStrings: array of const; aMargin: integer=20; aTimeout: integer=100);
  29.     procedure popKeydown(Sender: TObject; var {%H-}Key: Word; {%H-}Shift: TShiftState);
  30.     procedure popMouseEnter(Sender: TObject);
  31.     procedure popPaint(Sender: TObject);
  32.   end;
  33.  
  34. procedure WindowPopup(aStrings: array of const; aBackColor: TColor=clSkyBlue;
  35.                       aMargin: integer=20; aTimeout: integer=100);
  36.  
  37. implementation
  38.  
  39. procedure WindowPopup(aStrings: array of const; aBackColor: TColor;
  40.   aMargin: integer; aTimeout: integer);
  41. var
  42.   dlg: TPopNotifier;
  43. begin
  44.   Assert(High(aStrings) > -1,'WindowPopup() has no data');
  45.   dlg:=TPopNotifier.Create(aStrings, aMargin, aTimeout);
  46.   try
  47.     dlg.Color:=aBackColor;
  48.     dlg.ShowModal;
  49.   finally
  50.     dlg.Free;
  51.   end;
  52. end;
  53.  
  54. { TPopNotifier }
  55.  
  56. procedure TPopNotifier.popShow(Sender: TObject);
  57. var
  58.   i, len, lenMax, incr, maxIdx, doubleMargin, tp, lf, wd: integer;
  59. begin
  60.   lenMax:=0;
  61.   maxIdx:=High(FStrArray);
  62.   for i:=0 to maxIdx do begin
  63.     len:=Canvas.TextWidth(FStrArray[i]);
  64.     if (len > lenMax) then
  65.       lenMax:=len;
  66.   end;
  67.   doubleMargin:=FMargin shl 1;
  68.   incr:=doubleMargin + FMargin;
  69.   Inc(lenMax, incr);
  70.   FLineHeight:=Canvas.TextHeight(FStrArray[0]);
  71.   FMaxHite:=FLineHeight*Length(FStrArray) + doubleMargin;
  72.   tp:=Screen.Height - FMargin;
  73.   wd:=lenMax-FMargin;
  74.   lf:=Screen.Width - lenMax;
  75.   SetBounds(lf, tp, wd, 0);
  76.   FTimer.Enabled:=True;
  77.   FTimerStart:=GetTickCount64;
  78. end;
  79.  
  80. procedure TPopNotifier.timerOnTimer(Sender: TObject);
  81. var
  82.   d: QWord;
  83.   h, t: integer;
  84. begin
  85.   d:=(GetTickCount64 - FTimerStart) div 2;
  86.   case FTimeoutStarted of
  87.     False: begin
  88.       h:=Height + d;
  89.       t:=Top - d;
  90.       if (h < FMaxHite) then
  91.         SetBounds(Left, t, Width, h);
  92.       FTimer.Enabled:=h < FMaxHite;
  93.       if not FTimer.Enabled then begin
  94.         FDrawStrings:=True;
  95.         Invalidate;
  96.         FTimeoutStarted:=True;
  97.         FTimer.Enabled:=True;
  98.       end;
  99.       FTimerStart:=GetTickCount64;
  100.     end;
  101.     True: begin
  102.       Dec(FTimeout);
  103.       if (FTimeout < 0) then begin
  104.         FTimer.Enabled:=False;
  105.         ModalResult:=mrOK;
  106.       end;
  107.     end;
  108.   end;
  109. end;
  110.  
  111. constructor TPopNotifier.Create(aStrings: array of const; aMargin: integer;
  112.   aTimeout: integer);
  113. var
  114.   i, maxIdx: integer;
  115. begin
  116.   inherited CreateNew(nil);
  117.   FTimer:=TTimer.Create(Self);
  118.   FTimer.Interval:=20; // optimum value is hardware dependent
  119.   FTimer.OnTimer:=@timerOnTimer;
  120.   if (aTimeout < 100) then
  121.     aTimeout:=100;
  122.   FTimeout:=aTimeout;
  123.   OnPaint:=@popPaint;
  124.   OnKeyDown:=@popKeydown;
  125.   OnMouseEnter:=@popMouseEnter;
  126.   OnShow:=@popShow;
  127.   FMargin:=aMargin;
  128.   BorderStyle:=bsNone;
  129.   maxIdx:=High(aStrings);
  130.   SetLength(FStrArray, maxIdx+1);
  131.   for i:=0 to maxIdx do
  132.     case aStrings[i].VType of
  133.       vtString: FStrArray[i]:=aStrings[i].VString^;
  134.       vtAnsiString: FStrArray[i]:=AnsiString(aStrings[i].VAnsiString);
  135.     end;
  136. end;
  137.  
  138. procedure TPopNotifier.popKeydown(Sender: TObject; var Key: Word; Shift: TShiftState);
  139. begin
  140.   ModalResult:=mrOK;
  141. end;
  142.  
  143. procedure TPopNotifier.popMouseEnter(Sender: TObject);
  144. begin
  145.   ModalResult:=mrOK;
  146. end;
  147.  
  148. procedure TPopNotifier.popPaint(Sender: TObject);
  149. var
  150.   i: integer;
  151. begin
  152.   if FDrawStrings then begin
  153.     for i:=0 to High(FStrArray) do
  154.       Canvas.TextOut(FMargin, i*FLineHeight + FMargin, FStrArray[i]);
  155.   end;
  156. end;
  157.  
  158. end.
  159.  

balazsszekely

  • Guest
Re: Vertical show form
« Reply #8 on: April 09, 2016, 07:46:41 am »
@howardpc
It's a nice solution and it works well! Under windows I would take into account the height of the taskbar.

balazsszekely

  • Guest
Re: Vertical show form
« Reply #9 on: April 09, 2016, 09:23:00 am »
Inspired by @howardpc's solution I modified my own. This time there is no vertical movement, but in my opinion still looks nice and most importantly works!  I also added autoclose feature. What do you think @xinyiman?

xinyiman

  • Hero Member
  • *****
  • Posts: 2259
    • Lazarus and Free Pascal italian community
Re: Vertical show form
« Reply #10 on: April 09, 2016, 10:16:34 am »
Ok work  ;D
Win10, Ubuntu and Mac
Lazarus: 2.1.0
FPC: 3.3.1

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: Vertical show form
« Reply #11 on: April 09, 2016, 12:13:02 pm »
@GetMem
I like your new solution. I think it is better not to use a modal window (as I did), and you ingeniously and simply show a fake (working) close button.

 

TinyPortal © 2005-2018