Warning: session_start(): open(/var/lib/php/sessions/sess_4ef39dlbasf8q990kqt9fq1vki, O_RDWR) failed: No space left on device (28) in /var/www/tb-usercake/models/config.php on line 51
Warning: session_start(): Failed to read session data: files (path: /var/lib/php/sessions) in /var/www/tb-usercake/models/config.php on line 51
!7
abstract sclass DynTabs extends DynModule {
sclass Tab { S name, moduleID; }
transient NotifyingList tabs;
transient JComponent grid;
new Set tabbableLibIDs;
int gapBelow = 0;
transient O isTabbableModule; // func(module) -> bool
bool isTabbableModule(O mod) {
if (isTabbableModule != null) ret isTrue(callF(isTabbableModule, mod));
ret contains(tabbableLibIDs, dm_moduleLibID(mod));
}
void start2 {}
start {
initialBounds();
tabs = notifyingList(r change + r updateTabs);
start2();
dm_vmBus_onMessage_q('moduleStarted, voidfunc(S moduleID) { addTabForModule(moduleID) });
dm_vmBus_onMessage_q('deletingModule, voidfunc(O module) { removeTabForModule(dm_moduleID(module)) });
dm_vmBus_onMessage_q('moduleNameChange, voidfunc(O module, S oldName, S newName) { updateTabForModule(dm_moduleID(module)) });
dm_q(r { for (S moduleID : dm_listModuleIDs()) addTabForModule(moduleID) });
dm_vmBus_onMessage_q('newActiveModule, vf selectModule);
}
void initialBounds {
if (dm_bounds() == null) dm_setBounds(100, 25, dm_desktopWidth()-200, 70);
}
visualize {
grid = hgridWithSpacing(); updateTabs();
ret centerAndEastWithMargins(grid, jbutton("+", rThread dm_newEditor));
}
void updateTabs q {
if (grid == null) ret;
replaceComponentsOfHGrid(grid, map(cloneList(tabs), func(final Tab tab) -> JComponent {
JLabel lbl = setOpaqueBackground(toColor("E0E0E0"), addInnerMargin(3, 0, jcenteredlabel(tab.name)));
onLeftClick(lbl, r { showModule(tab.moduleID) });
componentPopupMenuItems_top(lbl,
"Close Tab", rThread { dm_deleteModule(tab.moduleID) },
"Move Left", rThread { syncMoveElementLeft(tabs, tab) },
"Move Right", rThread { syncMoveElementRight(tabs, tab) });
ret lbl;
}));
selectModule(dm_activeModule());
}
void addTabForModule(S moduleID) {
if (isTabbableModule(moduleID) && !containsWhere(tabs, +moduleID)) {
tabs.add(nu Tab(name := moduleName(moduleID), +moduleID));
if (dm_isVisible(moduleID)) placeUnderMe(moduleID);
}
}
void removeTabForModule(S moduleID) { removeWhere(tabs, +moduleID); }
void updateTabForModule(S moduleID) {
Tab tab = firstWhere(tabs, +moduleID);
if (tab != null) { tab.name = moduleName(moduleID); tabs.change(); }
}
S moduleName(O module) {
ret dropPrefix("Editing: ", dm_moduleName(module));
}
void selectModule(O module) {
if (module == null || dm_isMe(module) || !dm_isVisible()) ret;
int idx = indexOfWhere(tabs, moduleID := dm_moduleID(module));
for i over tabs: {
JComponent c = cast getComponentAtIndex(grid, i);
if (i == idx) makeBold(c); else makeNonBold(c);
}
}
void showModule(O module) { dm_showModule(module); placeUnderMe(module); }
void placeUnderMe(O module) {
if (!dm_isVisible()) ret;
Rect r = dm_bounds(module), me = dm_bounds();
if (me != null) dm_setBounds(module, me.x, me.y2()+gapBelow, me.w, r.h);
}
}