forked from dmcoles/ReBuild
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Rebuild_manual.txt
871 lines (726 loc) · 31.8 KB
/
Rebuild_manual.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
---------------------------------------------------------------------------
Rebuild - Reaction GUI Builder
Version 1.2.0
---------------------------------------------------------------------------
1. Introduction
Rebuild is a GUI builder for the reaction user inteface system. Reaction is
part of the Amiga OS for all versions from 3.2 and above. Reaction started
out as a product called ClassAct which was later enhanced and turned into
Reaction.
ClassAct had a GUI builder program called ClassMate (developed in 1997)
which was shareware and only freely available in demo form which had
severly limited functionality. I used ClassMate as a design template when
I made Rebuild. It has a similar look but the code is entirely new.
It includes support for many more gadget types than ClassMate did and has
been improved in many ways to allow for easier use.
Just a few of the improvements are:
1) Support for both E and C languages
2) Menu design is shown in the preview window
3) Support for multiple windows in a single project
4) Copy buffer making it easier to move or duplicate gadgets
5) More flexible system of arranging gadgets and layouts
6) Multi-level undo/redo
7) Realtime code preview
2. License
The program is released into the public domain for anyone to use however
they wish with no restrictions apart from that the program should not be
sold for profit.
You may use this program to assist with the development any application
without restriction however use of this project is entirely at your own
risk. I will not accept responsibilty for any issues arising from the
use of Rebuild.
3. Using Rebuild
Upon loading Rebuild you will be presented with the main working window of
the GUI designer. GUI designs in Rebuild are built using a hierarchical
structure represented as a tree layout in the main window. You will also
see a preview window where you will see an accurate representation of your
current GUI design.
Initially you will be presented with a default design that has a single
window and a root layout gadget. You can add/remove windows from your
design using buttons in the toolbar at the bottom or by using the menus.
The toolbar buttons are context sensitive, so if you select the window
node in the tree view and press the 'Add' button it will add a new window.
If you have selected a layout or any other gadget, selecting 'Add' will
allow you to add more gadgets to your design.
The default window layout starts with a vertical layout gadget. Any
gadgets added to this will be displayed stacked vertically. You can change
this in the gadget properties (double click on the layout in the tree
structure).
You can create complicated layout designs by breaking them down into
smaller parts and using layouts within layouts to denote the arrangement
of horizontal or vertical within that layout area.
If you wanted to create a screen similar to this:
.--------------------. .-------.
| | | Ok |
| ListView | '-------'
| | .-------.
| | | Canel |
`--------------------' `-------'
.-----. .------. .----. .-------.
| Add | | Edit | | Up | | Down |
`------ `------ `----' `-------'
You could create it using an arrangement like this:
Layout - Vert
Layout - Horiz
ListBrowser Object
Layout - Vert
Button Object
Button Object
Layout - Horiz
Buton Object
Buton Object
Buton Object
Buton Object
There are some example files included in the examples folder.
In addition to the layout control there are two other gadget types that
can have child controls added to them. The ClickTab gadget and the Virtual
gadget.
The ClickTab gadget displays tabs according to its list (see list manager
section below). In addition it can also support different pages of controls
for each tab. Child gadgets are added to a ClickTab control in exactly the
same way as they are added to a layout control. Each child control will
be displayed in a different tab. Typically you would add a layout control
to the ClickTab for each tab. Then you can build up a UI design for that tab
by adding further child controls to each layout.
The Virtual gadget displays a group of gadgets within a scrollable area.
You can display a larger number of gadgets than would normally be visible
in the window by allowing the user to scroll around the virtual area. The
virtual gadget allows only one child control to be added directly. That
would typically be a layout control in order that further gadgets can
be displayed within the virtual scroll area.
You can also control the screen settings that are using for your GUI design
and add menu definitions for each window. You can also specify a set of
Arexx commands. The screen settings and Arexx commands will not affect how
the design works in Rebuild but they will be included in the source code
that you generate.
Note:
The TextField gadget is not a Reaction gadget and is not included by defaullt
in OS 3.2. You should avoid using this gadget. It was included in the
original ClassAct library but was not carried forwards into the Reaction
implementation. The stand alone textfield gadget can be downloaded from
the Aminet here:
http://aminet.net/package/dev/gui/textfield
If you use this gadget in your GUI design and it is not installed on your
system you will only see a placeholder graphic in the preview window.
If you generate code and attempt to run that code on a system where the
TextField gadget is not installed it will fail on startup.
4. The list manager
Some of the gadget types (List Browser, Chooser, RadioButton and ClickTab)
require a list of items to function. You can set up any number of lists
in the list manager and add items to those lists. Once this is done you can
add them to a gadget. You can add the same list to more than one gadget.
If you need to go back later and modify the list, it can easily be edited
in the list manager even after it has been added to a gadget.
5. The copy buffer
On the right side of the main window you will see the copy buffer.
Using the buttons below you can copy or move items from the main design
window into the copy buffer. This is highly useful if you want to
duplicate a gadget several times with the same settings or move a gadget
from one window to another in your design.
6. The code window
Rebuild is able to generate fully working SAS C and Amiga E code for the
GUI designs you create. The code preview window will show the source code
for the current design. The source code is updated in real-time as you
make changes. If you wish to save the source code there is an option on
the file menu. You can also close the source code window if you do not
wish to see it. Even if the source window is closed you will still be
able to save the source code.
The source code will be based upon the code generation options as
explained in the next section.
In order to compile the source code you will need the Amiga OS 3.2 NDK.
The E-VO E compiler has this as standard so I recommend if you plan to use
the E source code then I recommend you use this.
If you are using C then the NDK can be obtained from the aminet
http://aminet.net/package/dev/misc/NDK3.2
Compiling the E or C source should not require any additional libraries or
includes than the ones present in the NDK and as part of the OS.
You may also be able to use the resulting code with older versions of the OS
if you have ClassAct installed - although it should be noted that despite
the ClassAct documentation stating that it works with OS2.0 and above, it is
my experience that it does not actually work with anything below OS 3.0
7. Source code generation options
When you click the 'Code' button you will be presented with 4 options:
1. E or C source
2. Use ids for GA_ID / Use array index for GA_ID
3. Generate full code / Generate definitions only
4. Use NDK Macros in definitions
The first option is pretty self explantory. You can pick between E or C
language and the GUI design will be exported to a code file in that language.
The last option will determine whether the resulting code will be a complete
working example that can be compiled. If you compile and run the code you
will be presented with a window very similar to the preview window shown in
Rebuild. The code generated can then be expanded to include any logic you
need to form your application.
If you choose 'Generate definitions only' then the resulting code will not
be complete and is intended for you to copy and paste the GUI definitions
into an application source file.
The second option controls how the GUI code is constructed and will impact
on the value used for the GA_ID property for each gadget. When you are
coding the message processing loop for your application the GA_ID values
will be important for you to identify the gadget that is sending the
message.
IF you choose to 'Use ids for GA_ID' then each gadget will have a GA_ID
value based upon its unique ID allocated by Rebuild. every item in the GUI
design gets a unique ID and these will never change (unless you delete the
gadget). Even after you delete a gadget the old ID will never be re-used.
This means you are free to reference these ID's in your custom code and
you don't have to worry that changing the GUI design and re-generating the
code will mean you have to re-write your code.
If you choose to use the option 'Use array index for GA_ID' then the GA_ID
for each gadget will be numbered sequentially from 0 for each window.
This means that it is simpler to handle the coding to manage the GUI because
you can always use the ID as an index into the gadgets array generated in
the code but it does also mean that if you rearrange the GUI design in any
way then the GA_ID values will change and if you have hard code any of these
values into your custom code then it will need to be re-coded.
There is more information regarding this in the next section.
Finally the option to use NDK macros or not alters the code generator and
if the option is enabled then you will see something like this in the code
LAYOUT_AddChild, main_gadgets[button_10] = ButtonObject,
...
...
ButtonEnd,
ButtonObject and ButtonEnd are macros defined in the NDK. Many of the
gadgets have such macros defined but they do not work well with the GCC
compiler. So we have given the option to generate code that does not use
them.
When the macros are disabled you will instead see code that looks like this:
LAYOUT_AddChild, main_gadgets[button_10] = NewObject(BUTTON_GetClass(),NULL,
...
...
TAG_END),
This option has been added partly to allow for user preference in generated
code but also because GCC does not handle these macro's correctly unless
additional compile options are specified. So this gives the user the option
to generate code that does not use these macros. The alternative for GCC is
to use the -DNO_INLINE_STDARG parameter when compiling.
8. Tips on working with the rebuild generated source code.
Here is an example of some C code generated by rebuild. I have annotated it
with some comments to explain the intended use of some of the parts of the
code. The generated code is only intended as a possible starting point for
the application. In order to make the application functional there will be
a lot of additional coded needed to drive the GUI.
Rebuild is not designed to be a fully functional development environment,
it is purely a GUI design tool. If you use this code structure as a basis
for your application, it would be recommended that you try to separate
your custom code from the auto-generated code as much as possible in
order to reduce the amount of rework needed if you change the GUI design
and have to regenerate the code.
#include <clib/macros.h>
#include <clib/alib_protos.h>
#include <clib/compiler-specific.h>
#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/utility.h>
#include <proto/graphics.h>
#include <proto/intuition.h>
#include <proto/gadtools.h>
#include <proto/icon.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <proto/window.h>
#include <proto/layout.h>
#include <proto/button.h>
#include <proto/string.h>
#include <proto/label.h>
#include <libraries/gadtools.h>
#include <reaction/reaction.h>
#include <intuition/gadgetclass.h>
#include <reaction/reaction_macros.h>
#include <classes/window.h>
#include <exec/memory.h>
void window_3( void );
struct Screen *gScreen = NULL;
struct DrawInfo *gDrawInfo = NULL;
APTR gVisinfo = NULL;
struct MsgPort *gAppPort = NULL;
struct Library *WindowBase = NULL,
*ButtonBase = NULL,
*StringBase = NULL,
*LabelBase = NULL,
*GadToolsBase = NULL,
*LayoutBase = NULL,
*IconBase = NULL;
struct IntuitionBase *IntuitionBase = NULL;
//window ids
//this enumeration will contain all of the window ids contained in the
//rebuild project.
enum win { window_3_id = 3 };
//Window_3 gadgets
//this enumeration should be used to access the main_gadgets array. the names
//of the enumerations have the reaction gadget id's on the end so these names
//will never change even if the design is update (eg another gadget added).
//If the code is regenerated then the positions will change but the names
//will not. This means its safe to use these enumeration names in any custom
//code you may write.
enum window_3_idx { layout_5, string_6, string_7, layout_8, button_9, button_10 };
//this enumeration should be used when you need to check the GA_ID values
//against a particular gadget (eg when writing your message handling code
//the enumeration names will be in the same order as those in the enum
//above and the names will be the same as those above with _id appended.
enum window_3_id { layout_5_id = 5, string_6_id = 6, string_7_id = 7, layout_8_id = 8,
button_9_id = 9, button_10_id = 10 };
int setup( void )
{
if( !(IntuitionBase = (struct IntuitionBase*) OpenLibrary("intuition.library",0L)) ) return 0;
if( !(GadToolsBase = (struct Library*) OpenLibrary("gadtools.library",0L) ) ) return 0;
if( !(WindowBase = (struct Library*) OpenLibrary("window.class",0L) ) ) return 0;
if( !(IconBase = (struct Library*) OpenLibrary("icon.library",0L) ) ) return 0;
if( !(LayoutBase = (struct Library*) OpenLibrary("gadgets/layout.gadget",0L) ) ) return 0;
if( !(ButtonBase = (struct Library*) OpenLibrary("gadgets/button.gadget",0L) ) ) return 0;
if( !(StringBase = (struct Library*) OpenLibrary("gadgets/string.gadget",0L) ) ) return 0;
if( !(LabelBase = (struct Library*) OpenLibrary("images/label.image",0L) ) ) return 0;
if( !(gScreen = LockPubScreen( 0 ) ) ) return 0;
if( !(gVisinfo = GetVisualInfo( gScreen, TAG_DONE ) ) ) return 0;
if( !(gDrawInfo = GetScreenDrawInfo ( gScreen ) ) ) return 0;
if( !(gAppPort = CreateMsgPort() ) ) return 0;
return -1;
}
void cleanup( void )
{
if ( gDrawInfo ) FreeScreenDrawInfo( gScreen, gDrawInfo);
if ( gVisinfo ) FreeVisualInfo( gVisinfo );
if ( gAppPort ) DeleteMsgPort( gAppPort );
if ( gScreen ) UnlockPubScreen( 0, gScreen );
if (GadToolsBase) CloseLibrary( (struct Library *)GadToolsBase );
if (IconBase) CloseLibrary( (struct Library *)IconBase );
if (IntuitionBase) CloseLibrary( (struct Library *)IntuitionBase );
if (ButtonBase) CloseLibrary( (struct Library *)ButtonBase );
if (StringBase) CloseLibrary( (struct Library *)StringBase );
if (LabelBase) CloseLibrary( (struct Library *)LabelBase );
if (LayoutBase) CloseLibrary( (struct Library *)LayoutBase );
if (WindowBase) CloseLibrary( (struct Library *)WindowBase );
}
//this is a generic routine that will be used to run the message loop
//for all windows in this project. You should use the window id to determine
//which window is being displayed. In order to avoid a huge message
//processing loop with many different windows and gadgets being handled
//I would recommend creating a function for each window and calling that
//according to the window id.
//
//Currently this code structure is designed for projects with modal windows.
//If you wanted to display a settings page for example you would call the
//window function in the gadget press handling code you have written.
//This would create the window object and call runWindow. Once that
//window is closed control would return to the calling window.
//
//If this structure does not suit your application then you can code the
//message handling from scratch and just use the window definitions that
//can be generated using Rebuild.
//
void runWindow( Object *window_object, int window_id, struct Menu *menu_strip, struct Gadget *win_gadgets[] )
{
struct Window *main_window = NULL;
if ( window_object )
{
if ( main_window = (struct Window *) RA_OpenWindow( window_object ))
{
WORD Code;
ULONG wait = 0, signal = 0, result = 0, done = FALSE;
GetAttr( WINDOW_SigMask, window_object, &signal );
if ( menu_strip) SetMenuStrip( main_window, menu_strip );
while ( !done)
{
wait = Wait( signal | SIGBREAKF_CTRL_C );
if ( wait & SIGBREAKF_CTRL_C )
done = TRUE;
else
while (( result = RA_HandleInput( window_object, &Code )) != WMHI_LASTMSG)
{
switch ( result & WMHI_CLASSMASK )
{
case WMHI_CLOSEWINDOW:
done = TRUE;
break;
case WMHI_MENUPICK:
//put your menu handling code here
//it is advised that you call a separate function for this
puts("menu pick");
break;
case WMHI_GADGETUP:
//put your gadget handling code here
//it is advised that you call a separate function for this
puts("gadget press");
break;
case WMHI_ICONIFY:
if ( RA_Iconify( window_object ) )
main_window = NULL;
break;
case WMHI_UNICONIFY:
main_window = RA_OpenWindow( window_object );
if ( menu_strip) SetMenuStrip( main_window, menu_strip );
break;
}
}
}
}
}
}
//this is the window function, it creates the window and displays it
//it will return once the window is closed
//
void window_3( void )
{
struct Gadget *main_gadgets[ 7 ];
Object *window_object = NULL;
window_object = WindowObject,
WA_Title, "Please log in...",
WA_Left, 5,
WA_Top, 20,
WA_Width, 250,
WA_Height, 80,
WA_MinWidth, 150,
WA_MinHeight, 80,
WA_MaxWidth, 8192,
WA_MaxHeight, 8192,
WINDOW_AppPort, gAppPort,
WA_CloseGadget, TRUE,
WA_DepthGadget, TRUE,
WA_SizeGadget, TRUE,
WA_DragBar, TRUE,
WINDOW_Position, WPOS_CENTERSCREEN,
WINDOW_IconTitle, "MyApp",
WA_NoCareRefresh, TRUE,
WA_IDCMP, IDCMP_GADGETDOWN | IDCMP_GADGETUP | IDCMP_CLOSEWINDOW,
WINDOW_ParentGroup, VLayoutObject,
LAYOUT_SpaceOuter, TRUE,
LAYOUT_DeferLayout, TRUE,
LAYOUT_AddChild, main_gadgets[layout_5] = LayoutObject,
GA_ID, layout_5_id,
LAYOUT_Orientation, LAYOUT_ORIENT_VERT,
LAYOUT_AddChild, main_gadgets[string_6] = StringObject,
GA_ID, string_6_id,
GA_RelVerify, TRUE,
GA_TabCycle, TRUE,
STRINGA_MaxChars, 80,
StringEnd,
CHILD_Label, LabelObject,
LABEL_Text, "User name",
LabelEnd,
LAYOUT_AddChild, main_gadgets[string_7] = StringObject,
GA_ID, string_7_id,
GA_RelVerify, TRUE,
GA_TabCycle, TRUE,
STRINGA_MaxChars, 80,
StringEnd,
CHILD_Label, LabelObject,
LABEL_Text, "Password",
LabelEnd,
LAYOUT_AddChild, main_gadgets[layout_8] = LayoutObject,
GA_ID, layout_8_id,
LAYOUT_Orientation, LAYOUT_ORIENT_HORIZ,
LAYOUT_AddChild, main_gadgets[button_9] = ButtonObject,
GA_ID, button_9_id,
GA_Text, "OK",
GA_RelVerify, TRUE,
GA_TabCycle, TRUE,
BUTTON_TextPen, 1,
BUTTON_BackgroundPen, 0,
BUTTON_FillTextPen, 1,
BUTTON_FillPen, 3,
ButtonEnd,
LAYOUT_AddChild, main_gadgets[button_10] = ButtonObject,
GA_ID, button_10_id,
GA_Text, "Cancel",
GA_RelVerify, TRUE,
GA_TabCycle, TRUE,
BUTTON_TextPen, 1,
BUTTON_BackgroundPen, 0,
BUTTON_FillTextPen, 1,
BUTTON_FillPen, 3,
ButtonEnd,
LayoutEnd,
LayoutEnd,
LayoutEnd,
WindowEnd;
//a blank entry at the end in case you need to loop through the
//array and know where the end of the data is
main_gadgets[6] = 0;
//call the code to display the window
//the window id is window_3_id from the window ids enumeration and
//it has no menu structure.
runWindow( window_object, window_3_id, 0, main_gadgets );
if ( window_object ) DisposeObject( window_object );
}
int main( int argc, char **argv )
{
if ( setup() )
{
window_3();
}
cleanup();
}
Here is the same example GUI design in E
OPT OSVERSION=37
MODULE 'reaction/reaction_macros',
'reaction/reaction_lib',
'window','classes/window',
'gadgets/layout','layout',
'libraries/gadtools','gadtools',
'icon',
'button','gadgets/button',
'string','gadgets/string',
'label','images/label',
'images/bevel',
'amigalib/boopsi',
'exec',
'intuition/intuition',
'intuition/imageclass',
'intuition/screens',
'intuition/gadgetclass'
->window ids
ENUM WINLOGON_ID = 3
->winLogon gadgets
ENUM LAYOUT_5, STRING_6, STRING_7, LAYOUT_8, BUTTON_9, BUTTON_10
ENUM LAYOUT_5_ID = 5, STRING_6_ID = 6, STRING_7_ID = 7, LAYOUT_8_ID = 8,
BUTTON_9_ID = 9, BUTTON_10_ID = 10
DEF gScreen=0,gVisInfo=0,gDrawInfo=0,gAppPort=0
PROC setup()
IF (windowbase:=OpenLibrary('window.class',0))=NIL THEN Throw("LIB","win")
IF (layoutbase:=OpenLibrary('gadgets/layout.gadget',0))=NIL THEN Throw("LIB","layo")
IF (gadtoolsbase:=OpenLibrary('gadtools.library',0))=NIL THEN Throw("LIB","gadt")
IF (iconbase:=OpenLibrary('icon.library',0))=NIL THEN Throw("LIB","icon")
IF (buttonbase:=OpenLibrary('gadgets/button.gadget',0))=NIL THEN Throw("LIB","btn")
IF (stringbase:=OpenLibrary('gadgets/string.gadget',0))=NIL THEN Throw("LIB","strn")
IF (labelbase:=OpenLibrary('images/label.image',0))=NIL THEN Throw("LIB","labl")
IF (gScreen:=LockPubScreen(NIL))=NIL THEN Raise("pub")
IF (gVisInfo:=GetVisualInfoA(gScreen, [TAG_END]))=NIL THEN Raise("visi")
IF (gDrawInfo:=GetScreenDrawInfo(gScreen))=NIL THEN Raise("dinf")
IF (gAppPort:=CreateMsgPort())=NIL THEN Raise("port")
ENDPROC
PROC cleanup()
IF gVisInfo THEN FreeVisualInfo(gVisInfo)
IF gDrawInfo THEN FreeScreenDrawInfo(gScreen,gDrawInfo)
IF gAppPort THEN DeleteMsgPort(gAppPort)
IF gScreen THEN UnlockPubScreen(NIL,gScreen)
IF gadtoolsbase THEN CloseLibrary(gadtoolsbase)
IF iconbase THEN CloseLibrary(iconbase)
IF windowbase THEN CloseLibrary(windowbase)
IF layoutbase THEN CloseLibrary(layoutbase)
IF buttonbase THEN CloseLibrary(buttonbase)
IF stringbase THEN CloseLibrary(stringbase)
IF labelbase THEN CloseLibrary(labelbase)
ENDPROC
PROC runWindow(windowObject,windowId, menuStrip, winGadgets:PTR TO LONG) HANDLE
DEF running=TRUE
DEF win:PTR TO window,wsig,code,msg,sig,result
IF (win:=RA_OpenWindow(windowObject))
GetAttr( WINDOW_SIGMASK, windowObject, {wsig} )
IF menuStrip THEN SetMenuStrip( win, menuStrip )
WHILE running
sig:=Wait(wsig)
IF (sig AND (wsig))
WHILE ((result:=RA_HandleInput(windowObject,{code}+2)) <> WMHI_LASTMSG)
msg:=(result AND WMHI_CLASSMASK)
SELECT msg
CASE WMHI_CLOSEWINDOW
running:=FALSE
CASE WMHI_GADGETUP
WriteF('gadget press\n')
CASE WMHI_MENUPICK
WriteF('menu pick\n')
CASE WMHI_ICONIFY
RA_Iconify(windowObject)
CASE WMHI_UNICONIFY
win:=RA_OpenWindow(windowObject)
IF menuStrip THEN SetMenuStrip( win, menuStrip )
ENDSELECT
ENDWHILE
ENDIF
ENDWHILE
ENDIF
EXCEPT DO
RA_CloseWindow(windowObject)
ENDPROC
PROC winlogon() HANDLE
DEF windowObject
DEF mainGadgets[7]:ARRAY OF LONG
windowObject:=WindowObject,
WA_TITLE, 'Please log in...',
WA_LEFT, 5,
WA_TOP, 20,
WA_WIDTH, 250,
WA_HEIGHT, 80,
WA_MINWIDTH, 150,
WA_MINHEIGHT, 80,
WA_MAXWIDTH, 8192,
WA_MAXHEIGHT, 8192,
WINDOW_APPPORT, gAppPort,
WA_CLOSEGADGET, TRUE,
WA_DEPTHGADGET, TRUE,
WA_SIZEGADGET, TRUE,
WA_DRAGBAR, TRUE,
WINDOW_POSITION, WPOS_CENTERSCREEN,
WINDOW_ICONTITLE, 'MyApp',
WA_NOCAREREFRESH, TRUE,
WA_IDCMP, IDCMP_GADGETDOWN OR IDCMP_GADGETUP OR IDCMP_CLOSEWINDOW,
WINDOW_PARENTGROUP, VLayoutObject,
LAYOUT_SPACEOUTER, TRUE,
LAYOUT_DEFERLAYOUT, TRUE,
LAYOUT_ADDCHILD, mainGadgets[LAYOUT_5]:=LayoutObject,
GA_ID, LAYOUT_5_ID,
LAYOUT_ORIENTATION, LAYOUT_ORIENT_VERT,
LAYOUT_ADDCHILD, mainGadgets[STRING_6]:=StringObject,
GA_ID, STRING_6_ID,
GA_RELVERIFY, TRUE,
GA_TABCYCLE, TRUE,
STRINGA_MAXCHARS, 80,
StringEnd,
CHILD_LABEL, LabelObject,
LABEL_TEXT, 'User name',
LabelEnd,
LAYOUT_ADDCHILD, mainGadgets[STRING_7]:=StringObject,
GA_ID, STRING_7_ID,
GA_RELVERIFY, TRUE,
GA_TABCYCLE, TRUE,
STRINGA_MAXCHARS, 80,
StringEnd,
CHILD_LABEL, LabelObject,
LABEL_TEXT, 'Password',
LabelEnd,
LAYOUT_ADDCHILD, mainGadgets[LAYOUT_8]:=LayoutObject,
GA_ID, LAYOUT_8_ID,
LAYOUT_ORIENTATION, LAYOUT_ORIENT_HORIZ,
LAYOUT_ADDCHILD, mainGadgets[BUTTON_9]:=ButtonObject,
GA_ID, BUTTON_9_ID,
GA_TEXT, 'OK',
GA_RELVERIFY, TRUE,
GA_TABCYCLE, TRUE,
BUTTON_TEXTPEN, 1,
BUTTON_BACKGROUNDPEN, 0,
BUTTON_FILLTEXTPEN, 1,
BUTTON_FILLPEN, 3,
ButtonEnd,
LAYOUT_ADDCHILD, mainGadgets[BUTTON_10]:=ButtonObject,
GA_ID, BUTTON_10_ID,
GA_TEXT, 'Cancel',
GA_RELVERIFY, TRUE,
GA_TABCYCLE, TRUE,
BUTTON_TEXTPEN, 1,
BUTTON_BACKGROUNDPEN, 0,
BUTTON_FILLTEXTPEN, 1,
BUTTON_FILLPEN, 3,
ButtonEnd,
LayoutEnd,
LayoutEnd,
LayoutEnd,
WindowEnd
mainGadgets[6]:=0
runWindow(windowObject,WINLOGON_ID,NIL,mainGadgets)
EXCEPT DO
IF windowObject THEN DisposeObject(windowObject);
ENDPROC
PROC main() HANDLE
setup()
winlogon()
EXCEPT DO
cleanup()
ENDPROC
9. Tooltype settings
Some of the defaults for the Rebuild application can be configured by
editing the Rebuild.info file.
Many of these settings are also saved into your project file, so if you
reload the file it will also restore the state of the settings you had
last used.
Here is a list of the tooltypes that can be defined
LANG=E / C (controls the default language shown)
USEIDS=YES / NO (code export default setting)
FULLCODE=YES / NO (code export default setting)
USEMACROS=YES / NO(code export default setting)
CODEPATH= (select the default path for the code save)
SAVEPATH= (select the default path for project save)
SHOWBUFFER=YES / NO (show the copy buffer at startup)
SHOWSETTINGS=YES / NO (show settings when adding new gadgets)
PROJECTICONS=YES / NO (create an icon for project files)
WARNONDELETE=YES / NO (Warn when an item is deleted)
PREVIEWCODE=YES / NO (Show code preview window at startup)
WINDOWTOP =
WINDOWLEFT =
WINDOWWIDTH =
WINDOWHEIGHT = (override the main window size and position)
CODEWINDOWTOP =
CODEWINDOWLEFT =
CODEWINDOWWIDTH =
CODEWINDOWHEIGHT = (override the code preview window size and position)
10. Futher inforation
ReBuild is written using my own E-VO compiler.
The full source code is available on gitgub:
https://github.com/dmcoles/ReBuild
If you find any issues with this product please do feel free to raise an
issue in the gitgub repo or if you wish to contact me for any reason
regarding this project please do.
Michael Bergmann has put in a lot of time and effort in testing Rebuild and
has also developed a tutorial for Rebuild. This tutorial goes into depth
regarding the use of Rebuild and each of the gadget types.
There have been some changes to this tool since that tutorial was written
so the tutorial may not fully reflect the current workings of the current
version.
The tutorial is available separately from gitub repository:
https://github.com/dmcoles/ReBuild/tree/main/tutorial
My thanks go to Michael for this great work.
11. Future (possible) enhancements
I have many ideas for future enhancements to this project. My plan was to
release something which could at least cover all of the functionality of
the old ClassMate tool for the first version of Rebuild.
Just a few of my ideas (some of which may or may not be possible) are:
* add more languages to the code generator
* option to generate codecraft project files
* add hint text to the settings pages to help users
11. Version history
1.0.0
- Initial release
1.1.0
- Creating a virtual gadget could cause crashes (due to a bug
in the version of E-VO used to compile 1.0.0)
- About dialog changed 'Rebuilder' To 'Rebuild'
- Loading a bitmap with no image selected reported an incorrect error
- Added option to generate code that does not use macros in the object
definitions (for better GCC compatibility).
- add GA_TabCycle property to click tab
- code generated for fuel gauge now uses GA_Text instead child label
- fuel gauge used incorrect default number of ticks
- GetScreenMode did not include child label in generated code
- Glyph did not include child label in generated code
- Glyph used incorrect default type
- Added USEMACROS tooltype
- Sketchboard was missing many of the settings in the generated code
- SizeBRight and SizeBBottom did not work correctly in preview window
1.2.0
- fix getfile readonly code not being generated when TRUE
- use macros setting was not fully applied to all object definitions
- fix os4 issues with penmap and bitmap gadgets
- rename 'name' fields to 'label'
- add identifier field for all gadgets
- add child labels for gradient slider and palette gadgets
- add support for checkable/toggle/mutual menu items
- add 'move into vlayout' and 'move into hlayout' menu options
- implement reopen function
- add hint text option to all gadgets
- rename incorrect window gadget help label
- set window gadget help to default to true
- window activate flag defaults to true
- adding new gadget now inserts after currently selected gadget instead
of at the end
- add menu keyboard shortcuts
- add undo/redo capability
- save code preview and preview window positions to project file
- update project file format to v2
- add tooltype options for code previews and code preview window position
- settings saved to envarc:
- add realtime code preview window
- set selected item to root layout for new project
- make main window and code preview window remember their last positions
- add preview window width + height properties
- add link to vscroll to text field gadget
- add link to hscroll and link to vscroll to text editor gadget
- add link to slider gadget for integer gadget
- add horizontal scroll flag to texteditor
- throw an error on startup if neither textfield or texteditor gadgets
are present
- all gadget types now have label property
- set preview window settings based on window definition
- re-arrange some gadget settings pages to try to better fit them in
640*256
- Add an edit button on main window
(C) Darren Coles 2024