I’m implementing a tool with two modes of interacting with nodes: Zooming or Panning
… the user can toggle between the two. In both cases they must still be able to click on individual nodes, however, rubber band selection is not required. So, I’ve replaced the GoToolRubberbanding at startup with either a GoToolZooming or GoToolPanning (in modal mode). Subsequently I try to replace the corresponding tool with the other. The replacement is the part that doesn’t work. Code below:
Initialization code in the forms ctor (initialTool is a custom enum of type ViewTool) follows - currently the initial tool is always a Pan tool:
switch (initialTool)
{
case ViewTool.Pan:
GoToolPanning tool = new GoToolPanning(m_view);
tool.AutoPan = false;
tool.Modal = true;
m_view.ReplaceMouseTool(typeof(GoToolRubberBanding), tool);
break;
case ViewTool.Zoom:
m_view.ReplaceMouseTool(typeof(GoToolRubberBanding), new GoToolZooming(m_view));
break;
}
The toggling code in the ToolMode property follows:
public ViewTool ToolMode
{
get { return m_toolMode; }
set
{
if (m_toolMode != value)
{
m_toolMode = value;
switch (m_toolMode)
{
case ViewTool.Pan:
GoToolPanning tool = new GoToolPanning(m_view);
tool.AutoPan = false;
tool.Modal = true;
m_view.ReplaceMouseTool(typeof(GoToolZooming), tool);
break;
case ViewTool.Zoom:
m_view.ReplaceMouseTool(typeof(GoToolPanning), new GoToolZooming(m_view));
break;
}
}
}
}
So the idea is to replace the GoToolRubberBanding right of the bat on construction and then swap out the Panning and Zooming tools thereafter. The problem is that the zoom tool is never activated. If I step throught the debugger - after the statement:
m_view.ReplaceMouseTool(typeof(GoToolPanning), new GoToolZooming(m_view));
in the ToolMode setter the m_view.Tool property is still of type GoToolPanning and the panning tool continues to function. It would appear that ReplaceMouseTool is having no effect?
OK… By default, there is a GoToolPanning as a MouseDownTool and GoToolRubberbanding is a MouseMoveTool. So, you end up with 2 GoToolPannings installed after your first replace.
and the second one replaces the MouseDown GoToolPanning with the GoToolZooming. (If you do that replace again, the zooming works.)
No, something is still wrong. I changed my initialization code to the following:
m_view.ReplaceMouseTool(typeof(GoToolRubberBanding), null);
switch (initialTool)
{
case ViewTool.Pan:
GoToolPanning tool = m_view.FindMouseTool(typeof(GoToolPanning)) as GoToolPanning;
Debug.Assert(tool != null);
tool.AutoPan = false;
tool.Modal = true;
break;
case ViewTool.Zoom:
m_view.ReplaceMouseTool(typeof(GoToolPanning), new GoToolZooming(m_view));
break;
}
If I understand correctly then the initialization code removes the GoToolRubberBanding. Then the existing GoToolPanning is set to modal mode or replaced if the initialTool is Zoom.
The toggle code remains the same. In fact I even tried this in the Zoom case:
case ViewTool.Zoom:
m_view.ReplaceMouseTool(typeof(GoToolPanning), new GoToolZooming(m_view));
m_view.ReplaceMouseTool(typeof(GoToolPanning), new GoToolZooming(m_view));
break;
After even two replaces the m_view.Tool property is still of type GoToolPanning.
Oooh, you’re totally right. Ok, so I’m initializing the GoToolPanning regardless of initial tool type now.
However, the toggle is still broken. The line
m_view.ReplaceMouseTool(typeof(GoToolPanning), new GoToolZooming(m_view));
Still has no apparent effect. In the debugger, right after executing the above line of code m_view.Tool is still set to type GoToolPanning. Should I not be replacing the panning tool? Should I replace a different tool? Or is there another way to toggle between these two tool types?
Cool, that works exactly the way I want it too. But, I’m wondering if there is a more correct way to achieve the same effect? That is, this feels rather ‘hacky’ to me. Comments?
When I was playing with this earlier, it wasn’t exactly clear to me the exact UI you were going for, so I just concentrated on getting the tools set up, not the mode switching.
But DoMouseUp is the right way to end a MouseDown tool, so I think what you're doing is fine.