學習 kityminder 筆記(六)

接上篇, 接着學習 kityminder. css

== core/keyreceiver.js == node

extend class Minder {
   init-hook(): 構造時設置選項, 偵聽 'paperrender' 事件, 以調用 _initKeyReceiver()
   _initKeyReceiver(): 建立 DOM 元素 <input class='km-receiver'>, 添加到容器 <div> 中.
       在此 <input> 上偵聽 keydown, keyup, keypress 等多個事件, 而後轉給 minder 對象處理.
       看起來彷佛是用於專門接收 key 事件的, 也許容器不方便接收 key 事件?
   事件 on_focus(): 設置上面的 <input> 爲 focus.
   彷佛是將 <div> 的 focus,blur 同步給 <input>.
} 算法

 

== core/module.js == 數組

閉包變量: _modules = {}, 註釋爲已註冊的模塊. promise

對外提供函數 Module.register(name, module): 註冊一個模塊.
   如今對什麼是模塊的概念不太清晰, 另 seajs 也是加載模塊, 那麼有區別? 閉包

extend class Minder {  // 註釋: 模塊聲明週期維護.
   init-hook(): 調用 _initModules()
   _initModules(): 某種(預先?)模塊加載機制, 可能先要註冊模塊, 而後這裏在 minder 構造時完成一些加載工做.
       還涉及 command, event, renderer, shortcut 等等, 稍後細研究吧. 
   _garbage(): 刪掉全部子節點, 等於清空文檔?
   destroy(): 清空文檔, for-each(modules).destroy(this)
   reset(): 清空, for-each(modules).reset(this); 至關於每模塊提供 destroy, reset 方法可被調用.
} app

實際查看了一下, 在 minder 對象中有一個 _modules{}, 裏面有 Arrange, Clipboard, Connect, ...
   大約 30 個模塊? ._query 爲 null, ._rendererClasses 有 left,right,top 等幾個. ._commands 前面
   遇到過. ide

模塊看起來是一種擴展功能的機制, 稍後須要更深刻看看. 函數

 

== core/readonly.js : 只讀模式支持 == 工具

extend class Minder {
   init-hook(): 若是選項有 readonly, 則設置爲 disabled.
   disable(): 禁用命令. 對命令對象的 query 方法包裝(修飾)一下, 在 readonly 狀態下返回 null/0.
       產生 'readonly' 事件. 設置狀態 _status='readonly'
   enable(): 恢復命令. 去掉 query command 的包裝. 設置狀態爲 'normal'.
}

由此知道 minder._status 表示的文檔狀態是 normal, readonly 等幾種.

 

== core/render.js ==

class Renderer {
   ctor(node): this.node = node; 問題: 一個實例對應一個 node? 這裏 node 是什麼?
   create(node): throw ('not impl') 也許設計由派生的子類來實現.
   update(): draw(), place()
   draw(): throw 'not impl'; 也許子類實現.
   place(): throw 'not impl'; 也許子類實現.
   還有一些方法略, 大體可認爲是一個接口聲明, 幾個主要?功能可能須要子類實現, 因此應該有(數個?)實現子類?
}

extend class Minder {
   renderNodeBatch(nodes): 與 node render 機制有關, 如今理解不了, 須要稍後.
   renderNode(node): render 單個節點. 彷佛有或建立 node renderers[],
      而後 for-each(renderer).do_sth()
      在 render 以前產生 'beforerender' 事件, 以後產生 'noderender' 事件.
}

實際查看了一下例子, root._renderers[] 含11項, 分別是 TextRenderer, PriorityRenderer 等等.
   root 的幾個子節點每一個也都有 _renderers[], 也都是 11 項... 每一個節點都要建立這麼多嗎?

在 minder._rendererClasses{} 彷佛保存有 name=>renderers[] 的映射.

extend class MinderNode {
   render(): 即 minder.renderNode(此節點)
   renderTree(): 即 minder.renderNodeBatch(全部子孫節點)
   getRenderer(type): 獲得該 type 的 renderer. 這裏 type 有哪些須要後續瞭解.
   getContentBox(): 可能每一個 node 對應有一個 content-box, 對應類爲 kity.Box()
   getRenderBox(): 相關概念有 renderer, content-box, transform-matrix 等. 暫不清楚.
}

