Skip to content

Commit

Permalink
Traktor: CaptionBar now inherit from ToolBar; allowing caption to con…
Browse files Browse the repository at this point in the history
…tain toolbar items. Also simplified EventSubject since prioritize by class never worked.
  • Loading branch information
apistol78 committed May 21, 2024
1 parent f96e6c0 commit 92542fd
Show file tree
Hide file tree
Showing 8 changed files with 69 additions and 117 deletions.
58 changes: 27 additions & 31 deletions code/Editor/App/EditorForm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -476,7 +476,7 @@ bool EditorForm::create(const CommandLine& cmdLine)
1280_ut,
900_ut,
ui::WsResizable | ui::WsSystemBox | ui::WsMinimizeBox | ui::WsMaximizeBox | ui::WsNoCanvas,
new ui::TableLayout(L"100%", L"*,*,*,100%,*", 0_ut, 0_ut)
new ui::TableLayout(L"100%", L"*,*,100%,*", 0_ut, 0_ut)
))
return false;

Expand All @@ -490,12 +490,8 @@ bool EditorForm::create(const CommandLine& cmdLine)
m_shortcutTable->create();
m_shortcutTable->addEventHandler< ui::ShortcutEvent >(this, &EditorForm::eventShortcut);

// Create caption bar.
Ref< ui::CaptionBar > captionBar = new ui::CaptionBar();
captionBar->create(this);

// Create menu bar.
m_menuBar = new ui::ToolBar();
// Create caption menu bar.
m_menuBar = new ui::CaptionBar();
m_menuBar->create(this);
m_menuBar->addEventHandler< ui::ToolBarButtonClickEvent >(this, &EditorForm::eventMenuClick);

Expand Down Expand Up @@ -541,30 +537,30 @@ bool EditorForm::create(const CommandLine& cmdLine)
m_menuBar->addItem(menuBuild);

// Create toolbar.
m_toolBar = new ui::ToolBar();
m_toolBar->create(this, ui::WsNone);
m_toolBar->addImage(new ui::StyleBitmap(L"Editor.ToolBar.Save"));
m_toolBar->addImage(new ui::StyleBitmap(L"Editor.ToolBar.Cut"));
m_toolBar->addImage(new ui::StyleBitmap(L"Editor.ToolBar.Copy"));
m_toolBar->addImage(new ui::StyleBitmap(L"Editor.ToolBar.Paste"));
m_toolBar->addImage(new ui::StyleBitmap(L"Editor.ToolBar.Undo"));
m_toolBar->addImage(new ui::StyleBitmap(L"Editor.ToolBar.Redo"));
m_toolBar->addImage(new ui::StyleBitmap(L"Editor.ToolBar.Build"));
m_toolBar->addImage(new ui::StyleBitmap(L"Editor.ToolBar.CancelBuild"));

m_toolBar->addItem(new ui::ToolBarButton(i18n::Text(L"TOOLBAR_SAVE"), 0, ui::Command(L"Editor.Save")));
m_toolBar->addItem(new ui::ToolBarSeparator());
m_toolBar->addItem(new ui::ToolBarButton(i18n::Text(L"TOOLBAR_CUT"), 1, ui::Command(L"Editor.Cut")));
m_toolBar->addItem(new ui::ToolBarButton(i18n::Text(L"TOOLBAR_COPY"), 2, ui::Command(L"Editor.Copy")));
m_toolBar->addItem(new ui::ToolBarButton(i18n::Text(L"TOOLBAR_PASTE"), 3, ui::Command(L"Editor.Paste")));
m_toolBar->addItem(new ui::ToolBarSeparator());
m_toolBar->addItem(new ui::ToolBarButton(i18n::Text(L"TOOLBAR_UNDO"), 4, ui::Command(L"Editor.Undo")));
m_toolBar->addItem(new ui::ToolBarButton(i18n::Text(L"TOOLBAR_REDO"), 5, ui::Command(L"Editor.Redo")));
m_toolBar->addItem(new ui::ToolBarSeparator());
m_toolBar->addItem(new ui::ToolBarButton(i18n::Text(L"TOOLBAR_BUILD"), 6, ui::Command(L"Editor.Build")));
m_toolBar->addItem(new ui::ToolBarButton(i18n::Text(L"TOOLBAR_CANCEL_BUILD"), 7, ui::Command(L"Editor.CancelBuild")));
m_toolBar->addItem(new ui::ToolBarSeparator());
m_toolBar->addEventHandler< ui::ToolBarButtonClickEvent >(this, &EditorForm::eventToolClicked);
m_toolBar = new ui::ToolBar();
m_toolBar->create(this, ui::WsNone);
m_toolBar->addImage(new ui::StyleBitmap(L"Editor.ToolBar.Save"));
m_toolBar->addImage(new ui::StyleBitmap(L"Editor.ToolBar.Cut"));
m_toolBar->addImage(new ui::StyleBitmap(L"Editor.ToolBar.Copy"));
m_toolBar->addImage(new ui::StyleBitmap(L"Editor.ToolBar.Paste"));
m_toolBar->addImage(new ui::StyleBitmap(L"Editor.ToolBar.Undo"));
m_toolBar->addImage(new ui::StyleBitmap(L"Editor.ToolBar.Redo"));
m_toolBar->addImage(new ui::StyleBitmap(L"Editor.ToolBar.Build"));
m_toolBar->addImage(new ui::StyleBitmap(L"Editor.ToolBar.CancelBuild"));

