!7 sclass TaskBar extends DynSCP { transient SimpleLiveValue lvInvisible = stringLiveValue(); transient bool vertical; transient ReliableSingleThread rst = new(r { revisualize2(); sleepSeconds(1); }); bool shouldBeVertical() { Rect r = dm_getBounds(); ret r != null && r.h > r.w*0.3; } JComponent visualize2() { L buttons = makeButtons(); JLabel lblInvisible = onLeftClick(jLiveValueLabel(lvInvisible), r dm_showInvisibleModulesList); ret (vertical = shouldBeVertical()) ? jscroll_dynamicvstack(dynamicVStack2(listPlusInBeginning( (L) (L) buttons, withMargin(6, lblInvisible)))) : centerAndEast(hgrid(buttons), withLeftAndRightMargin(6, 3, lblInvisible)); } void enhanceFrame(Container f) { super.enhanceFrame(f); addTitlePopupMenuItem(f, "Place on bottom", rThread placeOnBottom); onResize(f, r { if (vertical != shouldBeVertical()) { print("Revisualizing task bar"); vertical = shouldBeVertical(); revisualize(); } }); } void placeOnBottom { Container frame = dm_frame(); Rectangle desktop = getBounds(dm_desktopPane()); if (frame != null && desktop != null) { packInternalFrameVertically_noFix((JInternalFrame) frame); Rectangle me = getBounds(frame); dm_setBounds(dm_current(), 0, desktop.height-me.height, desktop.width, me.height); } } void update { rst.trigger(); } L makeButtons() { new L out; new L invisible; L modules = dm_listModules(); // TODO: get module names all at once for (fO m : modules) if (m != this) if (dm_isVisible(m)) { final WeakReference ref = new(m); // allow GC for modules out.add(jbutton(dm_moduleName(m), r { dm_showModule(ref!) })); } else invisible.add(m); lvInvisible.set(empty(invisible) ? "" : "+ " + l(invisible) + " invisible"); ret out; } }