2008年11月29日星期六

Flex - 不規則底部形狀的 DataGrid   [+/-]

Ticore's Blog

假如 Designer 設計了這樣的 GUI 給你去開發
一個 DataGrid 底下帶有不規則外型的面板
你會怎樣做呢?

實作方式 1. 將 DataDrid 底部切齊面板,造成空間的浪費

實作方式 2. 將底下的面板壓在 DataGrid 上,利用到空間,但是卻造成 ScrollBar 被擋住

以上兩種方式都不好
Designer 用 Photoshop 設計的時候,往往都不會想到那麼多
問題到了實作階段才浮現
此時要再修改設計已經太慢了,只能採用上述 實作方式 1. 造成空間的浪費
那樣真的還不如用矩形面板來的好看

從 RD 的角度來看,其實還有一種方式~~

讓不規則形狀面板壓在 DataGrid 內容上
但是改變 DataGrid ScrollBar 的尺寸,與面板切齊

光是這樣還不夠
當 ScrollBar 捲到最下面時候,DataGrid 的最後一筆內容
應該是不能被面板遮住的

這樣應該是比較完美的設計方式了
空間利用與使用性都能兼顧
不過現成 GUI 組件是做不到的
需要自行修改組件來達到這樣的功能

至於該如何修改 Flex 組件,請見下回分解~

相關連結:
Flex Bottom Bleeding DataGrid 2
Flex Bottom Bleeding DataGrid

Read more...

2008年11月23日星期日

了解 Adobe Alchemy   [+/-]

Ticore's Blog

相信大多數的 Flasher 一開始聽到 Alchemy 都不了解它是什麼以及做什麼用的
這裡有一篇文章可以幫助大家了解一下 Alchemy 的用途以及原理
Automata - Understanding Adobe Alchemy

以下僅對文章內容做個摘要翻譯

Alchemy 最主要的部分其實是 LLVM - Low Level Virtual Machine 的一個後台
LLVM 將不同的語言編譯為類似精簡指令集 (RISC-like) 的命令
任何人都可以撰寫新的 LLVM 後台,將它們轉換為實際可以在不同平台上執行的
這些平台包含 x64, ARM, PowerPC
Alchemy 則是將它轉為可以在 ActionScript 上執行的
ActionScript 平台最特別的地方是,它只是一個語言並非像其它平台是一個 CPU
假如有看過 Alchemy 產生的中間代碼
就會發現它是同時包含 ActionScript 3.0 與組合語言的

經由 Alchmey 編譯過的 C, C++ 程式全部都要遵守一些限制
就像一個普通的 SWF 位於安全沙箱內一樣
所有的視覺上的輸出必須要透過 display list
所有的網路與檔案的存取都必須透過既有的類別
在這層界面下,當你產生 Alchemy 編譯的 Lib. 實體
它就會配置一大塊記憶體到 ByteArray 內
這就是為什麼 Alchemy 能夠在 ActionScript 內
使用 pointers, malloc, free 等功能的方式

那麼 Alchemy 適合做哪些操作呢?
答案就是記憶體存取與函式呼叫
Alchemy 編譯的代碼會利用 Flash Player 10 新增的 bytecode 來操作 ByteArray
這裡的 ByteArray 也就是 Alchemy 內所謂的記憶體
函式呼叫會比較快的原因是在 ActionScript 函式呼叫時
傳遞參數需要做裝箱 (boxed) 與拆箱 (unboxed) 的動作
但是 Alchemy 的代碼不需要做這些

需要注意以上速度的提升可能會受到 Alchemy 與 AS3.0 之間來回跳躍而被抵消
這過程叫做 marshaling,是非常昂貴的
應該儘量降低發生次數,盡可能試著在 C 代碼中建立呼叫
並且避免在這之間傳遞太多參數,最好的方式是直接操作 Alchemy 的 "記憶體"