另外一個小問題, 在建立 node._renderers[] 的時候, 是用 new Renderer(node), 但查看時倒是不一樣的
   Renderer 子類(如 TextRenderer, ImageRenderer等), 那麼 new 發生了什麼?

Renderer 是一個重要的概念, 咱們須要更多學習...

 

== core/connect.js ==

閉包變量 _connectProviders{} 註釋爲: 連線提供方.

這裏註冊一個 'default' 的 connect-provider. 細節稍後.

extend class MinderNode {
   getConnect(): 註釋爲獲取當前節點的連線類型. 缺省返回 'default',  可能名字對應 connect-provider
   getConnectProider(): 根據名字找該名字的 connect-provider.
   getConnection(): 獲得當前節點的連線對象. 實際查看這個對象是一個 Path 類的實例.
}

extend class Minder {
   getConnectContainer(): 獲得對應成員變量.
   createConnect(node): 建立 node._connection = kity.Path 對象, 更新 connect.
   removeConnect(node): 遍歷?刪除全部子孫節點的 ?
   updateConnect(node): 獲得相關對象: parent(node), connection(kity.Path), connect-provider,
      調用 provider() 方法對 node<--connect-->parent 創建連線吧. 猜想 default connect-provider
      就用簡單曲線連起來. 這樣連線應對應一個 path 對象, 具體怎麼曲線由 provider 計算...
}

register module Connect {
   init(): 彷佛是建立一個 <g> 元素, 用於容納全部連線的 <path>.
   events: {  // 回顧 module.js , 這裏至關於偵聽以下事件.
      on 'nodeattach': 建立 connect.
      on 'nodedetach': 刪除 connect.
      on 'layoutapply layoutfinish noderender': 更新 connect.
   }
}

這裏正好能夠回顧一下 module, 瞭解註冊模塊要作什麼, 如今已知模塊可偵聽一些事件.
查看 km._eventCallbacks{}, 裏面有多種事件對應的 callback[].

 

== core/layout.js ==

閉包變量 _layouts{}, 用於註冊 name->layout 的映射.
   經過查看, 裏面有 bottom, filetree-xxx, fish-bone-xxx, mind 等多種佈局實現(子類). 
   缺省 layout 爲 'mind'.

// 此類不少註釋摘抄過來: 佈局基類, 具體佈局(子類)須要從該類派生.
class Layout {
   doLayout(): 子類須要實現的佈局算法. 該算法輸入一個節點, 排布該節點的子節點(相對父節點的變換)
      註釋給出的例子中最後是 child.setLayoutTransform(transform-matrix), 即要給出最終變換矩陣.
   align(): 對齊指定的節點. 根據對齊到哪個邊, 產生新的變換 matrix (疊加一個平移變換).
   stack(): ?多是將一組節點沿某個 axis(軸) 疊成一排(列)?
   move(): 平移一組節點.
   getBranchBox(): 獲取給定的節點[]所佔的佈局區域 (box?), 是單個node box 的總的 merge. (UnionRect)
   getTreeBox(): 工具方法:計算給定的節點的子樹所佔的佈局區域. 彷佛意思是包含全部子節點的 box.
   getOrderHint(): 可能由子類實現. 這裏返回一個空數組.
}

// 註釋: 佈局支持池子管理 (什麼是池子...?)
extend class Minder {
   init-hook(): 調用刷新 refresh()?
   getLayoutList(): ?
   getLayoutInstance(name): 建立指定名字的 layout 實現(子)類.
}

