ToolBar: Now we can press-move-release mouse to select tools over different ToolStrips

This commit is contained in:
David Capello 2014-04-13 17:34:02 -03:00
parent 5567e3dfc5
commit 49844267a5
2 changed files with 104 additions and 46 deletions

View File

@ -71,7 +71,7 @@ private:
Rect getToolBounds(int index); Rect getToolBounds(int index);
ToolGroup* m_group; ToolGroup* m_group;
Tool* m_hot_tool; Tool* m_hotTool;
ToolBar* m_toolbar; ToolBar* m_toolbar;
BITMAP* m_overlapped; BITMAP* m_overlapped;
}; };
@ -102,9 +102,9 @@ ToolBar::ToolBar()
this->border_width.r = 1*jguiscale(); this->border_width.r = 1*jguiscale();
this->border_width.b = 0; this->border_width.b = 0;
m_hot_tool = NULL; m_hotTool = NULL;
m_hot_index = NoneIndex; m_hotIndex = NoneIndex;
m_open_on_hot = false; m_openOnHot = false;
m_popupWindow = NULL; m_popupWindow = NULL;
m_tipWindow = NULL; m_tipWindow = NULL;
m_tipOpened = false; m_tipOpened = false;
@ -112,8 +112,8 @@ ToolBar::ToolBar()
ToolBox* toolbox = App::instance()->getToolBox(); ToolBox* toolbox = App::instance()->getToolBox();
for (ToolIterator it = toolbox->begin(); it != toolbox->end(); ++it) { for (ToolIterator it = toolbox->begin(); it != toolbox->end(); ++it) {
Tool* tool = *it; Tool* tool = *it;
if (m_selected_in_group.find(tool->getGroup()) == m_selected_in_group.end()) if (m_selectedInGroup.find(tool->getGroup()) == m_selectedInGroup.end())
m_selected_in_group[tool->getGroup()] = tool; m_selectedInGroup[tool->getGroup()] = tool;
} }
} }
@ -125,7 +125,7 @@ ToolBar::~ToolBar()
bool ToolBar::isToolVisible(Tool* tool) bool ToolBar::isToolVisible(Tool* tool)
{ {
return (m_selected_in_group[tool->getGroup()] == tool); return (m_selectedInGroup[tool->getGroup()] == tool);
} }
bool ToolBar::onProcessMessage(Message* msg) bool ToolBar::onProcessMessage(Message* msg)
@ -141,10 +141,9 @@ bool ToolBar::onProcessMessage(Message* msg)
closeTipWindow(); closeTipWindow();
ToolGroupList::iterator it = toolbox->begin_group(); ToolGroupList::iterator it = toolbox->begin_group();
for (int c=0; c<groups; ++c, ++it) { for (int c=0; c<groups; ++c, ++it) {
ToolGroup* tool_group = *it; ToolGroup* tool_group = *it;
Tool* tool = m_selected_in_group[tool_group]; Tool* tool = m_selectedInGroup[tool_group];
toolrc = getToolGroupBounds(c); toolrc = getToolGroupBounds(c);
if (mouseMsg->position().y >= toolrc.y && if (mouseMsg->position().y >= toolrc.y &&
@ -153,6 +152,11 @@ bool ToolBar::onProcessMessage(Message* msg)
invalidate(); invalidate();
openPopupWindow(c, tool_group); openPopupWindow(c, tool_group);
// We capture the mouse so the user can continue navigating
// the ToolBar to open other groups while he is pressing the
// mouse button.
captureMouse();
} }
} }
@ -189,7 +193,7 @@ bool ToolBar::onProcessMessage(Message* msg)
for (int c=0; c<groups; ++c, ++it) { for (int c=0; c<groups; ++c, ++it) {
ToolGroup* tool_group = *it; ToolGroup* tool_group = *it;
Tool* tool = m_selected_in_group[tool_group]; Tool* tool = m_selectedInGroup[tool_group];
toolrc = getToolGroupBounds(c); toolrc = getToolGroupBounds(c);
if (mouseMsg->position().y >= toolrc.y && if (mouseMsg->position().y >= toolrc.y &&
@ -197,7 +201,7 @@ bool ToolBar::onProcessMessage(Message* msg)
new_hot_tool = tool; new_hot_tool = tool;
new_hot_index = c; new_hot_index = c;
if ((m_open_on_hot) && (m_hot_tool != new_hot_tool)) if ((m_openOnHot) && (m_hotTool != new_hot_tool))
openPopupWindow(c, tool_group); openPopupWindow(c, tool_group);
break; break;
} }
@ -216,31 +220,63 @@ bool ToolBar::onProcessMessage(Message* msg)
} }
// hot button changed // hot button changed
if (new_hot_tool != m_hot_tool || if (new_hot_tool != m_hotTool ||
new_hot_index != m_hot_index) { new_hot_index != m_hotIndex) {
m_hot_tool = new_hot_tool; m_hotTool = new_hot_tool;
m_hot_index = new_hot_index; m_hotIndex = new_hot_index;
invalidate(); invalidate();
if (m_hot_index != NoneIndex) if (m_hotIndex != NoneIndex)
openTipWindow(m_hot_index, m_hot_tool); openTipWindow(m_hotIndex, m_hotTool);
else else
closeTipWindow(); closeTipWindow();
if (m_hot_tool) if (m_hotTool) {
StatusBar::instance()->showTool(0, m_hot_tool); if (hasCapture())
UIContext::instance()->getSettings()->setCurrentTool(m_hotTool);
else
StatusBar::instance()->showTool(0, m_hotTool);
}
}
// We can change the current tool if the user is dragging the
// mouse over the ToolBar.
if (hasCapture()) {
MouseMessage* mouseMsg = static_cast<MouseMessage*>(msg);
Widget* pick = getManager()->pick(mouseMsg->position());
if (ToolStrip* strip = dynamic_cast<ToolStrip*>(pick)) {
releaseMouse();
MouseMessage* mouseMsg2 = new MouseMessage(
kMouseDownMessage,
mouseMsg->buttons(),
mouseMsg->position());
mouseMsg2->addRecipient(strip);
getManager()->enqueueMessage(mouseMsg2);
}
} }
break; break;
} }
case kMouseUpMessage:
if (!hasCapture())
break;
releaseMouse();
// fallthrough
case kMouseLeaveMessage: case kMouseLeaveMessage:
if (hasCapture())
break;
closeTipWindow(); closeTipWindow();
if (!m_popupWindow) if (!m_popupWindow)
m_tipOpened = false; m_tipOpened = false;
m_hot_tool = NULL; m_hotTool = NULL;
m_hot_index = NoneIndex; m_hotIndex = NoneIndex;
invalidate(); invalidate();
StatusBar::instance()->clearText(); StatusBar::instance()->clearText();
@ -285,12 +321,12 @@ void ToolBar::onPaint(ui::PaintEvent& ev)
for (int c=0; c<groups; ++c, ++it) { for (int c=0; c<groups; ++c, ++it) {
ToolGroup* tool_group = *it; ToolGroup* tool_group = *it;
Tool* tool = m_selected_in_group[tool_group]; Tool* tool = m_selectedInGroup[tool_group];
ui::Color face; ui::Color face;
int nw; int nw;
if (UIContext::instance()->getSettings()->getCurrentTool() == tool || if (UIContext::instance()->getSettings()->getCurrentTool() == tool ||
m_hot_index == c) { m_hotIndex == c) {
nw = PART_TOOLBUTTON_HOT_NW; nw = PART_TOOLBUTTON_HOT_NW;
face = hotFace; face = hotFace;
} }
@ -316,7 +352,7 @@ void ToolBar::onPaint(ui::PaintEvent& ev)
// Draw button to show tool configuration // Draw button to show tool configuration
toolrc = getToolGroupBounds(ConfigureToolIndex); toolrc = getToolGroupBounds(ConfigureToolIndex);
toolrc.offset(-getBounds().x, -getBounds().y); toolrc.offset(-getBounds().x, -getBounds().y);
bool isHot = (m_hot_index == ConfigureToolIndex); bool isHot = (m_hotIndex == ConfigureToolIndex);
theme->draw_bounds_nw(g, theme->draw_bounds_nw(g,
toolrc, toolrc,
isHot ? PART_TOOLBUTTON_HOT_NW: isHot ? PART_TOOLBUTTON_HOT_NW:
@ -333,7 +369,7 @@ void ToolBar::onPaint(ui::PaintEvent& ev)
// Draw button to show/hide mini editor // Draw button to show/hide mini editor
toolrc = getToolGroupBounds(MiniEditorVisibilityIndex); toolrc = getToolGroupBounds(MiniEditorVisibilityIndex);
toolrc.offset(-getBounds().x, -getBounds().y); toolrc.offset(-getBounds().x, -getBounds().y);
isHot = (m_hot_index == MiniEditorVisibilityIndex || isHot = (m_hotIndex == MiniEditorVisibilityIndex ||
App::instance()->getMainWindow()->getMiniEditor()->isMiniEditorEnabled()); App::instance()->getMainWindow()->getMiniEditor()->isMiniEditorEnabled());
theme->draw_bounds_nw(g, theme->draw_bounds_nw(g,
toolrc, toolrc,
@ -383,11 +419,11 @@ void ToolBar::openPopupWindow(int group_index, ToolGroup* tool_group)
if (tool->getGroup() == tool_group) if (tool->getGroup() == tool_group)
++count; ++count;
} }
m_openOnHot = true;
if (count <= 1) if (count <= 1)
return; return;
// In case this tool contains more than just one tool, show the popup window // In case this tool contains more than just one tool, show the popup window
m_open_on_hot = true;
m_popupWindow = new PopupWindow("", false); m_popupWindow = new PopupWindow("", false);
m_popupWindow->Close.connect(Bind<void, ToolBar, ToolBar>(&ToolBar::onClosePopup, this)); m_popupWindow->Close.connect(Bind<void, ToolBar, ToolBar>(&ToolBar::onClosePopup, this));
@ -556,7 +592,7 @@ void ToolBar::selectTool(Tool* tool)
{ {
ASSERT(tool != NULL); ASSERT(tool != NULL);
m_selected_in_group[tool->getGroup()] = tool; m_selectedInGroup[tool->getGroup()] = tool;
UIContext::instance()->getSettings()->setCurrentTool(tool); UIContext::instance()->getSettings()->setCurrentTool(tool);
invalidate(); invalidate();
@ -569,8 +605,8 @@ void ToolBar::onClosePopup()
if (!hasMouse()) if (!hasMouse())
m_tipOpened = false; m_tipOpened = false;
m_open_on_hot = false; m_openOnHot = false;
m_hot_tool = NULL; m_hotTool = NULL;
invalidate(); invalidate();
} }
@ -582,7 +618,7 @@ ToolStrip::ToolStrip(ToolGroup* group, ToolBar* toolbar)
: Widget(kGenericWidget) : Widget(kGenericWidget)
{ {
m_group = group; m_group = group;
m_hot_tool = NULL; m_hotTool = NULL;
m_toolbar = toolbar; m_toolbar = toolbar;
m_overlapped = NULL; m_overlapped = NULL;
@ -611,8 +647,13 @@ bool ToolStrip::onProcessMessage(Message* msg)
{ {
switch (msg->type()) { switch (msg->type()) {
case kMouseDownMessage:
captureMouse();
// fallthrough
case kMouseMoveMessage: { case kMouseMoveMessage: {
gfx::Point mousePos = static_cast<MouseMessage*>(msg)->position(); MouseMessage* mouseMsg = static_cast<MouseMessage*>(msg);
gfx::Point mousePos = mouseMsg->position();
ToolBox* toolbox = App::instance()->getToolBox(); ToolBox* toolbox = App::instance()->getToolBox();
Tool* hot_tool = NULL; Tool* hot_tool = NULL;
Rect toolrc; Rect toolrc;
@ -630,27 +671,44 @@ bool ToolStrip::onProcessMessage(Message* msg)
} }
// Hot button changed // Hot button changed
if (m_hot_tool != hot_tool) { if (m_hotTool != hot_tool) {
m_hot_tool = hot_tool; m_hotTool = hot_tool;
invalidate(); invalidate();
// Show the tooltip for the hot tool // Show the tooltip for the hot tool
if (m_hot_tool) if (m_hotTool)
m_toolbar->openTipWindow(m_group, m_hot_tool); m_toolbar->openTipWindow(m_group, m_hotTool);
else else
m_toolbar->closeTipWindow(); m_toolbar->closeTipWindow();
if (m_hot_tool) if (m_hotTool)
StatusBar::instance()->showTool(0, m_hot_tool); StatusBar::instance()->showTool(0, m_hotTool);
}
if (hasCapture()) {
if (m_hotTool) {
m_toolbar->selectTool(m_hotTool);
invalidate();
}
Widget* pick = getManager()->pick(mouseMsg->position());
if (ToolBar* bar = dynamic_cast<ToolBar*>(pick)) {
releaseMouse();
MouseMessage* mouseMsg2 = new MouseMessage(
kMouseDownMessage,
mouseMsg->buttons(),
mouseMsg->position());
mouseMsg2->addRecipient(bar);
getManager()->enqueueMessage(mouseMsg2);
}
} }
break; break;
} }
case kMouseDownMessage: case kMouseUpMessage:
if (m_hot_tool) { if (hasCapture())
m_toolbar->selectTool(m_hot_tool);
closeWindow(); closeWindow();
}
break; break;
} }
@ -696,7 +754,7 @@ void ToolStrip::onPaint(PaintEvent& ev)
int nw; int nw;
if (UIContext::instance()->getSettings()->getCurrentTool() == tool || if (UIContext::instance()->getSettings()->getCurrentTool() == tool ||
m_hot_tool == tool) { m_hotTool == tool) {
nw = PART_TOOLBUTTON_HOT_NW; nw = PART_TOOLBUTTON_HOT_NW;
face = theme->getColor(ThemeColor::ButtonHotFace); face = theme->getColor(ThemeColor::ButtonHotFace);
} }

View File

@ -71,16 +71,16 @@ namespace app {
void onClosePopup(); void onClosePopup();
// What tool is selected for each tool-group // What tool is selected for each tool-group
std::map<const tools::ToolGroup*, tools::Tool*> m_selected_in_group; std::map<const tools::ToolGroup*, tools::Tool*> m_selectedInGroup;
// Index of the tool group or special button highlighted. // Index of the tool group or special button highlighted.
int m_hot_index; int m_hotIndex;
// What tool has the mouse above // What tool has the mouse above
tools::Tool* m_hot_tool; tools::Tool* m_hotTool;
// True if the popup-window must be opened when a tool-button is hot // True if the popup-window must be opened when a tool-button is hot
bool m_open_on_hot; bool m_openOnHot;
// Window displayed to show a tool-group // Window displayed to show a tool-group
ui::PopupWindow* m_popupWindow; ui::PopupWindow* m_popupWindow;