m_toolBar->addItem(new ui::ToolBarButton(i18n::Text(L"TOOLBAR_SAVE"), 0, ui::Command(L"Editor.Save")));
m_toolBar->addItem(new ui::ToolBarSeparator());
m_toolBar->addItem(new ui::ToolBarButton(i18n::Text(L"TOOLBAR_CUT"), 1, ui::Command(L"Editor.Cut")));
m_toolBar->addItem(new ui::ToolBarButton(i18n::Text(L"TOOLBAR_COPY"), 2, ui::Command(L"Editor.Copy")));
m_toolBar->addItem(new ui::ToolBarButton(i18n::Text(L"TOOLBAR_PASTE"), 3, ui::Command(L"Editor.Paste")));
m_toolBar->addItem(new ui::ToolBarSeparator());
m_toolBar->addItem(new ui::ToolBarButton(i18n::Text(L"TOOLBAR_UNDO"), 4, ui::Command(L"Editor.Undo")));
m_toolBar->addItem(new ui::ToolBarButton(i18n::Text(L"TOOLBAR_REDO"), 5, ui::Command(L"Editor.Redo")));
m_toolBar->addItem(new ui::ToolBarSeparator());
m_toolBar->addItem(new ui::ToolBarButton(i18n::Text(L"TOOLBAR_BUILD"), 6, ui::Command(L"Editor.Build")));
m_toolBar->addItem(new ui::ToolBarButton(i18n::Text(L"TOOLBAR_CANCEL_BUILD"), 7, ui::Command(L"Editor.CancelBuild")));
m_toolBar->addItem(new ui::ToolBarSeparator());
m_toolBar->addEventHandler< ui::ToolBarButtonClickEvent >(this, &EditorForm::eventToolClicked);

