Curl Global Community
ツリー構造について - Printable Version

+- Curl Global Community (https://communities.curl.com)
+-- Forum: Discussions (https://communities.curl.com/forumdisplay.php?fid=1)
+--- Forum: General Curl questions (https://communities.curl.com/forumdisplay.php?fid=2)
+--- Thread: ツリー構造について (/showthread.php?tid=1095)



ツリー構造について - rom - 07-02-2014

こんにちは!

ツリー構造について再び質問です。

ツリーの階層毎にイベントアクションの動作を変えたいのですが
やり方がわかりません・・・

ご教授お願いいたします。


RE: ツリー構造について - rom - 07-02-2014

現在このようにして階層を取得していますが
他に方法があればご教授ください。

よろしくおねがいします。

Code:
{if-non-null current = tree.current-node then
                        {let rank:int=1}
                        {let rank_node:#TreeNode=current}
                        {while rank_node.parent != null do
                            {set rank_node = rank_node.parent}
                            {inc rank}
                        }
                        {popup-message rank&"階層です"}
                    }



RE: ツリー構造について - e.kou - 07-04-2014

今の方法が一番シンプルでいいとおもいますが、
別の方法としては、
TreeControl部品を継承してカスタマイズ(プロパティ追加)するのもいいと思います。
ツリー構造が変更されない前提条件であれば
ツリー作成時に階層情報を持ったせることで、毎回ループ処理を行わないで抽出できます。




RE: ツリー構造について - e.kou - 07-08-2014

romさん
サンプルソース作成したので、合わせて確認してみてください。
Code:
||++  TreeNode拡張
||++  TreeNodeに階層フィールドを追加
{define-class public ExTreeNode {inherits DefaultTreeNode}
  field public node-level:int  {constructor public {default
                          ...
                      }
    {construct-super
        {splice ...}
    }
  }
}||++  TreeControl生成
{TreeControl
    data-model =
        {TreeModel
            root =
                {ExTreeNode node-data="Food",
                    {ExTreeNode node-data="Fruit",
                        {ExTreeNode node-data="Apples",
                            {ExTreeNode node-data="Macintosh"},
                            {ExTreeNode node-data="Cortland"},
                            {ExTreeNode node-data="Gala"},
                            {ExTreeNode node-data="Delicious"}
                        },
                        {ExTreeNode node-data="Oranges"}
                    },
                    {ExTreeNode node-data="Vegetables",
                        {ExTreeNode node-data="Squash"},
                        {ExTreeNode node-data="Tomatoes"},
                        {ExTreeNode node-data="Cucumbers"}
                    }
                }
        },    ||++ tree-item-creation-procに階層値を設定
    tree-item-creation-proc ={proc {node:TreeNode}:TreeItem
                                 {type-switch node
                                  case et:ExTreeNode do
                                     {if et.parent == null then
                                         set et.node-level = 1
                                      else
                                         def par = et.parent
                                         {type-switch et.parent
                                          case etp:ExTreeNode do
                                             set et.node-level = etp.node-level+1
                                         }
                                     }
                                 }
                                 {return {DefaultTreeItem node}}
                             },    ||++ アクションイベント
    {on Action at tc:TreeControl do
        {type-switch tc.current-node
         case et:ExTreeNode do
            {popup-message et.node-level&"階層です。"}
        }
    }
}




RE: ツリー構造について - umemura - 07-08-2014

階層の取得についてはromさんの取得方法で大きな問題はないと思います。


e.kouさんのサンプルにもあるように、
クラスの継承だけでなく、tree-item-creation-proc を使うことで、
いろいろな実装方法が考えられそうですね。

個人的には、ExTreeNode に「階層情報」のフィールドを持たせたのであれば、
ExTreeNode の責任範囲をかんがえたときには、
自分自身で階層情報を取得したほうが、よりシンプルかなと思いました。

また、ツリー生成のタイミングと、表示のタイミングが異なるケースはあまりなさそうですが、
サンプルのように、TreeItem の位置が変更されることも考えて、
一応、ゲッターの中で再取得するようにしてみました。
(サンプルでは、ExTreeItem を利用して、ドラッグでツリーを移動することができます)

Code:
||++  TreeNode拡張
||++  TreeNodeに階層フィールドを追加
{define-class public ExTreeNode {inherits DefaultTreeNode}
  ||現在の階層を返すゲッター
  {getter public {node-level}:int
    let rank:int = 1
    let rank_node:#TreeNode=self
    {while rank_node.parent != null do
        {set rank_node = rank_node.parent}
        {inc rank}
    }
    {return rank}
  }
  {constructor public {default  ... }
    {construct-super  {splice ...} }
  }
}

||ドラッグで移動可能なTreeItem
||※実用には「もとに戻す」機能が必要
{define-class public ExTreeItem {inherits DefaultTreeItem }

  {constructor public {default ...}
    {construct-super {splice ...}}

    set self.dragee = {ImageDragee}

    {self.add-event-handler
        {on e:DragOver do
            {e.will-accept-drop?
                {proc {type:Type, x:Distance, y:Distance,
                       effect:#DragEffect}:DragEffect
                    {return drag-effect-copy}
                }
            }
        }
    }

    {self.add-event-handler
        {on e:Drop do
            {e.accept-drop
                {proc {a:any, x:Distance, y:Distance,
                       effect:#DragEffect}:DropResult
                    {return
                        {DropResultCopy
                            action =
                                {proc {}:void
                                    {type-switch a
                                     case ti:DefaultTreeItem do
                                        {self.node.append ti.node}
                                        {if not self.expanded? then
                                            {self.toggle-node}
                                        }
                                    }
                                }
                        }
                    }
                }
            }
        }
    }
  }
}

||++  TreeControl生成
{TreeControl
    data-model =
        {TreeModel
            root =
                {ExTreeNode node-data="Food",
                    {ExTreeNode node-data="Fruit",
                        {ExTreeNode node-data="Apples",
                            {ExTreeNode node-data="Macintosh"},
                            {ExTreeNode node-data="Cortland"},
                            {ExTreeNode node-data="Gala"},
                            {ExTreeNode node-data="Delicious"}
                        },
                        {ExTreeNode node-data="Oranges"}
                    },
                    {ExTreeNode node-data="Vegetables",
                        {ExTreeNode node-data="Squash"},
                        {ExTreeNode node-data="Tomatoes"},
                        {ExTreeNode node-data="Cucumbers"}
                    }
                }
        },
    tree-item-creation-proc ={proc {node:TreeNode}:TreeItem
                                 {return {ExTreeItem node}}
                             },
    ||++ アクションイベント
    {on Action at tc:TreeControl do
        {type-switch tc.current-node
         case et:ExTreeNode do
            {popup-message et.node-level&"階層です。"}
        }
    }
}



RE: ツリー構造について - rom - 07-08-2014

>e.kou さん
>>今の方法が一番シンプルでいいとおもいますが

何だか褒められたみたいで嬉しいです!有難うございます!

>TreeControl部品を継承してカスタマイズ(プロパティ追加)
上記のような考えが出てこなくて困ってます!
やりたいことがあった時はどのように調べてるのでしょうか><?


>umemura さん
いつも回答ありがとうございます!
「責任範囲」を考えたり質問に対してより深く
回答してくれて、とても勉強になります!

継承してカスタマイズすると色々出来るんだなと実感しました!