// Note: renderUIUrl etc are called in Swing thread // TODO: improve AutoComboBox and put it back in srecord noeq UIURLSystem(Enterable owner, SimpleLiveValue uiURL) { settable bool showHomeButton = true; // key: ui URL transient Map uiMap = syncCIMap(); // these are additionally displayed at the top of the list // first URL will be shown as "Home" button (if home button is enabled) LS preferredURLs = syncList(); sclass Entry { S url; S toolTip; IF0 makeComponent; *(S *url, IF0 *makeComponent) {} *(S *url, S *toolTip, IF0 *makeComponent) {} } settable transient SingleComponentPanel scp; JComboBox comboBox; transient JButton btnHome; simplyCached JComponent urlBar() { //comboBox = autoComboBox(url(), cloneKeys(uiMap)); comboBox = jcombobox(urlsForComboBox()); //centerComboBox(comboBox); comboBox.setRenderer( new CenteredComboBoxRenderer( new ListCellRendererWithToolTip(url -> toolTipForURL(url), (ListCellRenderer) comboBox.getRenderer()))); //comboBoxDynamicToolTip(comboBox, url -> toolTipForURL(url)); onSelectedItem( bindComboBoxToLiveValue(comboBox, uiURL), url -> showUIURL(url) ); Runnable cbAction = comboBoxAction(comboBox, url -> showUIURL(url)); JPanel buttons = jline(jbutton("Go", cbAction)); JComponent panel = withLabel("Show", centerAndEastWithMargin( comboBox, buttons)); if (showHomeButton) { S homeURL = homeURL(); btnHome = jimageButtonScaledToWidth(16, #1103101, homeURL != null ? "Go to " + homeURL : "Go to home URL", l0 goHome); updateHomeButton(); panel = westAndCenterWithMargin(btnHome, panel); } uiURL.onChange(-> updateHomeButton); ret panel; } void updateHomeButton { setEnabled(btnHome, homeURL != null && !eq(homeURL, url())); } JComponent renderUIUrl aka renderUIURL aka uiGet(S url) { try { temp tempEnter(owner); var entry = uiMap.get(url); if (entry == null) ret jCenteredLabel("URL not found: " + url); var component = entry.makeComponent!; ret component; } catch print e { ret jErrorView(e); } } bool hasURL(S url) { ret uiMap.containsKey(url); } void showUIURL(S url) { temp tempEnter(owner); /*LS parts = trimAll(splitAtColon(url)); for (int n = l(parts); n > 0; n--) { url = join(":", takeFirst(n, parts)); if (hasURL(url)) { ... } }*/ setURL(trim(url)); go(); } void go { setComponent(scp, renderUIUrl(url())); } S url() { ret uiURL!; } void setURL(S url) { uiURL.set(url); } selfType put(WithToolTip url, IF0 maker) { ret put(url!, url.toolTip(), maker); } selfType put(S url, S toolTip default null, IF0 maker) { uiMap.put(url, new Entry(url, toolTip, maker)); this; } S toolTipForURL(S url) { var e = uiMap.get(url); ret e?.toolTip; } LS urlsForComboBox() { var sorted = cloneKeys(uiMap); ret concatLists(listSetIntersection(preferredURLs, sorted), sorted); } void addPreferredUIURL(S uiURL) { preferredURLs.add(uiURL); } S homeURL() { ret first(preferredURLs); } void goHome { showUIURL(homeURL()); } }