1 / 38

Michelle Hedstrom May 17, 2005

Introduction to Dashboard Widgets. Michelle Hedstrom May 17, 2005. Agenda. Introduction to Dashboard/Widgets Building your first widget Adding on - web searching! Scrollbars and saved searches What’s Next Debugging. What is Dashboard?. Part of Mac OS 10.4 (Tiger).

manju
Download Presentation

Michelle Hedstrom May 17, 2005

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Introduction to Dashboard Widgets Michelle Hedstrom May 17, 2005

  2. Agenda • Introduction to Dashboard/Widgets • Building your first widget • Adding on - web searching! • Scrollbars and saved searches • What’s Next • Debugging

  3. What is Dashboard? • Part of Mac OS 10.4 (Tiger). • Lets You Run Mini-Applications (Widgets). • Pretty wrapper around Apple’s WebKit. • Virtual Layer - only comes when called.

  4. What is a Widget? • Mini application - can run in Safari. • Stored as a bundle. • HTML, JavaScript, & CSS. • Information, application, or accessory. • New widget object

  5. Components of a Widget • HTML Files, Info.plist, Default.png, Icon.png • Optional: JavaScript & CSS Files Picture from http://developer.apple.com/macosx/dashboard.html

  6. Making a Widget • Put all required files in a folder. • Add on to folder name .wdgt extension - turns into bundle. • Double-click .wdgt file to launch in Dashboard. • Optionally, move to ~/Library/Widgets.

  7. We’re Not Talking About… • Error checking • Preferences • Most design conventions Aqua bad Custom good

  8. Tools Needed • A Mac with Tiger (OS 10.4) installed • Text editor • Graphics editor (optional) • Xcode Tools (optional)

  9. Build Stage 1 • Create the widget itself. • Put in the background graphic. • Add in the search form field with results area.

  10. Stage 1 HTML <html> <head> <link rel="stylesheet" href="YahooClass.css" type="text/css" /> <title>Yahoo Class Widget</title> </head> <body> <div class="front"> <input type="search" id="searchYahoo" size="30" /> <div id="resultsArea"> </div> </body> </html> front searchYahoo resultsArea

  11. Stage 1 CSS .front { width: 290px; height: 314px; background-image: url(Default.png); } .searchYahoo { position: absolute; top: 60px; left: 40px; text-align:left; } #resultsArea { background-color: white; position: absolute; font-size: small; top: 90px; left: 30px; width: 240px; height: 190px; }

  12. Stage 1 Info.plist CFBundleDisplayName - actual widget name displayed in Finder and widget bar. CFBundleIdentifier - Uniquely identifying string in reverse domain format. CFBundleName - Name of widget, must match name of bundle on disk minus the .wdgt extension. CFBundleVersion - version number. MainHTML - name of the main HTML file implementing widget.

  13. Build Stage 2 • Run search when user types in search terms. • Display results in results box. • Clicking on URL opens in widget window.

  14. Stage 2 Info.plist AllowNetworkAccess - if widget requires any network resources.

  15. Stage 2 HTML <html> <head> <link rel="stylesheet" href="YahooClass.css" type="text/css" /> <script language="JavaScript" src="Main.js"></script> <title>Yahoo Class Widget</title> </head> <body> <div class="front"> <input type="search" id=“searchYahoo” size="30" onSearch="doSearch(this.value)" /> <div id="resultsArea"> </div> </div> </body> </html>

  16. Stage 2 JS - Vars var baseSearchURL = "http://api.search.yahoo.com/WebSearchService/V1/"; var searchMethod = "webSearch"; var appID = "DashboardSearch"; var numResultsReturned = "5"; var req; • Requirements of Yahoo Search API. • Num results returned optional - defaults to 10 if not provided.

  17. Stage 2 JS - doSearch() function doSearch(searchValue) { var searchURL= baseSearchURL+searchMethod+"?"+"appid="+appID+"&query="+searchValue+"&results="+numResultsReturned; req = new XMLHttpRequest(); req.open("GET",searchURL,false); req.send(null); document.getElementById('resultsArea').innerHTML = (parseXML(req.responseXML)); } • Building the search URL: • http://api.search.yahoo.com/WebSearchService/V1/webSearch?appid=DashboardSearch&query=Michelle&results=5

  18. …Stage 2 JS - doSearch()… function doSearch(searchValue) { var searchURL= baseSearchURL+searchMethod+"?"+"appid="+appID+"&query="+searchValue+"&results="+numResultsReturned; req = new XMLHttpRequest(); req.open("GET",searchURL,false); req.send(null); document.getElementById('resultsArea').innerHTML = (parseXML(req.responseXML)); } • HTTP request that returns XML DOM object. • req.open with false boolean - synchronous mode just for demo. Asynchronous better - check for onreadystatechange event. • req.send arg. used to transmit content for a POST request, null otherwise.

  19. …Stage 2 JS - doSearch()… function doSearch(searchValue) { var searchURL= baseSearchURL+searchMethod+"?"+"appid="+appID+"&query="+searchValue+"&results="+numResultsReturned; req = new XMLHttpRequest(); req.open("GET",searchURL,false); req.send(null); document.getElementById('resultsArea').innerHTML= (parseXML(req.responseXML)); } • Looks for a div called resultsArea. • Gets the area where the content is stored for that div.

  20. …Stage 2 JS - doSearch() function doSearch(searchValue) { var searchURL= baseSearchURL+searchMethod+"?"+"appid="+appID+"&query="+searchValue+"&results="+numResultsReturned; req = new XMLHttpRequest(); req.open("GET",searchURL,false); req.send(null); document.getElementById('resultsArea').innerHTML = (parseXML(req.responseXML)); } • Gets results back of search as a document object. • Passes off to parseXML function.

  21. Stage 2 JS - parseXML() function parseXML(xmlResults) { var resultsStrings = ""; var indResponse = xmlResults.getElementsByTagName("Result"); for (i=0; i<indResponse.length; i++) { var title = indResponse[i].getElementsByTagName("Title")[0].firstChild.nodeValue; var URL = indResponse[i].getElementsByTagName("ClickUrl")[0].firstChild.nodeValue; var summary = indResponse[i].getElementsByTagName("Summary")[0].firstChild.nodeValue; resultsStrings += "<A HREF=\""+URL+"\">"+title+"</a><br>"+summary+"<p>"; } return resultsStrings; } • Find all nodes named Result. • Each individual search result is one such XML node.

  22. …Stage 2 - parseXML() function parseXML(xmlResults) { var resultsStrings = ""; var indResponse = xmlResults.getElementsByTagName("Result"); for (i=0; i<indResponse.length; i++) { var title = indResponse[i].getElementsByTagName("Title")[0].firstChild.nodeValue; var URL = indResponse[i].getElementsByTagName("ClickUrl")[0].firstChild.nodeValue; var summary = indResponse[i].getElementsByTagName("Summary")[0].firstChild.nodeValue; resultsStrings += "<A HREF=\""+URL+"\">"+title+"</a><br>"+summary+"<p>"; } return resultsStrings; } • Iterate through all results, from high level object to value of each individual field we want. • Format all results in way we want with clickable title.

  23. Stage 2 - CSS #resultsArea { background-color: white; position: absolute; font-size: small; top: 90px; left: 30px; width: 240px; height: 190px; overflow: hidden; } Without overflow:hidden With overflow:hidden

  24. Build Stage 3 • Scroll bars for results. • Clicking on URL opens in default browser. • Saved keyword search.

  25. Scrollbar • Custom built scrollbar - Apple code • “Define a parent DIV with overflow CSS property set to hidden” front #resultsArea { background-color: white; background-image: none; position: absolute; font-size: small; top: 90px; left: 30px; width: 240px; height: 190px; overflow:hidden; } searchYahoo resultsArea

  26. Scrollbar Step 2 • “Place all scrollable content in a div within the parent div: this ‘child’ div should have an undefined overflow, or a value of visible.” Changed resultsArea to mainContent in Main.js <div id=“resultsArea”> <div id=“mainContent”> </div </div>

  27. Scrollbar Step 3 • “Declare the Scroller divs and place them inside the parent div.”  <div id="resultsArea"> <div id="mainContent"> </div> <div id='myScrollBar'> <div id='myScrollTrack' onmousedown='mouseDownTrack(event);' onmouseup='mouseUpTrack(event);'> <div class='scrollTrackTop' id='myScrollTrackTop'></div> <div class='scrollTrackMid' id='myScrollTrackMid'></div> <div class='scrollTrackBot' id='myScrollTrackBot'></div> </div> <div id='myScrollThumb' onmousedown='mouseDownScrollThumb(event);'> <div class='scrollThumbTop' id='myScrollThumbTop'></div> <div class='scrollThumbMid' id='myScrollThumbMid'></div> <div class='scrollThumbBot' id='myScrollThumbBot'></div> </div> </div> </div>

  28. Scrollbar Step 4 • “It is important that the child div start with a CSS top property set to 0;” #mainContent { position:absolute; left:0; top: 0; right:35px; }

  29. Scrollbar Step 5 • Scrollbar CSS from Apple #myScrollBar { /* border-style:solid; border-color:yellow; */ position:absolute; top:6px; bottom:14px; right:0px; width:19px; display:block; -apple-dashboard-region:dashboard-region(control rectangle); } /* Scroller track */ .scrollTrackTop { /* border-style:solid; border-color:red; */ position:absolute; top:0px; width:19px; height:18px; background:url(Images/top_scroll_track.png) no-repeat top left; } …

  30. apple-dashboard-region #myScrollBar { /* border-style:solid; border-color:yellow; */ position:absolute; top:6px; bottom:14px; right:0px; width:19px; display:block; -apple-dashboard-region:dashboard-region(control rectangle); } Region used for specific purpose. 1st param - type of region defined. 2nd param - shape of region

  31. Stage 3 HTML … <head> <link rel="stylesheet" href="YahooClass.css" type="text/css" /> <script language="JavaScript" src="Main.js"></script> <script language="JavaScript" src="Scroller.js"></script> <title>Yahoo Class Widget</title> </head> <body onload='setup();'> … Use the JavaScript file provided by Apple. Call a setup function after load.

  32. Stage 3 JS - setup() function setup() { scrollerInit(document.getElementById("myScrollBar"), document.getElementById("myScrollTrack"), document.getElementById("myScrollThumb")); document.getElementById('mainContent').innerHTML = ""; calculateAndShowThumb(document.getElementById('mainContent')); } Call Apple defined init function. Set our content area to empty. Figure out the height of the view, and make the thumb proportional (Apple defined func.).

  33. Stage 3 JS - doSearch() function doSearch(searchValue) { var searchURL= baseSearchURL+searchMethod+"?"+"appid="+appID+” &query="+searchValue+"&results="+numResultsReturned; req = new XMLHttpRequest(); req.open("GET",searchURL,false); req.send(null); document.getElementById('mainContent').innerHTML = (parseXML(req.responseXML)); calculateAndShowThumb(document.getElementById('mainContent')); } Resize the scrollbar for the current amount of text in the area.

  34. Saved Keyword Search Change: <input type="search" id="searchYahoo” size="30" onSearch="doSearch(this.value)" /> To:  <input type="search" id="searchYahoo" size="30" results="5" onSearch="doSearch(this.value)" /> Results is number of past searches saved.

  35. Open URL in Default Browser function parseXML(xmlResults) { var resultsStrings = ""; indResponse = xmlResults.getElementsByTagName("Result"); for (var i=0; i<numResultsReturned; i++) { var title = indResponse[i].getElementsByTagName("Title")[0].firstChild.nodeValue; var URL = indResponse[i].getElementsByTagName("ClickUrl")[0].firstChild.nodeValue; var summary = indResponse[i].getElementsByTagName("Summary")[0].firstChild.nodeValue; if (window.widget) { resultsStrings += "<A HREF=\"javascript:widget.openURL('"+URL+"')\">"; } else { resultsStrings += "<A HREF=\""+URL+"\">"; } resultsStrings += title+"</a><br>"+summary+"<p>"; } return resultsStrings; }

  36. What’s Next? • Truncate summary or build summary box at bottom of screen. • Preferences to support language, type of search, num results returned.

  37. Debugging • Safari JavaScript Console • Open Terminal window, type: • defaults write com.apple.Safari IncludeDebugMenu 1 • Relaunch Safari, check “Log JavaScript Exceptions” in Debug Menu • Choose “Show JavaScript Console” in Debug menu. • Write directly to JS Console • window.console.log(“Problem if you get here") • Shows up in dark green • Create Debug div • Good ‘ol alerts

  38. Resources • Developing Dashboard Widgets -http://developer.apple.com/macosx/dashboard.html • Apple Dashboard Documentation -http://developer.apple.com/documentation/AppleApplications/Dashboard-date.html • Yahoo Search API - http://developer.yahoo.net/ • /Library/WidgetResources for premade graphics/buttons • /Developer/Examples/Dashboard • /Developer/Applications/Utilities/Property List Editor • Me! - mhedstrom@ogre.com

More Related