Thread: [Anygui-devel] A simpler API?
Brought to you by:
mlh
From: Magnus L. H. <ml...@id...> - 2001-07-02 08:21:46
|
Do we need a simpler API? Just a thought... My experience from the early days of Piddle development tells me that a simple API can be a good thing -- to get the project off the ground. If designed correctly, the small API may be extended at a later time, yet will be easier to implement quickly. And a working software package will probably gain more support than an almost-working one... Dissatisfied users are a great source of feedback and volunteer work <0.5 wink> Another advantage with a simple API is that it will work with backends such as htmlgui (HTML 4.0 based) which Alex has been thinking about. Maybe I'm off the mark -- maybe Greg's API (e.g.) is simple enough... (It isn't exactly complicated.) I just thought perhaps we could cut some corners wrt. (among other things) the menu setup etc... I'll try to think about what we _really_ need for a 0.1-release... I hope someone else will too :) -- Magnus Lie Hetland http://www.hetland.org "Reality is that which, when you stop believing in it, doesn't go away." -- Philip K. Dick |
From: Alex M. <al...@ya...> - 2001-07-02 10:42:18
|
"Magnus Lie Hetland" <ml...@id...> writes: > Do we need a simpler API? Just a thought... My Yes, for all reasons you list. But maybe we should also take a step back and evidence all the specific design decisions in Greg's excellent API, just so we are sure they're optimal for out purposes rather than just accepting them by default. Starting from the start...: > I'll try to think about what we _really_ need for > a 0.1-release... I hope someone else will too :) Right -- I'm doing so, therefore I put my reflections on the list for everybody to share and comment. One general reflection first... Greg's excellent spec is designed as stand-alone. anygui is intended to be often just a "cap" on some richer underlying GUI framework. Therefore, I think there must be *architected* ways for client-code of anygui to determine _which_ underlying GUI framework is in use AND gain direct access to the underlying-framework objects that anygui is internally using. This will enable an interesting usage pattern: program to anygui for minimal GUI functionality, fully portable and close to hassle-free -- then add nice-to-have tweaks if and only if the actual underlying is, say, wxPython (or whatever the client-code author knows well and wants to support first and foremost). I'm not sure of where this "query/access the underlying stratum" is best placed, architecturally -- global functions of a dedicated control module, probably -- maybe a property on each object returning an "underlying framework object" or tuple thereof. A given backend to anygui may respond None to such requests, meaning "I'm not gonna tell you (as there's nothing good you could do with it anyway)" or similar. But an architected way to pose the questions is what seems important to me right now. OK, now for some specific issues/doubts/objections...: A. why document/view? I agree we need some organizing principle in the overall architecture, but why document/view (or rather model/view) rather than the classic MVC (model/view/controller)? MVC isn't much more complex after all. I can live with doc/view, but I'd like to make sure this is a deliberate design decision rather than a "just-happened" -- I'm no GUI expert, it just seems to me that MVC buys you more for very little cost. To clarify, the issue is with e.g. this sentence in the tutorial: "Our View class will have two responsibilities: (1) drawing the blobs on the screen; (2) handling user input actions". Why should one class have two responsibilities, rather than splitting them -- have the View just care about viewing, and a separate Controller class to handle user-input needings mods to the Document? B. why accessors/mutators? Why foo() to read, set_foo() to write? (I do like the slight, very-handy redundancy of kw args for set in constructors and the .set() method). Why not just foo to read, foo=whatever to write? It's simpler and more Pythonic for the client and it's NOT a big trouble for us to have a single mixin class translating this Pythonic access-style to method calls in __getattr__ and __setattr__. I'm definitely -1 on the foo()/set_foo() choice -- and while I'm not a GUI expert, I _am_ an OO expert and have strong feelings in the matter:-). C. event handling Why not more uniformity between mouse-events, key-events and command-events? The latter should not be so tightly bound (conceptually, terminologically, ...) to menus. The highly-dynamic just-in-time determination of enabled status &c is cool for "local" interfaces where turnaround can be assumed "instantaneous from the user's viewpoint", of course. Although it can give problems for the DHTML implementation I had in mind, I guess it should still be kept, for simplicity's sake. Maybe (perhaps not in the 1st release) we could allow an object to state "please don't call my setup_menus() until further notice, here is what I think should be enabled/checkmarked in case you need to know". But back to simplicity -- if (command events) "are handled in a similar way to events", why the "are not explicitly represented as Event objects"? What if any is the down-side of uniformity of representation? And why are mouse-down events ignored if "the View object in which they occur [...] does not handle them", rather than behaving like others? Conceptual simplicity for the client-coder of the anygui interface would seem to benefit from uniformity here. Am I missing something? (I'm also thinking of model_changed "messages" from models to views, &c. Shouldn't all of these events be modeled rather uniformly...?) Specifically C1. Event should be generalized to model any kind of event, not _just_ mouse & keys. Properties which may not be determinable (where, when, &c) should be specified as None. Also, _which_ button was clicked (when there's more than one!) must be easily found, and of course so must "what key was pressed" for key events, and I don't see either of those clarified in the specs at Doc\Event.html. D. Application class D1. std_menu_bar(): I think we're missing Help as a standard command (and probably Redo; but I'm unsure about Revert, is that meant to be the Undo-latest-Undo command...? but apparently not, given revert_cmd in Document...). Hmmm, maybe SelectAll, too? D2. if we do consider Help standard, a help_cmd() method in the Application class to provide some minimal metadata about the app (name, version, author's email, &c) in an alertbox might be worth it (perhaps providing encouragement to client-coders to supply at least such minimal stuff:-) E. FileRef/DirRef Do we truly need these new abstractions...? Couldn't we do with something simpler/closer to what Python gives us...? F. Why not SPING for drawing? Couldn't we somehow reuse the riches in SPING/Piddle rather than having a newly-invented, albeit simple, drawing API? If the 'native' drawing API of anyguy's Canvas was specified as exactly coincident with what a SPING back-end must/can expose, wouldn't this be a big overall win? Client-code would draw with SPING (or whatever's on top of it), anygui's implementer could be lazy and get away with drawLine/Polygon/Image/String OR go hog-wild with quality... ...am I missing something...? Z. Tiny/nitpicky stuff (not worth discussing at this point but things I noticed and wondered about while studying...): Z1. shouldn't a RadioGroup always deal with lists of RadioButton? specialcasing everything so that a single RadioButton need not be passed as a singleton list seems misplaced, given that lists are the common case. Also, setting value to a value that is not of any radiobutton currently in the group should presumably be specified to raise ValueError and leave value unchanged. And what happens when remove is called for the radiobutton that's currently selected, or when two radiobuttons have the same value...? Z2. Action's 3rd case shouldn't be a generic tuple but specifically a tuple with 2 or 3 items -- a callable, then a sequence, then optionally as the 3rd item a dictionary of keyword-args -- surely this is more general and no less simple than a generic tuple (affording no way to 'curry' keyword-args) Z3. how does setup_menus guess which menu commands are relevant to the specific dropdown menu that the user is trying to dropdown...? It doesn't seem to me the MenuState object has that info -- am I missing something? Shouldn't a Menu object also be passed to setup_menus...? Z4. I think TextField should have a method for select-all rather than requiring: query text, set selection to (0, len(text)). Shouldn't there be a background-color possibility too? Z5. Shouldn't we have a standard Button-displaying-Pixmap class? Z6. Shouldn't ScrollFrame expose properties/&c to let client-code determine/affect scrollstate? Z7. I'm not sure I understand Frame.place -- is it just me, or is the spec confusing, or...? Z8. Shouldn't it be possible to 'disable' a button/textfield/...? Phew -- enough for now I hope... please everybody, feel free to respond to any subset of this big mail (next time I'll try to cut it into smaller pieces -- hadn't thought of that this time, and it's a bit of a hassle to cut it up now, so...). Alex |
From: Magnus L. H. <ml...@id...> - 2001-07-02 11:20:55
|
From: "Alex Martelli" <al...@ya...> > > "Magnus Lie Hetland" <ml...@id...> writes: > > > Do we need a simpler API? Just a thought... My > > Yes, for all reasons you list. But maybe we should > also take a step back and evidence all the specific > design decisions in Greg's excellent API, just so we > are sure they're optimal for out purposes rather than > just accepting them by default. Good point. > Starting from the start...: > > > I'll try to think about what we _really_ need for > > a 0.1-release... I hope someone else will too :) > > Right -- I'm doing so, therefore I put my reflections > on the list for everybody to share and comment. > > > One general reflection first... Greg's excellent spec > is designed as stand-alone. anygui is intended to be > often just a "cap" on some richer underlying GUI > framework. Therefore, I think there must be > *architected* ways for client-code of anygui to > determine _which_ underlying GUI framework is in > use AND gain direct access to the underlying-framework > objects that anygui is internally using. Hm. I agree with you, with the proviso that this is well thought-out... If this becomes an easy cop-out (or whatever one might call it ;) then the genericity of anygui may be lost... I guess (as with most things Pythonic) this can be solved by an appeal to people's sense of style. I.e. make it the "anygui way" to always provide a pure anygui alternative to your backend-passthrough tweaks... > This will > enable an interesting usage pattern: program to > anygui for minimal GUI functionality, fully portable > and close to hassle-free -- then add nice-to-have > tweaks if and only if the actual underlying is, say, > wxPython (or whatever the client-code author knows > well and wants to support first and foremost). Yes... I agree that this is a good thing. And it would probably remove some objections to using anygui. An idea: We could make some simple system/protocol for making pure anygui replacements for fancy "native" widgets, and collect them in one place (like the anygui distribution <wink>). Then, each time someone felt the need to make such a replacement, they could submit it... (I, for one, would like a tree-widget substitution... And a status bar... And...) > I'm not sure of where this "query/access the underlying > stratum" is best placed, architecturally -- global > functions of a dedicated control module, probably -- > maybe a property on each object returning an "underlying > framework object" or tuple thereof. A given backend to > anygui may respond None to such requests, meaning "I'm > not gonna tell you (as there's nothing good you could > do with it anyway)" or similar. But an architected way > to pose the questions is what seems important to me > right now. I guess so. It would be very easy to get this info from the anygui module/object itself... For instance: >>> import anygui >>> print anygui.backend None >>> from anygui import * >>> anygui.backend 'wx' Or something... (Of course "constants" like WX = 'wx' etc. could be defined...) > OK, now for some specific issues/doubts/objections...: > > > A. why document/view? > > I agree we need some organizing principle in the > overall architecture, but why document/view (or > rather model/view) rather than the classic MVC > (model/view/controller)? MVC isn't much more > complex after all. I was a bit puzzled about this as well... > I can live with doc/view, but > I'd like to make sure this is a deliberate design > decision rather than a "just-happened" -- I'm no > GUI expert, it just seems to me that MVC buys you > more for very little cost. I'm no expert either... And simply assumed that Greg was. > To clarify, the issue is with e.g. this sentence > in the tutorial: "Our View class will have two > responsibilities: (1) drawing the blobs on the > screen; (2) handling user input actions". Why > should one class have two responsibilities, rather > than splitting them -- have the View just care > about viewing, and a separate Controller class > to handle user-input needings mods to the Document? Yes... It seems easy to use this as well... class Component(View,Controller): ... rather than class Component(View): ... > B. why accessors/mutators? > > Why foo() to read, set_foo() to write? I was thinking about commenting that too -- I would much rather have __getattr__/__setattr__ stuff... I _really_ like Jython AWT/Swing "magic" like: f = Frame() f.size = (400, 300) :) [snip] > I'm definitely -1 on the foo()/set_foo() > choice -- and while I'm not a GUI expert, I _am_ an OO > expert and have strong feelings in the matter:-). Me too. (Not the expert bit, but the feeling bit ;) I think that was my only objection at first reading. > C. event handling > > Why not more uniformity between mouse-events, key-events > and command-events? The latter should not be so tightly > bound (conceptually, terminologically, ...) to menus. Hm. Swing actions are nice here... With names, icons, etc. etc. > The > highly-dynamic just-in-time determination of enabled > status &c is cool for "local" interfaces where turnaround > can be assumed "instantaneous from the user's viewpoint", > of course. Although it can give problems for the DHTML > implementation I had in mind, I guess it should still be > kept, for simplicity's sake. I'm not sure it _is_ that simple... In terms of implementation in other backends, I mean. But then again, I may just be a bit dense :) > Maybe (perhaps not in the > 1st release) we could allow an object to state "please > don't call my setup_menus() until further notice, here > is what I think should be enabled/checkmarked in case > you need to know". How would you represent that info? Or do you simply mean that we should have an advisory boolean variable as a filter before calling setup_menus? > But back to simplicity -- if (command > events) "are handled in a similar way to events", why the > "are not explicitly represented as Event objects"? What > if any is the down-side of uniformity of representation? Beats me. > And why are mouse-down events ignored if "the View object > in which they occur [...] does not handle them", rather > than behaving like others? Conceptual simplicity for > the client-coder of the anygui interface would seem to > benefit from uniformity here. Am I missing something? Don't know. I (as you may have noticed) like generality and consistency. I would like all events to behave similarly. > (I'm also thinking of model_changed "messages" from > models to views, &c. Shouldn't all of these events be > modeled rather uniformly...?) Hm. Probably. Reminds me of the JavaBeans framework where vetoing attribute changes is handled by events... But that may be stretching things :) > Specifically > C1. Event should be generalized to model any kind of > event, not _just_ mouse & keys. Agreed. This might (hopefully) make the API simpler too. I think it would be nice to have as few classes, methods, and classes as possible :) > Properties which may > not be determinable (where, when, &c) should be > specified as None. Also, _which_ button was clicked > (when there's more than one!) must be easily found, and > of course so must "what key was pressed" for key events, > and I don't see either of those clarified in the specs at > Doc\Event.html. Again, I just keep agreeing with you. > D. Application class > D1. std_menu_bar(): I think we're missing Help as a standard > command (and probably Redo; but I'm unsure about Revert, > is that meant to be the Undo-latest-Undo command...? > but apparently not, given revert_cmd in Document...). > Hmmm, maybe SelectAll, too? Hm. Maybe we should just leave this out for the first release? (Though transparent undo/redo handling would be _extremely_ useful, IMO. Perhaps we could integrate an action pattern with the event system? <0.6 wink>) > D2. if we do consider Help standard, a help_cmd() method in > the Application class to provide some minimal metadata > about the app (name, version, author's email, &c) in an > alertbox might be worth it (perhaps providing encouragement > to client-coders to supply at least such minimal stuff:-) Yeah... Perhaps we could link this to docstrings, or __author__ etc? (But we still might not need this for the first release, IMO...) > E. FileRef/DirRef > Do we truly need these new abstractions...? Couldn't we > do with something simpler/closer to what Python gives us...? Ah... There was the second objection I forgot. I guess these are tied with the Document system or something (i probably didn't read it thoroughly enough), but this is one of the things I find slightly annoying about some other packages... That they duplicate a lot of the features we already have. Makes a bad case for inclusion in the standard libraries :) > F. Why not SPING for drawing? I thought about that myself. And as one of the creators of Piddle, I would, of course, like to use it :) > Couldn't we somehow reuse the riches in SPING/Piddle rather > than having a newly-invented, albeit simple, drawing API? It seems like this new API is more or less a subset... Or at least closely related to PostScript. > If the 'native' drawing API of anyguy's Canvas was specified > as exactly coincident with what a SPING back-end must/can > expose, wouldn't this be a big overall win? I think so. Sping is more complex... But perhaps tying in with Sping could draw some interest to both projects? After all, the goal of the original Piddle project was very close to this -- making a generic API for graphic stuff. > Client-code would > draw with SPING (or whatever's on top of it), anygui's implementer > could be lazy and get away with drawLine/Polygon/Image/String > OR go hog-wild with quality... > ...am I missing something...? Nope. > Z4. I think TextField should have a method for select-all rather > than requiring: query text, set selection to (0, len(text)). > Shouldn't there be a background-color possibility too? Actually, I would really like to have styled text too... It seems that all of our backends can handle it... But perhaps not for our first release ;) > Z7. I'm not sure I understand Frame.place -- is it just me, or > is the spec confusing, or...? <ahem> I didn't even read all of it... > Z8. Shouldn't it be possible to 'disable' a button/textfield/...? Yup. > Phew -- enough for now I hope... please everybody, feel > free to respond to any subset of this big mail (next time > I'll try to cut it into smaller pieces -- hadn't thought > of that this time, and it's a bit of a hassle to cut it > up now, so...). Big mails are fine by me. This is a technical discussion, after all :) Another thing: Is the component layout system OK? I don't like coordinates much... (And I have gotten used to Java's layout managers, so I may be a bit biased...) > Alex -- Magnus Lie Hetland http://www.hetland.org "Reality is that which, when you stop believing in it, doesn't go away." -- Philip K. Dick |
From: Alex M. <al...@ya...> - 2001-07-02 12:16:27
|
"Magnus Lie Hetland" <ml...@id...> writes: ... > > *architected* ways for client-code of anygui to > > determine _which_ underlying GUI framework is in > > use AND gain direct access to the underlying-framework > > objects that anygui is internally using. > > Hm. I agree with you, with the proviso that this is > well thought-out... If this becomes an easy cop-out > (or whatever one might call it ;) then the genericity > of anygui may be lost... > > I guess (as with most things Pythonic) this can be solved > by an appeal to people's sense of style. I.e. make it > the "anygui way" to always provide a pure anygui > alternative to your backend-passthrough tweaks... anygui provides a small subset of what a rich GUI API like wxWindows' might supply. It may grow a bit in successive releases, but it will never come even close to covering everything -- sliders, spinners, notebooks aka 'propertypages/propertysheets' in MFC terms, dockable subwindows, coolbars, ... What I had in mind with this proposal was that anygui clients would program their GUI's to anygui's API (if they don't mean to do that, why are they using anygui at all?-), in terms that can be much less refined (e.g., separate toplevel windows in lieu of notebooks or dockables) BUT keep the ability to access sophisticated stuff IF the underlying framework provides it AND they know what to do with it (reparent a frame to notebook-page and/or dockable, that sort of thing -- or, say, have a textfield as the number-entry means in anygui terms, but replace it with a slider or spinner when running on certain underlying frameworks...). If we provide this decently well, then a GUI originally sketched in anygui terms can later be "grown" in terms of one (or a few) other underlying frameworks without having to throw away and reprogram much of what one has already done. Yes, ideally the "simple fallback 100% pure anygui approach" would be maintained and kept up to date so the overall app can still run anywhere (with less-slick look&feel, but still run) -- but that does not have to be a _must_, just, as you suggest, a strong stylistic & pragmatical suggestion ("one day you'll need your app to be running RIGHT NOW on a peculiar palmtop device you've never seen before -- why not pay the small premium to ensure it does...?"). > Yes... I agree that this is a good thing. And it would > probably remove some objections to using anygui. > > An idea: We could make some simple system/protocol for > making pure anygui replacements for fancy "native" > widgets, and collect them in one place (like the > anygui distribution <wink>). Then, each time someone > felt the need to make such a replacement, they could > submit it... (I, for one, would like a tree-widget > substitution... And a status bar... And...) _Excellent_ idea. > I guess so. It would be very easy to get this info from > the anygui module/object itself... For instance: > > >>> import anygui > >>> print anygui.backend > None > >>> from anygui import * > >>> anygui.backend > 'wx' > > Or something... (Of course "constants" like WX = 'wx' etc. > could be defined...) Yes, but client-code that wants to do peculiar stuff when backend is 'wx' (I would NOT bother predefining such constants, strings seem good here:-) still needs to access the "underlying object[s]" for a given anygui level object (Component, Frame, ...?other?...). > > I'm no > > GUI expert, it just seems to me that MVC buys you > > more for very little cost. > > I'm no expert either... And simply assumed that > Greg was. Is Greg on the list? Maybe we could ask him? Sure we do have other GUI-experts around...? > > Why foo() to read, set_foo() to write? > > I was thinking about commenting that too -- I would > much rather have __getattr__/__setattr__ stuff... > I _really_ like Jython AWT/Swing "magic" like: > > f = Frame() > f.size = (400, 300) > > :) We may be too much in agreement, you and I -- I, too, had in mind the nice way Jython Pythonizes AWT here!-) > > C. event handling > > > > Why not more uniformity between mouse-events, key-events > > and command-events? The latter should not be so tightly > > bound (conceptually, terminologically, ...) to menus. > > Hm. Swing actions are nice here... With names, icons, > etc. etc. I miss the "icons", I think. Should I brush up on Swing, or can you clarify how those might fit in "an action" (or "a command")? > > The > > highly-dynamic just-in-time determination of enabled > > status &c is cool for "local" interfaces where turnaround > > can be assumed "instantaneous from the user's viewpoint", > > of course. Although it can give problems for the DHTML > > implementation I had in mind, I guess it should still be > > kept, for simplicity's sake. > > I'm not sure it _is_ that simple... In terms of implementation > in other backends, I mean. But then again, I may just be > a bit dense :) It's definitely the natural approach on MFC, for example. (Your "is this enabled/disabled/checked" callbacks also get invoked on idletime for toolbar-visualization purposes, as well as when a dropdown or popup menu is about to appear). For dynamic HTML, if you can stomach Javascript and XSLT, http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dncodecorn/ html/corner052499.asp offers one example, and it doesn't seem to me the callbacks to enable/disable stuff would be problematic given the amount of work it's dynamically doing to build and popup the menus anyway. Simpler examples may be those at http://popup.jscentral.com/ or maybe even better http://choisworld.com/dynamic13.html (you need to View/Source on this one -- again you need some stomach for Javascript, which makes it a hard go for me since I detest JS, but the point is the needed functionality IS right there in the Dynamic HTML object-model...). > > Maybe (perhaps not in the > > 1st release) we could allow an object to state "please > > don't call my setup_menus() until further notice, here > > is what I think should be enabled/checkmarked in case > > you need to know". > > How would you represent that info? Or do you simply mean > that we should have an advisory boolean variable as > a filter before calling setup_menus? A boolean variable won't cut it, I fear. I was rather thinking of a mapping, itemname->(enabled/disabled and checked/unchecked). Before calling setup_menus check if the object has 'posted' (and not yet retracted) such a mapping (maybe as a property...?). If the mapping is there, then use it in lieu of calling setup_menus -- with a series of calls to .get('itemname', (None, None, None)) (not sure how to best represent the default response of "leave enabling/disabling and checkmarking both alone"). Maybe we could somehow leverage the mechanism that Python already provides for us when we call getattr: go to the object's dict first, perhaps check also a default dict (from the object's class), if neither gives satisfaction call __getattr__ (so the call only happens if no other answer can be provided -- this would still let an object do SOME occasional menuitem-setup, but only for rare items for which it cannot provide a stock, static response by setting the entries in appropriate dictionaries). > > (I'm also thinking of model_changed "messages" from > > models to views, &c. Shouldn't all of these events be > > modeled rather uniformly...?) > > Hm. Probably. Reminds me of the JavaBeans framework where > vetoing attribute changes is handled by events... But > that may be stretching things :) Yes, probably. I love generality, uniformity, and event-driven programming, but "this here is a song about anyguy"... > > Specifically > > C1. Event should be generalized to model any kind of > > event, not _just_ mouse & keys. > > Agreed. This might (hopefully) make the API simpler too. > I think it would be nice to have as few classes, methods, > and classes as possible :) I don't think using event objects to model events that are currently unmodeled will reduce the number of classes and methods in the API, I'm just thinking in terms of documenting/explaining the anygui API to newbies. I think I could save a paragraph or three if uniformity reigned:-). > > D. Application class > > D1. std_menu_bar(): I think we're missing Help as a standard > > command (and probably Redo; but I'm unsure about Revert, > > is that meant to be the Undo-latest-Undo command...? > > but apparently not, given revert_cmd in Document...). > > Hmmm, maybe SelectAll, too? > > Hm. Maybe we should just leave this out for the first release? > (Though transparent undo/redo handling would be _extremely_ > useful, IMO. Perhaps we could integrate an action pattern > with the event system? <0.6 wink>) OK, OK, you're right, we can't really do it. I just kept thinking, if we have Undo as standard, we should also have Redo. Maybe leave _both_ out in anygui 0.1 ... ? > > D2. if we do consider Help standard, a help_cmd() method in > > the Application class to provide some minimal metadata > > about the app (name, version, author's email, &c) in an > > alertbox might be worth it (perhaps providing encouragement > > to client-coders to supply at least such minimal stuff:-) > > Yeah... Perhaps we could link this to docstrings, or > __author__ etc? (But we still might not need this for the > first release, IMO...) Not for 0.1, OK. But "Help" in a standard place should be there -- isn't that pretty standard across GUI frameworks? > > E. FileRef/DirRef > > Do we truly need these new abstractions...? Couldn't we > > do with something simpler/closer to what Python gives us...? > > Ah... There was the second objection I forgot. I guess these > are tied with the Document system or something (i probably > didn't read it thoroughly enough), but this is one of the > things I find slightly annoying about some other packages... > That they duplicate a lot of the features we already have. > Makes a bad case for inclusion in the standard libraries :) I did try to study what those were for but it still was not clear to me -- apparently attempting to model very general platforms where files are not necessarily representable by path strings or similar kinds of URI's. Or maybe I'm missing something here. > > F. Why not SPING for drawing? > > I thought about that myself. And as one of the creators of > Piddle, I would, of course, like to use it :) > > > Couldn't we somehow reuse the riches in SPING/Piddle rather > > than having a newly-invented, albeit simple, drawing API? > > It seems like this new API is more or less a subset... Or > at least closely related to PostScript. Yes, that does appear to be the design intent. > > If the 'native' drawing API of anyguy's Canvas was specified > > as exactly coincident with what a SPING back-end must/can > > expose, wouldn't this be a big overall win? > > I think so. Sping is more complex... But perhaps tying in with > Sping could draw some interest to both projects? After all, the > goal of the original Piddle project was very close to this -- > making a generic API for graphic stuff. Maybe, if we do NOT want to make having SPING installed a prereq for using anygui at all, we might have it "fail-soft" -- if SPING is not around, anygui falls back to a truly-seriously-minimal drawing API, that only supplies what the backend canvas does, dressing it up the _very minimum_ needed to ensure the signatures of those drawing methods that also exist in minimal state are the same as those SPING exposes when it's present. This might reduce the total-minimal-footprint needed for very-elementary anygui use. If any unsupported drawing method is called when SPING's not found, an alert pops up with an ad for SPING including a clickable URL for download and dynamic inst^H^H^H^H OK I'm letting imagination run away *again*, sorry, forget this para and go back to the previous one that seems more soberly doable:-). > > Z4. I think TextField should have a method for select-all rather > > than requiring: query text, set selection to (0, len(text)). > > Shouldn't there be a background-color possibility too? > > Actually, I would really like to have styled text too... It > seems that all of our backends can handle it... But perhaps not > for our first release ;) Agreed. And similarly for using a general canvas as a background and...:-) > > Z7. I'm not sure I understand Frame.place -- is it just me, or > > is the spec confusing, or...? ... > Another thing: Is the component layout system OK? I don't like > coordinates much... (And I have gotten used to Java's layout > managers, so I may be a bit biased...) These issues are cognates. Frame.place (plus a Component's "elasticity" in move & size, currently 0 or 1 only) are what determine component-layout. (And I think TK's good old simple layout managers can whup any Java layout mgrs -- the kind I knew back in AWT 1.0 at least, haven't done any GUI'ing with Java for QUITE a while now:-). So maybe we should study the specs & perhaps the code behind them again (but it's been even longer since I programmed to XLib, so I can't guarantee the latter...:-). Alex |
From: Magnus L. H. <ml...@id...> - 2001-07-02 12:52:22
|
From: "Alex Martelli" <al...@ya...> > "Magnus Lie Hetland" <ml...@id...> writes: [about access to backend] Well put. I agree. > > Then, each time someone > > felt the need to make such a replacement, they could > > submit it... (I, for one, would like a tree-widget > > substitution... And a status bar... And...) > > _Excellent_ idea. Perhaps we could even get our own (sub-)section in the vaults of parnassus... "Get your generic widgets here!" ;) > Yes, but client-code that wants to do peculiar stuff > when backend is 'wx' (I would NOT bother predefining > such constants, strings seem good here:-) still needs > to access the "underlying object[s]" for a given anygui > level object (Component, Frame, ...?other?...). Ah. Yes. Right. Hm. If there is a one-to-one correspondence between anygui widgets and foogui widgets, a simple attribute (in each widget etc.) would do... But would that always be the case? I really hope we can find a _really_ simple solution for this... If we need a different protocol for each backend, I certainly would like the idea a lot less. > Is Greg on the list? Nope. I cc'ed a mail to him off the list where I mentioned his work on the X-backend. I didn't want to badger him about getting on the list... (I assumed he would if he wanted to :) > Maybe we could ask him? Sure > we do have other GUI-experts around...? Don't know. Any GUI-experts here? Oh, well. I guess we all know _some_ GUI-stuff... And after all, this API is meant for non-GUI-experts ;) > > Hm. Swing actions are nice here... With names, icons, > > etc. etc. > > I miss the "icons", I think. Should I brush up on Swing, > or can you clarify how those might fit in "an action" (or > "a command")? Ah. Commands may be associated with menu items, buttons, or toolbar-...-err-buttons. These may use the title, desc., icon etc. associated with the action. (E.g. scissors with "cut" etc.) I don't think we need to do it that way, but it was kind of cute, IMO :) > > I'm not sure it _is_ that simple... In terms of implementation > > in other backends, I mean. But then again, I may just be > > a bit dense :) > > It's definitely the natural approach on MFC, for example. > (Your "is this enabled/disabled/checked" callbacks also get > invoked on idletime for toolbar-visualization purposes, as > well as when a dropdown or popup menu is about to appear). Fair enough. But is it easy to _implement_? I can't see how to do it in Java, for instance. But, as I said, that may be just because ... I don't know how to do it. Or maybe I'm talking about something completely different from you... > > For dynamic HTML, if you can stomach Javascript and XSLT, > http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dncodecorn/ > html/corner052499.asp > offers one example, and it doesn't seem to me the callbacks > to enable/disable stuff would be problematic given the > amount of work it's dynamically doing to build and > popup the menus anyway. Right. But do you have that access in all platforms? Using AWT, for instance, all the menu-stuff is done magically -- all you have access to is the resulting command. (Or am I perhaps wrong here? Could you do something with a mouse listener?) > Simpler examples may be those > at http://popup.jscentral.com/ or maybe even better > http://choisworld.com/dynamic13.html (you need to View/Source > on this one -- again you need some stomach for Javascript, > which makes it a hard go for me since I detest JS, Remember that it was inspired by Python <wink> > but the > point is the needed functionality IS right there in the > Dynamic HTML object-model...). Well, that's nice. > > How would you represent that info? Or do you simply mean > > that we should have an advisory boolean variable as > > a filter before calling setup_menus? > > A boolean variable won't cut it, I fear. Ah. I was afraid of that. > I was rather > thinking of a mapping, itemname->(enabled/disabled and > checked/unchecked). IC. Would this necessarily be faster than a method? (Or wasn't that the point?) > Maybe we could somehow leverage the mechanism that Python > already provides for us when we call getattr: go to the > object's dict first, perhaps check also a default dict > (from the object's class), if neither gives satisfaction > call __getattr__ (so the call only happens if no other > answer can be provided -- this would still let an object > do SOME occasional menuitem-setup, but only for rare > items for which it cannot provide a stock, static response > by setting the entries in appropriate dictionaries). Sounds like a good idea to me. > > Hm. Probably. Reminds me of the JavaBeans framework where > > vetoing attribute changes is handled by events... But > > that may be stretching things :) > > Yes, probably. I love generality, uniformity, and > event-driven programming, but "this here is a song > about anyguy"... ?-) > I don't think using event objects to model events that > are currently unmodeled will reduce the number of classes > and methods in the API, :( > I'm just thinking in terms of > documenting/explaining the anygui API to newbies. :) (Barf. I'm using far too many smileys... May have something to do with the fact that I spent last night programming.) > I think I could save a paragraph or three if uniformity > reigned:-). A good thing. > > Hm. Maybe we should just leave this out for the first release? > > (Though transparent undo/redo handling would be _extremely_ > > useful, IMO. Perhaps we could integrate an action pattern > > with the event system? <0.6 wink>) > > OK, OK, you're right, we can't really do it. I just kept > thinking, if we have Undo as standard, we should also have > Redo. Maybe leave _both_ out in anygui 0.1 ... ? I think so. But I would love to have undo/redo as a (transparent) part of anygui some day. And it _could_ be interwoven with the event system, right? > > Yeah... Perhaps we could link this to docstrings, or > > __author__ etc? (But we still might not need this for the > > first release, IMO...) > > Not for 0.1, OK. But "Help" in a standard place should be > there -- isn't that pretty standard across GUI frameworks? Hm. I guess it is. But a default implementation that doesn't really help you can be more annoying than not having it there, IMO. But if/when we include a "standard menu setup", I guess help should be part of it. (And maybe an "about" choice...) [FileRef/DirRef] > I did try to study what those were for but it still was not > clear to me -- apparently attempting to model very general > platforms where files are not necessarily representable by > path strings or similar kinds of URI's. Or maybe I'm > missing something here. Hm. I say we leave them out -- I'm sure we can put them in later if we need them. > Maybe, if we do NOT want to make having SPING installed a prereq > for using anygui at all, I wouldn't want it as a prerequisite, no... But using the same API would allow us to plug it in somehow... > we might have it "fail-soft" -- if SPING > is not around, anygui falls back to a truly-seriously-minimal > drawing API, _or_ the backend can implement all the methods... You don't really need Sping for that. Hm. I don't know. Maybe Sping is overkill for the first release? > that only supplies what the backend canvas does, > dressing it up the _very minimum_ needed to ensure the signatures > of those drawing methods that also exist in minimal state are the > same as those SPING exposes when it's present. This might reduce > the total-minimal-footprint needed for very-elementary anygui use. Right. The footprint. Hm. > If any unsupported drawing method is called when SPING's not found, > an alert pops up with an ad for SPING including a clickable URL > for download and dynamic inst^H^H^H^H OK I'm letting imagination > run away *again*, sorry, forget this para and go back to the > previous one that seems more soberly doable:-). <LOL> > > Actually, I would really like to have styled text too... It > > seems that all of our backends can handle it... But perhaps not > > for our first release ;) > > Agreed. And similarly for using a general canvas as a background > and...:-) And... And... Right. > > Another thing: Is the component layout system OK? I don't like > > coordinates much... (And I have gotten used to Java's layout > > managers, so I may be a bit biased...) > > These issues are cognates. Frame.place (plus a Component's > "elasticity" in move & size, currently 0 or 1 only) are what > determine component-layout. (And I think TK's good old simple > layout managers can whup any Java layout mgrs OK. Not much of a Tk expert... But I can use a BorderLayout for quite a lot ;) > So maybe we should study the > specs & perhaps the code behind them again (but it's been > even longer since I programmed to XLib, so I can't guarantee > the latter...:-). I've never done any serious programming in X at all... But, yes. I think we may assume that there is quite a lot of thought behind the API as it stands. > Alex -- Magnus Lie Hetland http://www.hetland.org "Reality is that which, when you stop believing in it, doesn't go away." -- Philip K. Dick |
From: Alex M. <al...@ya...> - 2001-07-02 16:45:26
|
"Magnus Lie Hetland" <ml...@id...> writes: ... > Ah. Yes. Right. Hm. If there is a one-to-one > correspondence between anygui widgets and foogui > widgets, a simple attribute (in each widget etc.) would > do... But would that always be the case? I really hope I assumed one-to-many -- where the "gimme the underlying widget[s]" property/method/whatever would return the single corresponding widget OR the tuple of corresponding widgets. The roles of the widgets in a tuple would have to be documented by the backend's author of course, but then using them in any way WOULD be backend-specific. > > I miss the "icons", I think. Should I brush up on Swing, > > or can you clarify how those might fit in "an action" (or > > "a command")? > > Ah. Commands may be associated with menu items, buttons, > or toolbar-...-err-buttons. These may use the title, desc., > icon etc. associated with the action. (E.g. scissors > with "cut" etc.) I don't think we need to do it that way, > but it was kind of cute, IMO :) Oh, sure, it IS what any Windows user is used to these days (the 'icons' being called buttons of the toolbar or coolbar or whatever:-). Presumably, btw, a command may also be invokable with some keyboard shortcut (at least in some backends). > > > I'm not sure it _is_ that simple... In terms of implementation > > > in other backends, I mean. But then again, I may just be > > > a bit dense :) > > > > It's definitely the natural approach on MFC, for example. > > (Your "is this enabled/disabled/checked" callbacks also get > > invoked on idletime for toolbar-visualization purposes, as > > well as when a dropdown or popup menu is about to appear). > > Fair enough. But is it easy to _implement_? I can't see how > to do it in Java, for instance. But, as I said, that may be > just because ... I don't know how to do it. Or maybe I'm > talking about something completely different from you... ...or maybe it _can't_ be done in Java/AWT, if the toolkit doesn't favour you with a callback/event/whatever when a menu is about to popup/scrolldown/whatever. Now *THAT* would be serious. > > For dynamic HTML, if you can stomach Javascript and XSLT, > > > http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dncodecorn/ > > html/corner052499.asp > > offers one example, and it doesn't seem to me the callbacks > > to enable/disable stuff would be problematic given the > > amount of work it's dynamically doing to build and > > popup the menus anyway. > > Right. But do you have that access in all platforms? Using > AWT, for instance, all the menu-stuff is done magically -- > all you have access to is the resulting command. (Or am I > perhaps wrong here? Could you do something with a mouse > listener?) I'm too rusty on that, sorry. So how do you normally enable/disable, &c, menu-entries in AWT? > > Simpler examples may be those > > at http://popup.jscentral.com/ or maybe even better > > http://choisworld.com/dynamic13.html (you need to View/Source > > on this one -- again you need some stomach for Javascript, > > which makes it a hard go for me since I detest JS, > > Remember that it was inspired by Python <wink> *WHAT*?! *EEEEEEEEEEK...* So why didn't they just USE Python?! > > I was rather > > thinking of a mapping, itemname->(enabled/disabled and > > checked/unchecked). > > IC. Would this necessarily be faster than a method? (Or > wasn't that the point?) If the mapping is a builtin dictionary, and all the info about enabling/disabling &c is static in there, it should be zippy-fast. But what I had in mind was that such a mapping could be "posted" by an object (assuming the enabled/disabled states it desires vary rarely) and then, if the GUI is being painted remotely from the engine running behind it, the remote-GUI-painter can have a local copy of the mapping to consult so it doesn't have to make the user wait before a menu drops-down... *IF* the enab/disab state on the menu IS entirely static, at least. > > Maybe we could somehow leverage the mechanism that Python > > already provides for us when we call getattr: go to the > > object's dict first, perhaps check also a default dict > > (from the object's class), if neither gives satisfaction > > call __getattr__ (so the call only happens if no other > > answer can be provided -- this would still let an object > > do SOME occasional menuitem-setup, but only for rare > > items for which it cannot provide a stock, static response > > by setting the entries in appropriate dictionaries). > > Sounds like a good idea to me. ...maybe... I think it needs more work. > > > Hm. Probably. Reminds me of the JavaBeans framework where > > > vetoing attribute changes is handled by events... But > > > that may be stretching things :) > > > > Yes, probably. I love generality, uniformity, and > > event-driven programming, but "this here is a song > > about anyguy"... > > ?-) "remember Alice? It's a song about Alice" (which I'd SWEAR Arlo once sang "remember Alice? this here is a song about Alice"), "Alice's Restaurant", By Arlo Guthrie, cfr e.g. http://www.arlo.net/lyrics/alices.shtml. Other sources have the quote as "remember Alice? There's a song about Alice" (e.g. http://www.fortunecity.com/tinpan/parton/2/alice.html). Arthur Penn's 1968 movie is cult-worthy IMVHO (and I'm an almost-archetipal movie-cultist, so I should know...:-). > > > Hm. Maybe we should just leave this out for the first release? > > > (Though transparent undo/redo handling would be _extremely_ > > > useful, IMO. Perhaps we could integrate an action pattern > > > with the event system? <0.6 wink>) > > > > OK, OK, you're right, we can't really do it. I just kept > > thinking, if we have Undo as standard, we should also have > > Redo. Maybe leave _both_ out in anygui 0.1 ... ? > > I think so. But I would love to have undo/redo as a (transparent) > part of anygui some day. And it _could_ be interwoven with the > event system, right? Yes, it could, in that requests to undo/redo could come in as events (and non-undoable/redoable changes could disable the relevant menuitem &c), but I'm not sure what you mean by "transparent" in this context. What gui-toolkit makes undo/redo "trasparent" to the application...? > > > Yeah... Perhaps we could link this to docstrings, or > > > __author__ etc? (But we still might not need this for the > > > first release, IMO...) > > > > Not for 0.1, OK. But "Help" in a standard place should be > > there -- isn't that pretty standard across GUI frameworks? > > Hm. I guess it is. But a default implementation that doesn't > really help you can be more annoying than not having it there, > IMO. So it's disabled by default so the author is reminded to add some modicum of help and enable it...?-) > > Maybe, if we do NOT want to make having SPING installed a prereq > > for using anygui at all, > > I wouldn't want it as a prerequisite, no... But using the same > API would allow us to plug it in somehow... > > > we might have it "fail-soft" -- if SPING > > is not around, anygui falls back to a truly-seriously-minimal > > drawing API, > > _or_ the backend can implement all the methods... You don't > really need Sping for that. Hm. I don't know. Maybe Sping is > overkill for the first release? If it's at all hard to do, I guess; I was hoping to luck out and find it very very easy to integrate:-). > > > Another thing: Is the component layout system OK? I don't like > > > coordinates much... (And I have gotten used to Java's layout > > > managers, so I may be a bit biased...) > > > > These issues are cognates. Frame.place (plus a Component's > > "elasticity" in move & size, currently 0 or 1 only) are what > > determine component-layout. (And I think TK's good old simple > > layout managers can whup any Java layout mgrs > > OK. Not much of a Tk expert... But I can use a BorderLayout for > quite a lot ;) > > > So maybe we should study the > > specs & perhaps the code behind them again (but it's been > > even longer since I programmed to XLib, so I can't guarantee > > the latter...:-). > > I've never done any serious programming in X at all... But, yes. I > think we may assume that there is quite a lot of thought behind the > API as it stands. So I'll see what I can do to rip it out in the course of the next few days...:-). Alex |
From: Magnus L. H. <ml...@id...> - 2001-07-03 01:17:24
|
From: "Alex Martelli" <al...@ya...> > "Magnus Lie Hetland" <ml...@id...> writes: [...] > The roles of the widgets in a tuple would have > to be documented by the backend's author of course, but > then using them in any way WOULD be backend-specific. OK. You would have to know the backend anyway, so... As long as the protocol is this simple: "For this backend, the attribute Button.impl will contain the tuple (foo, bar, baz), where foo is ..." etc. Then that would be simple and consistent across all backends, and the only difference would be how these implementing widgets actually _work_ (which is a part of the backend, really). I don't know how this works in swigged native backends, but I guess it would be easy to do something like this there as well. > Oh, sure, it IS what any Windows user is used to these > days (the 'icons' being called buttons of the toolbar > or coolbar or whatever:-). Presumably, btw, a command > may also be invokable with some keyboard shortcut (at > least in some backends). Yup. These really ought to be tied in with undo/redo ;) (And I think we may safely forget the Icons for now...) > > Fair enough. But is it easy to _implement_? I can't see how > > to do it in Java, for instance. But, as I said, that may be > > just because ... I don't know how to do it. Or maybe I'm > > talking about something completely different from you... > > ...or maybe it _can't_ be done in Java/AWT, if the toolkit > doesn't favour you with a callback/event/whatever when a > menu is about to popup/scrolldown/whatever. Now *THAT* > would be serious. I think that is actually the case. At least I've never seen anything like such a callback (or event type) in AWT, and I've used it for quite a few years... There may be something like it in Swing (I see no reason why ther couldn't be, since it's "pure" Java), but I haven't really seen it there either... I'll have a look. Do we have these callbacks on all other platforms? Native Mac? wxPython? Tkinter? Can we simulate it somehow (by doing the setup at target selection time, as I mentioned earlier), at least on platforms that don't support it? Any other work-arounds? And another thing - I think maybe we should just forget AWT and go with Swing. (Then again, maybe not...) > I'm too rusty on that, sorry. So how do you normally > enable/disable, &c, menu-entries in AWT? Hm. I haven't done that much. I guess you'd do that in some ad-hoc manner, depending on events/program state :P But as I said, I'll take a look. I guess Robin can probably answer this about wxPython... > > Remember that it was inspired by Python <wink> > > *WHAT*?! *EEEEEEEEEEK...* So why didn't they just USE > Python?! No idea. I guess they wanted something... Err... "Simpler"? No... More like C/Java, perhaps. Hm. > If the mapping is a builtin dictionary, and all the info > about enabling/disabling &c is static in there, it should > be zippy-fast. But what I had in mind was that such a > mapping could be "posted" by an object (assuming the > enabled/disabled states it desires vary rarely) and then, > if the GUI is being painted remotely from the engine > running behind it, the remote-GUI-painter can have a local > copy of the mapping to consult so it doesn't have to make > the user wait before a menu drops-down... *IF* the enab/disab > state on the menu IS entirely static, at least. Right. And the local cache would of course be a combination of the relevant dicts... Or will there always be only one? > > Sounds like a good idea to me. > > ...maybe... I think it needs more work. I'm sure you're right. > > ?-) > > (and I'm an > almost-archetipal movie-cultist, so I should know...:-). Errr... OK. :) > > I think so. But I would love to have undo/redo as a (transparent) > > part of anygui some day. And it _could_ be interwoven with the > > event system, right? > > Yes, it could, in that requests to undo/redo could come in > as events (and non-undoable/redoable changes could disable > the relevant menuitem &c), but I'm not sure what you mean > by "transparent" in this context. Oh, right. Just that all the API calls are stored in a (finitely sized) queue of some sort, and that you can undo/redo yourself back and forth... And that the user of anygui need not do anything special to achieve that. > What gui-toolkit makes undo/redo "trasparent" to the > application...? Not the application - the programmer. Somewhat like ZODB makes storage "transparent". > > Hm. I guess it is. But a default implementation that doesn't > > really help you can be more annoying than not having it there, > > IMO. > > So it's disabled by default so the author is reminded to add > some modicum of help and enable it...?-) Perhaps we could even have som simple AI check whether the help material is useful enough to allow enabling the menu? <wink> > > _or_ the backend can implement all the methods... You don't > > really need Sping for that. Hm. I don't know. Maybe Sping is > > overkill for the first release? > > If it's at all hard to do, I guess; I was hoping to luck > out and find it very very easy to integrate:-). Ah. There is one backend for Tkinter and one for wxPython... And the Java 2D API is so rich it would be trivial to implement it there. And there is QuickDraw for Mac... Hm. > > I've never done any serious programming in X at all... But, yes. I > > think we may assume that there is quite a lot of thought behind the > > API as it stands. > > So I'll see what I can do to rip it out in the course of > the next few days...:-). Good. > Alex -- Magnus Lie Hetland http://www.hetland.org "Reality is that which, when you stop believing in it, doesn't go away." -- Philip K. Dick |
From: Alex M. <al...@ya...> - 2001-07-03 08:00:52
|
"Magnus Lie Hetland" <ml...@id...> writes: ... > > > I think so. But I would love to have undo/redo as a (transparent) > > > part of anygui some day. And it _could_ be interwoven with the > > > event system, right? > > > > Yes, it could, in that requests to undo/redo could come in > > as events (and non-undoable/redoable changes could disable > > the relevant menuitem &c), but I'm not sure what you mean > > by "transparent" in this context. > > Oh, right. Just that all the API calls are stored in a > (finitely sized) queue of some sort, and that you can undo/redo > yourself back and forth... And that the user of anygui need not > do anything special to achieve that. But when an "API call" actually affects the Model (i.e., is interesting for undo/redo purposes) we need to 'snapshot' the Model's state in either "incremental difference" terms, or, when that is feasible and easier, as a complete persisted state. Since the semantics of Model state are totally up to the application (and the programmer thereof), how can this be "transparent"? > > What gui-toolkit makes undo/redo "trasparent" to the > > application...? > > Not the application - the programmer. Somewhat like ZODB makes > storage "transparent". I think I still don't get it. The best undo/redo support I can think of receiving from a framework is still anything but transparent to me as a programmer, to wit: when a Model is about to change its state, it can record on the framework's queue a Memo object which includes callbacks to perform for Undo and Redo of this particular change (and possibly some auxiliary info, such as what to show on an "Undo Menu" if the GUI offers that, "Undo Insert" vs "Undo Delete" &c, whether the change _is_ undoable at all, that sort of thing). The framework can then take care of where to hold the queue and its items, when to flush it (because saved changes are not undoable anymore, for example), etc. But I still wouldn't call this at all "transparent" since the application programmer is left with the task of getting the 'Memo object' right. In API terms it's almost trivial, as the Memo could be an optional argument to the Model's "changed()" method -- besides setting the isChanged flag, the method would presumably communicate suitably with the framework (so e.g. if changed() is called without args, the FW knows the change is not undoable and therefore any undoable changes that might have been queued could be flushed, etc). But, "transparent"...? Am I missing some tweak that would allow that...? Alex |
From: Magnus L. H. <ml...@id...> - 2001-07-03 19:56:59
|
From: "Alex Martelli" <al...@ya...> > > But when an "API call" actually affects the Model (i.e., is > interesting for undo/redo purposes) we need to 'snapshot' the > Model's state in either "incremental difference" terms, or, > when that is feasible and easier, as a complete persisted > state. Hm. I never did read that pattern from the pattern book (Gamma et al) too thoroughly, but I think the point is to use Action objects that can modify the model both ways, i.e. the action can undo itself. If all modifications are done through such actions (events) then Bob's your uncle (or something). > Since the semantics of Model state are totally up to > the application (and the programmer thereof), how can this > be "transparent"? See above. May not be feasible - I don't know. > > > What gui-toolkit makes undo/redo "trasparent" to the > > > application...? > > > > Not the application - the programmer. Somewhat like ZODB makes > > storage "transparent". > > I think I still don't get it. Well... If you still don't get it after my explanation above, I may simple be wrong :) > The best undo/redo support I can think of [...] You shouldn't have to store the state explicitly... If I press a key when in a text field, a "key down" event or whatever is sent, possibly translated into an "insert letter x in field y at position z" action. This is performed, and put into the undo-queue/stack. If I later want to undo it, it is performed in reverse (every action would need how to reverse itself, or signal that it cannot be undone), i.e. "remove character from position z in field y". Perhaps I should take a look at the original pattern again... Except that I've got all my books packed in boxes because I'm moving to a new office... :) > But, "transparent"...? Am I missing some > tweak that would allow that...? It seems you missed my point altogether. It may not be a valid one, but nonetheless... ;) > > Alex > -- Magnus Lie Hetland http://www.hetland.org "Reality is that which, when you stop believing in it, doesn't go away." -- Philip K. Dick |
From: Thomas H. <tho...@io...> - 2001-07-03 18:30:25
|
> B. why accessors/mutators? > > Why foo() to read, set_foo() to write? (I do like > the slight, very-handy redundancy of kw args for set > in constructors and the .set() method). Why not just > foo to read, foo=whatever to write? It's simpler and > more Pythonic for the client and it's NOT a big trouble > for us to have a single mixin class translating this > Pythonic access-style to method calls in __getattr__ > and __setattr__. I'm definitely -1 on the foo()/set_foo() > choice -- and while I'm not a GUI expert, I _am_ an OO > expert and have strong feelings in the matter:-). > Which is the pattern to use? Something like this: class Mixin: def __setattr__(self, name, value): try: setter = getattr(self, '_set_' + name) except AttributeError: # no setting method self.__dict__[name] = value else: # let the setting method do it setter(name, value) class Window(..., Mixin): def _set_width(self, value): # intercept the 'width' attribute self.__dict__['width'] = value if self.is_realized(): self.resize(self.width, self.height) Thomas |
From: Alex M. <al...@ya...> - 2001-07-03 20:48:58
|
"Thomas Heller" <tho...@io...> writes: ... > > B. why accessors/mutators? > > > > Why foo() to read, set_foo() to write? (I do like ... > Which is the pattern to use? Something like this: > > class Mixin: > def __setattr__(self, name, value): > try: > setter = getattr(self, '_set_' + name) > except AttributeError: > # no setting method > self.__dict__[name] = value This latter might interfere with an accessor -- the accessor would not be called if name is found in the __dict__. I don't know if we need to support attributes having an accessor but no mutator -- but it seems a natural way to model read-only attributes. Therefore we might want something like: def __setattr__(self, name, value): getattr(self, '_set_'+name, _setany)(name, value) def _setany(self, name, value): if getattr(self, '_get_'+name, 0): raise AttributeError, "%s is read-only"%name self.__dict__[name]=value def __getattr__(self, name, value): try: return getattr(self,'_get_'+name)() except AttributeError: raise AttributeError,name This has the slight disadvantage that all _set_*() methods should accept a redundant name for signature uniformity with _setany. Maybe better therefore to go back to something closer to your scheme giving up the _setany...: def __setattr__(self, name, value): try: setter=getattr(self, '_set_'+name) except AttributeError: if getattr(self, '_get_'+name, 0): raise AttributeError, "%s is read-only"%name self.__dict__[name]=value else: setter(value) > else: > # let the setting method do it > setter(name, value) I don't think the name needs to be passed, and indeed: > class Window(..., Mixin): > def _set_width(self, value): ...you're not passing it here, which seemse sensible. > # intercept the 'width' attribute > self.__dict__['width'] = value > if self.is_realized(): > self.resize(self.width, self.height) Seems nice to me! Alex _________________________________________________________ Do You Yahoo!? Get your free @yahoo.com address at http://mail.yahoo.com |