dontcareabout / gf Goto Github PK
View Code? Open in Web Editor NEWGoddamn Fuckwork
Home Page: https://dontcareabout.github.io/GF/
Goddamn Fuckwork
Home Page: https://dontcareabout.github.io/GF/
LayerSprite.setCursor()
是為了滿足 LayerSprite
implement LSprite
。
但是目前只有作 bg.setCursor()
(然後好像還沒作用... 😱 ),而忽略了 LayerSprite
也是個 Layer
、按照道理應該所有 member 要是相同 cursor。
因此應該是把 setCursor()
的實作改為 setMemberCursor()
(或著至少要解決這個需求),然後連帶考慮 LayerContainer.processLayerOnLoad()
是否要修正。
有遇到狀況是 LayerSprite
已經 new 好、還沒有實際掛到畫面上,但是已經設定好處理外部 event 的 handler 要求 redraw()
就會炸出 NPE。
改不改其實無關生死,理論上沒啥檯面上的影響,只是 console 能少一些無謂的 exception log 當然是最好......
要把一個 LayerSprite
實際用 GXT component 的方式操作,必須得先生一個 LayerContainer
,有點囉唆。(例如想把 GF 版的 TextButton
拿來用當 GXT component 使用)
所以如果 LayerSprite
可以提供 asWidget()
之類的 method,實際上是回傳一個 LayerContainer
instance、resize 的行為比照 GXT 的 SimpleContainer
好像就很完美...... \囧/ (至於 UiBinder 就... 再說啦 XD)
這是 #33 的延伸 (胡說,明明就是設計缺陷 [指]),不能 undeploy()
之後重新 redeploy()
,那麼 hidden(visible)的能力就變得很重要。
GXT 的 Sprite
具備 setHidden()
跟 isHidden()
。以此來說,如果 Layer
的 member 們統一隨 Layer
的hidden 而顯示 / 不顯示,也的確很合理。
目前塞在 adjustMember()
當中計算只是方便而已,(應該)沒有必要性。反之,如果沒有呼叫過 adjustMember()
則無法取得值,這設計本身就有點詭異 🙊
假若 LayerContainer
需要 getViewSize()
來決定自身大小(好讓其 parent 產生 scroll bar),就會造成近似 deadlock 的狀態。
Layer
除了是處理多個 LSprite
(位置、與 DrawComponent
的關係),也處理 Sprite*Event
(handler、propagation)LayerSprite
可視為具備 Layer
能力的 LRectangleSprite
LayerContainer
承載的是 Layer
而不是 LayerSprite
Layer
設計。沒想到套在實際應用就...... 💀主要炸點在於 Layer
沒什麼實質用途。因為 Layer
的處理對象是 LSprite
,如果 layer 的 memeber 也要是 layer,那就必須得用 LayerSprite
...... 那還不如乾脆統統都用 LayerSprite
就算了......
這點在 LayerContainer
當中特別明顯,LayerContainer
必須用上一堆 instanceof 跟 casting 才能實際處理 LayerSprite
。
LayerContainer
改為承載 LayerSprite
LayerSpriteContainer
比較好,可是我有點懶得改.......Layer
處理 Sprite*Event
的功能移到 LayerSprite
去有沒有漏掉什麼呢? 😱
我忘了你的電話,有事找你討論,請回電 :)
同一個 Layer
instance(正確來說是 Layer
上的 LSprite
),作下列的動作都不會成功:
//In LayerContainer constructor
TextButton foo = new TextButton("GF 的 TextButton");
addLayer(foo);
//type-1
clear();
addLayer(foo);
//type-2
foo.undeploy();
addLayer(foo);
主要原因應該是 Layer.redeploy()
有檢查 Sprite.getComponent()
要不為 null 才實際作 DrawComponent.addSprite()
,但是 GXT 底層找不到有作 Sprite.setComponent(null)
之類的動作。
如果是這個原因,那勢必要重新改寫 LayerContainer.clear()
,使其有機會對每一個 Layer
作 Layer.undeploy()
。
LayerSprite.clear()
移除時是移除 所有 member,LayerSprite
的 background 也是 member 之一,所以就會....... 😱
從 TextButton
發明之後就陸續有炸過,只是一直沒有搞 SSCCE、有的時候還莫名就正常...... 😱
這次整理出的 SSCCE 是:
TextButton foo
,然後呼叫 onResize(getOffsetWidth(), getOffsetHeight())
(後面簡寫,省去參數)onResize()
當中指定 foo
的大小跟位置此時會發現:
onResize()
:顯示不正常onResize(1,1)
後再作 onResize()
:顯示不正常onResize(1,1) 後用 deferred 方式再作
onResize()`: 🆗onResize()
:顯示不正常簡直就是各種莫名其妙阿阿阿...... Orz
例如下面這個狀況:
TextButton btn = new TextButton("WTF"); //註:TextButton 是個 LayerSprite
VerticalLayoutContainer vlc = new VerticalLayoutContainer();
vlc.add(btn, layoutData);
當 layoutData
的設定是會給 btn
大小,那麼 btn
的顯示會如預期,這沒有問題。
但若是希望 btn
依照程式邏輯動態大小、然後搭配 layoutData
給 (-1, -1)、讓 vlc
可以出現 scroll bar 這種情況就無法作到。
因此應該在 LayerSprite.resize()
的時候也可以改變 asWidget() 的 instance 大小(可是瑞凡,這樣程式碼好像會很醜...... 🙈 )
提供類似 HorizontalLayoutContainer
的 layout 工具
原本以為 Layer
不需要負責處理 redraw,還寫在 JavaDoc 裡頭...... 💃
隨著時代(?)的演進,好像不加不行了。首先是「外部 event 導致 DrawComponent 內狀態改變,若不要求作 DrawComponent.redrawSurface()
」則畫面不會 update。使用 GF-Test 架構的 SSCCE 如下:
public class WTF extends VerticalLayoutContainer implements Issue {
public WTF() {
//Issue_21.add() 要改為 public
final Issue_21 issue_21 = new Issue_21();
add(issue_21, new VerticalLayoutData(1, 1));
TextButton foo = new TextButton("foo");
add(foo, new VerticalLayoutData(1, 100));
foo.addSpriteSelectionHandler(new SpriteSelectionHandler() {
@Override
public void onSpriteSelect(SpriteSelectionEvent event) {
issue_21.add();
}
});
}
//Issue 實作細節略
}
點擊 foo
是不會有任何效果,在改變 browser 視窗大小(以觸發 DrawComponent.redrawSurface()
)之後就會顯示正常。 說真的,不知道是不是這樣才算正常、Issue_21 是異常?
接著再加上 #15 之後,在大多數情況下連自己維護一個 DrawComponent
/ LayerContainer
的事情都省了,要作 DrawComponent.redrawSurface()
還真有點困難、而且多半也不是什麼好主意 XD
所以,似乎是要來弄個 Layer.redraw()
這樣?(反正之前就設計成 Layer
會持有 DrawComponent
的 instance)打算可以接一個 boolean 參數來決定是不是 redrawSurfaceForce()
......
如果一個 Layer
/ LayerSprite
在呼叫過 deploy()
(也許是用 LayerContainer.addLayer()
)之後又新增 sprite,則目前沒有簡單的方法可以順利顯示新增的 sprite。
目前的想法是在 Layer
裡頭增加一個不用傳參數的 redeploy()
來讓 caller 呼叫....... [遠目]
當初不讓這個 interface 是 public,主要是擔心如果有人亂實作會導致奇怪的後果。(謎之聲:誰沒事會去自己弄一個出來?弄出來有問題自己負責阿 [指])
但是現在發現 LSprite
如果不是 public interface,那麼 Layer.getMembers()
對 caller 而言沒有任何意義。這也導致了「要移除所有 member」無法作到、不然就是 sub class 自己再維護一份 member list(謎之聲:WTF)。
所以,似乎有兩個選項:
LSprite
改為 public interfaceLayer.getMembers()
改為 default level不管選哪一個,Layer
都應該提供「移除所有 member」的 method...... [遠目]
實際炸出這個問題的場景是「用 LayerSprite
作 CSS Flexbox 的基本效果」,程式碼大致如下:
VerticalLayoutContainer scroll = new VerticalLayoutContainer();
scroll.setScrollMode(ScrollMode.AUTOY);
scroll.add(new FlexboxLayerSprite(), new VerticalLayoutData(1, -1));
VerticalLayoutContainer base = new VerticalLayoutContainer();
//base 要改成 SimpleLayoutContainer 之類的都行,這裡這樣寫只是較貼近大多數的實作需求
base.add(foo, new VerticalLayoutData(1, 60));
base.add(scroll, new VerticalLayoutData(1, 1));
FlexboxLayerSprite.adjustMember()
必須依照 base 給予的 width,才能計算出所需要的 height。
在 base
改變 width 時,FlexboxLayerSprite
的 width 跟著改變,所以必須作兩個回合的 adjustMember()
:
@Override
protected void adjustMember() {
double needHeight = computeHeight();
//第一回合
if (getHeight() != needHeight ) {
resize(getWidth(), needHeight);
//resize() 會再度觸發 adjustMember() 所以後面不繼續作
return;
}
//實際調整 member 的邏輯
}
看起來邏輯好像正確,但實際結果 scroll
的大小是正確的(廢話),可是 FlexboxLayerSprite.asWidget()
的大小卻是有問題的,目前原因不明.......
即使沒有出問題,可能也要提供一個機制來避免這繞來繞去的邏輯(謎之聲:designer 都搞不清楚了,誰會相信一般 caller 可以正確而快樂的寫出來...... 😱 )。至於這應該作在 LayerSprite.resize()
?還是讓 LayerSprite.asWidget()
可以有不同的 return class?還是有其他種可能?就....... 還沒有一個定論(謎之聲:先生出 SSCCE 吧你 [指])
當然,最簡單的解法是 LayerSprite
直接提供 scroll 的功能,但是... 實作太硬,不考慮...... 🙈
原本連接的網址: https://spreadsheets.google.com/feeds/list/SHEET_ID/TAB_INDEX/public/values?alt=json
v4 的網址: https://sheets.googleapis.com/v4/spreadsheets/SHEET_ID/values/TAB_NAME?alt=json&key=API_KEY
既有 SheetHappen
API 勢必破壞,故得跳中版號...... 😱
剛剛才發現 TextButton
居然沒有提供任何 getter....... 🙈
目前的 setMemberCursor()
只處理當下已經在 Layer
上的 LSprite
,呼叫完之後再加到 Layer
上頭的 LSprite
則不會設定。這會導致該 Layer
的行為不符合一般期望。
update:連同 #28 一起修..... Orz
stringField()
的 name 無法對應上 sheet 的 column name,在執行期才會炸 JS 錯誤且不易解讀 / 處理getIndex()
的值改為該筆資料在 sheet 的 row number(目前少 1)前情提要: http://blog.dontcareabout.us/2020/08/spriteoverevent.html
因為只要有給顏色就不會有這個問題,然後實測發現即使 opacity 給 0(完全透明)也可以。所以,為了避免忘記前情提要而在處理 SpriteOverEvent
/ SpriteOutEvent
時老是出問題,所以一律給一個透明底色。
LayerSprite.setBgColor()
也一併禁止傳入 Color.NONE
值
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.