Top Banner
Michelle Hedstrom May 17, 2005
38

Michelle Hedstrom May 17, 2005

Jan 19, 2016

Download

Documents

Manju

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). - PowerPoint PPT Presentation
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Michelle Hedstrom May 17, 2005

Michelle Hedstrom

May 17, 2005

Page 2: 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

Page 3: Michelle Hedstrom May 17, 2005

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.

Page 4: Michelle Hedstrom May 17, 2005

What is a Widget?

• Mini application - can run in Safari.• Stored as a bundle.• HTML, JavaScript, & CSS.• Information, application, or accessory.

New widget object

Page 5: Michelle Hedstrom May 17, 2005

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

Page 6: Michelle Hedstrom May 17, 2005

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.

Page 7: Michelle Hedstrom May 17, 2005

We’re Not Talking About…

• Error checking

• Preferences

• Most design conventions

Aqua bad

Custom good

Page 8: Michelle Hedstrom May 17, 2005

Tools Needed

• A Mac with Tiger (OS 10.4) installed

• Text editor

• Graphics editor (optional)

• Xcode Tools (optional)

Page 9: Michelle Hedstrom May 17, 2005

Build Stage 1

• Create the widget itself.

• Put in the background graphic.

• Add in the search form field with results area.

Page 10: Michelle Hedstrom May 17, 2005

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>

resultsArea

searchYahoo

front

Page 11: Michelle Hedstrom May 17, 2005

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;}

Page 12: Michelle Hedstrom May 17, 2005

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.

Page 13: Michelle Hedstrom May 17, 2005

Build Stage 2

• Run search when user types in search terms.

• Display results in results box.

• Clicking on URL opens in widget window.

Page 14: Michelle Hedstrom May 17, 2005

Stage 2 Info.plist

•AllowNetworkAccess - if widget requires any network resources.

Page 15: Michelle Hedstrom May 17, 2005

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>

Page 16: Michelle Hedstrom May 17, 2005

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.

Page 17: Michelle Hedstrom May 17, 2005

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

Page 18: Michelle Hedstrom May 17, 2005

…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.

Page 19: Michelle Hedstrom May 17, 2005

…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.

Page 20: Michelle Hedstrom May 17, 2005

…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.

Page 21: Michelle Hedstrom May 17, 2005

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.

Page 22: Michelle Hedstrom May 17, 2005

…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.

Page 23: Michelle Hedstrom May 17, 2005

Stage 2 - CSS

Without overflow:hidden

With overflow:hidden

#resultsArea { background-color: white; position: absolute; font-size: small; top: 90px; left: 30px; width: 240px; height: 190px; overflow: hidden;}

Page 24: Michelle Hedstrom May 17, 2005

Build Stage 3

• Scroll bars for results.

• Clicking on URL opens in default browser.

• Saved keyword search.

Page 25: Michelle Hedstrom May 17, 2005

Scrollbar

• Custom built scrollbar - Apple code

• “Define a parent DIV with overflow CSS property set to hidden”

resultsArea

searchYahoo

front

#resultsArea { background-color: white; background-image: none; position: absolute; font-size: small; top: 90px; left: 30px; width: 240px; height: 190px; overflow:hidden;}

Page 26: Michelle Hedstrom May 17, 2005

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.”

<div id=“resultsArea”> <div id=“mainContent”> </div</div>

•Changed resultsArea to mainContent in Main.js

Page 27: Michelle Hedstrom May 17, 2005

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>

Page 28: Michelle Hedstrom May 17, 2005

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;}

Page 29: Michelle Hedstrom May 17, 2005

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;

}…

Page 30: Michelle Hedstrom May 17, 2005

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

Page 31: Michelle Hedstrom May 17, 2005

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.

Page 32: Michelle Hedstrom May 17, 2005

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.).

Page 33: Michelle Hedstrom May 17, 2005

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.

Page 34: Michelle Hedstrom May 17, 2005

Saved Keyword Search

<input type="search" id="searchYahoo” size="30" onSearch="doSearch(this.value)" />

Change:

To: <input type="search" id="searchYahoo" size="30" results="5" onSearch="doSearch(this.value)" />

•Results is number of past searches saved.

Page 35: Michelle Hedstrom May 17, 2005

Open URL in Default Browserfunction 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;}

Page 36: Michelle Hedstrom May 17, 2005

What’s Next?

• Truncate summary or build summary box at bottom of screen.

• Preferences to support language, type of search, num results returned.

Page 37: Michelle Hedstrom May 17, 2005

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

Page 38: Michelle Hedstrom May 17, 2005

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! - [email protected]