updateTitle();
updateMRU();
Expand Down
5 changes: 3 additions & 2 deletions code/Editor/App/EditorForm.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,14 @@ class StreamServer;
namespace traktor::ui
{

class ShortcutTable;
class CaptionBar;
class Dock;
class DockPane;
class Menu;
class MenuItem;
class MultiSplitter;
class ProgressBar;
class ShortcutTable;
class StatusBar;
class Tab;
class ToolBar;
Expand Down Expand Up @@ -192,7 +193,7 @@ class EditorForm
Ref< ui::DockPane > m_paneWest;
Ref< ui::DockPane > m_paneEast;
Ref< ui::DockPane > m_paneSouth;
Ref< ui::ToolBar > m_menuBar;
Ref< ui::CaptionBar > m_menuBar;
Ref< ui::ToolBar > m_toolBar;
Ref< ui::MenuItem > m_menuItemRecent;
Ref< ui::MenuItem > m_menuItemOtherPanels;
Expand Down
71 changes: 24 additions & 47 deletions code/Ui/CaptionBar.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* TRAKTOR
* Copyright (c) 2023 Anders Pistol.
* Copyright (c) 2023-2024 Anders Pistol.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
Expand All @@ -15,18 +15,12 @@

namespace traktor::ui
{
namespace
{

const Unit c_preferedHeightMargin = 8_ut;

}

T_IMPLEMENT_RTTI_CLASS(L"traktor.ui.CaptionBar", CaptionBar, Widget)
T_IMPLEMENT_RTTI_CLASS(L"traktor.ui.CaptionBar", CaptionBar, ToolBar)

bool CaptionBar::create(Widget* parent, uint32_t style)
{
if (!Widget::create(parent, style))
if (!ToolBar::create(parent, style))
return false;

m_buttonMinimize = new MiniButton();
Expand All @@ -46,14 +40,13 @@ bool CaptionBar::create(Widget* parent, uint32_t style)
addEventHandler< MouseDoubleClickEvent >(this, &CaptionBar::eventMouseDoubleClick);
addEventHandler< MouseMoveEvent >(this, &CaptionBar::eventMouseMove);
addEventHandler< SizeEvent >(this, &CaptionBar::eventSize);
addEventHandler< PaintEvent >(this, &CaptionBar::eventPaint);

return true;
}

Size CaptionBar::getPreferredSize(const Size& hint) const
{
Size preferedSize(0, getFontMetric().getHeight() + pixel(c_preferedHeightMargin) * 2);
Size preferedSize = ToolBar::getPreferredSize(hint);
if (getParent())
preferedSize.cx = getParent()->getInnerRect().getWidth();
return preferedSize;
Expand Down Expand Up @@ -85,37 +78,53 @@ void CaptionBar::eventButtonClick(ButtonClickEvent* event)

void CaptionBar::eventMouseButtonDown(MouseButtonDownEvent* event)
{
// Check if user press on a toolbar item first; then don't move form,
ToolBarItem* item = getItem(event->getPosition());
if (item != nullptr)
return;

m_mousePosition = getParent()->clientToScreen(event->getPosition());
m_parentRect = getParent()->getRect();

m_haveCapture = true;
setCapture();

event->consume();
}

void CaptionBar::eventMouseButtonUp(MouseButtonUpEvent* event)
{
releaseCapture();
if (m_haveCapture)
{
m_haveCapture = false;
releaseCapture();
event->consume();
}
}

void CaptionBar::eventMouseDoubleClick(MouseDoubleClickEvent* event)
{
Form* parentForm = dynamic_type_cast< Form* >(getParent());
Form* parentForm = dynamic_type_cast< Form* >(getAncestor());
if (!parentForm)
return;

if (!parentForm->isMaximized())
parentForm->maximize();
else
parentForm->restore();

event->consume();
}

void CaptionBar::eventMouseMove(MouseMoveEvent* event)
{
if (!hasCapture())
if (!m_haveCapture)
return;

const Point position = getParent()->clientToScreen(event->getPosition());
const Rect rc = m_parentRect.offset(position - m_mousePosition);
getParent()->setRect(rc);

event->consume();
}

void CaptionBar::eventSize(SizeEvent* event)
Expand Down Expand Up @@ -145,36 +154,4 @@ void CaptionBar::eventSize(SizeEvent* event)
}
}

void CaptionBar::eventPaint(PaintEvent* event)
{
Canvas& canvas = event->getCanvas();
Rect rc = getInnerRect();
const StyleSheet* ss = getStyleSheet();

canvas.setBackground(ss->getColor(this, L"background-color"));
canvas.fillRect(rc);

const std::wstring text = getParent()->getText();
canvas.setForeground(ss->getColor(this, L"color"));

Font font = getFont();
font.setBold(true);
font.setSize(font.getSize() + 2_ut);
canvas.setFont(font);

Rect rcText = rc;
rcText.left = pixel(8_ut);
rcText.right = rc.right;
canvas.drawText(rcText, text, AnLeft, AnCenter);

#if defined(_WIN32)
// #hack When using Form without a system caption Windows doesn't draw top shadow line.
const Color4ub shadowColor = ss->getColor(this, L"background-color") * Color4ub(128, 128, 128, 255);
canvas.setForeground(shadowColor);
canvas.drawLine(rc.left, rc.top, rc.right, rc.top);
#endif

event->consume();
}

}
9 changes: 4 additions & 5 deletions code/Ui/CaptionBar.h
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
/*
* TRAKTOR
* Copyright (c) 2023 Anders Pistol.
* Copyright (c) 2023-2024 Anders Pistol.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#pragma once

#include "Ui/Widget.h"
#include "Ui/ToolBar/ToolBar.h"

// import/export mechanism.
#undef T_DLLCLASS
Expand All @@ -26,7 +26,7 @@ class MiniButton;
/*! Caption bar control.
* \ingroup UI
*/
class T_DLLCLASS CaptionBar : public Widget
class T_DLLCLASS CaptionBar : public ToolBar
{
T_RTTI_CLASS;

Expand All @@ -41,6 +41,7 @@ class T_DLLCLASS CaptionBar : public Widget
Ref< MiniButton > m_buttonClose;
Point m_mousePosition;
Rect m_parentRect;
bool m_haveCapture = false;

void eventButtonClick(ButtonClickEvent* event);

Expand All @@ -53,8 +54,6 @@ class T_DLLCLASS CaptionBar : public Widget
void eventMouseMove(MouseMoveEvent* event);

void eventSize(SizeEvent* event);

void eventPaint(PaintEvent* event);
};

}
36 changes: 8 additions & 28 deletions code/Ui/EventSubject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,17 +33,14 @@ void EventSubject::raiseEvent(Event* event)
// Invoke event handlers reversed as the most prioritized are at the end and they should
// be able to "consume" the event so it wont reach other, less prioritized, handlers.
const auto& eventHandlers = i->second;
for (size_t j = 0; j < eventHandlers.handlers.size(); ++j)
for (Ref< IEventHandler > eventHandler : eventHandlers.handlers)
{
for (Ref< IEventHandler > eventHandler : eventHandlers.handlers[j])
{
if (!eventHandler)
continue;
if (!eventHandler)
continue;

eventHandler->notify(event);
if (event->consumed())
break;
}
eventHandler->notify(event);
if (event->consumed())
break;
}
}
}
Expand All @@ -57,30 +54,13 @@ void EventSubject::removeAllEventHandlers()
void EventSubject::addEventHandler(const TypeInfo& eventType, IEventHandler* eventHandler)
{
auto& eventHandlers = m_eventHandlers[&eventType];
int32_t depth = 0;

// Use class hierarchy depth as handler priority.
for (const TypeInfo* type = getTypeInfo().getSuper(); type; type = type->getSuper())
++depth;

// Skip both Object and EventSubject bases as they will only take up space in the event vectors.
depth -= 2;
T_ASSERT(depth >= 0);

// Ensure there are enough room in the event handlers vector.
if (depth >= (int32_t)eventHandlers.handlers.size())
eventHandlers.handlers.resize(depth + 1);

// Insert event handler first to ensure it's called before previously added handlers.
auto& handlers = eventHandlers.handlers[depth];
handlers.insert(handlers.begin(), eventHandler);
eventHandlers.handlers.push_front(eventHandler);
}

