(*
*******************************************************************************
*         Copyright (C) SofCon 2004 All Rights Reserved                       *
*******************************************************************************
*
*    project:     Vizualizacni knihovny pro jednotku KIT
*
*
*    title:       StdMBCus
*
*******************************************************************************
*
*    description: funkce pro snadne vytvareni std. message boxu
*
*    version:     0.01
*
*     (vyse uvedena verze je pouze verze teto knihovny, ktera
*      je soucasti baliku LIBV, jehoz verze je uvedena v knihovne
*      Iodrv.pas)
*
*    language:    Borland Pascal
*
*    author:      Binko
*    history:     date        sign   remark
*                 27/07/04    bin     prvni vydani
*
*****************************************************************************
*)


{$I SETS.INC}
unit StdMBcus;

interface

uses
  objects,iodrv, controls, grctrls, fonts,
{$ifdef COLOR}
  BmpMsgsC,
{$else}
  BmpMsgsM,
{$endif}
  rstring; {, resStr, resStrCZ, resStrEn;}

const
  cidStdMsgDlg = $FF11; {asi hodit do controls.pas}


const {msf ... }
  msfBtMask    = $000F;
  msfBtOk      = $0001;
  msfBtCancel  = $0002;
  msfBtYes     = $0004;
  msfBtNo      = $0008;
{
  msfBtOkCancel = msfBtOk + msfBtCancel;
  msfBtYesNo = msfBtYes + msfBtNo;
}
  msfIconMask  = $1800;
  msfIconErr   = $0800;
  msfIconAsk   = $1000;
  msfIconExcl  = $1800;

  msfCloseMask      = $E000;
  msfCloseAfter5s   = $2000;
  msfCloseAfter10s  = $4000;
  msfCloseAfter30s  = $6000;
  msfCloseAfter1m   = $8000;
  msfCloseAfter2m   = $A000;
  msfCloseAfter5m   = $C000;
  msfCloseAfter10m  = $E000;


function StdMBF( const ABounds: TRect; const ATitle, AText: string; AFlags: Word ): PCustomDialog; far;


implementation


procedure StdMBFNotify( var N : TNotification ); far;
begin
  case N.Control^.Id of
    cidStdMsgDlg:
      begin
        case N.Code of
          nmTimer:
            begin
              ClearNotification( N );
              N.Control^.EndModal( mrCancel );
            end;
          nmExit:
            begin
              N.Control^.CancelTimer( 1 );
              ClearNotification( N );
            end;
        end;
      end;
  end;
end;

function StdMBF( const ABounds: TRect; const ATitle, AText: string; AFlags: Word ): PCustomDialog;
var
  Dlg  : PDialog;
  R    : TRect;
  Text : PStaticText;
  bt   : array [1..4] of PButton;
  cb   : byte; {current button, last button}
  img  : PImage;

  width : integer;
  height : integer;
  fontheight : word;

  linecount : byte;

  topLine : word;
  bottomLine : word;
  leftline : word;

  li : longint; {docasna prom}

  function CountLines( const AText: string ): Byte; assembler;
  asm
          LES   DI, [AText]
          XOR   DX, DX
          XOR   CX, CX
          MOV   CL, ES:[DI]
          INC   DI
          JCXZ  @@3
          INC   DX
          MOV   AL, 13
   @@1:
          REPNE SCASB
          JNE   @@2
          INC   DX
   @@2:
          OR    CX, CX
          JNZ   @@1
   @@3:
          MOV   AX, DX
  end;

begin
  Dlg := new( PDialog, Init( ABounds, ATitle ));
  Dlg^.Id := cidStdMsgDlg;
  Dlg^.Customize( ccDialog );

  Dlg^.GetExtent( R );

  width := R.B.X - R.A.X;
  height := R.B.Y - R.A.Y;
  fontHeight := GetTextHeight( Application^.Font );

  if (width < 60) or (height <= (3 * fontHeight)) then RunError( 249 );

  topLine := R.A.Y + fontHeight + 2 + 1;
  bottomLine := R.B.Y - 1;
  leftLine := R.A.X;