// 註釋: MinderNode 上的佈局支持.
extend class MinderNode {
   get/setLayout(): 得到當前節點的佈局名稱. 若是未給出就使用父節點的 layout, 直到缺省爲 'mind'.
   layout(name): 設置指定 name 的佈局, 並調用 minder.layout()
   get/setLayoutTransform(): 獲取當前節點相對於父節點的佈局變換. (返回是一個 matrix)
   getGlobalLayoutTransformPreview(): 第一輪佈局計算後, 得到的全局佈局位置. (返回合併後的 matrix?)
   getLayoutPointPreview(): ?
   get/setGlobalLayoutTransform(): 得到節點相對於全局的佈局變換. (?)
         set(): 相對於全局的變換(冗餘優化), 暫不明白.
   get/setVertexIn(p): 多是設置連線的進入點?
   get/setVertexOut(p): 多是設置連線的出點?
   getLayoutVertexIn(): 對 in 點用 global-layout-transform 進行變換?
   getLayoutVertextOut(): 對 out 點 xxx 變換.
   get/setLayoutVectorIn(): 獲取/設置某種向量 (kity.Vector?)
   get/setLayoutVectorOut(): 也許是入點/出點方向向量?
   getLayoutBox(): 對 content-box 進行 glt 變換.
   getLayoutPoint(): 獲得佈局原點?
   get/set/has/resetLayoutOffset(): 獲取/設置佈局相關的一個點 (kity.Point).
   get/isLayoutRoot():
}

extend class Minder {
   layout(): 清空前次layout; 第一輪佈局, 第二佈局; 應用佈局結果; 發佈 layout 事件.
       會遞歸調用子節點的 layout(). 彷佛實際用 layout-instance.doLayout() 實質佈局.
   refresh(): 多是徹底重繪/重佈局. 發佈事件, 以及 interact-change().
   applyLayoutResult(): 彷佛應用動畫給更新, 若是過複雜則不動畫.
}

佈局是重點功能, 稍後回來再回顧.

 

== core/theme.js ==

閉包變量 _themes{}, 估計存放支持的全部 theme. 查看了一下大約有20種, 大約是顏色+樣式組合.
   數據形式像 css. 在 src/theme/ 下面有 6 個 js, 用於註冊多種 theme.

extend class Minder {
   static getThemeList(): 即獲取 _themes{}.
   init-hook: 設置(缺省) theme.
   useTheme(): 切換腦圖實例上的主題.
       實驗: 在控制檯上執行 km.useTheme('fresh-green') 果真變爲綠色主題~
   get/setTheme(): 獲取/設置主題, 發佈事件.
   getStyle(): 得到腦圖實例上的樣式. 可能像 css 方式訪問.
   getNodeStyle(): 獲取指定節點的樣式.
}

extend class MinderNode {
   getStyle(): 等價於 minder.getNodeStyle(this)
}

register module Theme {
   選項略;
   commands: { 爲 minder 添加命令 ThemeCommand }
}

如今仍是未徹底理解 register module, 是否這些註冊等也均可以用 init-hook 等方式完成?

 

== core/template.js 顯示模板(形式) ==

閉包變量 _templates{}. 查看一下大體有 6 種: default,filetree, fish-bone, ...
這裏 template 應是指圖的形式, 如缺省,魚骨圖,文件樹等.

extend class Minder {
   static getTemplateList(): 即獲取 _templates{}
   use/get/setTemplate(): 切換到該形式.
   getTheme(): 被這裏修改了.
}

extend class MinderNode {
   getLayout(): 這裏修改/加強了原 getLayout() 方法, 根據 template 是否支持.
   getConnect(): 相似的修改.
}

register module TemplateModule {
    添加 template 命令, 容許切換顯示形式(模板).
}

 

 

== core/promise.js ==

這多是外部某個 js 代碼, 因不瞭解 promise 的意圖, 暫時先跳過.

 

== core/_boxv.js ==

調試工具, 爲 kity.Box 提供一個可視化的渲染. 當 url 中含特定 boxv 時.

extend class kity.Box {
   visualization get: 設置 vrect 大小.
}

extend class Minder {
   init-hook: 註冊事件.
   on event paperrender: 建立調試用 vrect, 在上面改變大小. 有空作作實驗.
}

 

== core/patch.js 打補丁 ==

extend class Minder {
   applyPatches(): 應用所給補丁[]. 如今不瞭解在補丁什麼...?
}

 

這裏結束了 core/*.js 小節, 下面是 module/*.js 部分. 那就放下一篇筆記吧.

相關文章
相關標籤/搜索