void EventSubject::removeEventHandler(const TypeInfo& eventType, IEventHandler* eventHandler)
{
auto& eventHandlers = m_eventHandlers[&eventType];
for (auto i = eventHandlers.handlers.begin(); i != eventHandlers.handlers.end(); ++i)
i->remove(eventHandler);
eventHandlers.handlers.remove(eventHandler);
}

bool EventSubject::hasEventHandler(const TypeInfo& eventType)
Expand Down
5 changes: 1 addition & 4 deletions code/Ui/EventSubject.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
#include "Core/Ref.h"
#include "Core/RefArray.h"
#include "Core/Containers/SmallMap.h"
#include "Core/Containers/StaticVector.h"
#include "Ui/Enums.h"

// import/export mechanism.
Expand Down Expand Up @@ -180,12 +179,10 @@ class T_DLLCLASS EventSubject : public Object
void removeAllEventHandlers();

private:
typedef RefArray< IEventHandler > EventHandlers;

struct HandlerEntry
{
int32_t disableCounter = 0;
StaticVector< EventHandlers, 16 > handlers;
RefArray< IEventHandler > handlers;
};

SmallMap< const TypeInfo*, HandlerEntry > m_eventHandlers;
Expand Down
1 change: 1 addition & 0 deletions code/Ui/StyleBitmap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#include "Core/Containers/StaticVector.h"
#include "Core/Io/DynamicMemoryStream.h"
#include "Core/Io/FileSystem.h"
#include "Core/Io/MemoryStream.h"
Expand Down
1 change: 1 addition & 0 deletions code/Ui/Widget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#include "Core/Containers/StaticVector.h"
#include "Core/Log/Log.h"
#include "Core/Misc/SafeDestroy.h"
#include "Core/Misc/String.h"
Expand Down

0 comments on commit 92542fd

Please sign in to comment.