/* XOWA: the XOWA Offline Wiki Application Copyright (C) 2012 gnosygnu@gmail.com This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package gplx.gfui; import gplx.*; import java.awt.Color; import java.awt.Font; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.AbstractButton; import javax.swing.BorderFactory; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; import javax.swing.JSeparator; import javax.swing.border.EmptyBorder; public class GfuiMenuBar implements GfoInvkAble { public Object Under() {return winMenu;} public boolean Visible() {return visible;} private boolean visible; public void Visible_set(boolean v) { this.visible = v; MenuBar_visible_set(v); boolean menuBandExists = win.Lyt().Bands_has(menuBand.Key()); if ( visible && !menuBandExists) win.Lyt().Bands_add(menuBand); else if (!visible && menuBandExists) win.Lyt().Bands_del(menuBand.Key()); GftGrid.LytExecRecur(win); } GftBand menuBand = GftBand.fillWidth_().Key_("GfuiMenuBar"); public void Load_cfg(String cfgKey) { try { root.ForeColor_(ColorAdp_.Black).BackColor_(ColorAdp_.White); root.ExecProps(); curOwnerItm = root; GfsCore._.AddObj(this, "GfuiMenuBar_"); GfsCore._.ExecRegy("gplx.gfui.GfuiMenuBar.ini"); } catch (Exception e) {GfuiEnv_.ShowMsg(Err_.Message_gplx(e));} } String separatorText, mnemonicPrefix; int separatorIdx = 0; public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) { if (ctx.Match(k, Invk_visible_toggle)) this.Visible_set(!visible); else if (ctx.Match(k, Invk_SeparatorText_)) separatorText = GfoMsgUtl.SetStr(ctx, m, separatorText); else if (ctx.Match(k, Invk_MnemonicPrefix_)) mnemonicPrefix = GfoMsgUtl.SetStr(ctx, m, mnemonicPrefix); else if (ctx.Match(k, Invk_Visible_)) { boolean v = m.ReadBoolOr("v", true); if (ctx.Deny()) return this; Visible_set(v); } else if (ctx.Match(k, Invk_RegTop)) { String s = m.ReadStrOr("v", null); if (ctx.Deny()) return this; GfuiMenuBarItm itm = GfuiMenuBarItm.sub_(root); itm.Type_(GfuiMenuBarItmType.Top); itm.Text_(s); itm.Ipt_(Read_prop_ipt(IptKey_.None, itm)); itms.Add(s, itm); itm.ExecProps(); curOwnerItm = itm; } else if (ctx.Match(k, Invk_RegSpr)) { String text = m.ReadStr("text"); if (ctx.Deny()) return this; GfuiMenuBarItm itm = GfuiMenuBarItm.sub_(curOwnerItm); itm.Type_(GfuiMenuBarItmType.Spr); itm.Text_(text); itm.Key_(curOwnerItm.Key() + "." + text + Int_.Xto_str(separatorIdx++)); itm.ExecProps(); } else if (ctx.Match(k, Invk_RegCmd)) { String text = m.ReadStr("text"); String cmd = m.ReadStrOr("cmd", null); String tipText = m.ReadStrOr("tipText", null); if (ctx.Deny()) return this; GfuiMenuBarItm itm = GfuiMenuBarItm.sub_(curOwnerItm); itm.Type_(GfuiMenuBarItmType.Cmd); itm.Text_(text); itm.Cmd_(cmd); itm.TipText_(tipText); itm.Ipt_(Read_prop_ipt(IptKey_.None, itm)); itm.Key_(curOwnerItm.Key() + "." + text); itm.ExecProps(); } else return GfoInvkAble_.Rv_unhandled; return this; } public static final String Invk_visible_toggle = "MenuBar_toggle" , Invk_Visible_ = "Visible_", Invk_SeparatorText_ = "SeparatorText_", Invk_MnemonicPrefix_ = "MnemonicPrefix_" , Invk_RegTop = "RegTop", Invk_RegCmd = "RegCmd", Invk_RegSpr = "RegSpr" ; GfuiMenuBarItm curOwnerItm = null; IptKey Read_prop_ipt(IptKey ipt, GfuiMenuBarItm itm) { if (mnemonicPrefix == null) return ipt; String text = itm.Text(); int pos = String_.FindFwd(text, mnemonicPrefix); if (pos == String_.Find_none || pos == String_.Len(text) - 1) return ipt; // mnemonic not found String keyChar = String_.MidByLen(text, pos + 1, 1); if (!Char_.IsLetterEnglish(String_.CharAt(keyChar, 0))) return ipt; // keyChar is not a character; EX: 'A & B' (keyChar = space) String keyCharRaw = "key." + String_.Lower(keyChar); ipt = IptKey_.parse_(keyCharRaw); text = String_.MidByLen(text, 0, pos) + String_.Mid(text, pos + 1); // remove mnemPrefix; ex: &File -> File && key.f itm.Text_(text); return ipt; } void MenuBar_visible_set(boolean v) {winMenu.setVisible(v);} void InitMenuBar(GxwWin win) { ownerForm = (JFrame)win; ownerForm.setJMenuBar(winMenu); winMenu.setBorder(GxwBorderFactory.Empty); } JMenuBar winMenu = new JMenuBar(); JFrame ownerForm; GfuiMenuBarItm root; void Init(GfuiWin win) { InitMenuBar((GxwWin)win.UnderElem()); root = GfuiMenuBarItm.root_(winMenu); itms.Add(root.Key(), root); this.win = win; IptBnd_.cmd_to_(GfuiEnv_.IptBndMgr_win, win, this, Invk_visible_toggle, IptKey_.add_(IptKey_.Ctrl, IptKey_.Shift, IptKey_.F12)); win.SubItms_add(SubItms_key, this); } Hash_adp itms = Hash_adp_.new_(); GfuiWin win; public static final String SubItms_key = "menuBar"; public static GfuiMenuBar new_(GfuiWin win) { GfuiMenuBar rv = new GfuiMenuBar(); rv.Init(win); return rv; } GfuiMenuBar() {} } class GfuiMenuBarItm { public String Key() {return key;} public GfuiMenuBarItm Key_(String val) {key = val; return this;} private String key = ""; public String Text() {return text;} public GfuiMenuBarItm Text_(String val) {text = val; return this;} private String text = ""; public String Cmd() {return cmd;} public GfuiMenuBarItm Cmd_(String val) {cmd = val; return this;} private String cmd = ""; public GfuiMenuBarItmType Type() {return type;} public GfuiMenuBarItm Type_(GfuiMenuBarItmType val) {type = val; return this;} GfuiMenuBarItmType type; public IptKey Ipt() {return ipt;} public GfuiMenuBarItm Ipt_(IptKey val) {ipt = val; return this;} IptKey ipt; public String TipText() {return tipText;} public GfuiMenuBarItm TipText_(String val) {tipText = val; return this;} private String tipText = ""; public ColorAdp ForeColor() {return foreColor;} public GfuiMenuBarItm ForeColor_(ColorAdp val) {foreColor = val; return this;} ColorAdp foreColor; public ColorAdp BackColor() {return backColor;} public GfuiMenuBarItm BackColor_(ColorAdp val) {backColor = val; return this;} ColorAdp backColor; public String FontFamily() {return fontFamily;} public GfuiMenuBarItm FontFamily_(String val) {fontFamily = val; return this;} private String fontFamily = ""; public float FontSize() {return fontSize;} public GfuiMenuBarItm FontSize_(float val) {fontSize = val; return this;} float fontSize = -1; public FontStyleAdp FontStyle() {return fontStyle;} public GfuiMenuBarItm FontStyle_(FontStyleAdp val) {fontStyle = val; return this;} FontStyleAdp fontStyle; public GfuiMenuBarItm OwnerItm() {return ownerItm;} public GfuiMenuBarItm OwnerItm_(GfuiMenuBarItm val) {ownerItm = val; return this;} GfuiMenuBarItm ownerItm; public Object Under() {return under;} void ExecProps() { if (type == GfuiMenuBarItmType.Root) Exec_root(); else if (type == GfuiMenuBarItmType.Cmd) Exec_cmd(); else if (type == GfuiMenuBarItmType.Spr) Exec_spr(); else Exec_mnu(); } void Exec_root() { SetProps((JMenuBar)under); } void Exec_mnu() { JMenu itm = new JMenu(text); if (ownerItm.type == GfuiMenuBarItmType.Root) ((JMenuBar)ownerItm.Under()).add(itm); else { ((JMenu)ownerItm.Under()).add(itm); } SetMnemonic(itm); SetProps(itm); under = itm; } void Exec_cmd() { JMenuItem itm = new JMenuItem(text); JMenu ownerMenu = ((JMenu)ownerItm.Under()); ownerMenu.add(itm); itmCmd = GfuiMenuBarItmCmd.new_(this); itm.addActionListener(itmCmd); SetMnemonic(itm); SetProps(itm); under = itm; } void Exec_spr() { JMenu ownerMenu = ((JMenu)ownerItm.Under()); JSeparator itm = new JSeparator(); ownerMenu.add(itm); SetProps(itm); under = itm; } void SetMnemonic(AbstractButton itm) { char mnem = GetMnemonic(text, ipt); if (mnem != '\0') itm.setMnemonic(mnem); } void SetProps(JComponent itm) { if (backColor != null) itm.setBackground(ColorAdpCache._.GetNativeColor(backColor)); if (foreColor != null) itm.setForeground(ColorAdpCache._.GetNativeColor(foreColor)); itm.setFont(MakeFont(itm.getFont())); if (String_.Len(tipText) > 0) itm.setToolTipText(tipText); } Font MakeFont(Font cur) { if (fontFamily == null && fontStyle == null && fontSize == -1) return cur; String family = fontFamily == null ? cur.getFamily() : fontFamily; int style = fontStyle == null ? cur.getStyle() : fontStyle.Val(); int size = fontSize == -1 ? cur.getSize() : (int)fontSize; return new Font(family, style, (int)size); } GfuiMenuBarItm Under_(Object o) {under = o; return this;} char GetMnemonic(String text, IptKey ipt) { if (ipt.Val() == IptKey_.None.Val()) return '\0'; String iptStr = ipt.XtoUiStr(); if (String_.Len(iptStr) > 1) return '\0'; return String_.CharAt(iptStr, 0); } GfuiMenuBarItmCmd itmCmd; Object under; public static GfoMsg CmdMsg(GfuiMenuBarItm itm) { if (itm.cmd == null) throw Exc_.new_null("cmd was null for menu").Args_add("key", itm.key, "text", itm.text); return gplx.gfml.GfmlDataNde.XtoMsgNoRoot(itm.cmd); } public static GfuiMenuBarItm new_() {return new GfuiMenuBarItm();} public static GfuiMenuBarItm sub_(GfuiMenuBarItm owner) { GfuiMenuBarItm rv = new_(); rv.ownerItm = owner; rv.foreColor = owner.foreColor; rv.backColor = owner.backColor; rv.fontFamily = owner.fontFamily; rv.fontSize = owner.fontSize; rv.fontStyle = owner.fontStyle; return rv; } public static GfuiMenuBarItm root_(Object underMenuBar) { GfuiMenuBarItm rv = new GfuiMenuBarItm().Type_(GfuiMenuBarItmType.Root).Key_("root").Under_(underMenuBar); return rv; } GfuiMenuBarItm() {} } class GfuiMenuBarItmType { public int Val() {return val;} int val; public String Name() {return name;} private String name; GfuiMenuBarItmType(int v, String n) {val = v; name = n; regy.Add(n, this);} public static GfuiMenuBarItmType parse_(String raw) { try {return (GfuiMenuBarItmType)regy.Get_by(raw);} catch (Exception e) {Exc_.Noop(e); throw Exc_.new_parse("GfuiMenuBarItmType", raw);} } static Hash_adp regy = Hash_adp_.new_(); public static final GfuiMenuBarItmType Root = new GfuiMenuBarItmType(1, "root"); public static final GfuiMenuBarItmType Top = new GfuiMenuBarItmType(2, "top"); public static final GfuiMenuBarItmType Mnu = new GfuiMenuBarItmType(3, "mnu"); public static final GfuiMenuBarItmType Cmd = new GfuiMenuBarItmType(4, "cmd"); public static final GfuiMenuBarItmType Spr = new GfuiMenuBarItmType(5, "spr"); } class GxwBorderFactory { public static final javax.swing.border.Border Empty = new EmptyBorder(0, 0, 1, 0); } class GfuiMenuBarItmCmd implements ActionListener { public void actionPerformed(ActionEvent ev) { try { GfsCore._.ExecOne(GfsCtx._, GfuiMenuBarItm.CmdMsg(itm)); } catch (Exception e) { GfuiEnv_.ShowMsg(Err_.Message_gplx(e)); } } public static GfuiMenuBarItmCmd new_(GfuiMenuBarItm itm) { GfuiMenuBarItmCmd cmd = new GfuiMenuBarItmCmd(); cmd.itm = itm; return cmd; } GfuiMenuBarItm itm; }