Alchemy 非常厲害但不是萬靈丹
能夠大大加速 C, C++ 程式轉換為 Flash Lib. 的進程
而且比起手寫的 ActionScript 有可能帶來執行速度上的提升

相關連結:
窮得只剩下 Compiler - 淺談編譯技術的革命
Alchemy 煉金術 實測結果
Adobe Alchemy 煉金術

Read more...

2008年11月20日星期四

Alchemy 煉金術 實測結果   [+/-]

Ticore's Blog

看到 Adobe Alchemy 好像非常神奇的樣子
當然要裝起來玩玩看!
這裡是它的安裝方法
Alchemy:Documentation:Getting Started
真的好麻煩,總共要裝 gcc, java, perl, flex sdk, alchemy
Windows 版的還要再加裝 cygwin

我是同時嘗試安裝 Windows, Ubuntu 版,因為等網路下載很慢
結果到最後只有 Windows Cygwin 安裝成功
Ubuntu 上好像是因為遇到權限的問題,無法成功覆蓋 gcc 路徑

實際編譯 C Code 產生 SWC Lib. 畫面:

在編譯過程中,可以看到它是先產生中間 as 檔案,然後才編譯為 SWC 的
把中間 as 檔案複製出來看一下
結果大致像這樣:

裡面有一部份 ActionScript 3.0,然後剩下的都是奇怪的代碼

假如想要把 C function 拿進 Alchemy 給 Flash 用也不是那麼簡單的事情
請先參考這個 Developing with Alchemy:C API

我照著 Alchemy 內的範例,添加了一個迴圈加總的函式

//Simple String Echo example
//mike chambers
//mchamber@adobe.com

#include <stdlib.h>
#include <stdio.h>

//Header file for AS3 interop APIs
//this is linked in by the compiler (when using flaccon)
#include "AS3.h"

//Method exposed to ActionScript
//Takes a String and echos it
static AS3_Val echo(void* self, AS3_Val args) {
 //initialize string to null
 char* val = NULL;
 
 //parse the arguments. Expect 1.
 //pass in val to hold the first argument, which
 //should be a string
 AS3_ArrayValue( args, "StrType", &val );
 
 //if no argument is specified
 if (val == NULL) {
  char* nullString = "null";
  //return the string "null"
  return AS3_String(nullString);
 }
 
 //otherwise, return the string that was passed in
 return AS3_String(val);
}


static AS3_Val sum(void* self, AS3_Val args) {
 int val = 0;
 int res = 0;
 AS3_ArrayValue( args, "IntType", &val );
 int i;
 for (i = 0 ; i < val ; ++i) {
  res += i;
 }
 return AS3_Int(res);
}

//entry point for code
int main() {
 //define the methods exposed to ActionScript
 //typed as an ActionScript Function instance
 AS3_Val echoMethod = AS3_Function( NULL, echo );
 AS3_Val sumMethod = AS3_Function( NULL, sum );

 // construct an object that holds references to the functions
 AS3_Val result = AS3_Object( "echo: AS3ValType, sum: AS3ValType", echoMethod, sumMethod );

 // Release
 AS3_Release( echoMethod );
 AS3_Release( sumMethod );

 // notify that we initialized -- THIS DOES NOT RETURN!
 AS3_LibInit( result );

 // should never get here!
 return 0;
}

編譯為 SWC Lib. 之後,使用以下 AS3 程式進行測試:

package {
 import flash.display.Sprite;
 import flash.utils.getTimer;
 import cmodule.sum.CLibInit;
 
 public class AlchemyTest extends Sprite {
  
  public function AlchemyTest() {
   var loader:CLibInit = new CLibInit();
   var lib:Object = loader.init();
   trace(lib.sum);
   trace(lib.echo);
   
   var no:int = 1000000;
   
   var st:int = getTimer();
   trace(lib.sum(no));
   trace(getTimer() - st);
   
   st = getTimer();
   trace(sum(no));
   trace(getTimer() - st);
   
   st = getTimer();
   trace(lib.sum(no));
   trace(getTimer() - st);
  }
  
  public function sum(i:int):int{
   var res:int = 0;
   var j:int = 0;
   for (j = 0 ; j < i ; ++j) {
    res += j;
   }
   return res;
  }
 }
}
// Ticore's Blog - http://ticore.blogspot.com/

