World

The top level navigation in Glamorous Toolkit is called Glamorous World. It is implemented in the GToolkit-World package and consists of a custom window space GtWorld BlSpace subclass: #GtWorld instanceVariableNames: 'worldElement' classVariableNames: '' package: 'GToolkit-World-UI' with GtWorldElement GtWorldTabElement subclass: #GtWorldElement instanceVariableNames: 'spotterDropdown subSpaceDropdown notificationsDropdown announcer' classVariableNames: 'IsWorldSpotterPreviewDisplayed WorldSpotterSize' package: 'GToolkit-World-UI' as its root element. The interface consists of a tab group with a GtHome BlElement subclass: #GtHome instanceVariableNames: 'sectionsHolder feedElement notificationsElement knowledgeBase' classVariableNames: '' package: 'GToolkit-World-UI' default tab available at all times. Additional tabs can be closed and moved around by the means of drag and drop.

Dragging tabs to change their order

It is possible to rearrange tabs in the world by drag and dropping them. Each tab except the home one is made draggable by adding a custom drag handler instantiated by GtWorldTabElement>>#createTabDragHandler createTabDragHandler ^ BlDragHandler new restrictDragToHorizontal; liftItem: [ :aSourceElement | BlDragItem new sourceElement: aSourceElement; domainObject: aSourceElement model; stencil: [ :aDragItem | (self createBaseTab: aDragItem domainObject) select; opacity: 0.85 ] ] . The tab group widget then creates a drop handler BrGlamorousSpaceTabGroupAptitude>>#createTabDropHandler createTabDropHandler ^ BlDropHandler new acceptOnlyFromThisElement; whenDragOverDo: [ :anItemsDraggedOverEvent | | container locationElement position | container := anItemsDraggedOverEvent currentTarget. locationElement := container childWithId: #'drop-area--drop-location' ifFound: [ :anElement | anElement ] ifNone: [ | anElement | anElement := BlElement new background: container theme default primaryBorderColor; width: 2; elevation: (BlRelativeElevation elevation: 100); constraintsDo: [ :c | c ignoreByLayout. c vertical matchParent ]. container addChild: anElement as: #'drop-area--drop-location'. anElement ]. position := anItemsDraggedOverEvent position x. self dragOverTo: position in: container withMarker: locationElement ]; whenDragLeftDo: [ :anItemsLeftEvent | anItemsLeftEvent currentTarget removeChildNamed: #'drop-area--drop-location' ]; whenHorizontalDroppedDo: [ :anItemsDroppedEvent :anIndex | self dropTabs: (anItemsDroppedEvent items collect: [ :eachDragItem | eachDragItem sourceElement ]) at: anIndex ] that is responsible for interactivity and detection of a tab index where drop should occur. Eventually, the actuall tab movement happens in BrGlamorousSpaceTabGroupAptitude>>#dropTabs:at: dropTabs: aCollectionOfTabs at: anIndex anIndex = 0 ifTrue: [ ^ self ]. self widgetDo: [ :aTabGroup | | targetTabIndex | targetTabIndex := anIndex. aCollectionOfTabs do: [ :eachTab | aTabGroup moveTab: eachTab atCursor: targetTabIndex ]. aCollectionOfTabs ifNotEmpty: [ :theTabs | theTabs first select ] ] .