Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Beginning Mac OS X Tiger Dashboard Widget Development (2006)

.pdf
Скачиваний:
17
Добавлен:
17.08.2013
Размер:
9.7 Mб
Скачать

Adding Drag and Drop to the Widget

When you get the file over the Dropper widget, you’ll see a plus added to the cursor to let you know that you have reached your destination and can drop the file (Figure 10-4).

Figure 10-4

Release the file and the display box in the widget is updated with the path URL to the file (Figure 10-5).

Figure 10-5

This is very straightforward and something you do unconsciously in your daily use of the Macintosh. Let’s take a look at the widget’s support for drag and drop.

Using Drag and Drop

You may have noticed that whenever you drag a file in the Finder, you see a lighter representation of it. The application icon highlights whenever you drag the file over an application that may be able to work with it in some fashion. Dashboard provides the ability to mimic this same behavior through a set of events. Support for drag and drop in widgets is provided through three events and can be applied to the individual elements of the HTML page in your widget: ondragstart, ondrag, and ondragend.

161

Chapter 10

When you begin dragging an object, the ondragstart event is called. As you drag, the ondrag event is sent repeatedly to the object you are dragging. Once you reach the destination and drop the object, it is sent the ondragend event and it reports the status of the drop — either successful or unsuccessful.

While a drag is in process, any element that has the potential to receive the drop is sent an event whenever the object is dragged is near it. These events allow you to provide feedback to the user about the progress of the drag by changing the cursor during drag or changing the widget to let the user know that the drop can or cannot be accepted. The events are ondragenter, ondragover, ondragleave, and ondrop.

The ondragenter and ondragleave events let the element that might receive the drop know when the object is entering its boundaries or when the object has left the element’s boundaries. The ondragover event lets the element know that the object could drop on it. The ondrop event is sent to the element whenever the object is dropped and allows the widget to respond to the drop.

If you show the contents of the Dropper widget and take a look at the source files, you can see how these events are tied to the elements in the HTML and CSS files through the JavaScript.

HTML

When you examine the HTML file you can see the basic structure with the CSS and JavaScript files incorporated in the Head section. The ondragenter, ondragover, and ondragleave events are included in the <body> tag, and each of these events has its own handler assigned to it as well. Whenever a file enters within the body of the widget these handlers are called and any action assigned in them will be executed.

<html>

<head>

<!-- The CSS for this widget --> <style type=”text/css”>

@import “Dropper.css”; </style>

<!-- The JavaScript for this widget -->

<script type=’text/javascript’ src=’Dropper.js’ charset=’utf-8’/> </head>

<!-- Note the drag and drop handlers set up for body; if any of these events happen, the relevant handler is called -->

<body ondragenter=’dragenter(event);’ ondragover=’dragover(event);’ ondrop=’dragdrop(event)’ ondragleave=’dragleave(event)’>

<img id=”arrow” src=”Default.png” > <!-- The background image for the widget -->

<!-- The “info window” that shows the information that this widget outputs --> <div class=”theInfo”>

<img src=”images/top.png”> <div class=”infoWrap”>

<div id=”infoLabel”>Drag an item from Finder, show Dashboard, and drop it on this Widget.</div>

<div id=”infoURL”></div> </div>

162

Adding Drag and Drop to the Widget

<img src=”images/bottom.png”> </div>

</body>

</html>

Like the Fortune widget, Dropper has a graphic with default text that is replaced by the file URL. The default text is included in the infoLabel <div> and the infoURL <div> holds the file URL whenever the file is dropped on the widget.

CSS

The CSS file for the Dropper widget contains a header with information about how the styles are used. If the style is going to remain static, you begin it with a period. If the style is going to change programmatically, you begin it with a hash.

*/

/* Styles

*Style sheets allow for precise control of elements within your widget.

*All style information is contained within the <style> tags. If you want to

*utilize style information, use the class or id attributes on most any tag, and * set them equal to one of your defined styles. Use the class attribute when a

*style is to remain static, and id if you change the style in your scripts.

*When defining the style, begin the style with a period (.) if it is to remain

* static, and a hash (#) if it is going to be altered programatically. */