結果~~~

function Function() {}
function Function() {}
1783293664
178
1783293664
86
1783293664
178

天啊,我還刻意跑了好多次
Alchemy v0.4a 產生的 Lib. 居然比 AS3 實作的還要慢一倍左右
真是無言以對,難道我的測試過程中有問題嗎?
還是 Alchemy 還有其它的什麼特異功能?

相關連結:
了解 Adobe Alchemy
Adobe Alchemy 煉金術
Alchemy:Documentation:Getting Started
Adobe Alchemy
Developing with Alchemy:C API
Developing with Alchemy:AS3 API
Adobe Labs Forums - Alchemy

Read more...

2008年11月19日星期三

Adobe Alchemy 煉金術   [+/-]

Ticore's Blog

Adobe Labs 又出新東西 Alchemy
據說是可以將 C, C++ Code 編譯為 SWC Library 給 Flash 使用

這在之前就有相關的消息了
假如單純只是將 C, C++ 語言翻譯為 ActionScript 對實際使用上幫助還是很有限的吧
不過再仔細看看,必須要 Flash Player 10 或 AIR 1.5 以上才可以用
而且它號稱會比 AS3 還要快,只比 Native 慢 2-10 倍左右
有這麼神奇嗎?

我實際下載 Sample Library 用 ASV 6 pre5 反編譯測試一下
已經無法看到 ActionScript Code
只能看到 P-Code
天啊,難道這就是所謂的 Native 擴充能力嗎? (用詞不是很精確就是了)
不過 Alchemy 也保證這樣使用方式無法突破安全性限制

相關連結:
了解 Adobe Alchemy
Alchemy 煉金術 實測結果
Alchemy:Documentation:Getting Started
Adobe Alchemy
Developing with Alchemy:C API
Developing with Alchemy:AS3 API

Read more...

Dreamweaver CS4 小技巧 - 修改 Flash wmode 預設值   [+/-]

Ticore's Blog

現在 Adobe Dreamweaver CS4 已經改用 swfobject_modified.js
來處理插入 HTML 的 Flash 物件
可是插入之後,wmode 預設值卻是 opaque
與以前的預設值似乎不太一樣
加上 opaque 模式下,滑鼠滾輪事件會失效
以下就分享一個小技巧,讓你可以修改 wmode 預設值

其實 Dreamweaver 很多的命令都是採用外部 JavaScript 撰寫而成的
只要到 Dreamweaver CS4 安裝目錄下,打開這個檔案:

C:\Program Files\Adobe\Adobe Dreamweaver CS4\configuration\Objects\Media\Flash.js

先將檔案備份起來
將所有 "opaque" 字串改為 "window" 或是其它你想要的預設值
然後存檔就完成了~

Read more...

2008年11月17日星期一

最近開始學習 C++ 與 Qt4   [+/-]

Ticore's Blog

最近開始學習 C++ 與 Qt4 了~~
先是找了幾本電子書、網頁教學來看看,把 Qt4 文件瞄一下
感覺其實並沒有比 Flash ActionScript + Flex Ref. 多到哪去
才開始放心去學,哈~~

先是花了一些時間,把以前剛轉行時買的 C++ 教學範本 拿出來看
記得以前第一次看的時候,很多都看不太懂啊
現在看起來至少快多了
不過很多的用法仍然與 Script 語言或是 Java, C# 等差異頗大
像是指標、參考、物件指定與傳遞的方式等等...

