ksxd flash 07: ลากไฟล์ใส่ Flash App ด้วย Flash และ AIR
posted on 14 May 2009 08:12 by korstudio in Flashความจริงแล้ว ฟังก์ชั่นนี้มีมาตั้งแต่ AIR 1.0 แล้วครับ แต่ผมเพิ่งค้นพบว่ามันมี!!!
จากกระทู้ Tutorial ที่ ไทยแฟลชเดฟ ( จิ้มที่นี่ )
พี่คีได้นำเอาคำสั่งจาก AIR มาสอนให้ลองเล่นกันครับ
และบทความนี้ จะนำเอา Tutorial จากลิงค์ มาดัดแปลงเล็กน้อย
และแจกจ่ายไปให้เล่นกันอีกที
เอ บางคนอาจจะงง AIR นี่มันอะไร(วะ)
อะ เดี๋ยวผมจะเกริ่นนำให้ฟังคร่าวๆ
AIR หรือ Adobe Integrated Runtime
คือแพล็ตฟอร์มหนึ่งของ Flash ที่รันเป็นโปรแกรมบน Desktop ครับ
หรืออธิบายให้ง่ายลงไปอีกคือ Flash ในภาคที่เป็น Desktop Application* นั่นเอง
(*แปล Desktop Application = โปรแกรมที่รันบนเครื่อง ไม่ได้รันบนเว็บ เช่น Microsoft Word เป็นต้น)
ด้วยความที่มันป็น Desktop Application มันก็เลยมีคำสั่งแปลกๆ ใหม่ๆ
ที่ช่วยให้ทำงานบน Desktop Application ได้ดีขึ้น อย่างเช่น การเขียนไฟล์ลงเครื่อง (AIR 1.5)
การเข้าถึงไฟล์บนเครื่อง การนำไฟล์/ข้อความจากคลิปบอร์ด เป็นต้น
รวมไปถึง การลากไฟล์ ลงไปในโปรแกรมที่เขียนจาก AIR ด้วย
(คือ อย่างผมเนี่ย เวลาเปิดไฟล์ ผมขี้เกียจกด File > Open ผมก็จัดการ ลากไฟล์ใส่โปรแกรมเลย
ง่ายกว่าอีก ในกรณีที่เปิดโฟลเดอร์ทิ้งไว้อยู่แล้ว)
ซึ่งการจะเขียน AIR นั้นจะต้องมีโปรแกรม Flash CS 3 ขึ้นไป
แต่สำหรับ Flash CS 3 นั้น จะต้องไปอัพเดตเป็นเวอร์ชั่น 9.0.2 ก่อน
แล้วลงตัว Add-on เพิ่มเข้าไปให้สามารถสร้างไฟล์ AIR ได้
แต่ถ้าใครใช้ Flash CS 4 ก็สบายหน่อย เพราะเลือก New Flash File (Adobe AIR) ได้เลยจ้ะ
หรือถ้าฝ่ายโปรแกรมเมอร์ที่ทำงากับ Flex อยู่แล้ว
ก็สามารถเลือกคอมไพล์จาก Fex Builder ให้ทำเป็น AIR ได้ทันทีเช่นกัน
สรุปว่า AIR สามารถสร้างได้จาก 3 ทางคือ
- Flash IDE หรือ Flash CS 3, Flash CS 4
- FlexSDK/AIRSDK (หาโหลดได้ฟรี จากเว็บของ Adobe)
- Flex Builder 3
อ้อ.. ใช้ ActionScript 3.0 ในการเขียนเท่านั้นครับ
เกริ่นนำไปบ้างแล้ว มาเข้าสู่เนื้อหาจริงๆ กันเถอะครับ (เดี๋ยวยาว)
เอาล่ะ จาก Tutorial (ลิงค์อยู่ด้านบน) ผมจึงเอามาองทำเป็น แกเลอรี่รูป (เขียนทับศัพท์ถูกมั้ยนี่)
แบบง่ายๆ ดู เผื่อใครปิ๊งไอเดียจะเอาไปพัฒนาต่อ ก็ไม่ว่ากันนะจ๊ะ
หลักการทำงานของโปรแกรมคือ
1. มีการลากไฟล์เข้ามาในพื้นที่ที่กำหนด
2. โปรแกรมตรวจจับได้ว่ามีเหตุการณ์การลากไฟล์เข้ามา (NativeDragEvent.NATIVE_DRAG_ENTER)
3. ตรวจสอบนามสกุลไฟล์ว่าตรงตามที่เราอนุญาตหรือไม่ (ใช่ครับ เรากำหนดได้ว่า จะรับไฟล์อะไร ไม่รับอะไร)
4. เมื่อมีการปล่อยเมาส์ (คือทิ้งไฟล์ลงพื้นที่ที่กำหนด) ก็จะทำการเพิ่มไฟล์เหล่านั้น ลงไปใน TileList
5. TileList ทำการแสดงชื่อ และรูปภาพขนาดเล็ก (จริงๆ คือรูปขนาดเท่าของเดิมแต่โดนบีบให้อยู่ในพื้นที่น่ะครับ)
6. รอจับเหตุการณ์ ถ้ามีการดับเบิ้ลคลิกที่ Thumbnail ให้แสดงรูปใหญ่
7. โดยมี MovieClip ขนาดใหญ่ + UILoader รอรับพาธรูปอยู่แล้ว
คลาสที่ใช้เพิ่มเติม (Import)
แน่นอนครับว่า มันไม่ได้ใช้คลาสพื้นฐานที่ไม่ต้อง import ดังนั้นเราจึงต้อง import เข้ามาให้โปรแกรมรู้จัก
คลาสที่จำเป็นครับ
- flash.desktop.NativeDragManager => เป็นคลาสที่จัดการทุกอย่างที่เกี่ยวกับการลาก-วางไฟล์ครับ
- flash.desktop.Clipboard => คลาสตัวนี้จะจำว่า มีไฟล์อะไรที่กำลังโดนลากอยู่บ้าง
- flash.desktop.ClipboardFormats => คลาสรูปแบบของข้อมูลที่เราต้องการจากคลิปบอร์ดครับ
- flash.events.NativeDragEvent => Event ที่เกี่ยวกับการลาก-วางไฟล์
- fl.events.ListEvent => Event ที่เกี่ยวกับ List ทั้งหลาย เช่น คลิกวัตถุในลิสต์, ข้อมูลในลิสต์เปลี่ยน ฯลฯ
- com.korstudio.utils.EasyFilter => เอ่อ... คลาสขี้เกียจส่วนตัวของผมเองครับ (แนบมาในไฟล์ rar แล้ว)
สิ่งที่ต้องวาด/เตรียม
- พื้นที่สำหรับวางไฟล์ที่ลาก
วาดเป็นขนาดเท่าไหร่ก็ได้ครับ แล้วทำเป็น MovieClip ตั้ง Instance name ว่า dropArea_mc
- ที่แสดง Thumbnail
เปิดหน้าต่าง Components (Ctrl+F7) แล้วลาก TileList จากหมวด User Interface มาวางครับ
- ที่แสดงภาพใหญ่
สร้าง MovieClip มาอันหนึ่ง ด้านในให้วาดกรอบสี่เหลี่ยมใหญ่ๆ ไว้
แล้วก็ลาก Component ที่ชื่อ UILoader มาวางครับ ตั้ง Instance Name ว่า loader
จากนั้นวาดรูปปุ่มปิด ทำเป็น Button แล้วตั้ง Instance Name ว่า close_btn
ตามรูปด้านล่างนี้ครับ

