lazarus/components/aggpas/find_compilers_win.dpr
mattias 36a2b1ea07 added aggpas
git-svn-id: trunk@21942 -
2009-10-01 12:24:32 +00:00

1496 lines
28 KiB
ObjectPascal

{target:win}
//
// AggPas 2.4 RM3 Demo application
// Milan Marusinec alias Milano (c) 2006 - 2008
// Note: Press F1 key on run to see more info about this demo
//
program
find_compilers_win ;
uses
SysUtils ,Windows ,
agg_basics ,
agg_platform_support ,
agg_color ,
agg_pixfmt ,
agg_pixfmt_rgb ,
agg_ctrl ,
agg_cbox_ctrl ,
agg_rbox_ctrl ,
agg_rendering_buffer ,
agg_renderer_base ,
agg_renderer_scanline ,
agg_rasterizer_scanline_aa ,
agg_scanline ,
agg_scanline_u ,
agg_render_scanlines ,
agg_gsv_text ,
agg_conv_stroke ,
file_utils_ ;
{$I agg_mode.inc }
{$I- }
type
src_key = record
key ,
val : string[99 ];
end;
const
flip_y = true;
g_appl = 'AggPas';
g_full = 'AggPas 2.4 RM3 vector graphics library';
g_agg_paths = 'src;src\ctrl;src\platform\win;src\util;src\svg;gpc;expat-wrap';
g_inc_paths = 'src';
g_out_paths = '_debug';
g_delphi_config = '-CG -B -H- -W-';
g_fpc_config = '-Mdelphi -Twin32 -WG -Sg -Se3 -CX -XX -Xs -B -Op3 -v0i';
g_max = 20;
g_max_demos = 100;
key_max = 99;
var
g_lock ,g_image : boolean;
g_found ,g_num_demos : unsigned;
g_search_results : array[0..g_max - 1 ] of shortstring;
g_demos : array[0..g_max_demos - 1 ] of string[99 ];
key_array : array[0..key_max - 1 ] of src_key;
key_count ,
key_lastx : unsigned;
key_scanx : shortstring;
type
the_application_ptr = ^the_application;
dialog_ptr = ^dialog;
func_action = function(appl : the_application_ptr; sender : dialog_ptr ) : boolean;
user_action_ptr = ^user_action;
user_action = record
func : func_action;
ctrl : rbox_ctrl;
end;
user_choice = record
ctrl : cbox_ctrl;
attr : shortstring;
end;
dlg_status_e = (ds_none ,ds_define ,ds_ready ,ds_waiting_input ,ds_running );
dialog = object
m_appl : the_application_ptr;
m_info : PChar;
m_text : char_ptr;
m_tx_x ,
m_tx_y : double;
m_aloc ,
m_size : unsigned;
m_clri ,
m_clrt : aggclr;
m_status : dlg_status_e;
m_actions : array[0..4 ] of user_action;
m_choices : array[0..25 ] of user_choice;
m_num_actions ,
m_num_choices : unsigned;
m_cur_action : user_action_ptr;
m_waiting : func_action;
constructor Construct(appl : the_application_ptr; info : PChar; clr : aggclr_ptr = NIL );
destructor Destruct;
procedure set_waiting(act : func_action );
procedure add_action(name : PChar; act : func_action; x1 ,y1 ,x2 ,y2 : double );
procedure add_choice(name ,attr : PChar; x ,y : double; status : boolean = false );
procedure change_text(text : PChar; x ,y : double; clr : aggclr_ptr = NIL );
procedure append_text(text : PChar );
function add_controls : boolean;
procedure set_next_status(status : dlg_status_e = ds_none );
function find_cur_action : boolean;
function call_cur_action : boolean;
procedure call_waiting;
end;
the_application = object(platform_support )
m_dlg_welcome ,
m_dlg_set_drives ,
m_dlg_searching ,
m_dlg_not_found ,
m_dlg_found_some : dialog;
m_cur_dlg : dialog_ptr;
m_ras : rasterizer_scanline_aa;
m_sl : scanline_u8;
m_Thread : THandle;
m_ApplID : LongWord;
m_DoQuit : boolean;
m_ShLast ,
m_DoShow : shortstring;
constructor Construct(format_ : pix_format_e; flip_y_ : boolean );
destructor Destruct;
procedure draw_text(x ,y : double; msg : PChar; clr : aggclr_ptr = NIL );
procedure on_init; virtual;
procedure on_draw; virtual;
procedure on_ctrl_change; virtual;
procedure on_idle; virtual;
procedure on_key(x ,y : int; key ,flags : unsigned ); virtual;
end;
{ NEXTKEY }
function NextKey(var val : shortstring ) : boolean;
begin
result:=false;
while key_lastx < key_count do
begin
inc(key_lastx );
if cmp_str(key_array[key_lastx - 1 ].key ) = key_scanx then
begin
val:=key_array[key_lastx - 1 ].val;
result:=true;
break;
end;
end;
end;
{ FIRSTKEY }
function FirstKey(key : shortstring; var val : shortstring ) : boolean;
begin
key_lastx:=0;
key_scanx:=cmp_str(key );
result:=NextKey(val );
end;
{ LOADKEYS }
procedure LoadKeys(buff : char_ptr; size : int );
type
e_scan = (expect_lp ,load_key ,load_val ,next_ln ,expect_crlf );
var
scan : e_scan;
key ,
val : shortstring;
procedure add_key;
begin
if key_count < key_max then
begin
key_array[key_count ].key:=key;
key_array[key_count ].val:=val;
inc(key_count );
end;
key:='';
val:='';
end;
begin
key_count:=0;
scan:=expect_lp;
key :='';
val :='';
while size > 0 do
begin
case scan of
expect_lp :
case buff^ of
'{' :
scan:=load_key;
else
break;
end;
load_key :
case buff^ of
#13 ,#10 :
break;
':' :
scan:=load_val;
'}' :
begin
add_key;
scan:=next_ln;
end;
else
key:=key + buff^;
end;
load_val :
case buff^ of
#13 ,#10 :
break;
'}' :
begin
add_key;
scan:=next_ln;
end;
else
val:=val + buff^;
end;
next_ln :
case buff^ of
#13 ,#10 :
scan:=expect_crlf;
' ' :
else
break;
end;
expect_crlf :
case buff^ of
'{' :
scan:=load_key;
#13 ,#10 :
else
break;
end;
end;
dec(size );
inc(ptrcomp(buff ) );
end;
end;
{ CONSTRUCT }
constructor dialog.Construct;
begin
m_clri.ConstrDbl(0 ,0 ,0 );
m_clrt.ConstrDbl(0 ,0 ,0 );
m_appl:=appl;
m_info:=info;
m_text:=NIL;
m_tx_x:=0;
m_tx_y:=0;
m_aloc:=0;
m_size:=0;
if clr <> NIL then
m_clri:=clr^;
m_status:=ds_define;
m_num_actions:=0;
m_num_choices:=0;
m_cur_action:=NIL;
m_waiting :=NIL;
end;
{ DESTRUCT }
destructor dialog.Destruct;
var
i : unsigned;
begin
if m_text <> NIL then
agg_freemem(pointer(m_text ) ,m_aloc );
if m_num_actions > 0 then
for i:=0 to m_num_actions - 1 do
m_actions[i ].ctrl.Destruct;
if m_num_choices > 0 then
for i:=0 to m_num_choices - 1 do
m_choices[i ].ctrl.Destruct;
end;
{ SET_WAITING }
procedure dialog.set_waiting;
begin
m_waiting:=@act;
end;
{ ADD_ACTION }
procedure dialog.add_action;
begin
case m_status of
ds_define ,ds_ready :
if m_num_actions < 5 then
begin
m_actions[m_num_actions ].ctrl.Construct(x1 ,y1 ,x2 ,y2 ,not flip_y );
m_actions[m_num_actions ].ctrl.add_item (name );
m_actions[m_num_actions ].func:=@act;
inc(m_num_actions );
set_next_status(ds_ready );
end;
end;
end;
{ ADD_CHOICE }
procedure dialog.add_choice;
begin
case m_status of
ds_define ,ds_ready :
if m_num_choices < 26 then
begin
m_choices[m_num_choices ].ctrl.Construct(x ,y ,name ,not flip_y );
m_choices[m_num_choices ].ctrl.status_ (status );
m_choices[m_num_choices ].attr:=StrPas(attr ) + #0;
inc(m_num_choices );
end;
end;
end;
{ CHANGE_TEXT }
procedure dialog.change_text;
begin
if StrLen(text ) + 1 > m_aloc then
begin
agg_freemem(pointer(m_text ) ,m_aloc );
m_aloc:=StrLen(text ) + 1;
agg_getmem(pointer(m_text ) ,m_aloc );
end;
move(text[0 ] ,m_text^ ,StrLen(text ) + 1 );
m_size:=StrLen(text );
m_tx_x:=x;
m_tx_y:=y;
if clr <> NIL then
m_clrt:=clr^;
end;
{ APPEND_TEXT }
procedure dialog.append_text;
var
new_text : char_ptr;
new_aloc : unsigned;
begin
if StrLen(text ) + m_size + 1 > m_aloc then
begin
new_aloc:=StrLen(text ) + m_size + 1;
agg_getmem(pointer(new_text ) ,new_aloc );
move(m_text^ ,new_text^ ,m_size );
agg_freemem(pointer(m_text ) ,m_aloc );
m_aloc:=new_aloc;
m_text:=new_text;
end;
move(text[0 ] ,char_ptr(ptrcomp(m_text ) + m_size )^ ,StrLen(text ) + 1 );
inc(m_size ,StrLen(text ) );
end;
{ ADD_CONTROLS }
function dialog.add_controls;
var
i : unsigned;
begin
result:=false;
case m_status of
ds_ready :
begin
m_appl.m_ctrls.Destruct;
m_appl.m_ctrls.Construct;
if m_num_actions > 0 then
for i:=0 to m_num_actions - 1 do
m_appl.add_ctrl(@m_actions[i ].ctrl );
if m_num_choices > 0 then
for i:=0 to m_num_choices - 1 do
m_appl.add_ctrl(@m_choices[i ] );
set_next_status;
result:=true;
end;
end;
end;
{ SET_NEXT_STATUS }
procedure dialog.set_next_status;
begin
if status <> ds_none then
m_status:=status
else
case m_status of
ds_define :
m_status:=ds_ready;
ds_ready :
m_status:=ds_waiting_input;
ds_waiting_input :
m_status:=ds_running;
end;
end;
{ FIND_CUR_ACTION }
function dialog.find_cur_action;
var
i : unsigned;
begin
result:=false;
case m_status of
ds_waiting_input :
if m_num_actions > 0 then
for i:=0 to m_num_actions - 1 do
if m_actions[i ].ctrl._cur_item = 0 then
begin
m_cur_action:=@m_actions[i ];
result:=true;
exit;
end;
end;
end;
{ CALL_CUR_ACTION }
// result of true means, that this was the last call
function dialog.call_cur_action;
begin
result:=false;
case m_status of
ds_running :
if m_cur_action <> NIL then
result:=m_cur_action.func(m_appl ,@self );
end;
end;
{ CALL_WAITING }
procedure dialog.call_waiting;
begin
if @m_waiting <> NIL then
m_waiting(m_appl ,@self );
end;
{ create_delphi }
procedure create_delphi(batch_file ,comp_path ,project : shortstring );
var
command : AnsiString;
suffix ,file_path ,file_name ,file_ext : shortstring;
df : text;
begin
// Compose the units path string
spread_name(comp_path ,file_path ,file_name ,file_ext );
command:=dir_str(file_path );
spread_name(command ,file_path ,suffix ,file_ext );
suffix:=file_path + 'lib';
// Compose the command string
command:='"' + comp_path + 'dcc32.exe" ';
command:=command + '-U"' + suffix + '";';
command:=command + g_agg_paths + ' ';
command:=command + '-I' + g_inc_paths + ' ';
command:=command + '-N' + g_out_paths + ' ';
command:=command + g_delphi_config + ' ';
command:=command + project;
// Create the file
AssignFile(df ,batch_file );
rewrite (df );
writeln (df ,command );
close (df );
end;
{ create_fpc }
procedure create_fpc(batch_file ,comp_path ,project : shortstring );
var
command : AnsiString;
suffix ,file_path ,file_name ,file_ext : shortstring;
df : text;
begin
// Compose the units path string
spread_name(comp_path ,file_path ,file_name ,file_ext );
command:=dir_str(file_path );
spread_name(command ,file_path ,suffix ,file_ext );
command:=dir_str(file_path );
spread_name(command ,file_path ,file_name ,file_ext );
suffix:=file_path + 'units\' + suffix;
// Compose the command string
command:='"' + comp_path + 'ppc386.exe" ';
command:=command + '-FD"' + suffix + '" ';
command:=command + '-Fu' + g_agg_paths + ' ';
command:=command + '-Fi' + g_inc_paths + ' ';
command:=command + '-FU' + g_out_paths + ' ';
command:=command + g_fpc_config + ' ';
command:=command + project;
// Create the file
AssignFile(df ,batch_file );
rewrite (df );
writeln (df ,command );
close (df );
end;
{ create_batch_files }
procedure create_batch_files(project : shortstring; var del ,fpc : unsigned );
var
i ,del_cnt ,fpc_cnt : unsigned;
batch ,batch_path ,comp_path ,file_path ,comp_name ,file_name ,file_ext : shortstring;
df : text;
begin
spread_name(ParamStr(0 ) ,batch_path ,file_name ,file_ext );
del_cnt:=1;
fpc_cnt:=1;
for i:=0 to g_found - 1 do
begin
spread_name(g_search_results[i ] ,comp_path ,comp_name ,file_ext );
spread_name(project ,file_path ,file_name ,file_ext );
if cmp_str(comp_name ) = cmp_str('dcc32' ) then
begin
// Make batch for Delphi
if del_cnt = 1 then
batch:=''
else
str(del_cnt ,batch );
batch:='delphi' + batch + '-' + file_name;
batch:=fold_name(batch_path ,batch ,'*.bat' );
create_delphi(batch ,comp_path ,project );
// Make file
if del_cnt = 1 then
file_ext:=''
else
str(del_cnt ,file_ext );
file_ext :='delphi' + file_ext + '_make_all';
file_name:=fold_name(batch_path ,file_ext ,'*.bat' );
AssignFile(df ,file_name );
if del = 0 then
rewrite(df )
else
append(df );
file_ext:='call "' + batch + '"';
writeln(df ,file_ext );
close (df );
inc(del_cnt );
end
else
begin
// Make batch for FreePascal
if fpc_cnt = 1 then
batch:=''
else
str(fpc_cnt ,batch );
batch:='fpc' + batch + '-' + file_name;
batch:=fold_name(batch_path ,batch ,'*.bat' );
create_fpc(batch ,comp_path ,project );
// Make file
if fpc_cnt = 1 then
file_ext:=''
else
str(fpc_cnt ,file_ext );
file_ext :='fpc' + file_ext + '_make_all';
file_name:=fold_name(batch_path ,file_ext ,'*.bat' );
AssignFile(df ,file_name );
if fpc = 0 then
rewrite(df )
else
append(df );
file_ext:='call "' + batch + '"';
writeln(df ,file_ext );
close (df );
inc(fpc_cnt );
end;
end;
inc(del ,del_cnt - 1 );
inc(fpc ,fpc_cnt - 1 );
end;
{ action_configure }
function action_configure(appl : the_application_ptr; sender : dialog_ptr ) : boolean;
var
i : unsigned;
text : shortstring;
rgba : aggclr;
del ,fpc : unsigned;
begin
rgba.ConstrDbl(0 ,0.5 ,0 );
appl.m_dlg_searching.change_text('Creating appropriate batch files ...' ,10 ,320 ,@rgba );
appl.force_redraw;
// Setup the final text
rgba.ConstrDbl(0 ,0.5 ,0 );
appl.m_dlg_found_some.change_text('' ,10 ,385 ,@rgba );
for i:=0 to g_found - 1 do
begin
str(i + 1 ,text );
text:='(' + text + ') ' + g_search_results[i ] + #13#0;
appl.m_dlg_found_some.append_text(@text[1 ] );
end;
// Create the batch files
if g_num_demos > 0 then
begin
appl.m_dlg_found_some.append_text(
#13 +
'Appropriate batch files for compiling the ' + g_appl + ' demos were created'#13 +
'in the directory, from which this helper utility was run.' );
del:=0;
fpc:=0;
for i:=0 to g_num_demos - 1 do
create_batch_files(g_demos[i ] ,del ,fpc );
if del > 0 then
appl.m_dlg_found_some.append_text(
#13#13 +
'Note: For the Delphi compiler, which was found on your system,'#13 +
'helper utility assumes, that the system libraries needed for'#13 +
'successful compilation are located in the parallel directory'#13 +
'"..\lib" of the particular Delphi compiler path.' );
if fpc > 0 then
appl.m_dlg_found_some.append_text(
#13#13 +
'Note: For the Free Pascal compiler, which was found on your system,'#13 +
'helper utility assumes, that the system libraries needed for'#13 +
'successful compilation are located in the parallel directory'#13 +
'"..\units\i386-win32" of the particular Free Pascal compiler path.' );
end
else
appl.m_dlg_found_some.append_text(
#13 +
'NO batch files for compiling the ' + g_appl + ' demos'#13 +
'were created in the directory, from which this helper'#13 +
'utility was run, because no *.dpr projects were found.' );
// Refresh
appl.force_redraw;
end;
{ action_set_drives }
function action_set_drives(appl : the_application_ptr; sender : dialog_ptr ) : boolean;
var
letter ,
path ,
drive : shortstring;
drive_type ,i ,count : unsigned;
begin
// Scan for drives in the system
letter:='C';
count :=0;
for i:=1 to 24 do
begin
path :=letter + ':\'#0;
drive:='';
drive_type:=GetDriveType(@path[1 ] );
case drive_type of
DRIVE_FIXED : drive:='fixed harddrive';
DRIVE_REMOVABLE : drive:='removable drive';
DRIVE_REMOTE : drive:='network or remote drive';
DRIVE_CDROM : drive:='CD-ROM drive';
DRIVE_RAMDISK : drive:='RAM disk';
end;
if drive <> '' then
begin
drive:=' ' + StrPas(@path[1 ] ) + ' (' + drive + ')' + #0;
appl.m_dlg_set_drives.add_choice(@drive[1 ] ,@path[1 ] ,30 ,360 - count * 30 ,count = 0 );
inc(count );
end;
inc(byte(letter[1 ] ) );
end;
appl.m_cur_dlg:=@appl.m_dlg_set_drives;
// OK Done
result:=true;
end;
{ action_while_search }
function action_while_search(appl : the_application_ptr; sender : dialog_ptr ) : boolean;
var
text : shortstring;
rgba : aggclr;
begin
while g_lock do;
g_lock:=true;
if appl.m_ShLast <> appl.m_DoShow then
begin
str(g_found ,text );
text:=
' ' + appl.m_DoShow + #13#13 +
'Compilers found: ' + text + #0;
//rgba.ConstrDbl(0 ,0 ,0.5 );
appl.m_dlg_searching.change_text(@text[1 ] ,10 ,320 );
appl.force_redraw;
appl.m_ShLast:=appl.m_DoShow;
end;
g_lock:=false;
end;
{ process_file }
function process_file(file_name : shortstring ) : boolean;
begin
if g_found < g_max then
begin
g_search_results[g_found ]:=file_name;
inc(g_found );
end;
end;
{ scan_files }
function scan_files(files : shortstring; appl : the_application_ptr ) : boolean;
var
SR : TSearchRec;
err : integer;
find ,file_path ,file_name ,file_ext : shortstring;
begin
result:=false;
{ Scan dirs and go further }
spread_name(files ,file_path ,file_name ,file_ext );
while g_lock do;
g_lock:=true;
appl.m_DoShow:=file_path;
g_lock:=false;
err:=SysUtils.FindFirst(str_dir(file_path ) + '*' ,faDirectory ,SR );
while err = 0 do
begin
if appl.m_DoQuit then
begin
SysUtils.FindClose(SR );
exit;
end;
if (SR.Name <> '.' ) and
(SR.Name <> '..' ) and
(SR.Attr and faDirectory = faDirectory ) then
begin
spread_name(files ,file_path ,file_name ,file_ext );
if not scan_files(fold_name(str_dir(file_path ) + SR.Name + '\' ,file_name ,file_ext ) ,appl ) then
exit;
end;
err:=SysUtils.FindNext(SR );
end;
SysUtils.FindClose(SR );
{ Scan files for Delphi compiler }
find:=fold_name(file_path ,'dcc32' ,'*.exe' );
err:=SysUtils.FindFirst(find ,faArchive ,SR );
while err = 0 do
begin
if appl.m_DoQuit then
begin
SysUtils.FindClose(SR );
exit;
end;
process_file(fold_name(files ,SR.Name ,SR.Name ) );
err:=SysUtils.FindNext(SR );
end;
SysUtils.FindClose(SR );
{ Scan files for FPC compiler }
find:=fold_name(file_path ,'ppc386' ,'*.exe' );
err:=SysUtils.FindFirst(find ,faArchive ,SR );
while err = 0 do
begin
if appl.m_DoQuit then
begin
SysUtils.FindClose(SR );
exit;
end;
process_file(fold_name(files ,SR.Name ,SR.Name ) );
err:=SysUtils.FindNext(SR );
end;
SysUtils.FindClose(SR );
{ OK }
scan_files:=true;
end;
{ FnSearch }
procedure FnSearch(appl : the_application_ptr );
var
i : unsigned;
begin
appl.m_ShLast:='';
appl.m_DoShow:='';
g_found:=0;
// OK, Go through selected drives and issue search
appl.m_dlg_searching.set_waiting(@action_while_search );
if appl.m_dlg_set_drives.m_num_choices > 0 then
for i:=0 to appl.m_dlg_set_drives.m_num_choices - 1 do
if appl.m_dlg_set_drives.m_choices[i ].ctrl._status then
if not scan_files(appl.m_dlg_set_drives.m_choices[i ].attr ,appl ) then
break;
appl.m_dlg_searching.set_waiting(NIL );
// Were we forced to quit ?
if appl.m_DoQuit then
NoP;
// Depending on the search result activate the next user dialog
if g_found > 0 then
begin
action_configure(appl ,NIL );
appl.m_cur_dlg:=@appl.m_dlg_found_some;
end
else
appl.m_cur_dlg:=@appl.m_dlg_not_found;
end;
{ ThSearch }
function ThSearch(Parameter : pointer ): integer;
begin
{ Synchronize }
while the_application_ptr(Parameter ).m_Thread = 0 do;
{ Call Thread }
FnSearch(Parameter );
{ Exit }
the_application_ptr(Parameter ).m_Thread:=0;
the_application_ptr(Parameter ).m_ApplID:=0;
{ Done }
EndThread(0 );
end;
{ action_begin_search }
function action_begin_search(appl : the_application_ptr; sender : dialog_ptr ) : boolean;
var
i : unsigned;
begin
result:=false;
// Check, if we have drives to search
if appl.m_dlg_set_drives.m_num_choices > 0 then
for i:=0 to appl.m_dlg_set_drives.m_num_choices - 1 do
if appl.m_dlg_set_drives.m_choices[i ].ctrl._status then
begin
result:=true;
break;
end;
if not result then
begin
appl.m_dlg_set_drives.m_actions[0 ].ctrl.cur_item_(-1 );
appl.m_dlg_set_drives.set_next_status(ds_waiting_input );
appl.force_redraw;
exit;
end;
// Go on to search dialog
appl.m_cur_dlg:=@appl.m_dlg_searching;
// Start Up the search thread
appl.m_Thread:=BeginThread(NIL ,65536 ,ThSearch ,appl ,0 ,appl.m_ApplID );
end;
{ action_stop_search }
function action_stop_search(appl : the_application_ptr; sender : dialog_ptr ) : boolean;
begin
appl.m_DoQuit:=true;
end;
{ action_exit }
function action_exit(appl : the_application_ptr; sender : dialog_ptr ) : boolean;
begin
appl.quit;
end;
{ CONSTRUCT }
constructor the_application.Construct;
var
rgba : aggclr;
begin
inherited Construct(format_ ,flip_y_ );
m_sl.Construct;
m_ras.Construct;
m_cur_dlg:=NIL;
m_Thread:=0;
m_ApplID:=0;
m_DoQuit:=false;
m_ShLast:='';
m_DoShow:='';
// Welcome dialog
m_dlg_welcome.Construct(
@self ,
'Welcome to the ' + g_full + '.'#13 +
''#13 +
'This helper utility will scan your system to search'#13 +
'for all available Object Pascal compilers.'#13 +
''#13 +
'It will also create appropriate batch files with current'#13 +
'paths and options needed to compile properly all'#13 +
'the ' + g_appl + ' demos.'#13+
''#13 +
'Currently Delphi and Free Pascal compilers are supported.' );
m_dlg_welcome.add_action('Continue' ,@action_set_drives ,480 ,15 ,580 ,45 );
// Set drives to search on dialog
m_dlg_set_drives.Construct(
@self ,
'Please select, on which drives of your system should'#13 +
'this helper utility perform search for Object Pascal compilers:' );
m_dlg_set_drives.add_action('Continue' ,@action_begin_search ,480 ,15 ,580 ,45 );
// Wait, searching dialog
m_dlg_searching.Construct(
@self ,
'Please wait ...'#13 +
''#13 +
'Helper utility is searching for Object Pascal compilers'#13 +
'on the drives, you have selected.' );
m_dlg_searching.add_action('Stop searching' ,@action_stop_search ,440 ,15 ,580 ,45 );
// Found nothing dialog
rgba.ConstrInt(255 ,0 ,0 );
m_dlg_not_found.Construct(
@self ,
'I am sorry, but NO Object Pascal compilers were found'#13 +
'on your system.'#13 +
''#13 +
'Please install Delphi or FreePascal'#13+
'and then rerun this utility.'#13#13+
'http://www.borland.com'#13#13 +
'- or - '#13#13 +
'http://www.freepascal.org' ,
@rgba );
m_dlg_not_found.add_action('Exit' ,@action_exit ,500 ,15 ,580 ,45 );
// Compilers found dialog
rgba.ConstrDbl(0 ,0.5 ,0 );
m_dlg_found_some.Construct(
@self ,
'Following Object Pascal compilers were found your system:' ,
@rgba );
m_dlg_found_some.add_action('Exit' ,@action_exit ,500 ,15 ,580 ,45 );
end;
{ DESTRUCT }
destructor the_application.Destruct;
begin
while m_Thread <> 0 do
m_DoQuit:=true;
inherited Destruct;
m_sl.Destruct;
m_ras.Destruct;
m_dlg_welcome.Destruct;
m_dlg_set_drives.Destruct;
m_dlg_searching.Destruct;
m_dlg_not_found.Destruct;
m_dlg_found_some.Destruct;
end;
{ DRAW_TEXT }
procedure the_application.draw_text;
var
pixf : pixel_formats;
rgba : aggclr;
rb : renderer_base;
rs : renderer_scanline_aa_solid;
t : gsv_text;
pt : conv_stroke;
begin
pixfmt_bgr24(pixf ,rbuf_window );
rb.Construct(@pixf );
rs.Construct(@rb );
t.Construct;
t.size_ (9.5 );
t.line_space_(10 );
pt.Construct(@t );
pt.width_ (1.2 );
t.start_point_(x ,y );
t.text_ (msg );
if clr <> NIL then
rs.color_(clr )
else
begin
rgba.ConstrDbl(0 ,0 ,0 );
rs.color_ (@rgba );
end;
m_ras.add_path (@pt );
render_scanlines(@m_ras ,@m_sl ,@rs );
t.Destruct;
pt.Destruct;
end;
{ ON_INIT }
procedure the_application.on_init;
var
SR : TSearchRec;
err : integer;
find ,file_path ,file_name ,file_ext : shortstring;
cf : file;
bf : pointer;
sz : integer;
target ,get : shortstring;
begin
wait_mode_(false );
// Load the list of current projects
g_num_demos:=0;
spread_name(ParamStr(0 ) ,file_path ,file_name ,file_ext );
find:=fold_name(file_path ,'*' ,'*.dpr' );
err :=SysUtils.FindFirst(find ,faArchive ,SR );
while err = 0 do
begin
// Load keys from the source file
key_count:=0;
get:=fold_name(file_path ,SR.Name ,SR.Name );
AssignFile(cf ,SR.Name );
reset (cf ,1 );
if IOResult = 0 then
begin
sz:=System.FileSize(cf );
if agg_getmem(bf ,sz ) then
begin
blockread (cf ,bf^ ,sz );
LoadKeys (bf ,sz );
agg_freemem(bf ,sz );
end;
close(cf );
end;
target:='win';
FirstKey('target' ,target );
// Add To List
if (cmp_str(target ) <> cmp_str('win' ) ) or
FirstKey('skip' ,get ) then
else
if g_num_demos < g_max_demos then
begin
g_demos[g_num_demos ]:=fold_name('' ,SR.Name ,SR.Name );
inc(g_num_demos );
end;
err:=SysUtils.FindNext(SR );
end;
SysUtils.FindClose(SR );
end;
{ ON_DRAW }
procedure the_application.on_draw;
var
pixf : pixel_formats;
rgba : aggclr;
rb : renderer_base;
rs : renderer_scanline_aa_solid;
i ,plus : unsigned;
begin
// Initialize structures
pixfmt_bgr24(pixf ,rbuf_window );
rb.Construct(@pixf );
rs.Construct(@rb );
rgba.ConstrDbl(1 ,1 ,1 );
rb.clear (@rgba );
// Render Dialog
if m_cur_dlg <> NIL then
case m_cur_dlg.m_status of
ds_waiting_input ,ds_running :
begin
// Render logo if has one
plus:=0;
if (m_cur_dlg = @m_dlg_welcome ) and
g_image then
begin
rb.copy_from(rbuf_img(1 ) ,NIL ,6 ,330 );
plus:=rbuf_img(1 )._height + 20;
end;
// Render base text
draw_text(10 ,420 - plus ,m_cur_dlg.m_info ,@m_cur_dlg.m_clri );
// Render dynamic text
if m_cur_dlg.m_text <> NIL then
draw_text(
m_cur_dlg.m_tx_x ,
m_cur_dlg.m_tx_y ,
PChar(m_cur_dlg.m_text ) ,
@m_cur_dlg.m_clrt );
// Render choices
if m_cur_dlg.m_num_choices > 0 then
for i:=0 to m_cur_dlg.m_num_choices - 1 do
render_ctrl(@m_ras ,@m_sl ,@rs ,@m_cur_dlg.m_choices[i ] );
// Render actions
if m_cur_dlg.m_num_actions > 0 then
for i:=0 to m_cur_dlg.m_num_actions - 1 do
render_ctrl(@m_ras ,@m_sl ,@rs ,@m_cur_dlg.m_actions[i ].ctrl );
end;
end;
end;
{ ON_CTRL_CHANGE }
procedure the_application.on_ctrl_change;
begin
if m_cur_dlg <> NIL then
case m_cur_dlg.m_status of
ds_waiting_input :
if m_cur_dlg.find_cur_action then
m_cur_dlg.set_next_status;
end;
end;
{ ON_IDLE }
procedure the_application.on_idle;
begin
if m_cur_dlg = NIL then
begin
m_cur_dlg:=@m_dlg_welcome;
if m_cur_dlg.m_status <> ds_ready then
m_cur_dlg:=NIL;
end
else
case m_cur_dlg.m_status of
ds_ready :
if m_cur_dlg.add_controls then
force_redraw;
ds_waiting_input :
m_cur_dlg.call_waiting;
ds_running :
if m_cur_dlg.call_cur_action then
NoP;
end;
end;
{ ON_KEY }
procedure the_application.on_key;
begin
if key = key_f1 then
message_(
'This is just an AggPas library helper utility which has nothing to do'#13 +
'with demonstrating any of graphical possibilities of AGG.'#13#13 +
'Author of this pascal port (Milano) recomends to proceed with this utility'#13 +
'on your system right after unpacking the archive, because it will'#13 +
'scan your computer for all available Object Pascal compilers and'#13 +
'it will create the up-to-date working batch files for fompiling the library demos.'#13#13 +
'In the welcome screen of this utility, there is a logo for the AGG library,'#13 +
'which was designed and proposed by Milano. It has the meaning of spiral primitive'#13 +
'upon the interactive polygon control, which should mean in "translation" that'#13 +
'"With AGG the possibilities are endless (the spiral) and custom adjustments'#13 +
'are easy possible. (interactive polygon)".' +
#13#13'Note: F2 key saves current "screenshot" file in this demo''s directory. ' );
end;
VAR
app : the_application;
BEGIN
g_lock :=false;
g_image:=false;
app.Construct(pix_format_bgr24 ,flip_y );
app.caption_ (g_appl + ' Startup utility (F1-Help)' );
if app.load_img(1 ,'aggpas_logo' ) then
g_image:=true;
if app.init(600 ,450 ,0 ) then
app.run;
app.Destruct;
END.