Hi all
I have a shell with 6 buttons, if I implement the shell's #queryCommand: method as MyShell>>queryCommand: query Transcript print: query commandSymbol; cr. super queryCommand: query. "etc etc" I see the following in the system transcript: #updateCSS #getCSS #addTag #addSection #removeSectionOrTag1 #rename If I then changed the button with command #removeSectionOrTag1 to #removeSectionOrTag. I only see #updateCSS #getCSS #addTag #addSection #rename Note that when the shell first appears, I do see #removeSectionOrTag being printed out, but after that, whenever I click on the shell to activate it, #removeSectionOrTag no longer appears. I can't reproduce it if I create a fresh shell with the same commands. Did I miss something obvious? -- Regards Hwee Boon MotionObj |
Yar Hwee Boon wrote:
> If I then changed the button with command #removeSectionOrTag1 to > #removeSectionOrTag. I only see I may be misunderstand what you are trying to do, but I don't think that the MVP framework is really designed to allow you to change the command of a button or menu item. At least, its not something that I've ever heard of anyone doing, so even if /it/ is supposed to work, it wouldn't be surprising if it turned out to be buggy. In one case where I wanted to do something similar (a VCR-style control panel where the 'Play' button would change into a 'Pause' button while the animation was running), I just used two separate buttons in the same place and #show / #hide them appropriately. I don't know if its at all relevant, but I suppose it might be worth remembering that you can change the text of a button or menu item from the corresponding queryCommand: with aCommandQuery text: '...whatever...'. -- chris |
On Thu, 8 Jul 2004 09:32:12 +0100, Chris Uppal
<[hidden email]> wrote: > Yar Hwee Boon wrote: > >> If I then changed the button with command #removeSectionOrTag1 to >> #removeSectionOrTag. I only see > > I may be misunderstand what you are trying to do, but I don't think that Ah.. sorry, rather, I must have not communicated my problem properly. What I mean was I changed the command from within the view composer and #show the shell again. I didn't try to change it during runtime. But see below for the discrepancy, in the 2nd case #removeSectionOrTag is not printed out, meaning that #queryCommand: was sent for that particular button merely because I changed the command. Which was quite of weird (to me at least). Sorry I can't give specific code, because I can't reproduce this with another class. With #removeSectionOrTag1: #updateCSS #getCSS #addTag #addSection #removeSectionOrTag1 #rename With #removeSectionOrTag: #updateCSS #getCSS #addTag #addSection #rename -- Regards Hwee Boon MotionObj |
Yar Hwee Boon wrote:
> What > I mean was I changed the command from within the view composer and #show > the shell again. I didn't try to change it during runtime. But see below > for the discrepancy, in the 2nd case #removeSectionOrTag is not printed > out, meaning that #queryCommand: was sent for that particular button > merely because I changed the command. I'm a little fuzzy on how the whole routing of CommmandQuery's work, but I had a thought. I think you're saying that, using #removeSectionOrTag1 it shows up in the #queryCommand: for your shell, but using #removeSectionOrTag it doesn't. Could it be that #removeSectionOrTag is already being handled by some lower level presenter that comes earlier in the command routing, such that that particular name doesn't make it up to your shell? ------------------------------------------- Bill Dargel [hidden email] Shoshana Technologies 100 West Joy Road, Ann Arbor, MI 48105 USA |
On Thu, 08 Jul 2004 16:16:11 -0400, Bill Dargel <[hidden email]>
wrote: > I'm a little fuzzy on how the whole routing of CommmandQuery's work, but > I had a thought. I think you're saying that, using #removeSectionOrTag1 > it shows up in the #queryCommand: for your shell, but using > #removeSectionOrTag it doesn't. Yup. > Could it be that #removeSectionOrTag is > already being handled by some lower level presenter that comes earlier > in the command routing, such that that particular name doesn't make it > up to your shell? I browsed for references of #removeSectionOrTag and didn't find any. -- Regards Hwee Boon MotionObj |
In reply to this post by Bill Dargel
Bill Dargel wrote:
> Could it be that #removeSectionOrTag is > already being handled by some lower level presenter that comes earlier > in the command routing, such that that particular name doesn't make it > up to your shell? That's my thought too. It's worth adding that it's not just Presenters that are on the default command route, but the Views are as well. Also, in certain circumstances, the Model and even the Comand itself can be involved. The command routing concept is one of the subtlest in Dolphin MVP; it's quite complex but very powerful. The thing is that it works so well most of the time that you tend to forget that its happening at all. If the button is enabled, then one way to find out what's going on would be to find any implementation of #removeSelectorOrTag in the image, put breakpoints in all of them, then click on the button. Then from the debugger it should be possible to work out what is actually handing it, and how the command ends up being routed there. -- chris |
In reply to this post by Yar Hwee Boon-3
Yar Hwee Boon wrote:
> I browsed for references of #removeSectionOrTag and didn't find any. Hmm... Did you also look for definitions of #removeSectionOrTag ? -- chris |
On Fri, 9 Jul 2004 10:08:26 +0100, Chris Uppal
<[hidden email]> wrote: > Did you also look for definitions of #removeSectionOrTag ? > > -- chris Opps. There is 1 other definition in a presenter I am using. Basically the view/presenter structure is: MyShell (defines MyShell>>removeSectionOrTag) MyPresenter (defines MyPresenter>>removeSectionOrTag) MyButton (command is #removeSectionOrTag) So the button command is meant to be MyShell>>removeSectionOrTag which then delegates (calls) MyPresenter>>removeSectionOrTag. Seems that this name clash is causing the problem, because if I rename MyPresenter>>removeSectionOrTag to something else, MyShell>>queryCommand: is being sent for the button's command. Is it incorrect to have them share the same name? Seems unavoidable? -- Regards Hwee Boon MotionObj |
On Fri, 09 Jul 2004 18:16:52 +0800, Yar Hwee Boon <[hidden email]>
wrote: > Opps. There is 1 other definition in a presenter I am using. Basically > the view/presenter structure is: > > MyShell (defines MyShell>>removeSectionOrTag) > MyPresenter (defines MyPresenter>>removeSectionOrTag) > MyButton (command is #removeSectionOrTag) > > So the button command is meant to be MyShell>>removeSectionOrTag which > then delegates (calls) MyPresenter>>removeSectionOrTag. Seems that this > name clash is causing the problem, because if I rename > MyPresenter>>removeSectionOrTag to something else, > MyShell>>queryCommand: is being sent for the button's command. Is it > incorrect to have them share the same name? Seems unavoidable? Just an update.. indeed, #queryCommand: is sent to both MyShell and MyPresenter for the commands of the buttons in MyShell, is that how it works? I had previously assumed that it should go to MyShell only. And because MyPresenter already defines #removeSectionOrTag, MyShell doesn't get the #queryCommand: call. Thanks. -- Regards Hwee Boon MotionObj |
Yar Hwee Boon wrote:
> > MyShell (defines MyShell>>removeSectionOrTag) > > MyPresenter (defines MyPresenter>>removeSectionOrTag) > > MyButton (command is #removeSectionOrTag) > > [...] > Just an update.. indeed, #queryCommand: is sent to both MyShell and > MyPresenter for the commands of the buttons in MyShell, is that how it > works? It isn't supposed to. Since the button is contained in MyShell, but not in MyPresenter, I don't think that MyPresenter should be involved at all. I've tried a couple of ways to reproduce this, but my tests just behave the way I expect them to. I /suspect/ that you've done something (by accident, perhaps) that has changed the command routing so that MyPresenter is on the command route when it normally wouldn't be. It's not easy to debug command handling, and is (I find) always rather confusing. The place I'd start is (as I said in the other post) putting a breakpoint in #removeSectionOrTag. After you've done that, you can invoke the command, and then in the debugger restart the operation way back down the stack at PushButton>>onActionPerformed, which will allow you to step through the whole command routing sequence. The first thing to look at is to see if the CommandPolicy has the 'source' and 'path' that you'd expect. -- chris |
On Sat, 10 Jul 2004 10:49:48 +0100, Chris Uppal
<[hidden email]> wrote: > I've > tried a couple of ways to reproduce this, but my tests just behave the > way I > expect them to. Thanks, I appreciate that very much. > I /suspect/ that you've done something (by accident, perhaps) that has > changed > the command routing so that MyPresenter is on the command route when it > normally wouldn't be. Definitely not intentional :) > confusing. The place I'd start is (as I said in the other post) putting > a > breakpoint in #removeSectionOrTag. After you've done that, you can #removeSectionOrTag wasn't sent to MyPresenter either.. clicking the button doesn't trigger anything, in fact I placed a self halt in PushButton>>actionPerformed and it was not called when I click the button. > whole command routing sequence. The first thing to look at is to see if > the > CommandPolicy has the 'source' and 'path' that you'd expect. I traced into ShellView>>commandSource. but didn't really get far enough with that, since the debugger window popping up is not helping with the isForeground check, and I was falling back to printing to the Transcript. But I did notice that it seems to be MyPresenter that is causing a problem, because if I replace it with another presenter that defines #removeSectionOrTag, everything works as expected. Any idea what I *could* have done wrong in that presenter? -- Regards Hwee Boon MotionObj |
Hwee Boon,
> #removeSectionOrTag wasn't sent to MyPresenter either.. clicking the > button doesn't trigger anything, in fact I placed a self halt in > PushButton>>actionPerformed and it was not called when I click the button. Are you certain that MyPresenter is being properly created and connected in the MVP triad? Something as simple as an incorrect name can cause very confusing problems. IIRC, the MVP framework is trying to be cooperative by allowing one presenter to drive many different views, but it occaisionally fails silently, which is either a bug or a feature depending on the situation. It might be nice to have an optional (probably on by default) #subPresentersCanBeAbsent or something that one can override to force the framework to generarate an error any time something isn't right between a presenter and its view. Have a good one, Bill -- Wilhelm K. Schwab, Ph.D. [hidden email] |
On Sun, 11 Jul 2004 11:38:37 -0400, Bill Schwab
<[hidden email]> wrote: > Are you certain that MyPresenter is being properly created and connected > in > the MVP triad? Something as simple as an incorrect name can cause very > confusing problems. IIRC, the MVP framework is trying to be cooperative Not that I can tell, of course it might have been obvious to someone else.. but I have been staring at this for days :) The good news is, I believe I can finally reproduce it. Can you, or Chris (Uppal) or anyone else help to verify by loading the package at http://motionobj.com/temp/HBRoutingReproduced.pac and running the following? Accordingly to MyShell>>queryCommand: both buttons should be disabled, but the #removeSectionOrTag button is active at my side. MyShell show. Hopefully its not something stupid that I'm doing. Thanks. -- Regards Hwee Boon MotionObj |
Yar Hwee Boon wrote:
> The good news is, I > believe I can finally reproduce it. Can you, or Chris (Uppal) or anyone > else help to verify by loading the package at > http://motionobj.com/temp/HBRoutingReproduced.pac and running the > following? Accordingly to MyShell>>queryCommand: both buttons should be > disabled, but the #removeSectionOrTag button is active at my side. I've given that a quick look. I can confirm that the same problem is happening on my machine too. Have you noticed that if you press the 'Remove' button, it gets disabled (possibly sounding a beep ? -- I can't tell on my machine since I don't allow it to make any sounds), and will stay disabled until you shift the focus away and back again. That's what happens to me anyway. I currently suspect that its a bug in the MVP framework for how Buttons are enabled/disabled in idle-time processing. The effect is that command route that the button uses when you press it is not the same as the one used to update the display in idle-time. I haven't worked out the details, and I could certainly be all wrong, but I think that the button includes the 'lastFocus' when it is doing an idle-time refresh (from #validateUserInterface), but not when it has actually been pressed. In this case (for reasons I haven't looked at yet) the MyPresenter is the lastFocus, so the buttons include it on their idle-time validation. That makes the 'Remove' button be enabled because MyPresenter does understand #removeSectionOrTag (and has no #queryCommand: of its own, so the default check is used). But if you actually press the button, then the command is routed using the normal route starting at the button and going out to the Shell without ever touching the MyPresenter. That's what it looks like to me just now, but I'm sure I must be missing something or else this kind of problem would show up all over. And it doesn't. More later (probably), but it's time for me to start cooking my dinner... -- chris |
Chris,
> I currently suspect that its a bug in the MVP framework for how Buttons are > enabled/disabled in idle-time processing. The effect is that command route > that the button uses when you press it is not the same as the one used to > update the display in idle-time. I haven't worked out the details, and I could > certainly be all wrong, but I think that the button includes the 'lastFocus' > when it is doing an idle-time refresh (from #validateUserInterface), but not > when it has actually been pressed. If nothing else, it's an interesting idea. It might explain an intermittent problem in one of my apps that runs on pen tablets (where the mouse cursor can very erratic). The problem is that buttons that should be enabled are sometimes disabled until the user clicks somewhere on the dialog box in question. AFAIK, I've never seen the problem on desktop machines. Have a good one, Bill -- Wilhelm K. Schwab, Ph.D. [hidden email] |
In reply to this post by Chris Uppal-3
On Sun, 11 Jul 2004 20:47:39 +0100, Chris Uppal
<[hidden email]> wrote: > Have you noticed that if you press the 'Remove' button, it gets disabled > (possibly sounding a beep ? -- I can't tell on my machine since I don't No, it doesn't beep. PushButton>>actionPerformed is not called. The button then becomes disabled (I believe) due to another #validateUserInterface call, which with a change of focus (onto the button itself), causes MyShell>>queryCommand: to be called correctly, which disables the button. > In this case (for reasons I haven't looked at yet) the MyPresenter is the > lastFocus, so the buttons include it on their idle-time validation. > That makes > the 'Remove' button be enabled because MyPresenter does understand > #removeSectionOrTag (and has no #queryCommand: of its own, so the > default check Same observation, I override MyPresenter>>#queryCommand: to confirm earlier. > is used). But if you actually press the button, then the command is > routed > using the normal route starting at the button and going out to the Shell > without ever touching the MyPresenter. Probably not though, as PushButton>>actionPerformed: wasn't called. > > That's what it looks like to me just now, but I'm sure I must be missing > something or else this kind of problem would show up all over. And it > doesn't. It does look like it should work, right? :) -- Regards Hwee Boon MotionObj |
Yar Hwee Boon wrote:
> The button > then becomes disabled (I believe) due to another #validateUserInterface > call, which with a change of focus (onto the button itself), causes > MyShell>>queryCommand: to be called correctly, which disables the button. Good point. > > That's what it looks like to me just now, but I'm sure I must be missing > > something or else this kind of problem would show up all over. And it > > doesn't. > > It does look like it should work, right? :) I haven't had a chance to investigate this any more, but it has occurred to me that a natural way to express what (I think) you are trying to do, which shouldn't suffer from this problem (or bug, if it is a bug) is for you to add the MyPresenter to the MyShell command routing explicitly. Then you could remove the forwarding commands in the MyShell as well as the stuff in MyShell>>queryCommand: For instance, in MyShell, define: commandPolicyWithSource: sourceView ^ (super commandPolicyWithSource: sourceView) prependTarget: (self presenterNamed: 'tree'); yourself. Which seems to work for me in your example, but may not really be what you are wanting to do. -- chris |
On Mon, 12 Jul 2004 10:54:57 +0100, Chris Uppal
<[hidden email]> wrote: > Which seems to work for me in your example, but may not really be what > you are > wanting to do. I think you have misunderstood me. What I would like to do is actually very simple. Refer to the layout and code below. When the user clicks Button1, I would like it to invoke MyShell>>removeSectionOrTag, that's all. MyPresenter>>removeSectionOrTag just *happens* to be there and has the same name (but of course what MyShell>>removeSectionOrTag does is to delegate to MyPresenter>>removeSectionOrTag). Did I misunderstood how the command should be routed? I *assumed* that a lookup for #removeSectionOrTag will done from the parent of Button1 (which is MyShell, therefore not involving MyPresenter) and move upwards. Does anyone has any docs or writeup on how this works, in case I've misunderstood? Thanks. MyShell MyPresenter Button1 MyShell>>removeSectionOrTag "do something". myPresenter removeSectionOrTag. "do something". -- Regards Hwee Boon MotionObj |
Yar Hwee Boon wrote:
> > Which seems to work for me in your example, but may not really be what > > you are > > wanting to do. > > I think you have misunderstood me. What I would like to do is actually > very simple. Refer to the layout and code below. When the user clicks > Button1, I would like it to invoke MyShell>>removeSectionOrTag, that's > all. No, adding the MyPresenter to the command route won't do that. I had thought that what you were really trying to do was to invoke the MyPresenter's #removeSectionOrTag from a button that is in the containing MyShell, and that the /only/ reason you were putting another #removeSectionOrTag in the main Shell was in order to forward to the sub-presenter (and similarly for the code in #queryCommand:). If that's wrong then we can forget about changing the command routing. > MyPresenter>>removeSectionOrTag just *happens* to be there and has the > same name (but of course what MyShell>>removeSectionOrTag does is to > delegate to MyPresenter>>removeSectionOrTag). Did I misunderstood how the > command should be routed? I *assumed* that a lookup for > #removeSectionOrTag will done from the parent of Button1 (which is > MyShell, therefore not involving MyPresenter) and move upwards. That's my understanding too. FWIW. > Does > anyone has any docs or writeup on how this works, in case I've > misunderstood? Thanks. The only documentation that /I/ know of is the code and comments -- especially some of the class comments. It has been discussed here a few times too; you may be able to find something if you look for "chain of command" or "c-of-c" pattern. (BTW, I'd like to continue investigating this -- it's stretching my understanding of command routing -- but I'm going to be busy arguing with bureaucrats for the next day or so. If I don't end up hanging myself, then I'll be back later) -- chris |
On Mon, 12 Jul 2004 19:53:26 +0100, Chris Uppal
<[hidden email]> wrote: > No, adding the MyPresenter to the command route won't do that. I had > thought > that what you were really trying to do was to invoke the MyPresenter's > #removeSectionOrTag from a button that is in the containing MyShell, and > that > the /only/ reason you were putting another #removeSectionOrTag in the > main > Shell was in order to forward to the sub-presenter (and similarly for > the code > in #queryCommand:). If that's wrong then we can forget about changing > the > command routing. Besides forwarding to the sub-presenter, I also set a isModified flag in MyShell>>removeSectionOrTag, as I am implementing MyShell with DocumentShell-like behavior (for saving, cancelling changes). So I can't change the command routing as you suggested. > > (BTW, I'd like to continue investigating this -- it's stretching my > understanding of command routing -- but I'm going to be busy arguing with > bureaucrats for the next day or so. If I don't end up hanging myself, > then > I'll be back later) Good luck and thanks. I'll be continuing my experiments too, will report back if I find anything. ps: I am seeing this behavior in toolbars too :) -- Regards Hwee Boon MotionObj |
Free forum by Nabble | Edit this page |