body { margin: 0;

}

.theInfo { opacity: 1.0;

position: absolute; top: 60px;

left: 25px;

}

.infoWrap {

background: url(“images/middle.png”); padding-right: 9px;

padding-left: 9px; width: 134px;

}

#infoLabel {

font: 9px “Lucida Grande”; font-weight: bold;

color: white; padding-top: 4px; padding-bottom: 2px; text-align: center;

163

Chapter 10

}

#infoURL {

font: 11px “Courier New”; font-weight: bold; color: white;

word-wrap: break-word; padding-top: 2px; padding-bottom: 4px;

}

In the Dropper widget, theInfo and infoWrap styles are both defined as static. If you refer to the HTML file, theInfo begins with the top part of the rectangle graphic (images/top.png) where the file URL will be placed and ends with the bottom portion of the rectangle graphic (images/bottom.png). The infoWrap style is also static and contains the middle portion of the graphic.

The infoLabel and infoURL styles are defined to be modified programmatically. The infoLabel contains the default text that is replaced by a new label when a file is dropped, and the infoURL holds the file URL.

JavaScript

The JavaScript file contains the event handler to do the work whenever an item or items are dropped on the widget. The dragdrop function begins by setting the variable uri, which will hold the file URL, to null. This ensures that the variable is cleared each time a new item is dropped on the widget. When the user releases the mouse button over the widget, the variable is set by event.dataTransfer.getData (“text/uri-list”), which gets the path to the file in URL format. The function also changes the label text.

The default behavior for WebKit with an ondrop event is to receive and incorporate the data. The event.preventDefault() in the dragdrop function prevents this default behavior and allows your handler to receive the data. You don’t have to pass any parameters for this method. The event.stopPropagation() is a method that also doesn’t require any parameters. Calling it keeps the event from continuing. If you want to cancel a drag, call the cancelDefault() method.

/******************/

//Drag and drop code

//This code handles the various drag and drop events /******************/

//The event handler for the image drop. This handles fetching the image URL and

//trying to place it inside of the widget.

function dragdrop (event)

{

var uri = null; try {

uri = event.dataTransfer.getData(“text/uri-list”); // attempt to load the URL

} catch (ex)

{

164

Adding Drag and Drop to the Widget

}

 

 

// if the acquisition is successful:

 

 

if (uri)

 

 

{

 

 

document.getElementById(“infoLabel”).innerText = “That item’s URL is:”;

//

Add the new label text

 

 

document.getElementById(“infoURL”).innerText = uri;

// And display

the file’s URL

 

 

}

 

 

event.stopPropagation();

event.preventDefault();

}

//The dragenter, dragover, and dragleave functions are implemented but not used.

//They can be used if you want to change the image when it enters the widget.

function dragenter (event)

{

event.stopPropagation();

event.preventDefault();

}

function dragover (event)

{

event.stopPropagation();

event.preventDefault();

}

function dragleave (event)

{

event.stopPropagation();

event.preventDefault();

}

The remaining three functions that you saw referenced in the <body> tag of the HTML file for indicating when a drag is over or inside of the widget boundaries have been stubbed at the bottom of the script but no actions have been assigned to them.

Try It Out

Adding the dragover Event

Now that you see how the drag events work, modify the Dropper.js file to change the image of the Dropper widget as you drag an item over it.

1.Show the contents of the Dropper widget.

2.Open the Dropper.js file and scroll to the bottom of the file.

3.In the dragover function, add JavaScript to change the image of the object you are dragging whenever it is over the body of the widget. Your code might look like this:

165

Chapter 10

function dragover (event)

{

document.getElementById(“arrow”).src = “images/drop.png”; event.stopPropagation();

event.preventDefault();

}

4.Save your changes to the Dropper.js file and close it.

5.Open the Dropper.html file and scroll to the body tag.

