> Path: cix!slxsys!uknet!mcsun!fuug!news.funet.fi!sunic!psinntp!psinntp!uunet!wupo > st!waikato.ac.nz!aukuni.ac.nz!cs18.cs.aukuni.ac.nz!jwil1 > From: jwil1@cs.aukuni.ac.nz (TMOTA) > Newsgroups: comp.sys.acorn > Subject: RISC OS Lib: [a small comment]+ [part 1] > Message-ID: <1992Feb25.041149.19510@cs.aukuni.ac.nz> > Date: 25 Feb 92 04:11:49 GMT > Sender: jwil1@cs.aukuni.ac.nz (The Master of the Arcane) > Organization: Computer Science Dept. University of Auckland > Lines: 1138 > In previous articles, various Acorn Personnel (James Bye) would have us believe that Acorn's RISC OS Library (As supplied with Desktop C v4.00) is really very professional, exceptionally useful, and is a high-quality product that bears up well when compared to the libraries supplied with compilers on other machines... I have mentioned previously that I have a few bugs to report in said libs... Well, I could email this to Acorn, except: a) It would cost me a mint... 80k is expensive to email from here b) I don't know the email address (something.acorn.ac.uk) c) I would get the usual lack-of-reply from Acorn, and be left wondering if my mail got to them d) You lot would miss out on the chance to see all the bugs I have found e) You lot would miss out on the reason for James Bye suddenly going quiet and refusing to argue about winges on the libraries... So the result is that I sat down for a day, and wrote down the few things that I coud remember that had caused me grief in the development of DSEdit II... Please note that I love the Archimedes. Acorn have good designers. The software is generally pretty good. The compiler is good. It's just the RISC OS Library with which I have gripes. Here is the resulting file. I apologise for the winge-y tone of voice, but I just can't help it when I remember how much time I have wasted coding AROUND RISC OSLib when I could have been letting a decent library do all the work for me... (I have posted in two parts due to the size of the thing) --- Problems, omissions, bugs, and design flaws relating to Acorn Desktop C version 4.00. (about 60 for RISC OS Lib alone, at last count, and I'm not even trying hard to remember things yet...Note that I have only mentioned the MANUAL once... this is NOT due to the manual being good...) Please note that I do not intend to be rude or offensive to anybody, but frustration brings out the sarcasm and rudeness in me... Don't take anything personally. Also, if I have something wrong due to lack of information, I am sorry (but it's probably Acorn's fault for not supplying proper documentation) Note also that most of the "addition" suggestions that can be added onto the libraries without having to have the library sources I have actually implemented, so I know that it's possible, I know that it works well, and I know that in most cases they don't take long to write (many are around 10-20 minutes of work, but provide really useful functions), and I am willing to give you my sources if it will help speed up the process of improving the libraries. Note also that I am not claiming to be able to write code better than anyone at Acorn... I think much of the code in RISC OS Lib is well written, just half of it is appallingly badly designed. (And the reason for this in my opinion is that it was not written as a cohesive library, but routines from Paint, Edit, and Draw that seemed useful were lumped together as a library) Note also that the compiler and the CLibrary are very good. The linker is good, but it would be nice if: a) it could link in only those functions needed from a file, rather than all functions in the file regardless of whether they are needed, or b) The RISC_OS Libraries are split up into teensy (I mean more teensy than they already are) sections so you don't have to include huge globs of code just to get a single function. (OK, so who cares now that the whole bloated lot of it is in ROM?) Note that the RISC_OSLib library (on average) is mediocre (half of it is brilliant, but is badly let down by the other half) And note that the DDE stinks. Conceptually, it's fine, but the interfaces are slower to use, more crude, and less intuitive than most of the command line interfaces for the CLI tools themselves! (oh, and they use more memory, as well... and I can usually write an obey file to start off the tasks set up as I want them far more quickly than I could set up the options in the frontend interfaces. And I am a person who usually prefers pointy-clicky-interfaces to CLIs when I have the choice!!) First, a few quick comments about RISC_OSLib, then some about SrcEdit and Make and stuff... (I apologise for the waffle, but note that each and every paragraph contains pertinant points, so please do read the lot (If you have an afternoon spare, that is)) Problems, omissions, bugs, and design flaws in Acorn C Libraries ================================================================ The following is a list of problems I have encountered with the C libraries from Desktop C. It does not cover even half of the things I have noticed, but I only just thought of writing all these things down...I didn't realise when I bought Desktop C that I had volunteered to be in the front-line testing troops...I thought Acorn would have tested the code before releasing it... Please note that all the sarcasm and implied insults are not to be taken personally by anyone! It's just that there are so many small things that annoy me about these libraries that I can't help but get annoyed at the senselessnes of some of the design decisions (or lack of design decisions...ooops sorry... there I go again...) The comments are organised into the "modules" from whence they sprang... Following that is a list of some new functions that would come in quite handy. Also, I have refrained from further comment on the naming of variables and functions. Suffice to say: (sorry, a few pages of "brief comment"...) -Variables should have names that describe what they are. The first rule of structured programming. Now, tell me what an "m" is. A menu, perhaps? or is it a mouse structure? I don't know about Acorn staff, but I personally can type the word "menu" almost as fast as I can fid the "m" key, and the extra time spent typing is more than offset by not having to spend 5 minutes reading through the datatypes in the manual trying to work out what the hell is going on... James Bye (I think) mentioned that now he has been using RISC OSLib for 4 years he knows everything well enough not to need to look in the manual... Well, I have been going for 4 months (intensively), and I still have to look up the NAME of every variable and funtion in the manual (or copy code from another part of my program). But I KNOW that if the naming was consistent, I would not have to do this... For example, I have already spent 4 years programming the WIMP from BASIC and ASSEMBLER, so I KNOW the SWI calls... working out that Wimp_OpenWindow maps to wimp_open_wind() is the thing that is causing me problems... because it is inconsistent, not just with the SWI call it represents, but also with other calls in RISC OS Lib which use "w{ind{ow}}" ( {} means optional) or a different naming style for a different function, so there is no "rule" by which I can convert SWI names into RISC OSLib function names, hence, I must look each and every one up in the manual. Try to work out what the following mean: event.type; event.data.buttonevent.mouse.window; as compared to e.e; e.data.but.m.w; Yes, there is more typing involved. But it is better programming style. It helps make code more readable, which is good. And if people *really* *want* to prgram in heiroglyphics, then they can simply add #define w window and happily confuse themselves into obscurity. I suggest you read the libraries with, say, Think C on the Macintosh, or Turbo C on the IBM, and you can read them and notice how readable everything is. (and how well designed most things are) Another useful thing to do when abbreviating variables is to always use the SAME abbreviation. For example: b and bbits are used interchangeably and aparrently at random, w, wind, and window are used randomly, m and m mean different things depending on the context, box means a screen coordinates rectangle OR a window coordinates rectangle, depending on the context. Why not call it a "ScreenBox" and an "ExtentBox" or something in the cases where it can only ever contain one type of box data? scx,scy and x,y are used randomly. I also personally beleive that it would be better to name enum/#defined constants not for the module from which they hail, but for the item they are related to. For example: (Acorn names taken randomly from the manual, my names chosen to fit in with SWI calls and FORMED naming) ACORN's name My name ============ ======= wimp_WTRESPASS window_NOBOUNDS wimp_BCLICKDEBOUNCE icontype_CLICKDEBOUNCE wimp_BRIGHT button_RIGHT (hmmm... with my names you can't confuse the "B"'s can you?) wimp_IFILLED icon_FILLED wimpINDIRECT icon_INDIRECT (notice that Acorn's name *isn't* wimp_IINDIRECT (with an "I" on the front like ALL the others have), so it's confusing if you weren't the person who wrote it. In fact he/she probably finds it confusing as well.) wimp_MOVE_WIND drag_MOVEWINDOW wimp_EREDRAW event_REDRAW wimp_EMREDRAW eventmask_REDRAW (interesting how the manual says "wimp ESEND = 1 << wimp_ESEND") wimp_MRAMFETCH msg_RAMFETCH wimp_MSEPARATE menu_SEPARATE (hmmm... with my names you can't confuse the "M"'s can you?) I also really liked wimp_Mwriteable as compared to wimp_BWritable (note they are both spelt differently, AND they are both lowercased (well, at least, according to the manual, which is WRONG) while most other enum/defines are in uppercase. This makes it VERY EASY to write code because it is INCREDIBLY EASY to remember exactly how Acorn "spelt" this particular thing. That was SARCASM by the way.) Maybe Acorn should buy their programmers dictionaries? Or... hey! heres an idea! They could TALK TO EACH OTHER while developing software, and sortof INTEGRATE all the parts to make one large, nice-to-use product! What a revolutionary idea! -Abbreviations, if used, should be standardised. A good rule of thumb is to shorten to 4 - 6 characters. Thus, icon would become icon (not i), menu would become menu (not m), mouse would become mouse (not m), window would become window (not w) (or at a stretch, wind would be acceptable). -Function names should have a consistent style. I don't care whether you pick Module_FunctionName() module_functionname() module_function_name() module_Function_Name() or whatever, just KEEP IT CONSISTENT! -I suggest module_FunctionName(), or Module_FunctionName(), to be consistent with the standard nomenclature of SWIs If you feel that you can't change the names now because of backwards compatability, then simply supply a file of #defines to fix the problem until people convert their code to the new names (a simple global search and replace operation): #define wimp_open_wind Wimp_OpenWindow #define wimp_get_point_info Wimp_GetPointerInfo #define wimp_getwindowoutline Wimp_GetWindowOutline ... That way, -new authors can learn a nice set of names. -old authors can struggle to realign themselves for about a week until the consistency impinges upon their fraggled brains and they realise that a simple formula can be used to work out what something's name should be -new programs can benefit from tidier coding, greater readability, easier debugging, etc. etc. -old programs simply include the #define file to keep backwards compatibility: this will slow compiles down slighty, and if it is a large slow-down, then they can still be linked with the OLD libraries and make do with all the bugs in the old libraries. And we all end up (in about 1 year) with a really good library, used for all the "current" software. The longer Acorn leaves this drastic change, the harder and more painful it is going to be, but IT WILL HAVE TO BE DONE sooner or later. The longer Acorn leaves this drastic change, the more people will write their own substitutes, meaning: -Acorn have less control over style of applications. If you use the proprietary acorn saveas code, your save-as window will work exactly as Acorn wants it to... -Application size will NOT be reduced because Acorn are now putting the libraries into ROM, as nobody will be using the Library code, but will be duplicating it for themselves. -Applications will be bigger and slower to write because the libraries' functions have to be re-written by the application writer. -Programs and bits of source code from different sources will become incompatible because they aren't built on a standard base. I just wish I could have found out how bad RISC OSLib is BEFORE Acorn decided to put it into ROM, as they are now going to be very unwilling to change things. (Or do I still have time to at least get a few bugfixes before the real RISC OS 3.00 release?) In fact, NOW (before people stat compiling with the new RISC_OS_Stubs) would be a great time to break away and fix the names. Thus, anything compiled by including code from RISC_OSLib would use the OLD Library, while new programs designed to use Stubs plus a shared library could use the new naming conventions. NOW IS THE TIME! It will only take a few days work to rationalise naming for the new library, so perhaps it is not too late to get the ROM library names correct? Or are the names only stored in Stubs? In which case, a new set of headers and stubs could be supplied for new nomenclature, and an old set of stubs and headers for old? It then wouldn't be too difficult to continue supplying the 2 sets of stubs, so that any new RISC OSLib functions could be added as extensions to the old stubs, so people with old programs would not have to convert them over to the new names. Please, if it is possible, then please change the names used ASAP. It would not be difficult, but it would be enough to change RISC OSLib from a lurking horror on my hard drive into a useful set of auxiliary routines to use... And once the major problems (as listed below) are fixed, it will become a joy to program with... general ======= Having realised that I would not be able to write anything other than Draw, Edit, or Paint if I used Acorn's Libraries as they stand, it would be nice if I could just replace *BITS* of their library (e.g. replace the entire dbox module with my own implementation, or add functions to it). However, many of the modules collaborate (e.g. dbox has hooks in to help, templates, resspr, wimp, etc.), and the internal commumincation "hooks" have NOT been made available to us. Thus, to replace dbox, I HAVE to write replacements for help, templates, and resspr. These in turn depend on other files, so I would essentially have to write the entire library from scratch, which is a shame because a) I don't have time to do Acorn's job for them, and b) Half of Acorn's libraries are actually quite good, so it seems a shame to write them off totally. Therefore, it would be very nice if some of the internal "hooks" (function calls and shared/global variables) could be declared as "extern" so that they can be "got at" from the library... (e.g. if I could get my hands on the template-list head pointer, I could go through the templates and modify the templates myself if I so wished (which I do wish). If I could get my hands on the memory pointers used by template_ calls, I would be able to DEALLOCATE memory chunks when closing windows, etc.) baricon ======= A bad assumption here is that everybody wants to do something when Select is clicked on an icon. I had to write a blank function just to sate baricon... passing NULL as the proc pointer just crashed my machine... It is also a heck of a lot of code to include into an application just to get an icon on the iconbar (because to get my ONE icon on the iconbar, I have to include code to add different types of icons, to the left and the right of the iconbar). Needless to say, I have replaced my use of baricon with about 5 lines of my own code. Smaller, faster, more easily adjusted for what I want. dbox ==== Automatically moving the caret around the window when the up/down cursor keys are pressed is all very well, but please, if there is only ONE writable icon in the window, leave the caret WHERE IT IS! (i.e. don't bump it to the end of the icon it is in!) dbox_fillin_fixedcaret appears to be faulty. That is, it DOESN'T leave the caret alone. I have dboxes that pop up with one writable in them, but because the writable's associated radio-button is OFF, I want the writable to be UNSELECTABLE (shaded), and therefore have no caret. I SPECIFICALLY REMOVE the caret, but as soon as I call fillin_fixedcaret, THE BLOODY CARET APPEARS IN THE ICON! Even if I have (eg) an Edit window open with the caret in it, fixed_caret sucks in the caret! Very annoying this is, too. Also, dbox doesn't seem to recognise "Write, click, drag" icons as being "writables". They ARE writables, so please treat them as such. (i.e. check for (buttontype >=14) or (buttontype == 14 || buttontype == 15)) You seem to think that a dbox is a thing that pops up with a message, the user clicks "OK" or "cancel", and it goes away again. However, a more generic dialogue manager would be *far* more useful: Allow a dbox to stay on-screen as long as necessary. This is very useful if the dbox is a "tool" window (cf !translatr - it has dbox's off it's menu, but if you click on the parent menu items, the dbox pops up and stays on screen until you close it - very useful) Allow more than one dbox to be open at once. As well as the above point, it is sometimes nice to pop up a secondary dbox if a button on a primary dbox is clicked. It is also quite common these days to use PANES in dbox's so it would be very useful to be able to open more than one window using the nice high-level dbox routines. (not to mention that if a dbox is "accidentally" left up when another is opened the program falls over in weird and wonderful ways... for example, what if I want to pop up a dbox on an alarm event? Will an alarm reach me while I have another dbox open? I should hope it would, but what happens when I try to open the alarm dbox? You guessed it, everything falls to pieces) Allow handlers to be registered for *specific* events for a dbox. What I really want here is to ask for NULL events to be passed to my dbox as well as to my main "Unknown Event Handler" so that my dbox can be independent of my main event handling code. (In fact, I want a proper event handler that can give NULLs to any window ... just imaging saying "I want to do a drag in THIS window, so I would like all NULL events to be passed to this window's drag handler, as well as to any other windows that wanted the NULLs. And then, when I deregister NULL event handlers, you can check, and if no NULLhandlers are registered, AUTOMATICALLY mask out NULL events. Useful!) Allow handlers to be associated with icons in dbox's. So if the user clicks on a radio-button (icon 6), then it's handler is called first to handle the event. If it fails to handle it, the event is passed to the raw eventhandler, then to dbox's handler... That way, the author can write a small function specific to special buttons (perhaps with a return value to tell dbox that it's time to remove the dbox as if the "ok" button had been clicked), to take a special action when they are clicked. Allow button types other than "CLICK" for "Action" buttons. It is really annoying to find that you can't make your "OK" button a "RELEASE" or a "RADIO" button (which does auto-selection of the icon, etc.) without having to attach a raw eventhandler to trap the click. (This could be fixed by attaching a button_event_handler as in the previous paragraph, that returns a code telling dbox "that was an affirmative-close click" or "that was a negative-close click" or whatever. It could also be fixed by having a function dbox_registerOKbutton and dbox_registerCANCELbutton, which registers certain icons as returning OK or CANCEL "clicks" when they are selected. Allow a nice way of the program "pushing" a button... i.e. if the user presses RETURN, it would be nice if I could fake a click upon the "OK" button without having to resort to nasty nasty methods (basically changing the event structure into a click event, and then returning FALSE so that dbox thinks the event is unprocessed, and so processes it...). This would be very easy if you could have handlers for specific buttons, because then I could just internally call the handler... (This could be done with dbox_registerOKkey(keycode_RETURN); and dbox_registerCANCELkey(keycode_ESCAPE); - and let us register several keys, so for example, return OR enter can be pressed, or escape OR delete can be pressed) Added functions to specify *how* the dbox will pop up: #define POPUP_CENTRED 1 #define POPUP_ONCARET 2 #define POPUP_ONPOINTER 3 #define POPUP_ONMENU 4 #define POPUP_ATLASTCLICK 5 and use it as follows... dbox = dbox_new("myerror"); dbox_popup(dbox, POPUP_CENTRED); /* Error box appears in screen center */ dbox_show(dbox); -This way, you can have error boxes always centered on-screen, or centered under the mouse pointer or over the last caret position, or hanging off a menu, or appearing where you clicked on the menu to pop it up (if you click on a menu item instead of following its arrow, the dialogue should appear under the pointer, not 3 miles to the left where it was placed in the template editor...) Another useful one would be able to specify "Centered over window", and give the window handle as an argument, so that the dbox appeasr over the top of the given window wherever that window might be at that point in time. It would be nice to have handlers for all the "special" windows that are used in RISC OS. You already have saveas, etc (see complaints about *that*, below), but what about the "print" dialogue box, a standard for a preference window (e.g. Impression-style preference window is a scrollable pane on a base window, which takes a fair bit of handling... code to pop up 2 windows like that and keep them together when dragged, etc. would be nice) Also, query boxes, save boxes, and the like, that you can attach event handlers to (I want to use 3-d icons and change the pointer shape depending on what icon the pointer is over) Also, a VERY VERY VERY VERY GOOD idea would be to have a set of error-reporting dialogue boxes that MULTITASK. That is, while the error report is up, OTHER PROGRAMS GET TO KEEP RUNNING, and even other parts of this same program keep running. I don't know why, but I think the standard Acorn error box is utter trash. It would also be nice to be able to include a template for the error box so that a nice-looking error box could be used. It would be very useful in the cases of dboxes popped up from menus to know if they were created by going over a menu-arrow, or clicking upon the menu item... -A new set of button types handled by the dbox manager would be good... for example, sliders (as used in the task manager memory displays) can be implemented as 2 icons, and if a standard was made, the programmer could simply call dbox_installslider(dbox, backicon, fronticon, &sliderhandle); and use dbox_setslider(dbox, sliderhandle, 50 /* =50% */); and percentage = dbox_readslider(dbox, sliderhandle); to set and read the position of the slider. -Not low-level WIMP routines, but they would present an interface that to the programmer seems like any other icon primitive... and also would give Acorn more control over how sliders look and work. Oh, and perhaps a flag with the installslider() function to say whether it should slide up and down, or left and right, and also whether it is a marker on a position (a volume slider, with a fixed-size moving icon in the middle) or a bar-graph style (task manager memory bar) thing (with an icon which is fixed on three sides and the last edge can be dragged to change it's length/height) Also, it is common to have an option button icon with a writeable icon as a pair... when the option button is OFF, we want the writeable to be shaded, and when it is ON, we want the icon to be active. If we were to tell dbox the icon numbers of these 2 icons, it could automatically handle altering the shaded-status of the writeable whenever the option button is clicked, and ALSO, if the user clicks in the writeable when it is shaded, turn ON the option button and activate the writeable. Also, placing the caret into the writable, and removing it from the writable as it is activated/deactivated would be good. -This is reasonably simple to do... I have done it in DSEdit II, and I am happy to give you my source code if you want... (And also, the response on an ARM-2 is still nice and fast, so there are no problems in that department) It would be nice if dbox didn't crash if you try to open a window containing an indirected sprite icon (At first, i wondered why you would *need* FileIcon(), but that soon became clear...) Handlers for radio-button groups would be nice... I use a simple grouping of sequential icon-numbers, but ESG numbers could be used as a better method, to do routines like: dbox_setradios(firstradio, lastradio, radioon); -which unselects ALL icons between firstradio and lastradio, and selects radioon (i.e. turns on one of a group of radio buttons and ensures all others are off) whichradio = dbox_readradios(firstradio, lastradio); -which returns the icon number (or perhaps a value 0, 1, 2, 3...) of the currently selected icon from that group shaderadios(first, last); unshaderadios(first,last); -which (un)shade whole groups of icons in one go -Once again, all routines that I have coded up for myself, because the libraries don't supply them for me (even though they are very common and useful functions) Better handling of the caret would be nice: dbox_setcaret(dbox, icon); -which places the caret AT THE END OF THE TEXT in the named icon, and icon = dbox_getcaret(dbox); It would also be quite nice if dbox_fillin placed the caret AT THE END of the text in the lowest-numbered icon...Sometimes it doesn't seem to do this very well. (i.e. it doesn't always find the END) draw ==== It would be nice if this worked. (Yes, I know the versions YOU get to work with all work fine...) event ===== How about registering event handlers for specific events for specific windows... The main use I want this for is when the user is dragging in one of my 20 windows, I want *THAT* window *ONLY* to get null events. That way, when I start the drag, I simply use event_addNULLeventhandler(windowhandle, nulleventhandlerproc, handle); and then I can have a handler specifically for that type of window/drag combination to updte the selected region or whatever... It would be nice to be able to register "users" of null events, functions that are called on every NULL (so ALL NULLhandlers are called EACH NULL poll, or (optionally) each handler in turn is called on each successive NULL event in a round-robin fashion). Thus, by registering a handler, NULL events are automatically enabled, and when all handlers have been deregistered, NULL events are again turned off. I have about 7 bits of code (which all handle up to 32 windows, so potentially over 200 NULL event users to keep track of) in DSEdit II that all hang off NULL events, and trying to keep track of whether NULLs are still needed is a nightmare! Also, I envisage a basic event handling scheme as follows (probably repeated elsewhere in this file, but I'll be on the safe side): event (or somebody - whoever polls the wimp and works out which window to pass the event to) supplies a basic wimp_Poll event dispatcher. This sends the event to any concerned windows, and if it receives back a FALSE (event not processed), it then goes into it's OWN event handler, which simply has a sensible default for each event: wimp_REDRAW: do a "blank" redraw (this means don't draw anythig in the window, which gives you a blank window, but at least the desktoip doesn't lock up) OPEN WINDOW: Open the window. This means if the programmer forgets to add this bit to his/her handler, the window will still be movable. CLOSE WINDOW: Close the window. Windows will then always close even if the programmer forgot the handler. etc. Also, a little bird tells me that you do a sequential search through a list of active windows trying to match window handles when you want to find the window an event should be passed to. Put this kind of code into a multi-document editor and you are asking for trouble... (When I delete a window, is it's handler still left on the list? i.e. do I have to remove tha handler myself, or is it done automatically?) Surely this list could be implemented as a binary search tree (look up "heap" in a data structures book to see how to do this inside an array), which would be much faster for lots of windows? help ==== It may surprise you to learn that some windows use more than 10 icons, so it is very annoying to place such an illogical and badly designed limit of 1 digit on help tags for dbox's. Why does help_dboxrawevents place such a moronic limit on the number of icons? Surely you have to go out of your way to place such a limit? Why not use code like: /* example: tag_base = "SAVE", so want "SAVE", "SAVE0", "SAVE21" type tags */ sprintf(tag, "%s%d", tag_base, icon); message = msgs_lookup(tag); /* ... and send help reply */ ...it works fine for me. (OK, so there has to be one little check to decide whether or not you just use the base tag: If there is no icon under the pointer, OR if there is no help for that particular icon, which involves checking if msgs_lookup() returns the tag as passed to it, in which case the message wasn't found... that is what I do, and it works beautifully... Icon #52 gives help, and icon #47 (which has no help) and empty areas of the window all just return the basic default help message for the overall window) --- This is sort of a digression from Desktop C, but we really need a *good* help system... Another useful thing would be to write a small module along the lines of !help that uses a new system - On startup, an application registers itself and its help-message file with the module. The helpmessage file contains all the information needed (in a tagged format similar to SrcEdit's language-help multi-line-per-tag format) to produce help and error messages for the application. When the application receives the new helpmessage, returns, instead of a help string, a help tag, which the help module displays as per normal help. This means several good things can be done: -More than a pathetic 4 lines/200 bytes of help can be given -Advanced format could be used to show a sequence of drawfile "pages" perhaps with cross-indexing. If the application generates an error, it calls a SWI or similar (which does not return to the app. until the error has been acknowleged by the user), which pops up a MULTITASKING error box showing a report generated from the error tag (if no tag is given, the app. can pass in an os_error, so "unknown" errors (ones for which tags don't exist) can be reported as normal. This "error" window can then have an EXTRA button, "more help", which, if pressed, can bring up any extra pages of help that the application has provided in its helpfile (or any Operating-system help automatically generated for common errors by the module itself.) For example: Error reported: "Could not save file '...'" -User clicks "more help", and the following comes up: The file '...' could not be saved to disc for one of the following reasons: a) The copy of the file on the disc is locked -Go to the filer, pop up the menu over the file, and... b) another file or directory of that name already exists -Try saving with a different name c) The disc is locked -If it is a floppy disc, remove the disc from the drive, and push the write-protect tab in the back left corner until you can't see through the hole. d) The disc could bot be found ... This would be extremely useful for the user, and could also be written to allow the programmer to add a buffer of debugging information, or information for the user to report back about the problem, etc. And wouldn't it be nice if all that text came up nicely laid-out as a drawfile page (or pages) just like the manual... Other advantages of this is are: * A global system help file can be provided, detailing the common errors, and help on any operating-system menus/windows, etc. -This would also centralise the help database (perhaps compression could then be applied) * having registered a help-file with the help module, an application continues on merrily, and DOESN'T HAVE TO LOAD in all it's help data, which for good help can be hundreds of kB. Instead, the module handles the help, and so if the user has help turned off, they gain a lot of memory. This will also improve the loading-time of applications, as they won't have to load all that extra data (even if not being used, the data has to be loaded) * The help files can be slaved off disc (common help items such as help on menus and icons can be loaded in on startup, but extra help, and error help can be slaved from disc when needed), so more memory savings can be made. --- magnify ======= See "saveas", below... basically, the code is not generic enough to allow any slight changes to the window (like 3-d icons, for example) It would also be nice if minimum and maximum magnification values could be set: Allowing any value between 1 and 50 for the "mul", and 1 to 9 for the "div" is OK, but I would like to be able to say "don't let the overall fraction fall below 1:4", which would allow 2:5 and 3:7, without allowing 1:9, etc. (i.e. limiting the divide parameter on it's own does not limit the fraction to any small number at all... it would be nice to say 1:10 is the smallest value that is allowed, but still allow 95:948 type values to be entered. menu ==== Language independence: It would be nice if menus could be constructed using msgtrans tags, and have a decodemenu() function that returned the original tags. That way, the menu could be reorganised externally (i.e. editing a text-file definition, or using a menu-template-editor) without the program falling over because the items are now in a different order. (In english, we can check for "amplify" and not need to know that it is menu item 3.5.1 or that it is "edit.amplitude.amplfy" or anything, but what happens when you change the menu text for the item into german? Currently, you lose the ability to change the positions of items in the menu... if tags were used, however, the tag-based menu definition could be totally reorganised and the program would not have to be changed to actually work with the new menu. (I am a big fan of users being able to reconfigure the application by editing templates, etc.) If a menu is popped up from the iconbar icon, menus_ does a good job of putting the menu in the right place (using the calculation, y= 96 + 44 * number_of_menu_items) However, if you put a dotted line under a menu item, this adds another 24 os-coordinates of height onto the menu, and it appears in the WRONG PLACE! (Read your style guide, guys - the menu is supposed to always appear in the same place, isn't it? ;-) The calculation to get this right is simple. Perhaps this has to do with the fact that nobody wanted dotted lines in draw, edit, or paint, so it didn't seem worth the trouble? Why don't you try to write more generic code, please? It's not difficult... and it makes everything so much nicer, better, etc. (Mind you, the strain of *thinking* beforehand is a bit high... ;-) Needless to say, I removed baricon from DSEdit II (after replacing its functionality completely my program !Runimage was about 1k smaller than it was using baricon), and wrote my own code to pop up the main menu. Now, my main menu pops up in the right place, despite having a dotted line in it. However, to get this to work, I noticed the following odd things: There is no menu call to SHOW a menu! It just assumes you have an event_attachmenu{maker} doing all the work for you, and gives you NO WAY of showing a menu! So what if I want to attach a menu to my iconbar icon or to any single icon in a window? I have to re-write the code from event_attachmenu{maker} for myself. There is also a very odd discrepancy with menu hits: The WIMP returns a block of menu hits as an array of int's. Each integer has the value 0,1, 2, etc. The menu system (under event_) returns an array of char. Each char has the value 1, 2, 3, etc. This leads me to the beleif that every time you get a menu hit, you watse bandwidth on what appears to be a meaningless copy-and-add-one-and-cast-to-char loop. WHY? This simply means that I can't interchange my menu handlers easily - I have to alter them to get them to work, which was unnecessary and annoying. -I understand (having just written code to do this myself) that on a MENUWARN message the WIMP doesn' pass back everything in a nice array, but why depart from the numbering scheme and int-array passed by the WIMP? Also, the menu hit returned by event_ when it calls your handler doesn't (to my knowledge) give me ANY way of telling whether the menu hit was a result of a click or movement of the pointer over the arrow. (This results in my dialogues appearing nicely next to the menu if you go over the arrow, but appearing in the templates-defined-position if you click on the menu item. This position is quite often nowhere near the menu or pointer or associated window. Also, event_ does it's darndest to stuff me up. I found that if I created the main menu, it worked fine, but as soon as I opened the menu for a window via the event_ attach mechanism, good old event_ decided that the main menu *I* had popped up must be one of its menus, so my 4 main-menu items called the routines for my first 4 sample menu items! And it does this BEFORE passing the event to me, so I don't get to know about it! Arrrrgh! Why doesn't event_ KNOW when it is (and ISN'T) resonsible for a menu? Because nobody at Acorn thought that anyone would want to create their own menus once they had seen how wonderful event_ was? Because event isn't clever enough to automatically remove the handler for a window that no longer exists? - I suspect this is the case: the library seems to be very good at allocting things automatically, and then leaving it as an (impossible, usually) exercise for the reader to deallocate them - see template for more about this. I find if I click on the third item of my menu, causing an error (the sample I'm trying to interrogate is no longer there, because the wrong menu code was called by event_), then this somehow tips off event_ to the fact that its menu is no longer open, and then my main menu comes back to me! If I call event_clear_current_menu() before opening my main menu, the same thing happens. If I call event_attachmenu{maker} with 0 when I close the window, it fixes the problem so long as no windows are open when I open my main menu. So I was right: attached menumakers aren't cleared when their attached windows are closed. This would be fine except there is NO DOCUMENTATION of this fact in the manual that I can find. Though this *still* leaves me with an incorrect menu while any sample windows are open... Oh, well, it seems I have a choice between a correct main menu (by writing everything myself), or an incorrect menu using event_... Well, I'll just go write all my menu code, then... (why was all this necessary? Oh, yeah... that's right, I wanted to have an icon on the iconbar that only took about 60 bytes of !Runimage instead of 1088 bytes, and have a dotted line in my menu... What a rebel!) Well, I've spent an hour on it, and now I open all my own menus, and the following improvements have been gained: * My !Runimage is still about 800 bytes smaller than when I was using baricon * I don't have a blank function for baricon to call when select is clicked * My menu over the iconbar appears in the correct place, despite its dotted line * When menus are clicked upon, I send a different message to when their submenu arrow is followed, with the result that my dialogues all appear in the correct place now. This "waste" of time is typical of my experience of RISC OSLib - half my development effort goes into understanding and then throwing away and re-writing bits of RISC OSLib - not because they are awful, but because they just won't let me do small but important things. e.g. I REFUSE to NOT put dotted lines on my menus just because of bad design of the libraries. Needless to say, this effort would not be necessary if the libraries had about five more ARM instructions in them, and I would be twice as far on with DSEdit II as I am currently. msgs ==== I felt sure that msgtrans let you do parameter substitution, but I can't see it anywhere in msgs_ ... When the text for a tag can't be found, it would be *really* nice if msgs_lookup() let you KNOW about it (later: Ah! so that's what it does! Why didn't the manual TELL ME about that?). By the way, SrcEdit 1.13 doesn't have help for it's iconbar icon... I've edited my help file so that it gives the more useful "floobie the spotted cat" instead of "main5"... Now if msgs_lookup were to give an error, *that* one would never have slipped by your incredibly comprehensive testing, guys (sorry, I can't help the sarcasm when talking about Src-"Four new features and four thousand more bugs"-Edit.) resspr ====== It would be quite nice if, upon failing to find a sprite in the resource area, the libraries would have a look in the wimp sprite pool... And more than one resspr resource area would be nice... without me having to write all the functionality of resspr for myself from scratch - make resspr a more generic high-level sprite handling routine than a specialised icons-for-windows-resource-area saveas ====== Some hooks in here would be nice - perhaps being able to specify a dbox_raweventhandler (i.e. just be able to get a saveas window's dbox or window handle with e.g. dbox = saveas_syshandle();) I found it very annoying that I had to completely write saveas code from scratch just to allow 3-d icons or pointer-change while over different icons in my saveas window... (All I wanted was a flipping redraw event...) template ======== It is not useful to assume that the templates are in a file called "Templates" without allowing people to *not* use "templates". For example, I think it will be common to have files for RISC OS 2 and 3, or outline-fonts and non-outline-fonts, in which case 2 template files would be nice... In this case, it would be nice if: a) You could specify the template file name (template_init("RO3Temps")) and only use "Templates" as a default if no name is passed in. b) If the file "Templates" is missing, IGNORE it, rather than producing the error "Not enough room to load templates - increase wimpslot" which seems a little erroneous to me... It would also be nice to be able to throw away all templates that are currently loaded (so that a new set can be loaded via template_readfile) Also, a way of deallocating the space malloc'd for a template by template_copy would be kind of useful... i.e. then we would actually be able to USE template_copy(). I also found it very annoying that when you change screen modes (e.g. from 12 to 20), antialiased fonts don't keep their aspect ratio - this is a WIMP problem, but I could fix it if the template manager would let me re-initialise all the currently loaded templates (by then closing and recreating windows, I could fix the font problem completely)... but of course, that is completely private template manager data, isn't it? If you would even give me a function like template_return_head_of_template_linked_list(); I could munge through the templates myself and fix the problem... txt === Throw it away. It's big, ugly, and as Edit proves, it doesn't work. (Though if you could fix it *and* make it work inside all writeable icons, it might be worth keeping) visdelay ======== Why not call these functions Hourglass_... as they are simply a frontend for the Hourglass SWIs? No, that might confuse people... werr ==== A MULTITASKING error box would be nice. (Sorry if I repeat this one, but I feel it's important) wimp ==== Apart from the abortive attempts at naming, this isn't too bad (mainly because it's based on a very good set of SWI calls) a wimp_get_wind_info() that doesn't expect you to allocate space for the icon-data "overflow" would be nice (I've written one, and it's really very easy...) All you need to do is grab enough memory for the window + icons, and then memcpy the window part of the data into the user-supplied data structure. It's very nice to be able to just get the window info without having to worry about the hassles of the icon space... And it is very common to want this window info... High level functions for some things would be nice: ForceRedraw an entire window, for example, or SetCaretPos to a simple window,icon position without having to fill out endless reams of forms and red tape. Functions to start drags of icons (e.g. save-as window file-icon) just to save a lot of effort every time you want to do just that... DSEdit currently uses my function to do this in about 20 different places... functions to fill in basic details of structures for you would be nice... like a "start a drag limited to within this icon/window" function, which fills in the parent-box of the window for you, "drag starting from this icon/window" which sets the initial-box... Methods for attaching handlers for specific events would be nice... I *hate* "Unknown events"... Why not just have a "NULL event handler" (see dbox, above), a "keypress" handler, a "help message handler", an "import/export message handler"... I think it's stupid to have to handle a load operation due to a drag to my icon in a completely different part of my code to the place where I load because of double-clicks. -What I envisage as being a really nice way of handling events is this: The Library suplys a basic event handler similar to this: switch(event.type) { case wimp_EOPEN: /* actually, event_OPEN */ Wimp_OpenWindow(...); break; case wimp_ECLOSE: /* actually, event_CLOSE */ Wimp_CloseWindow(...); break; case wimp_EREDRAW: /* actually, event_REDRAW */ { BOOL more; Wimp_RedrawWindow(..., &more); while (more) { /* do nothing */ Wimp_GetRectangle(..., &more); } } etc. ... } -i.e. an event handler that supplies a base level of event handling. For example, if I have a window that needs to be redrawn by my program, I can shove it into my program and it will work even before I have written redraw code for it, because Acorns Libraries already supply a base redraw level (nothing is drawn, but at least the computer doesn't appear to hang, as is normally the case) This is backed up by: - An optional user-supplied event handler. This is just a simple, raw event handler that handles ALL events (whether specific to a given window or not). This is called and returns TRUE if it handles the event, or else the event is passed on through the chain until it hits the default library handler as above, and actually gets dealt with in a "safe" fashion. - Window/Icon event handlers. Any window-specific event is passed to any registered handlers for that window. Perhaps (preferably) this will also include handlers for any events directed at specific icons as well. These both return TRUE/FALSE to indicate if they handled the event. - Specific event handlers. These handle specific events or groups of events. For example, I could register 3 NULL event handlers (one for a drag, and 2 for animation updates in two seperate windows, or example), and then every time a NULL EVENT comes in, it is passed to ALL three handlers (or optionally passed to the first handler, the next NULL passed to the sen\cond handler, and so on to give a round-robin scheduling of "background tasks") These event handlers will be called as follows: (stopping as soon as a handler returns TRUE) -Wimp_Poll returns event to library code. -If there are any specific handlers for this event, call them. -If the event pertains to a specific icon, and that icon has a registered handler, call it's handler. -If the event pertains to a specific window, call its handler. -If there is a general user event handler, call it -If the event has still not been processed, use the library handler code to deal with it in the safest basic fashion (i.e. empty redraw loop, ignore incoming messages, open/close any windows that need it, etc.) This gives enormous power over driving the program through events (and is the way in which *real* event-driven WIMPs like X-Windows operate), and also gives a default level of support that means a user-program can open, move, redraw (blank, but at least survive the redraw), and close a window without having *any* handler code built in to it! -If any event ever "falls through" the user's code, there is *always* a sensible default action to deal with it. Also, the default handler can go one step further for some things. For example, if a helprequest is received, use the icon number plus the name of the TEMPLATE from which the window was created to generate a msgtrans tag for the help text to return. Thus, on a save_as window (template "xfer_send"), the default action would be to send help to !help from the message in the messages file tagged "xfer_send12" (for icon 12), etc.) (and if msgs_lookup() worked properly, this could be made to not give help if it is unavailable instead of plurting out user-friendly tags!) wimpt ===== Well, here's an interesting mishmash of totally unrelated calls bunged into one module... How about putting the screen stuff into a module called "screen" (see below...) And how about making the error boxes MULTITASK? (have I mentioned this one?) Why should we have to call wimpt_checkmode() on every redraw, when YOU are handling events, and YOU could call wimpt_checkmode() when YOU get a mode change event? (Why is the stuff I want to get at all hidden away, but the stuff I don't want to know about I have to specify in infinite detail?) win === Fix the event handling as suggested in event and wimp, above. At least give a way of claiming idle events that works nicely (Add an idle event handler, it automatically turns on idle events, and passes them to the handler. Several handlers can be added if you need to do several different things on null events, which you do if you really want to multitask. When no handlers exist, turn off null events again.) Chuck the whole concept of unknown events. It sucks. (Or AT LEAST, call them by a sensible name like "Application events", because they aren't UNKNOWN, they simply aren't specific to any window) win_activeinc, activedec. Why on earth would anyone want their program to automatically quit if they close all it's windows. An exit(0) isn't too complex to do if you want to quit, and I certainly don't want my editor to go "ping!" and dissapear just because I closed an effing window... (I think these are just silly, but leave them in by all means :-) The most annoying thing is that when you realise you can reduce your code size by 1k by removing baricon(), your program suddenly decides life isn't worth living (I don't blame it, the poor thing is contaminated by certain library code), and quits. Why? Because somebody thought it would be useful to make your program go away if it didn't call a function every time it starts up. What does the function do? Well, it adds bloat to your program, takes some time up checking every time you open and close windows, and makes your program quit when you don't want it to. And why does it do this? Don't ask me, I can't see a single use for the bloody thing. I still think calling exit(0) once is a simpler way of quitting your program than trying to kill off all your windows... I mean, either you KNOW that you want to quit, in which case exit(0) is a very tidy nice way to go, or you don't know, in which case it should be up to the programmer to keep track of how many active windows they have. Or at least give us an option (two versions of win()?) so that we don't have to compile this bloody useless code into our applications. Give us the OPTION. win_settitle(): Don't tell people (in the manual) to copy the template so that titles can be independently changed: this means that huge quantities of memory get irretrievably chewed up by the template manager, and after opening about 20 windows the program dies as it runs out of memory... Gee, I guess that's more code you force us tp put into our programs which we can't ever use, isn't it? xfersend ======== Can't it clear its own unknown event processors? I suppose it can't... Maybe you need something like a way of registering event handlers for, oh, load message events, and xfer message events, and null message events... see wimp for details... This complaint is repeated below under SrcEdit (and Paint, and Draw), because these programs all use RISC OS Lib, and so the bug appears in ALL of them. When a save or load of a file is made via , xfersend/recv THROWS AWAY the leafname (or previous pathname) of the file, and replaces it with "". This is STUPID. The filename does NOT designate the file itself (in fact, it designates an extremely unsafe place to put the file), it will fall over if you subsequently drag the file somewhere (thus getting a filename like SCSI::4.$.directory., it will confuse people who don't know what is, and it is BLOODY ANNOYING, because after saving my sound sample into Edit so I can check the header information (ok, so maybe not the most common use, but it aplies to ANY Wimp$Scrap transfer), my sound editor has changed the filename from "SCSI::4.$.sounds.samplename" to "". If I remember correctly what I have read in the style guide, the name is not supposed to be changed if it's only a temporary file ("file is not safe") Anyway, WHATEVER the case: 1) Wimp$Scrap should NEVER appear as part of a filename from the user's point of view: It is messy, ugly, confusing, and potentially hazardous (if I save a file to edit via Wimp$Scrap, and then just hit "save", expecting it to go to disc, then I will not have saved a "safe" copy, even though I think I have) 2) It is *INCREDIBLY* annoying to have your file, named "floobie", changed to "" *just* because you gave a copy of it to another application. Losing the from-disc pathname is bad enough, but the leafname is THE NAME OF THE FILE, so even IF I give the file to another application, I EXPECT the LEAFNAME to come through intact. 3) If a file is loaded into an application, then it makes sense to give it the leafname from the DataLoad (or whatever) message rather than some default like "TextFile" or "". The thing is that the application KNOWS what the correct leafname is, but because the subsequent transfer is via a file called , it decides to take the easy way out, not remember the originally requested name, and uses instead. I also *hate* having to code around these stupidities in my own programs just to get a tidy interface. NEW FEATURES that would be useful: ================================= File functions. e.g. File size and filetype are quite common things to want to know about (you even say that in the manual), so why not a simple frontend (filetype = file_type(filename); filesize = file_size(filename);) to make life easier... I know I can write these for myself in 5 minutes (I HAVE already)... but that's what the library is *for*... it's supposed to contain all the common code functions that are *useful* to have lying around... And also the common code functions that can be SHARED by many applications to save space... --- Screen functions (under the name "screen" would be more useful than "wimpt") screen_width(); screen_height(); screen_xeig(); screen_yeig(); screen_dx(); screen_dy(); screen_bpp(); These could also be implemented as extern variables, updated by the screen code AUTOMATICALLY when a mode-change occurs (instead of this mucking about with calling wimpt_checkmode()). That way, being variables, they can be acessed nice and fast when needed, saving me from having redraw code that starts: { int dx, dy; dx = wimpt_dx(); dy = wimpt_dy(); ... ...And as you claim wimpt_dx() is faster than reading mode vars yourself, then it is *obvious* that you are using such variables internally... why not let us have *acess* to them? (without all this stupid function call overhead) --- Some more automatic functions (which really need to be in the WIMP) could also be handled by the libraries... Pointer-changing: When the mouse pointer moves over ANY writeable icon, it's really nice to have it change into a caret-pointer... At least some default pointer definitions (caret, resize, and menu, as in Impression/Interface, for example) could be supplied, plus functions to change the pointer to these shapes... Pointer_Arrow(); Pointer_Caret(); etc. far more user-friendly than "You give us the address of the sprite, plus the hot-spot coordinates, and we'll change the pointer for you" Auto-scrolling: When a mouse is being dragged and comes within "x" pixels of any edge of the window, the window should scroll automatically. If you are to get ALL programs to do this, you might start by making it a default feature of the libraries that is on by default but can be turned off if necessary. Note that if people set window maximum extents correctly (DON'T look at draw, edit, or paint for examples of this... they aren't correct... neither is the RISC OS 2 palette window... so tacky...), there can be no problems with this kind of automatic scrolling. (and if the programmer has to do something that causes problems, he can turn the automatic feature off...) --- And, of course, MULTITASKING error dilogues would be nice... CONCLUSION ========== As you can see, despite about 50% of Acorn's libraries being well designed and written, this is completely undermined by the fact that the rest is not. I would be perfectly willing to re-write or fix the bits which Acorn has stuffed up, except for the fact that everything is so interconnected that I would have to write almost the entire set of libraries from scratch just to be able to change one function in dbox...And although I could do this, I would like to earn some money and write my thesis sometime in the next 6 months... (oh, yes, I believe one person could write a large proportion of the functionality of Acorn's libraries in a year...maybe not including something as bloated and overkill-yet-still-unusable as txt, but at least a complete programming *base* that *functions*) So I have three ideas about how to get the libraries to a useable form: 1) Give this file to Acorn and wait for them to fix everything. Somehow, however, I doubt that Acorn are going to want to change all their function names because that might upset their clients... Despite the fact that it makes sense and will have to be done sometime -Well supply a "fix" of #defines, as mentioned above, or -Supply TWO versions of the library (or even better, now you can supply two versions of Stubs, which is an even easier and more compact (discwize) solution), the old version being one that will "be phazed out at a later date" and which "should not be used for developing new software products". You're doing it with the rest of the operating system, so why not do it here as well... 2) A group of Acorn enthusiasts get together and write seperate modules themselves, then combine their efforts to make one large library. This is good, but it seems a bit wasteful of the 5 years of labour Acorn has put into these libraries. This IS HAPPENING RIGHT NOW. I am working on it... I know lots of people are writing their own libraries out of desperation... I intend to send my code to Acorn for possible inclusion in the libraries, before I try to make it a compteing standard, but I can't vouch for the others... 3) Acorn kindly let people like myself get our hands on the source for the libraries, let us fix up Acorn's legacy, and then we give them back the code and they then give us a new, official library release. That way Acorn don't have to do or pay for the work, and although they don't have control of the way in which we do things, they obviously didn't have control over the way THEY did them before anyway, so they would be no worse off. Also, because we actually have to USE the end product, we actually know what needs to be done... And of course, if Acorn could vet what went into the final library, they could ensure a quality result at the end. (And possibly include sources for those portions which were not included as extra "bonus" code on the Desktop C release.) Personally, I think 3 is the best option, because it saves a lot of duplication of work in the areas where Acorn's libraries have been well thought out and written, but if Acorn don't help us, 2 is going ahead whether they like it or not, and they'd have even less control over the results... --- !SrcEdit ======== -!SrcEdit version 1.13 -Archimedes 410/1 with 2Mb -Oak SCSI card -Impression dongle (does this count? ;-) -No other expansions -Working mainly in multisync mode 78 (Impression 16-colour large workarea mode) Ok, here are a few things I have noticed about SrcEdit: Well, for starters, SrcEdit's screen update is *incredibly* flakey (for me). Within 5 minutes of using SrcEdit, I will notice at least one update problem. The most common one is that the left hand 4-pixel margin (the default margin) sometimes fails to redraw, so dragging windows across it leaves copies of bits of the window down the margin. By resizing the window a few times I can sometimes fix the problem... Also, characters at the 80 column mark (in my 80-column display width window) appear with 4 pixels (hmmm. same as the margin... fancy that) missing at the right (they fall 4 pixels under the scroll bar). Please either display the whole char, or wrap that car to the next line. Every now and then, character redraw falls over completely, and what you see on screen is nothing to do with what characters you are editing - press f12, return to redraw the desktop and a whole rectangle of text can change to reveal a line or something that was not showing before... Just the redraw is a line or so out, I think... Also, occasionally I load up a file by double-clicking, and I get half a window (20 lines of 80 columns) of garbage (random characters, including top-bit-set ones)... I freak out thinking that my file has been trashed, but if I close the window, and re-load the file, everything is fine. Twice, this has also popped up a window with about 4 lines of text from the file, a burst of "line noise" and then back to our regularly scheduled program... Basically, the redraw code has gone a *long* way downhill from the Edit I received on the applications disc with my 310 back in 1988... When you specify (say) 80 columns for the display width, SrcEdit doesn't get it right when you open a window (I have changed the templates to give a screen-height 80-column wide window by default, and set my edit options to always use 80 columns. I am running in mode 78). When a new window is opened, Edit sets the horizontal extent to 132 columns, and only "fixes" it to the correct size when the window is resized. (i.e. you click the fullsize icon, and the window leaps out to fill the screen, and then jumps back to 80 colums and finally the sausage fills the length of the horizontal scroll bar... tacky. If you could double-click a word in the Help window, and press f1 again, it would be good... I hate it when you read the help for (eg) printf, and it says "equivalent to fprintf". Great... now I have to alter my SOURCE CODE to say "fprintf" just so I can select something to get help on... A writable icon to enter a srarch string for help would also be useful (so I can just say "give me help on "fprintf" from a menu somewhere) Task windows under Edit work even less well than under Frontend applications... Try making a file with Edit running with: Prefix TaskWindow "amu" -name "Making DSEdit" -wimpslot 640k -quit and you will find that an Edit window pops up for the task (fine), but if you try to close the window ("Kill task and quit? y/n"), if you say "yes" (kill the task), then Edit SINGLE TASKS the make task until it quits (i.e. my machine effectively locks up for several minutes), and quite often the result of the compile on whatever file was in the process of compilation is corrupted as well, so I have to wait for the make to complete, but I also don't get valid output from the task. Under FrontEnd, when you close the window, the task stops IMMEDIATELY. If a task finishes (and quits as the above TaskWindow command does), then you can click select in the close icon of the window and it goes away. However, if you use shift-f2, a query dilaogue appears (This file not saved: are you sure you want to close it type message). This is very annoying, and completely inconsistent. Also, Edit is *very* flakey when it runs low on memory (at any time, but when using a task window:)... Occasionally, it manages to survive, and pauses the task until you can get some memory for it to run in... this is fine, except EDIT DOESN'T TELL YOU that the task IS PAUSED, so you sit there watching the screen like a dill pickle, waiting for the compile to finish... Again, FrontEnd puts (Paused) and (Completed) into task windows so you know what is happening, and this is very useful information. A better definition of what a "word" is (for double-clicking) would be nice. Perhaps even a way of specifying the character set that makes up a "word" and the "end-of-word-delimiter"? Or you could set these up depending on which language is set in the options. Basically, when editing C code, it is very frustrating clicking on "wimp_open_wind" and having it select "open_". open_is NOT a word in ANY sense, whether in the "select the whole function name" or in the "an english word" sense! Even in straight english text, double-clicking seldom selects a word... double-click on the "blah text, blah", and "text, " (yes, including the comman AND the space) is selected. And try the line above: clicking on the word text selects '"text, " (' (where the " marks are part of the line). OK, so you have decided that the space after a word should be moved with the word, so that english text works nicely, but it doesn't help if you include the next (rnadom_number(32)) characters as well, for ANY editing operation. Please can we have two strings that we can define? a word-content string, and a delimiter-string. Thus, for C, we can specify: word = "0-9a-zA-z_" delimiter = "( " and then function names will be correctly selected. If we use word = "A-Za-z" delimiter = ",.!? " (etc.) we can get english words, (NOT including the delimiter) or word = "A-Za-z,.!? " delimiter = ",.?! " and we will get the word including the first delimiter that is found. (Oh, and note that selecting the word plus delimiter is a very silly thing to do in the case of a quote of a close bracket, because if you have "the dog ran down the road pavement" and you double-click pavement to remove it, you will a) want to remove the preceding space (not selected, but that's OK) b) want to LEAVE the " where it is (is selected, a BAD thing) ) I also think that the idea of how the vertical scrollbar "works" is stupid. It doesn't give any useful information, it quite often goes wrong at the end of a document, it causes a lot more work for you & the wimp every time the screen is scrolled (so must slow down the already arthritic scroll rate), and it is completely inconsistent with every other RISC OS window known to man. As for dragging the scroll sausage: On an ARM-3 machine, you might feel that scrolling one line at a time as the sausage is dragged is nice (and I agree to some extent, because it's easier to keep track of where you are if the scrolling is smooth). BUT: I have tried this smooth scrolling on the A5000, and it still isn't fast enough to be usable. On an Arm-2 machine, what happens is this: You grab the scroll-sausage, and drag it to move up half a page (in any other application, that would be it, I would have moved the sausage to the right place with my practised hand, and I would be where I wanted to go) However, in SrcEdit, it startts to scroll... one line... the next line... incredibly slowly... The instinctive reaction is to drag faster, but nothing happens until... you hit the threshold, and Edit jumps up about 3 bloody pages. In frustration, you end up scrolling back down with the scroll arrow (3 minutes later you actually get to where you were going...) Even on a 5000, I found this incredibly irritating. Why write a very useful functionality into the WIMP, and then go out of your way in Edit to sabotage it? AT LEAST MAKE IT A CONFIGURABLE OPTION, PLEEEEEEASE! It would also be nice if Edit could work better on files not containing any line feed characters. This is more comoon than you think, and waiting for 10 seconds for a redraw before you can even get to the CR<->LF option is awful. Even worse is when you have to wait for 30 seconds for it to update 3 or 4 rectangles of the window... Why can't Edit check for characters 10 AND 13? And use them interchangeably? Well, that's not really the problem... the problem is that it hasn't been designed to cope with binaries and foreign text file, despite the fact that it is a very handy tool for browsing through them... Another very annoying thing is the way that Edit doesn't cope with Wimp$Scrap transfers. If you try for a RAMtransfer, but end up doing a Wimp$Scrap transfer, please DON'T set the NAME of the file to ! You still know the CORRECT leafname of the file, so DON'T replace ot with an operating system variable! This is ANNOYING, this is USELESS (saving "" sure as hell doesn't send it anywhere useful, and certainly isn't a good place to save a file for permanence..., this is STUPID, and also this will CONFUSE people who don't program Archimedes for a living. Along on the same tack, if you get a file called "floob" saved to you from another application, wouldm't it be sensible to give it the name "floob"? i.e. you KEEP the leafname you have been given, but it's up to the user to drag the file or enter the REST of the pathname when they want to save it, but AT LEAST *KEEP THE LEAFNAME* of the file. (And probably these two are due to bugs (call them design flaws if you prefer) in RISC OS Lib, so you will probably find them recurring in Draw and Paint and ...) (Oh, and if you were thinking "but that's how the style guide says to do it", then maybe you should think about fixing the design flaws in the style guide as well) And please, please, please, look it up in a book, use another computer, look at Impression, do what you have to, but PLEASE learn what the word "TAB" means!!! Edit doesn't handle tab (ASCII 9) characters at all. I could handle that if it made any sense... sounds like someone can't be bothered with the redraw problems... or maybe txt has design flaws (well, we know it has design flaws) that make it very difficult to do tabs... Anyway, "expand tabs" should give you an OPTION of how many spaces to expand by. Yeah, sure, 8 is the UNIX default, but even on UNIX, you can CHANGE your tab column width! And when you press TAB, characters should be INSERTED to move the caret to the correct tab position... I find the "go to the position of the next spoace in the line above" tabbing very useful in programming when my lines are all indented, and starting a fresh line at the indent level is a matter of pressing return and then tab... very nice... but if I move some text onto the next line, and then try to move it out to the indent position, I have to hit space 3 million (I exxagerate a little) times. How about an OPTION for doing that properly? And while about it, if the line above doesn't extend as far as the current caret x position, then please DON'T bump the caret back to ZERO! Look at the line above, and the line above that (perhaps stop the search 3 or 4 lines above), for a tab-position... That way, I can put blank lines between statements (or blank lines in tables), and still just hit TAB to go to the indent or the next column... Another very annoying thing is that while an edit window has the input focus, no control keypresses "get past" edit... I don't know about your source code, but I don't want to insert characters with ASCII codes < 32 into MY source code and textfiles very often... and when I do, I can still get around it with search and replace (which is already necessary for things like ctrl-L, because that is treated specially by Edit: If ctrl-keys are going to insert ctrl-codes into the document (an un-useful feature), then at least make ALL ctrl-keys do this, rather than just the ones which Edit doesn't have a specific use for!) This is not just a pain in itself, but is also VERY annoying when you have a hot-keys utility running (e.g. Menon), because I can't launch tasks with quick-key equivalents without a lot of hassle. A way of making edit pass on control characters would be nice. (It already does this with f12, so why not other useful-outside-edit-but-useless-inside-edit keypresses?) This applies even more so when you move onto a task window... I run a make task in an edit taskwindow, and while it is going, I hit f12 to get a commandline and NOTHING HAPPENS because EDIT swallows the keypresses. WHY?! If you *have* a taskwindow up, you might *still* want a command line... Please give us the OPTION of letting control characters through... especially when running non-interactive tasks in the window... And while you are about it, plonking up a task window when f12 is hit would be a reasonable replacement... (How come we don't get a multitasking command-line-in-a-window in RISC OS 3.00? All the code is there, so why do we have to stop the rest of the desktop from running and scroll up the screen in such a ridiculously toy-operating-system fashion? (and don't claim that the "New Task" writable menu is as good as taskwindow with scrollback, etc.) Throwback ========= OK. Well, for starters you must be using Edit's redraw code to redraw this, because the redraw keeps falling over... Edit definitely has a memory leak and I'm sure it is in the throwback window... after about 30 minutes of editing and compiling, I can quit Edit, and run it again, and I usually GAIN 64 KILOBYTES of memory! When you double-click a line in the throwback window for the first time, it takes AGES to set up (I presume) throwback pointers and things. (Even on an A5000, a 60kB source file (and yes, these are common) takes longer than for me to double-click the file, hit f5, type in the line number, and (quite often) fix the problem with that line as well... Also, if I load a file, edit it, and save it, the re-load it, the throwback lines are completely wrong (i.e. if I insert a line at the top of the file, all throwback lines after this become one line out of sync). Here is the best way to do thrownack lines: It is simple, requires less coding, makes less object code, uses less workspace, is much much much faster, and won't ever lose track of line (if written correctly, which is easy to do because it is a simple and straightforward procedure) Remember the line number of every throwback line (You do this already, so this is not a problem). Now, every time you insert a newline, you zap through the throwback list, and add one to each throwback line which is further on in the file than that line. Similarly, every time you delete a line, subtract one... For starters, this is very fast... Even if you have a huge list of errors (I would say 100 errors would be huge, even on a bad day I don't get more than about 20 from one compile), and it only takes basicall 1 processor cycle (ADD r,r,#1) to do the processing necessary... even if you take 1000 cycles for each add (including dereferencing, etc), that's only 100,000 cycles, which is approx an 80th of a second even on an ARM-2... which isn't too bad as an extra overhead for inserting a return, especially when compared to the redraw time, etc. And if the list is sorted (as it must be to appear in order in the window), then you save a lot more work, because you simply find the first line number greater than the current line in the list, and then process from there (so you don't need to compare all line numbers before you know whether you have to change them or not) So this will be very fast, as you can then get back to an "instant" goto when a throwback line is double clicked. Also, it is obvious that this method will require less source code, thus less object code, whicj is a good thing. And on top of that, it takes no workspace other than what the throwback window is already using, so you will probably save on workspace as well (when you remove your throwback pointers or whatever you are using) And on top of all that, I can then load and save the file as much as I like, and the throwvback will still actually apply correctly to the file I am working on. The throwback window could also be updated to show correct line numbers, (though this isn't necessary) so you don't have the problem of throwback window saying "error at line 120" but moving you to actuial line 76 when you double-click the line. Please, it makes sense, it should only take a short while (an hour?) to implement, and it will vastly improve throwback and throwback performance. --- Also, a useful option in Edit would be to display ctrl-characters inverted rather than in the format [01]. This is because then each character on screen represents one character/byte in the file, and it is MUCH easier to count characters and judge how far to move, etc. Edit is actually very useful as a binary editor, despite attempts to make it unsuitable (e.g. incredibly slow update if there are no LF's for a long time, making some characters take 4 "spaces" on screen ("[01]"), and others taking only one "space" ("A"), etc.) Another very useful option would be a "global search" which can be done on all (text) files in a certain directory. (basically an fgrep). That way, when you want to find all calls to baricon in your .c files (so that you can remove it and replace it with a call to some well written code, of course ;-) All you need to do is hit f4, turn on an option button, drag the directory "c" to the window, and do a "normal" find & replace. -This ideally should be done by having a "project" with Edit, so that edit knows that a set of text files (perhaps spread all over a disc, not just in one directory) are related, and are to be treated as a group by any group-options (such as search project for..., save all files in the project, etc.). Then you could even do stuff like double-clicking the filename in a #include line (e.g. "mywindow.h" to get "mywindow" selected), and then open that file in Edit just by hitting a key. Or even more useful, a Think C editing aid: double-click a function name, and the actual function code will be found. OK, so edit is a multi-language editor, but putting special-case code for C, pascal, and assembler would take very little space, and make it MUCH better. --- Also, if you click adjust on items in the throwback window, they are removed: very nice. Could you also remove titles for files if there are no throwback lines left for that file? I have also noticed that long pause when you double-click for the first time in the throwback window (calculation of pointers or whatever) comes back if I cllose the related text file, and reload it EVEN if I use Adjust to remove all but one of the throwback lines. This suggests to me that lines removed from the display are not removed from the throwback memory. Oh, and a general comment about "query" windows... (this also applies to Draw, paint, etc) If you close a window in edit and the file hasn't been saved, you get: "Do you want to save..." [yes] [no] but if you try to quit: "2 files edited but not saved. Do you wish to quit?" [yes] [no] ...so in one case, "NO" means "DISCARD" and in the other case "NO" means "DON'T DISCARD" GET YOUR ACT TOGETHER! (please) EITHER: Make YES always mean the same thing (i.e. "do you wish to discard the changes?" for the first case, or "Do you want to save them before you quit?" for the second OR: Change the text in the icons to help the user decide what to do: [SAVE] [DISCARD] and [QUIT] [ABORT] OR: Do BOTH of the above. This way, the user doesn't have to read the message, ruminate for 30 seconds about it's meaning, decide on a course of action, and then work out which button applies to that course of action. When I quit Edot and it pops up the query dialogue, I *KNOW* that it is because something is unsaved. I *KNOW* whether I want to quit or abort, but I sometimes lose changes or fail to quit (both very annoying and timewasting) simply because I failed to read the dialoguie box correctly. If the dialogue box was designed correctly, I would be able to say "I WANT TO QUIT", by clicking the "QUIT" button, and I wouldn't have to read the text message, because I already know what that is telling me... And if the default action is always the same, then I can take it without a second thought and always get it right (i.e. if the left button always means "discard all changes" and the right means "save the changes", then I will always get the right effect, whether the actual meaning is "quit and discard" or "close and discard" or "don't quit (so don't discard)" or "save (so don't discard)" --the DISCARDING is the most important issue, as it is the most dangerous thing: if you fail to quit when you wanted to, it's a hassle, but if you accidentally lose data, it's VERY VERY BAD! Another really handly thing would be if (Src)Edit were to scroll the window if you try to drag out of the top or bottom of it. It is *very* annoying having to stop the drag and go to the scroll arrow and scroll down one or two lines and then go back and continue dragging with adjust, and it is very simple to auto-scroll the window. Make ==== Well, throw it away... it's faster and easier to type a makefile in edit than to use the interface for Make... Why, for example, do you have to choose targets with a silly little clickky up/down icon... what about being able to pop up a menu of targets instead? Much easier, more convenient, and you can see the whole list of targets. And what about buttons to add standard things like Stubs and RISC OSLib automatically to the project? And why, oh, why, can't we click menu over an item in the "list members" window? When I have just deleted a source file, I shouldn't have to type in the files bloody pathname just to delete it from the makefile. Actually, it's quicker and easier to use Edit. And why not have a way of closing the make window "Project: name" and simply clicking select on the iconbar icon to bring it back? And why not design the template nicely so that "Make", the default option, is on the left, and "Save" is on the menu where "Save" is normally found? Gordon bennet! And these people have the nerve to tell ME about infringements against the so-called "Acorn style guide". pah! Actually, Acorn could improve their interfaces drastically if they actually FORCED their programmers to USE the software they produce...(I can't beleive that anyone who wrote cr*p like !Make would actually beleive it to be nice enough to use) ObjSize ======= I just tried to run !ObjSize. I gave it a "Next" slot of about 500k. It grabbed all available memory, and then complained that it couldn't get enough memory for the taskkwindow output. I retried with more memory (by quitting Edit, and dropping from 192k mode 78 to 40k mode 76. I gave it a larger "Next" slot, reserving about 100k to ensure there was some free memory. I ran !ObjSize. It grabbed ALL available memory, and then complained that there wasn't enough memory for the output again... I dropped to the command-line and typed "ObjSize ...", and it worked fine... *THIS* is one of the 500 or so reasons why people don't like the DDE. It's simply a very bad frontend for good CLI utilities. AMU === Well, it's obvious that nobody working at Acorn has anything less than 8Megs of RAM in their machines... amu runs in *my* taskwindow quite happily in about 640kB (For *big* projects like UMoria, about 800k is enough), so why is the default wimpslot for amu 1024k? -I can't see any reason to need this much memory (as I said, 800k is the most I've ever needed) -1024k is NOT enough to make link go as fast as possible (well, with a 1Meg slotsize, it still gives *me* the low memory warning) -1024k is enough to cause serious problems on a 2Meg machine (and believe it or not, there are some "Acorn developers" who can't afford 8 Megabyte Arm-600 300MIP machines) But don't worry about it, because I've already thrown !amu away... *THIS* is one of the 500 or so reasons why people don't like the DDE. It's simply a very bad frontend for good CLI utilities. Link ==== Is there some way of turning off the stupid "Not enough memory" warning? I know that I only have 2 megs in my machine. I also know (by experimentation) that I *CANNOT* give it a large enough slotsize for this error to go away, even if I only want to link a few bytes together. This means that on a 2 Meg machine, you *always* get the warning, so there is absolutely NO POINT in the warning. How do I turn it off? -- _________________ /____ _ _/_ __ The Master of the Arcane jwil1@cs.aukuni.ac.nz // / //_//_ /_/ Smileys ;-) indicate humorous or sarcastic remarks