public GTagBox(int distance, GUTag tag, double x, double y, int direct) { //记录展开方向(1:向右 -1:向左) Direct = direct; //计算大小 Inf = new TagBoxSizeInf(tag, distance, StaticCfg.Ins.GFontName); //*****计算位置***************** //计算OutterBox OutterBoxLeftTop.X = x; OutterBoxLeftTop.Y = y; if (Direct == -1) { OutterBoxLeftTop.X -= Inf.OutterBoxSize.Width; } //计算InnerBox在:OutterBox的中间 InnerBoxLeftTop.X = OutterBoxLeftTop.X + (Inf.OutterBoxSize.Width - Inf.InnerBoxSize.Width) / 2; InnerBoxLeftTop.Y = OutterBoxLeftTop.Y + (Inf.OutterBoxSize.Height - Inf.InnerBoxSize.Height) / 2;; }
private static GTagBoxTree ExpandChildMoreCompact(int level, int MaxLevel, ITagDB db, GTagBoxTree root, GTagBoxTree pre, GUTag ctag, int direct, Size size, TreeLayoutEnv env, LayoutMode mode) { double estimateWidth = 0; GTagBoxTree cur; Logger.D("ChoosePos:pre:{0}-{1}-{2} cur:{0}-{1},", pre?.GTagBox.Tag, pre == null ? 0 : db.QueryTagChildren(pre.GTagBox.Tag).Count, pre == null ? 0 : pre.totalRange.Right, ctag, db.QueryTagChildren(ctag).Count); //只有满足严格条件的情况下,才放在兄弟节点的后面,否则在父节点后展开 TagBoxSizeInf sizeinf = new TagBoxSizeInf(ctag, level + 1, StaticCfg.Ins.GFontName); bool leftOK = true, rightOK = true; int OneLineChild = GetTagTreeWidth(ctag, db, level + 1, MaxLevel, out estimateWidth); //右边是否有足够空间(初步预估,用OneLineChild*本节点的宽度预估) if (pre != null && direct == 1) { rightOK = pre.totalRange.Right + sizeinf.OutterBoxSize.Width < size.Width; } //左边是否有足够空间 if (pre != null && direct == -1) { leftOK = sizeinf.OutterBoxSize.Width < pre.totalRange.Left; } if (pre != null && (OneLineChild >= 0 && /*(db.QueryTagChildren(ctag).Count == 0 && db.QueryTagChildren(pre.box.Tag).Count == 0)*/ rightOK && leftOK )) { Logger.D("Place {0} after {1}:follow", ctag, pre.GTagBox.Tag); //这种情况下不换行 cur = ExpandNode(ctag, level + 1, db, direct == 1 ? pre.totalRange.Right : pre.totalRange.Left, //X pre.totalRange.Top, //Y direct, size, env, mode); } //第一个节点,没有兄弟节点,放在父节点后面 ==== > 放在父节点的同一行 //非叶子节点,也直接放在父节点后面 or ==== > 放在父节点的下一行 //前一个兄弟已经把这一行占完了 ==== > 放在父节点的下一行 else { if (pre == null) { Logger.D("Place {0} after {1}:follow", ctag, root.GTagBox.Tag); //不换行,跟在根节点后面 cur = ExpandNode(ctag, level + 1, db, direct == 1 ? root.GTagBox.OutterBox.Right : root.GTagBox.OutterBox.Left, //X root.totalRange.Top, //Y direct, size, env, mode); } else { Logger.D("Place {0} after {1}:newline", ctag, root.GTagBox.Tag); //换行,也是跟在根节点后面 cur = ExpandNode(ctag, level + 1, db, direct == 1 ? root.GTagBox.OutterBox.Right : root.GTagBox.OutterBox.Left, //X root.totalRange.Bottom, //Y direct, size, env, mode); } env.AddLine(root, cur, direct); } return(cur); }
private static int GetTagTreeWidth(GUTag tag, ITagDB db, int level, int maxlevel, out double width) { TagBoxSizeInf sizeinf = new TagBoxSizeInf(tag, level, StaticCfg.Ins.GFontName); width = sizeinf.OutterBoxSize.Width; int ret = -1; List <GUTag> children = db.QueryTagChildren(tag); if (level > maxlevel) { ret = 1; } else if (level == maxlevel) { ret = children.Count + 1; //所有子节点+自己 } //只有两种情况下不需要换行: //1. 父节点 -- 子, 孙,重孙 //2. 父节点 -- 子,子,子,子 else if (children.Count <= 1) //情况1: { //只有一列子孙节点,所有都是独生子 ret = 1; GUTag tmp = tag; for (int i = level; i < maxlevel; i++) { children = db.QueryTagChildren(tmp); if (children.Count > 1) { ret = -1; break; } else if (children.Count == 0) { ret++; break; } else if (children.Count == 1) { tmp = children[0]; sizeinf = new TagBoxSizeInf(tmp, level, StaticCfg.Ins.GFontName); width += sizeinf.OutterBoxSize.Width; ret++; } } return(ret); } else { //情况2:只有一层子节点,所有子节点都是叶子(显示为子,子,子,子) ret = children.Count; foreach (GUTag ctag in children) { if (db.QueryChildrenCount(ctag) > 0) //有子节点非叶子,并且自己子节点数量>1,表示不能在一行内显示 { ret = -1; break; } sizeinf = new TagBoxSizeInf(ctag, level, StaticCfg.Ins.GFontName); width += sizeinf.OutterBoxSize.Width; } } Logger.D("GetTagTreeWidth : {0} {1}", tag.ToString(), ret); return(ret); }