基本的 C++ 語法、Qt4 環境設置玩過之後
發現 Qt4 很多功能還挺有趣的
像是以 XML 設計 GUI Layout (產生的代碼比 Flex 還少)
以 CSS 自訂組件樣式 (Qt4 是動態解釋 CSS,並非像 Flex CSS 編譯為 AS Class)
重點是效能真的快很多 (跟 Flex 比啦~)

今天先來研究看看一個存在內心已久的問題
那便是 Flash 載入圖檔的方式,是將圖檔解開之後放在記憶體內
遇到大圖便會非常吃記憶體甚至超過 Flash Player 限制而無法呈現
大多數情況下,我們只是想要取得大圖的局部或是縮圖的預覽而已

一開始先傻傻的照著 Qt4 一般教學使用 QPixMap、QImage 載入大圖
結果~ 記憶體使用量爆增 ^^"
文件上似乎並沒有關於這方面的資訊
只好去看 Qt4 原始碼
終於看到一絲希望 QImageReader 內有一些可以設定讀取尺寸的方法可以用
像是 void setScaledSize(const QSize &size);
void setQuality(int quality);
void setScaledClipRect(const QRect &rect);
void setClipRect(const QRect &rect);

然後又實際用 7000*7000px PNG 圖檔測試
發現記憶體使用量還是先爆衝,取得預覽圖之後,記憶體使用量才掉下來
感覺實在沒什麼用處啊
那跟自己讀完圖檔之後,取得預覽圖,再把大圖丟棄不是一樣嗎?

又繼續追蹤 Qt4 解析圖檔的程式
發現在 QJpegHandler 似乎有對讀取預覽圖最佳化
實際用 7000*7000px JPG 圖檔測試
記憶體使用量也沒有爆衝
總算是得到一些成果
不過好像只有 JPG 解析才有這功能呢

QImageReader 載入 JPEG 之前設定尺寸的例子:

QPixmap img;
QImageReader reader("test.jpg");
reader.setScaledSize(QSize(600, 600));
img = reader.read();
Read more...

2008年11月10日星期一

Firefox Input, TextArea 詭異的 Bug   [+/-]

Ticore's Blog

不知道大家在使用 Firefox 3 搜尋 Google 的時候
是否有遇到過搜尋文字欄位不見的情況
我可是偶爾遇到呢!

Firefox 3 文字欄位正常的情況:

Firefox 3 文字欄位消失的情況:

真的是很詭異的問題,但是又不太容易重覆

今天又讓我遇到了,經過多次嘗試
終於找到發生的條件了

以下便是 Firefox Input, TextArea Bug 重複步驟:

  1. 建立一個 HTML 文件,插入一個含有 Input 文字欄位的 Table,Input 內必須有一些文字
  2. 使用 Firefox 3 瀏覽此文件
  3. 點一下 Input,讓鼠標 focus 在 Input 內
  4. 按下 Ctrl 鍵不放,滑鼠左鍵點一下 Input 的框線
  5. 此時放開 Ctrl 鍵,隨便打一個字母
  6. Input 文字欄位連外層的 table 整個不見了!

PS. 以下故意將 Input 框線設的很寬,並使用箭頭滑鼠指標,會比較容易點在框線上


Firefox 3 Input Bug Demo:

Input in table:

Input Bug Demo HTML:

<table border="1">
  <tr>
    <td>Input in table:<br/>
      <input value="text"
        style="cursor: default; border: solid 12px #999999;" /></td>
  </tr>
</table>

實際測試過會發生以上 Bug 的 Firefox 版本

  • Firefox 3.0.3 Win
  • Firefox 3.0.4 Win
  • Firefox 3.0.8 Win
  • Firefox 3.0.9 Win
  • Firefox 3.0.0 Linux
  • Firefox 3.0.3 Linux
  • Firefox 3.5 Win
  • Firefox 3.5.3 Win
  • Firefox 3.5.5 Win

Bugzilla 上類似的問題
Bug 462970 – textarea, input tag disappears (vanishes) when copy & pasted on the border.

Read more...