<body ondragenter=’dragenter(event);’ img src=’dropit.png’ ondragover=’dragover(event);’ ondrop=’dragdrop(event)’ ondragleave=’dragleave(event)’>

6.Add the image source information for the dragover event. Use the additional image included with the widget if you do not have one of your own.

7.Save and close the file.

8.Activate Dashboard and reload the widget to load your changes.

How It Works

Whenever you perform a drag within Dashboard, WebKit provides feedback by showing you an image of what you are dragging. WebKit does this by using a snapshot of the element you are dragging. Your modifications to the JavaScript and HTML files provide an image that WebKit can substitute for this snapshot.

Dragging Between Widgets

You may have also noticed that you can drag between widgets. Not every widget supports drag and drop, and only dragging of text objects is supported. For example, the To Do Tracker from Monkey Business Labs (Figure 10-6) and the Wikipedia widget both support drag and drop for text. When you begin dragging a text object, Dashboard gives you the standard feedback of showing the text you are dragging.

Figure 10-6

166

Adding Drag and Drop to the Widget

When you are over the text entry field in the Wikipedia widget, you get cursor feedback with the plus added to the arrow to let you know that you can drop the object (Figure 10-7).

Figure 10-7

Summar y

You probably use drag and drop most days and never think about it. You may unconsciously drag text and graphics from your word processor to the Finder desktop or links from your browser to your word processor or another browser window. Your widget may not need drag-and-drop capabilities, but you should think about how the user will use it. Drag-and-drop functionality is ingrained in the way we use our Macs and would be conspicuous in its absence.

In this chapter, you learned:

How to use the drag-and-drop events

How to incorporate drag and drop between the Finder and widgets

How to provide feedback to the user during a drag

In Chapter 11, you’ll look at how access keys enable your widget to work with resources on your Mac and the Internet. First, you should review some of the things you learned in this chapter by running through these exercises.

Exercises

1.

2.

3.

What method do you call if you want to cancel a drag?

What parameters are passed to the event.stopPropagation() method?

When was drag-and-drop functionality added to the Macintosh?

167

11

Access Keys

In Chapter 10, you learned about the different drag-and-drop events available to widgets as well as how to add drag-and-drop functionality to a widget. In this chapter, you’ll look at the access keys that are part of the widget Info.plist file. If your widget needs access to any content outside of its bundle, you will need to allow it to access those resources by specifying the kind of access that it needs.

By the end of this chapter, you will know:

What access keys are

How to use all of the access keys

When access keys are appropriate

Using Access Keys

In Chapter 2, you had a brief look at a widget with a plugin and the widget properties including access keys that are specified in the Info.plist file. You have probably looked at other widget properties as you’ve worked through the WeatherMaps example. At this point, you are familiar with the idea that if your widget retrieves web pages or maps from the Internet, you have to declare network access or it will not be able to retrieve those web pages. If your widget needs access to any files or applications outside of its bundle, you must declare that access.

Widgets have seven access keys that provide them with varying levels of access to your Macintosh, command-line utilities, your network, and the Internet. Those keys are

AllowFileAccessOutsideOfWidget, AllowSystem, AllowNetworkAccess,

AllowInternetPlugins, Plugin, AllowJava, and AllowFullAccess. The following sections explain each of these and provide examples.

Chapter 11

File System Access

The AllowFileAccessOutsideOfWidget access key allows your widget to open files and applications outside of the widget bundle. For example, the Tile Game widget that is part of Tiger has the AllowFileAccessOutsideOfWidget access key set so that it can use pictures that you drag on it (Figure 11-1).

Figure 11-1

If you remove the AllowFileAccessOutsideOfWidget key, you can’t drag another image onto the Tile Game. Even though you can grant your widget access outside of its bundle, that access will be limited to your access permissions on the file system. A good rule of thumb is that if you can open the file or application without having to enter the Administration password, your widget should be able to as well.

The AllowFileAccessOutsideOfWidget is a Boolean key. If you look in the Tile Game Info.plist file with the Property List Editor, you’ll see key and settings (Figure 11-2).

Figure 11-2

170