This doc file is a crib from "Libraries & Devices". I intend it to be as comprehensive as time & space allow. Custom Screen:dual playfield. Open a screen, either letting Intuition allocate a bitmap or providing one of your own (CUSTOMBITMAP). Then create a 2nd bitmap, its bitplanes, & a RasInfo structure for it. Then install these into the new screen's viewport, change the viewport flags to include DUALPF, then do a makescreen() and a RethinkDisplay(). This method keeps Intuition rendering in a single playfield. Windows:special types. Borderless is as it says, no border imagery is provided. Borders may still exist, however! If any system gadgets exist, border space will exist to encompass them. If no system gadgets present, the window has no border padding & can be used to fill the entire screen. Best combined with Backdrop mode. Benefits:ability to render into it just as if it was the actual screen display memory, but no trashing of menus or other windows! Warning:if it doesn't cover the entire display, no visual cue exists separating it from the screen display or other windows, so care must be taken. Gimmezerozero uses 2 bitmaps-outer one in which system gadgets are rendered, and inner one in which you do your rendering. Top left position of this inner window are (0,0), hence the name "gimmezerozero". Seriously degrades the performance of multitasking, however-lots of extra memory to shuffle around during resize etc. Area in which you can render is formally defined in the window variables BorderLeft, BorderRight, BorderTop and BorderBottom. There are also special GZZ_ variables in the window structure for mouse pointers etc., to take account of coords within inner window. For text only, using a console device uses far less memory-GZZ should be considered if mixing text & graphics, and your design really needs it. Requesters are rendered relative to inner window of GZZ type window, and system gadgets rendered in the outer window. Custom gadgets rendered in inner window unless you want them in the border (by setting GZZGADGET flag in gadgets concerned). Backdrop windows:always behind other windows. Note that a new backdrop window will even be opened behind currently existing backdrop windows! Also, the only system gadget allowable is the close gadget (but you can attach your own custom gadgets ad lib) and all non-backdrop windows will always be in front of the backdrop window. Furthermore, calling ShowTitle(screenhandle,FALSE) will hide the screen title behind the backdrop window-you get to all intents & purposes a completely blank screen to play with as you wish! SuperBitmap:you supply your own bitmap structure & pre-drawn bitplanes, at least as big as the window, or possibly bigger if wanted for some reason. Window refresh system then displays all non-obscured parts of it. Bit map is always present for reference, and if bigger than the actual window/screen, allows handy scrolling to be performed. IDCMP & system gadgets:if you couldn't care about resizing etc., only the close gadget needs paying regular attention to. If you want to care about resizing & depth-arrainging, IDCMP flags SIZEVERIFY, NEWSIZE, ACTIVEWINDOW and INACTIVEWINDOW are provided. Refresh types:Simple refresh means that obscured parts of an underlying window are discarded when another window overlaps. To refresh, it has to be re-rendered. This uses no extra RAM, & is best when you can refresh the display yourself quickly. IDCMP flags exist to tell you when to refresh your display, & Intuition provides functions to limit the refreshing to the damaged area in a relatively transparent fashion (i.e., you don't need to know precisely where it is, it's kept track for you). Smart refresh saves the damaged portion & re-renders it when revealed once more. If you resize an underlying window & then reveal it (e.g., change the depth arrangement of 2 or more windows) then you still have to re-render into the revealed window if you made it larger! (Unless you don't want to for some reason, such as laziness...) Super Bitmap is just that-the whole of your image exists already, & all you have to do (or let Intuition do) is redisplay revealed bits of it. Your display is always there in RAM. Mind you, this uses RAM like crazy-try a 6 bitplane EHB hi-res custom screen & 2 superbitmap windows on an Amiga with less than 1 Meg... Refreshing:if you're using simple-refresh, or you increase the size of an underlying smart-refresh window, you'll get a REFRESHWINDOW event. Once this is received, do a BeginRefresh() call, then do your refreshing, then do an EndRefresh() call. Your refreshing should stick ideally to functions within the Intuition & graphics libraries. Avoid calls that may lock the LayerInfo, or cause complicated IDCMP messages to be fired off rapidly, and avoid AutoRequest() and direct & indirect DOS-related calls during the Begin/EndRefresh sequence. Even if you do nothing between the calls, it is still a good idea to call BeginRefresh() and EndRefresh() simply to allow Intuition & the layer library to keep track of things after a REFRESHWINDOW event. Window flags: WINDOWSIZING : gives you the sizing gadget. SIZEBRIGHT & SIZEBBOTTOM flags determine whether it takes up space from the right of the window (default) or the bottom (when you want all possible horizontal space & are prepared to sacrifice some vertical space). WINDOWDEPTH : gives you both depth gadgets. WINDOWCLOSE : gives you the close gadget. Selecting it results in an Intuition IDCMP message. But it is up to your application to close the window using CloseWindow() !! This allows your application to do other things first (such as put up an "are you sure? (yes/no)" requester). WINDOWDRAG : Provided if 1) this bit is set 2) the NewWindow.Text argument is non-null 3) WINDOWDEPTH or WINDOWCLOSE also exist. Refresh flags : SIMPLE_REFRESH : you always get REFRESHWINDOW messages when changing the depth arrangement or resizing. Up to your application to do the refreshing! SMART_REFRESH : you only get a REFRESHWINDOW message if you resize. If you have no sizing gadget, this never occurs. Ideal if you want a fixed size window! SUPER_BITMAP : you provide your own bitmap structure, initialised bitplanes & Intuition uses them to determine the display state. If you change the contents of your bitmap's bitplanes, the change shows. Makes rendering possible to a covered window (I think) which is then correctly revealed (but I wouldn't take this as gospel!) Message flags : REPORTMOUSE : allows MOUSEMOVE events to be received at this window's userport. ACTIVATE : when set, makes this window the active one. Warning-if not the first window opened, could result in changing the end destination of IDCMP events, making a system hang possible under certain circumstances. Best make the 1st window an ACTIVATE, then leave application user to hand-activate future windows with the mouse. NOCAREREFRESH : what it says-you don't want refresh messages & couldn't give a shit about refreshing. Should only be used if the display has one window, fixed size, & hence never needs a refresh. Otherwise, you might need a refresh in a window but never be informed about it! RMBTRAP : tells Intuition to treat right mouse button like the left mouse button, & ingnore menus. Don't use if you have menus to access, or they'll NEVER be accessed. Your application can change this on the fly if needed (as one of mine did-but what a way to do it!) using something such as BSET #5,37(A0) or whatever (all you C programmers, tough shit!). It must, hovever, be a SINGLE instruction (often called Atomic), NOT a sequence such as MOVE.B 37(A0),D0 BSET #5,D0 MOVE.B D0,37(A0) or else Intuition could preempt it (guru, where are you?). Best of all, surround your chosen method with a Forbid() and a Permit() call to make life easier. Changing pointer:you need the SetPointer() call & a sprite definition. A sprite definition looks like this : sprite_def dc.w $0000,$0000 ;2 control words dc.w datal1p1,datal1p2 ;actual data dc.w datal2p1,datal2p2 ;l1p2 means line 1, plane 2 ... dc.w datalNp1,datalNp2 dc.w $0000,$0000 ;reserved for system Now call SetPointer(window,pointer,height,width,xoffset,yoffset) A0 A1 D0 D1 D2 D3 A0 = ptr to your window handle got from OpenWindow() A1 = ptr to your sprite def D0 = no of lines of your sprite (here N) D1 = no of pixels across (max 16) D2 = x distance to Hot Spot D3 = y distance to Hot Spot The "Hot Spot" is the actual point used by Intuition to determine what you've pointed to. Hot spot of (0,0) is the top left corner, (7,0) is the top middle of a 16-pixel pointer, and (0,10) is the middle of the left edge of a 20-line pointer. See the Preferences Pointer editor for ideas about this. Redirecting system requesters to your window/screen:you need to know a bit about Processes. Processes are like Exec Tasks, but more sophisticated. A Process is actually an extended task created by the dos.library, which has its own Process structure associated with it. A Process structure is like a Task structure, but has extra entries appended to it. Definition of a process structure can be found in, for example, the GenAm include file "includes/libraries/dosextens.i". Once you have the process structure definition, you can use it. Whenever a program is started up from WorkBench or CLI, it is treated as a process, not a mere task. A Process structure is set up for it, and by using FindTask(0L) you can get a pointer to it. Synopsis is as follows : SUBA.L A1,A1 ;pointer to name = NULL MOVE.L $4.W,A6 ;EXEC_BASE JSR FindTask(A6) ;get pointer to task/process struct MOVE.L D0,A4 ;now A4 points to your process structure! Put this code (or something like it) where it will be executed early in the runtime life of your program. Now you can save this pointer somewhere (I tend to have a main variable block referenced by A6, and macros for calling the library functions that save A6 before changing it to EXEC_BASE or whatever else. This block has an entry reserved for this pointer, usually called my_task_node(a6) ) for future use, and get the window handle used by the process using, e.g., MOVE.L pr_WindowPtr(A4),D0 MOVE.L D0,old_window(A6) MOVE.L my_window_handle(A6),D0 ;which I have ;created using the ;intuition library! MOVE.L D0,pr_WindowPtr(A4) ;and redirect! Now, all system requesters will be redirected to your custom window & your custom screen. Don't forget to reset pr_WindowPtr(A4) back to its original value before closing your window!!! Gadget handling:the correspondence between IDCMP events & gadget activation flags is as follows : GADGIMMEDIATE results in a GADGETDOWN event being sent RELVERIFY results in a GADGETUP event being sent GADGIMMEDIATE is fairly self-explanatory - if you want to know that a gadget has been selected the moment that the user clicks the left mouse button with the pointer over a gadget, set this flag. RELVERIFY (RELease VERIFY) can be used to send a GADGETUP event if the user releases the left mouse button, while still positioned over the gadget. RELVERIFY allows an escape from the accidental selection of a dangerous gadget (e.g., close window gadget!) that will activate a sequence of events which is catastrophic if not actually wanted. With RELVERIFY, the pointer can be moved off the gadget before the mouse button is released, and hence the catastrophe can be avoided. Of course, you can set both flags, and get two IDCMP events for any or all of your gadgets. You can even handle the events differently if you wish! Select boxes can be positioned relative to the left or right edge of the window/requester containing the gadget, or relative to the top or bottom edge. Use the GRELRIGHT/GRELBOTTOM flags. GRELRIGHT clear uses a LeftEdge positive offset in the gadget structure relative to the left edge of the window/requester. GRELRIGHT set uses a LeftEdge negative offset (with an explicit minus sign in the source!) relative to the current right hand edge of the window/requester. Similarly, TopEdge changes function in a directly analogous manner according to whether GRELBOTTOM is set or cleared. Hit box sizes can be made relative also. Setting GRELWIDTH & specifying a gg_Width of -28 makes the gadget 28 pixels smaller than the width of the window or requester. GRELHEIGHT and gg_Height behave similarly. Leaving the flags clear makes the width and height specifiers absolute. Setting FOLLOWMOUSE in a gadget's flags results in MOUSEMOVE IDCMP broad- casts for as long as the gadget is selected. The possibilities that exist when FOLLOWMOUSE is set on a selected gadget are : 1) GADGIMMEDIATE & RELVERIFY = 1. GADGETDOWN IDCMP received when gadget selected, MOUSEMOVE IDCMP received while button held down (if the mouse moves), and then a GADGETUP IDCMP received. Mouse reports from this gadget cease (although may still appear from elsewhere if you've set them up to do so). 2) GADGIMMEDIATE = 1, RELVERIFY = 0. GADGETDOWN IDCMP is received, MOUSEMOVE IDCMP received until button released. Then these MOUSEMOVE reports will stop from this source, but the program will have no way of knowing for sure that this has happened. 3) GADGIMMEDIATE = 0, RELVERIFY = 1. Program receives a series of mysterious, anonymous mouse movement reports (you may want this!) and then a GADGETUP IDCMP message. 4) GADGIMMEDIATE & RELVERIFY = 0. Program only gets mouse reports. You may want this. There are other ways of doing it, though. You can put gadgets in your window borders. Set one or more of the flags RIGHTBORDER, LEFTBORDER, TOPBORDER or BOTTOMBORDER. Intuition will adjust the borders to accomodate your custom gadgets when your window is opened. Note : if extra gadgets added or removed afterwards, Intuition does NOT readjust the borders! Also, setting border flags unintelligently within a single gadget results in your window being all border! THINK about it... Gadget mutual exclusion : Intuition doesn't do it (unlike menus). You have to do it yourself. You can't use TOGGLESELECT gadgets for exclusion, nor RELVERIFY. You must use GADGIMMEDIATE gadgets. Also, you cannot use a gadget with a border using complement mode highlighting, or a GADGHBOX mode gadget. Recommended method of exclusion : use RemoveGList() to excise the gadgets from your list temporarily, change the SELECTED bit of the flags in each one to change, use AddGList() to put them back in the list, and then call RefreshGList() to refresh the imagery. Alternatively, it may be possible to use OffGadget() and OnGadget() functions (But don't take this as the definitive gospel, or else all sorts of fun could occur. Experiment first with something harmless before ruining a project on which you've worked for two years...) Masking your gadgets:If you want a non-rectangular gadget, you can supply a mask. However, there exist restrictions. If the select box is clicked upon, a further test is made to see if the portion clicked upon lies within the mask, and counted as a hit only if such is the case, but RENDERING is NOT necessarily done through the mask! If the GADGHCOMP mode is chosen, then the complement rendering is restricted to the mask, but the gadget image is not rendered through the mask. In the case, for example, of an elliptical mask, the image is still a rectangle, and when displayed will interfere with the corner areas even though they are outside the elliptical bounday of the mask. Hence one cannot crowd such gadgets together without care. Also, the ghosting of a disabled gadget ignores the mask. It may be visible outside the boundary, depending upon colour choice. To get a mask, a BoolInfo structure is needed, and a pointer to it put in the gg_mulutualexclude entry of the gadget structure. Also, the Activation flag must have BOOLEXTEND set. Proportional gadgets:this needs the POT variables, the BODY variables, the KNOB definition and the CONTAINER definition. The POT variables are HorizPot and VertPot. These contain the position of the slider knob upon rendering. They can be initialised to any legal value within the slider range. The HorizBody and VertBody variables describe the step value to use for changing the pot variables. If you want to have a 16-step slider representing 16 possible settings of Red on a colour gadget, for example, then the body variable concerned must be equal to $FFFF/16. In general, for N steps, use $FFFF/N. If using AUTOKNOB (which isn't truly interesting), then the body variables scale the autoknob respectively. Setting HorizBody to $FFFF/16 gives you an AUTOKNOB that is 1/16th the container size. You can have both horizontal & vertical movement. Set FREEHORIZ for horizontal sliders, FREEVERT for vertical sliders. You can have a custom image for the knob. Just supply a standard Image structure for it, and put a pointer to it in the gg_image entry of the gadget structure. I can't say for certain if you can have a different render and select image-I haven't tried yet, although I don't see why not. I think it's safe to assume (experiment with this!) to have a render & a select image in the gadget structure for the knob. The container is the select box for the gadget. If you're using fancy imagery for the gadget, ensure that the hit box is within the area of your graphic reserved for the slider to move in, or else all sorts of interesting effects will occur (unless you want them...) If you use AUTOKNOB, set up an uninitialised Image structure for it. If you are supplying your own Image, be sure that the Image structure & the data are initialised! To modify the gadget, ModifyProp(), or better still, the added 1.3 NewModifyProp() can be used to change the flags, the pot variables and the body variables. To check if this gadget was played with, examine the KNOBHIT flag in the PropInfo structure. Notes:be sure that if 1) the gadget lives in a requester, that REQGADGET is set, else clear it for a normal window gadget; 2) that if your gadget is to go in the border area of a GIMMEZEROZERO window, that GZZGADGET is set, otherwise clear it; 3) that if you want some text associated with your gadget, that the gg_Text entry points to an initialised IntuiText structure, otherwise set it to NULL; 4) if you're using BOOLEXTEND, put a pointer to the BoolInfo structure in the gg_MutualExclude entry; 5) that for processing, the gg_GadgetID word is set to unique ordinal values for all of your gadgets; 6) If you have some requester gadgets, ensure that at least one of them has the ENDGADGET flag set, to signal to Intuition that this gadget allows the user to exit the requester. Typical processing of gadgets involves something like this:set up a table of jump addresses for each gadget numbered from 0 upwards, and when you get the IDCMP gadget message, get hold of the im_IAddress entry. This points to the gadget structure of the selected gadget. For example; MOVE.L im_IAddress(A0),A1 ;get gadget structure addr MOVE.W 38(A1),D0 ;get gadget ID LEA gadget_table(pc),A2 ;get jump table ADD.W D0,D0 ADD.W D0,D0 ;* 4 for longword access MOVE.L 0(A2,D0.W),A0 ;get jump table entry JSR (A0) ;and execute it! C programmers can sod off at this point-you've got your own docs with your fancy compiler package! BoolInfo structure:looks like this (devpac owners); rsreset bi_flags rs.w 1 ;set to BOOLMASK bi_mask rs.l 1 ;point to your mask Image structure bi_reserved rs.l 1 ;set to NULL bi_sizeof rs.w 0 Special tips on MENUVERIFY:this allows Intuition to verify that all windows are ready for menu rendering before it is done. Intuition will not allow menu operations to continue until the MENUVERIFY message has been replied to. The active window gets to see the MENUVERIFY IDCMP before all others, and has the option of cancelling menu operations altogether. You can use this to make the right button do other things if the pointer isn't on the menu bar. When the MENUVERIFY message arrives, check the im_Code field of the message. if it equals MENUWAITING, your window isn't the active one, and thus Intuition is waiting for you to verify that menu operations may continue. If the code is MENUHOT, then your window IS the active one, and you can then decide to cancel the menu operation. Set the im_Code field to MENUCANCEL before replying the message. To know whether menu operations terminate, wait for the MENUPICK IDCMP. If you cancelled the menu operation, you will receive a MOUSEBUTTONS message with the code MENUUP. Right-Amiga keystrokes also respect the MENUVERIFY, and are always paired with a MENUPICK message so that your program knows that the menu operation is over. Remember:if you're doing anything that directly or indirectly has you waiting for Intuition, turn MENUVERIFY off using ModifyIDCMP() before- hand, else a deadlock could occur. You cannot wait for a gadget or mouse event without also checking for any MENUVERIFY messages. The most common problem is system requesters using AutoRequest(). If you don't turn off MENUVERIFY & the user hits the right mouse button, Intuition will wait for you to reply to MENUVERIFY and a deadlock results because Intuition must be free to run and accept a response from the user within the requester. The same is true for DOS calls (they may bring up a system requester!), OpenLibrary(), OpenDevice(), and OpenDiskFont(). Requesters:At last! the info I wanted! Requesters REQUIRE a response from the user, and while active, the window locks out all user input except to the requester (unless the NOISYREQ flag is set). You can have: 1) system requesters. Generally out of your control, and occur, for example, when there is no disc in the drive (or the wrong one). You can redirect them to your window though-see above about the distinction between tasks and processes. 2) Your own application-specific requesters. Completely under your control. Trouble can occur if deadlocks aren't catered for (see MENUVERIFY above). 3) Double-Menu requesters. Activated by a double-click of the menu button. Once a requester comes into existence, all further input to that window via IDCMP messages is blocked (unless you set NOISYREQ in the rq_Flags entry of the requester structure). Output, however, is not blocked. You can still scribble all over the window, taking account of the fact, of course, that the requester is obscuring part of it. You can choose where the requester appears. Either it can be relative to the top left corner of the window, or relative to the pointer (set the POINTREL flag for this). System requesters, however, are always relative to the top left corner of the window, as are AutoRequest() requesters and BuildSysRequest() requesters. Requesters can be nested. Memory is generally the sole limitation. They must be satisfied, however, in reverse order in which they appear. Special IDCMPs for requesters: 1) REQVERIFY - you MUST reply to it before the requester is rendered. Allows you to ensure that the window is ready for the requester (all output done, for example). 2) REQSET - sent whenever a requester is opened 3) REQCLEAR - set whenever a requester is finished with Requester rendering:can be algorithmic or by custom bitmap. For an algorithmic requester, ensure that the PREDRAWN flag is cleared, and supply the usual kind of gadget list etc., that you would with a window. For a custom bitmap requester, set PREDRAWN, and supply a gadget list with all the usual hit boxes etc., but all Image pointers & gadget text pointers set to NULL. Ensure that the hit boxes correspond to the imagery of your pre-initialised custom bitmap! Note:requesters have their own ReqBorder entry, pointing to a border structure. You can set this to NULL, or alternatively provide as fancy a border as you wish. ReqText points to an IntuiText structure to be used within the requester. To bring up a de-luxe custom requester, set up a requester structure with all the pertinent data, and use Request(Req,Window). If an ENDGADGET gadget is selected, Intuition automatically erases the requester, otherwise you can use EndRequest(Req,Window) to kill it off yourself. Intuition Message structure:this is an extended exec message structure: rsreset im_message rs.b mn_size ;from exec/ports.i im_class rs.l 1 ;IDCMP type:bitwise im_Code rs.w 1 ;message code, e.g., menu number, RAWKEY/VANILLAKEY code im_Qualifier rs.w 1 ;tells if CTRL/ALT/SHIFT pressed im_IAddress rs.l 1 ;gadget structure addr of selected gadget im_MouseX rs.w 1 ;mouse position data im_MouseY rs.w 1 im_Seconds rs.l 1 im_Micros rs.l 1 im_Window rs.l 1 ;ptr to window structure im_SpecialLink rs.l 1 ;ptr to next IntuiMessage (DON'T ALTER!) im_sizeof rs.w 0 Preferences:the function GetPrefs(buffer,size) obtains the current values of the Preferences settings. 'Buffer' is a pointer (in A0) to the buffer you reserve to receive the Preferences data, and 'size' (in D0) is the size of the buffer in bytes. This allows the user to select only the first N bytes of the Preferences structure for consideration or alteration. The function GetDefPrefs(buffer,size) (again, A0,D0) obtains the default settings used by Intuition. The contents of the structure can be saved to the file 'df0:devs/system-configuration' if you want the settings to apply to your CLI upon startup, or to any other file of your choice, if you want your application to have its own custom Preferences settings. Changing the current Preferences settings is achieved using SetPrefs(buffer,size,flag) (here, the order is A0,D0,D1). The 'flag' variable is a BOOLEAN value (TRUE or FALSE) which determines whether the settings are valid for this application only or broadcast to all applications and for global use. The two structures needed are the timeval structure : rsreset tv_secs rs.l 1 tv_micros rs.l 1 tv_sizeof rs.w 0 and the Preferences structure itself : rsreset FontHeight rs.b 1 ;either TOPAZ_SIXTY or TOPAZ_EIGHTY PrinterPort rs.b 1 ;PARALLEL_PRINTER/SERIAL_PRINTER BaudRate rs.w 1 ;one of the standard baud rates KeyRptSpeed rs.b tv_sizeof KeyRptDelay rs.b tv_sizeof DoubleClick rs.b tv_sizeof PointerMatrix rs.w POINTERSIZE ;pointer data for the Intuition pointer XOffset rs.b 1 ;offsets to Hot Spot YOffset rs.b 1 Colour17 rs.w 1 ;Pointer colours Colour18 rs.w 1 Colour19 rs.w 1 PointerTicks rs.w 1 ;always a power of 2:1,2 or 4 recommended Colour0 rs.w 1 Colour1 rs.w 1 ;workbench colours Colour2 rs.w 1 Colour3 rs.w 1 ViewXOffset rs.b 1 ;offset of View from initial startup ViewYOffset rs.b 1 ;for configuring to individual monitors ViewInitX rs.w 1 ;initial View values from ViewInitY rs.w 1 ;graphics library EnableCLI rs.l 1 ;BOOLEAN PrinterType rs.w 1 ;see Includes & AutoDocs for these PrinterFilename rs.b FILENAME_SIZE ;constant PrintPitch rs.w 1 PrintQuality rs.w 1 PrintSpacing rs.w 1 PrintLeftMargin rs.w 1 PrintRightMargin rs.w 1 PrintImage rs.w 1 PrintAspect rs.w 1 PrintShade rs.w 1 PrintThreshold rs.w 1 ;for B/W rendering:intensity to trigger pixel print PaperSize rs.w 1 PaperLength rs.w 1 PaperType rs.w 1 SerRWBits rs.b 1 ;upper nibble=8-no of read bits, lower nibble = 8-no of write bits SetStopBuf rs.b 1 ;upper nibble=(no of stop bits - 1), lower nibble = table value for bufsize SerParShk rs.b 1 ;upper nibble=parity setting, lower nibble = value for handshake mode LaceWB rs.b 1 ;if interlaced workbench Workname rs.b FILENAME_SIZE ;obsolete RowSizeChange rs.b 1 ColumnSizeChange rs.b 1 PrintFlags rs.w 1 ;user preference flags PrintMaxWidth rs.w 1 PrintMaxHeight rs.w 1 PrintDensity rs.b 1 PrintXOffset rs.b 1 wb_Width rs.w 1 wb_Height rs.w 1 wb_Depth rs.b 1 ext_size rs.b 1 prefs_sizeof rs.w 0 When examining or altering this structure, using MOVE.L #prefs_sizeof,D0 before calling GetPrefs() etc gives you the whole structure. It is recommended to reserve some space for it using AllocMem() and then discard it after either a SetPrefs() or copying data items for your own use in other parts of your application. You can examine small portions of the preferences structure & alter them if you wish (and memory is tight) but watch out for side effects! Recommended selection shortcuts:LEFT Amiga key Key Function --- -------- --- These are handled by Intuition independently--- N Bring WorkBench to front (automatically handled by Intuition) M Send WorkBench to back (automatically handled by Intuition) V Give a POSITIVE response to an Intuition AutoRequest B Give a NEGATIVE response to an Intuition AutoRequest --- These are to be handled by your program!!!--- I Select a small piece to the right of the cursor, e.g., next word O Select a larger piece to the right of the cursor, e.g., next sentence P Select a much larger piece to the right of the cursor, e.g., next paragraph J Select a small piece to the left of the cursor, e.g., previous word K Select a larger piece to the left of the cursor, e.g., previous sentence L Select a much larger piece to the left of the cursor, e.g., previous paragraph The following recommendations are for menu shortcuts (Right Amiga key) Key Function --- -------- X Cut function C Copy function V Paste function I Change font style to Italic B Change font style to Bold U Change font style to underline P Reset font style to plain/defaults Z Undo (cancel) O Open project file S Save project file Q Quit Application Help key:Use it! If you want to provide help functions on line, use the HELP key (via a RAWKEY event perhaps) to bring them up. Prevent that useless feeling users get when the HELP key is pressed and nothing happens. Cursor keys:Amiga developers recommendations for cursor key usage in conjunction with the ALT/SHIFT/CTRL keys; Cursor Alone move one unit in given direction Cursor+ALT move next largest unit in given direction (e.g., forward one word, up a page, etc) Cursor+SHIFT move largest possible unit in given direction (e.g., end of line, top/bottom of file) Cursor+CTRL unassigned. Put special functions here if you need them. Mouse button:the convention is, LEFT button=SELECTION, RIGHT button= INFORMATION TRANSFER. Windows:redirect AmigaDOS requesters to your window (see earlier in this file) otherwise Intuition will bring the WorkBench screen to the front if a disc needs changing, for example. TAKE HEED OF ALL THE NOTES I INCLUDED IN THE REDIRECTION INFORMATION ABOVE, PARTICULARLY WHEN CLOSING YOUR WINDOW!!! Icons:should be designed with the light source coming from the top left of the screen. Icons should be visible in one as well as two bitplanes. Edging in black is suggested, so that they show up, no matter what the background. Make them beautiful to look at, make them reflect your program, and make them small-huge icons take up space on the screen and the disc. A minimalist approach is desirable! Exiting your program:make a call to OpenWorkBench() when exiting, even if you did not call CloseWorkBench(). WorkBench should be open as much as possible. If WorkBench was closed and your application has freed enough memory for it to open, it is preferable for it to be reopened. OpenWorkBench() may not work (particularly if there isn't enough memory for the screen). If every program calls OpenWorkBench(), however, then WorkBench will open if it can. Pointer colours:these are; Colour 0 : transparent Colour 1 : Hardware colour 17, medium intensity Colour 2 : Hardware colour 18, low intensity Colour 3 : Hardware colour 19, high intensity A note on style from someone called =RJ= "Design beautiful gadgets, requesters, menus. Think simplicity and elegance. Always remember the fourth grader, the sophisticated user, and the poor soul who is afraind of breaking the machine. "Dare to be gorgeous and unique. But don't ever be cryptic or otherwise unfathomable. Make it unforgettably great."