จากนั้นก็ตั้ง Instace name ให้ Symbol ตัวนี้ว่า bigPanel ครับ (เอามาวางบน Stage ก่อนนะครับ แล้วค่อยตั้ง)
เริ่มทำเลยดีกว่าครับ
1. ขั้นแรก เราก็ต้อง import คลาสที่จำเป็นก่อน (ตามที่ลิสต์ไว้ด้านบนเลย)
import flash.desktop.NativeDragManager;
import flash.events.NativeDragEvent;
import fl.events.ListEvent;
import flash.desktop.Clipboard;
import flash.desktop.ClipboardFormats;
import com.korstudio.utils.EasyFilter;
2. สร้างตัวแปร allowedFileExtension เพื่อกำหนดว่า เราจะอนุญาตให้ลากไฟล์อะไรเข้ามาบ้าง
ในตัวอย่างนี้อนุญาตไฟล์ jpg png gif และ swf ครับ
var allowedFileExtension:Array = ["jpg","png","swf","gif"];
3. กำหนดให้ bigPanel (กรอบแสดงภาพใหญ่) ซ่อนตัวก่อนครับ อย่าเพิ่งแสดงให้ใครเห็น
bigPanel.visible = false;
4. เพิ่ม event listener ให้กับตัว dropArea_mc (พื้นที่สำหรับวางไฟล์ที่ลาก) ครับ 3 อย่างคือ
NATIVE_DRAG_ENTER => เมื่อมีการลากไฟล์เข้ามายังพื้นที่
NATIVE_DRAG_EXIT => เมื่อคนลากไฟล์เกิดเปลี่ยนใจ เอาไฟล์ที่ลากออกไปนอกกรอบ
NATIVE_DRAG_DROP => หลังจากคนลากไฟล์ตกลงปลงใจได้แล้ว ก็ปล่อยไฟล์ลงบนพื้นที่
dropArea_mc.addEventListener(NativeDragEvent.NATIVE_DRAG_ENTER, onDragFileEnter);
dropArea_mc.addEventListener(NativeDragEvent.NATIVE_DRAG_EXIT, onDragFileExit);
dropArea_mc.addEventListener(NativeDragEvent.NATIVE_DRAG_DROP, onDropFile);
5. สังเกตว่า ใน event listener เรากำหนดชื่อฟังก์ชั่นไป 3 ฟังก์ชั่นคือ onDragFileEnter onDragFileExit
และ onDropFile แต่ตอนนี้ยังไม่มีฟังก์ชั่นเหล่านี้จริงๆ ดังนั้น เราจึงต้องมาสร้างฟังก์ชั่นเหล่านี้เองครับ
function onDragFileEnter(event:NativeDragEvent):void{
//ทำงานต่อเมื่อมีการลากไฟล์เข้ามาในพื้นที่ dropArea_mc
}
function onDragFileExit(event:NativeDragEvent):void{
//ทำงานเมื่อมีการลากไฟล์ออกจากพื้นที่ dropArea_mc
}
function onDropFile(event:NativeDragEvent):void{
//ทำงานต่อเมื่อมีการวางไฟล์ลงบนพื้นที่ dropArea_mc
}
6. ลุยทีละอย่างก่อน.. เริ่มที่ onDragFileEnter ครับ
function onDragFileEnter(event:NativeDragEvent):void{
//สร้างตัวแปร file เพื่อเก็บรายชื่อไฟล์ที่ลากค้างไว้ โดยดึงมาจาก Clipboard
var file:Array = event.clipboard.getData(ClipboardFormats.FILE_LIST_FORMAT) as Array;
//เอาไฟล์แรกมาเช็คดูนามสกุลไฟล์ว่า อยู่ในรายการที่อนุญาตให้ใช้มั้ย
//โดยส่งนามสกุลไฟล์ไปที่ฟังก์ชั่น checkExtension เพื่อตรวจเช็ค
//ซึ่งฟังก์ชั่นดังกล่าวจะเช็คแล้วส่งผลการเช็คกลับมาเป็น true หรือ false ครับ
if (checkExtension(file[0].extension)) {
//ถ้านามสกุลไฟล์ อยู่ในลิสต์ที่อนุญาต.. ก็อนุญาตให้วางได้ทั้งหมด
NativeDragManager.acceptDragDrop(dropArea_mc);
//ขั้นนี้เป็นการใส่ฟิลเตอร์ Brightness ให้ dropArea_mc ครับ จะได้เห็นว่ามีการตอบสนอง
EasyFilter.Brightness(dropArea_mc, -20);
}else{
//แต่ถ้าไม่.. ก็ให้ trace ออกมาว่า ไม่เอา
trace("Not accept *."+file[0].extension);
}
}
7. ถัดมาครับ มาทำที่ onDragFileExit ที่นี่ไม่มีอะไร นอกจากเอาฟิลเตอร์ออกครับ
function onDragFileExit(event:NativeDragEvent):void{
//เมื่อมีการลากไฟล์ออกจาก dropArea_mc ก็ให้เอาฟิลเตอร์ออก
EasyFilter.Remove(dropArea_mc);
}
8. และมาต่อที่ onDropFile ตรงนี้จะเยอะหน่อยครับ เพราะต้องจัดการนำไฟล์ไปลงที่ TileList ด้วย
function onDropFile(event:NativeDragEvent):void{
//คนลากไฟล์วางไฟล์ลงมาในพื้นที่แล้ว
//สร้างตัวแปร files เพื่อเก็บรายการไฟล์ที่ลากไว้อยู่จาก Clipbard ครับ
var files:Array = event.clipboard.getData(ClipboardFormats.FILE_LIST_FORMAT) as Array;
//วนลูปเพื่อนำไฟล์ไปใส่ใน TileList
for(var i:int = 0; i < files.length; i++){
//สร้างตัวแปรเพื่อเก็บค่าต่างๆ (อันนี้ผมว่าคงเดากันได้อยู่แล้ว)
var fileName:String = files[i].name;
var ext:String = fileName.substring(fileName.lastIndexOf(".")+1);
//สร้างตัวแปรเก็บพาธเต็มของรูป แล้วทดสอบให้ trace ออกมาดู
var nativePath:String = files[i].nativePath;
trace(nativePath);
//นำข้อมูลไปใส่ใน TileList (ชื่อไฟล์ และพาธรูปเพื่อแสดงรูป)
picPanel.addItem({label: fileName, source: nativePath});
}
//ลบฟิลเตอร์ออก
EasyFilter.Remove(dropArea_mc);
}
9. เก็บตกฟังก์ชั่นที่เหลือครับ คือฟังก์ชั่นที่ใช้เช็คนามสกุลไฟล์นั่นเอง
function checkExtension(ext:String):Boolean{
//วนลูปจากอาร์เรย์ allowedFileExtension ที่เก็บนามสกุลไฟล์ไว้ครับ
for(var n:String in allowedFileExtension){
//แปลงนามสกุลที่ส่งมาเป็นพิมพ์เล็ก แล้วก็นำไปเช็คกับค่าในแต่ละตำแหน่งของอาร์เรย์
//ถ้าตรงกัน ก็ให้หยุดลูปแล้วส่งไปว่า true
if(ext.toLowerCase() == allowedFileExtension[n]){
return true;
}
}
//จนแล้วจนรอดก็ลูปไม่เจอนามสกุลไฟล์ที่ว่าเลย เอิ่ม งั้นก็ไม่อนุญาตนะ ส่งไปว่า false โลด
return false;
}
10. กด Ctrl+Enter ทดสอบ
ตอนนี้โปรแกรมพอจะทำงานได้บ้างแล้ว เหลือตรงที่ ดับเบิ้ลคลิกรูป Thumbnail แล้วแสดงรูปใหญ่ครับ
11. กลับมายังหน้าต่าง Actions เพิ่มบรรทัดนี้ลงไป หลังจากบรรทัดที่ addEventListener ของ
picPanel (ที่เป็น TileList) ครับ
picPanel.addEventListener(ListEvent.ITEM_DOUBLE_CLICK, onItemDoubleClick);
12. แล้วก็สร้าง listener ต่อ
function onItemDoubleClick(event:ListEvent):void{
//สั่งแสดงกรอบใหญ่
bigPanel.visible = true;
//แล้วสั่ง UILoader ให้โหลดรูป โดยใช้พาธจาก Thumbnail ที่เลือกอยู่
bigPanel.loader.source = picPanel.selectedItem.source;
}
13. โค้ดทั้งหมดทั้งมวล จะได้ออกมาตามรูปนี้ครับ (บางจุดที่เห็นไม่เหมือนกันไม่ต้องตกใจครับ)
14. ทดสอบโปรแกรม โดยการลองลากไฟล์มาที่พื้นที่ที่กำหนด จากนั้นก็ลองดับเบิ้ลคลิกรูปเล็กดู
15. ในที่สุด ก็เสร็จสมบูรณ์ครับ เย้
แต่อย่าเพิ่งดีใจจนเกินไปนะครับ เพราะว่ามันเป็นเพียงแค่ ตัวอย่าง!!! (ผ่างงง)
หากนำไปใช้จริง เราต้องปรับปรุงอีกมากครับ แต่ก็คงไม่เกินความสามารถของพี่น้องแน่นอน
โหลดไฟล์ fla: ( จิ้มที่นี่ )
โหลดไฟล์ AIR ไปลองเล่น: ( จิ้มที่นี่ )