{ 1) tlacitka }
  cb := 0; { current (last) button }

  R.Assign( 1, 1, 2, 2 );
  if (( AFlags and msfBtYes ) <> 0 ) then
  begin
    inc( cb );
    bt[cb] := new( PButton, Init( R, 'Yes', btmEndModal, mrYes ));
    bt[cb]^.Customize( ccButton );
{    bt[cb]^.SetOptions( ofSelectable or ofShowFocus, 0 );}
  end;

  if (( AFlags and msfBtNo ) <> 0 ) then
  begin
    inc( cb );
    bt[cb] := new( PButton, Init( R, 'No', btmEndModal, mrNo ));
    bt[cb]^.Customize( ccButton );
{    bt[cb]^.SetOptions( ofSelectable or ofShowFocus, 0 );}
  end;

  if (( AFlags and msfBtOk ) <> 0 ) then
  begin
    inc( cb );
    bt[cb] := new( PButton, Init( R, 'Ok', btmEndModal, mrOk ));
    bt[cb]^.Customize( ccButton );
{    bt[cb]^.SetOptions( ofSelectable or ofShowFocus, 0 );}
  end;

  if (( AFlags and msfBtCancel ) <> 0 ) then
  begin
    inc( cb );
    bt[cb] := new( PButton, Init( R, 'Cancel', btmEndModal, mrCancel ));
    bt[cb]^.Customize( ccButton );
{   bt[cb]^.SetOptions( ofSelectable or ofShowFocus, 0 );}
  end;

  if ((cb * 70) <= width) then
  begin
    case cb of
      0: ;
      1: begin
           r.Assign( width div 2 - 30, bottomLine - 4 - fontHeight - 3 , width div 2 + 30, bottomLine - 4 );
           bt[1]^.Locate( r );
           Dlg^.Insert( bt[1] );
           bottomLine := bottomLine - 4 - fontheight - 3;
         end;
      2: begin
           r.Assign( width div 2 - 65, bottomLine - 4 - fontHeight - 3, width div 2 - 5, bottomLine - 4 );
           bt[1]^.Locate( r );
           Dlg^.Insert( bt[1] );
           r.Move( 70, 0 );
           bt[2]^.Locate( r );
           Dlg^.Insert( bt[2] );
           bottomLine := bottomLine - 4 - fontheight - 3;
         end;
      3: begin
           r.Assign( width div 2 - 30 - 70, bottomLine - 4 - fontHeight - 3, Width div 2 - 30 - 5, bottomLine - 4 );
           bt[1]^.Locate( r );
           Dlg^.Insert( bt[1] );
           r.Move( 70, 0 );
           bt[2]^.Locate( r );
           Dlg^.Insert( bt[2] );
           r.Move( 70, 0 );
           bt[3]^.Locate( r );
           Dlg^.Insert( bt[3] );
           bottomLine := bottomLine - 4 - fontheight - 3;
         end;
      4: begin
           r.Assign( width div 2 -5 -60 -10 -60, bottomLine - 4 - fontHeight - 3, Width div 2 -5 -60 -10, bottomLine - 4 );
           bt[1]^.Locate( r );
           Dlg^.Insert( bt[1] );
           r.Move( 70, 0 );
           bt[2]^.Locate( r );
           Dlg^.Insert( bt[2] );
           r.Move( 70, 0 );
           bt[3]^.Locate( r );
           Dlg^.Insert( bt[3] );
           r.Move( 70, 0 );
           bt[4]^.Locate( r );
           Dlg^.Insert( bt[4] );
           bottomLine := bottomLine - 4 - fontheight - 3;
         end;
    end
  end
  else
    runerror(249);

{2) ikony}
  if (( AFlags and msfIconMask ) <> 0 ) then
  begin
    if ( width < 34 ) then runerror( 249 );
    R.Assign( leftLine+4, topLine+1, leftLine + 32 + 4, bottomLine - 1 );
    Img := new( PImage, Init( r, nil ));

    case ( AFlags and msfIconMask ) of
{$ifdef COLOR}
      msfIconErr:  Img^.SetBitmap( GetMsgCBitmap( bidKrizek ));
      msfIconAsk:  Img^.SetBitmap( GetMsgCBitmap( bidOtaznik ));
      msfIconExcl: Img^.SetBitmap( GetMsgCBitmap( bidVykricnik ));
{$else}
      msfIconErr:  Img^.SetBitmap( GetMsgMBitmap( bidKrizek ));
      msfIconAsk:  Img^.SetBitmap( GetMsgMBitmap( bidOtaznik ));
      msfIconExcl: Img^.SetBitmap( GetMsgMBitmap( bidVykricnik ));
{$endif}
    end;

    Img^.Customize( ccImage );
    Img^.SetFlags( imfAlignCenterX or imfAlignCenterY, 0 );
    Dlg^.Insert( Img );

    leftLine := leftLine + 32 + 4;
  end;

{3) text }
  linecount := CountLines( RSToStr( @AText )^ );

  if (( LineCount * fontHeight) > (BottomLine - TopLine)) then RunError( 249 );
  R.Assign( LeftLine+3 , TopLine+1, width - 6, BottomLine -1 );
  Text := new( PStaticText, Init( r, AText ));
  if linecount = 1 then
    text^.TextFlags := tfCenterY
  else
  begin
{
    if ( LineCount = 2 ) then
    begin
      R.Assign( LeftLine+3, (topLine+BottomLine) div 2 - fontHeight, width - 6, (topLine+BottomLine) div 2 + fontHeight );
      Text^.Locate( R );
    end;
}
    Text^.TextFlags := tfMultiLine or tfCenterY;
  end;
  Dlg^.Insert( Text );

{4) samoopusteni}
  if ( AFlags and msfCloseMask ) <> 0 then
  begin
    Dlg^.AfterNotify := StdMbfNotify;
    case ( AFlags and msfCloseMask ) of
      msfCloseAfter5s : li :=  5000; {ms}
      msfCloseAfter10s: li := 10000;
      msfCloseAfter30s: li := 30000;
      msfCloseAfter1m : li := 60000;
      msfCloseAfter2m : li :=120000;
      msfCloseAfter5m : li :=300000;
      msfCloseAfter10m: li :=600000;
    end;
    Dlg^.ScheduleTimer( 1, li, toOneShot );
  end
  else
    Dlg^.AfterNotify := nil;

  StdMBF := Dlg;
end;

{
                  Application^.MessageBox( R, 'Confirmation',
                         'Do you really want to'#13'format c: ?',
                         msfIconAsk + msfBtYes + msfBtNo + msfBtCancel );
                  ClearNotification( N );
}
end.
