Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 36 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
36
Dung lượng
1,02 MB
Nội dung
System Resources As you saw earlier, if your computer has been off or asleep, the first time you activate Dashboard, you may see all of your widgets without their preferences while the information is retrieved. This is a tech- nique for conserving system resources while Dashboard isn’t activated. You can see the impact widgets have on your system if you launch Activity Monitor and leave it running while Dashboard activates. CPU, Disk Activity, and Network usage all spike (Figure 7-2). To monitor widgets, you will need to view All Processes in the Activity Monitor and filter for Dashboard because widgets run as children of Dashboard. Doing this allows you to see the widgets that are installed as well as their resource usage. During the initial spike when Dashboard activates, they use the most CPU and bandwidth. Figure 7-2 117 Widget Events 12_778257 ch07.qxp 6/9/06 9:32 AM Page 117 Once you close Dashboard, however, the widgets’ resource usage falls off, aside from the real and virtual memory that they use (Figure 7-3). While Dashboard provides an environment for widgets, it does not provide the memory space. Widgets run as child processes of the Dock and are listed individually in the BSD utility top and the Activity Monitor (Figure 7-4). You’ll also notice when you look in Activity Monitor that Dashboard doesn’t show up as a process. Figure 7-3 118 Chapter 7 12_778257 ch07.qxp 6/9/06 9:32 AM Page 118 Figure 7-4 Removing Widget Preferences As you noticed by looking in Activity Monitor at the resources used by widgets, a widget that isn’t installed in Dashboard doesn’t use any resources. This means that you can lessen system impact by removing unused widgets from Dashboard. You may remember that when you remove a widget from Dashboard by clicking the close box, it is not uninstalled or moved to the trash. It remains in the Widgets folder and visible in the Widgets tray until you need it again. Widget preferences also hang around unless you explicitly remove them. A removal event handler is available if you want to remove your widget’s preferences whenever it is removed from Dashboard. This isn’t required, but is just a good housekeeping practice. If you look at the Weather.js file for the Weather widget, you’ll see that I have written it to clear the pref- erences whenever the widget is removed from Dashboard. The onremove statement is set in the same group as the onhide and onshow statements. 119 Widget Events 12_778257 ch07.qxp 6/9/06 9:32 AM Page 119 if (window.widget) { widget.onremove = onremove; widget.onhide = onhide; widget.onshow = onshow; widget.onreceiverequest = receiverequest; } The onremove() function sets the preferences for each one of the options available in the Weather wid- get to null. function onremove () { if (window.widget) { widget.setPreferenceForKey (null, createkey(“show-lows”)); widget.setPreferenceForKey (null, createkey(“collapsed”)); widget.setPreferenceForKey (null, createkey(“celcius”)); widget.setPreferenceForKey (null, createkey(“zip”)); widget.setPreferenceForKey (null, createkey(“postal”)); widget.setPreferenceForKey (null, createkey(“savedcity”)); } } The effect of this action is that the preferences and their keys are removed from the widget-com.apple .widget.weather.plist file. You can see this in action if you remove the Weather widget. If you check the preferences file before you remove the widget, you’ll see all of the keys (Figure 7-5). Figure 7-5 120 Chapter 7 12_778257 ch07.qxp 6/9/06 9:32 AM Page 120 When you remove the widget from Dashboard, and open the preferences again, you’ll see that they have been removed with the exception of one string (Figure 7-6). Figure 7-6 If you add the Weather widget back to Dashboard, you’ll see that it opens with the default preference settings of Austin. Try It Out Adding onRemove to WeatherMaps Add the preferences removal function to the WeatherMaps widget so the preferences are reset whenever the widget is removed from Dashboard. 1. Open the weathermaps.js file in your text editor. 2. Add the remove properties to the JavaScript with the onHide and onShow group. if (window.widget) { // widget.onhide = onHide; widget.onshow = onShow; widget.onremove = onRemove; } 3. Now you are ready to add the onRemove function to the weathermaps.js file. You’ll want to reset each one of the preferences. 121 Widget Events 12_778257 ch07.qxp 6/9/06 9:32 AM Page 121 function onRemove() { if (window.widget) { widget.setPreferenceForKey(null, “radarMenu”); widget.setPreferenceForKey(null, “cTempMenu”); widget.setPreferenceForKey(null, “oTempMenu”); widget.setPreferenceForKey(null, “hTempMenu”); widget.setPreferenceForKey(null, “sWeatherMenu”); } 4. Save your changes and close the weathermaps.js file. You’ll need to reload the widget to make your changes take effect. 5. Hold down the Option key while your arrow is over the WeatherMaps widget and click the close box. 6. Switch to the Finder and open the ~/Library/Preferences/ folder and look for the widget- com.deadtrees.widget.weathermaps.plist. You shouldn’t be able to find it. When all of the preferences have been removed, the plist file is removed. 7. Open Dashboard again and you’ll see that your WeatherMaps widget is definitely preference- less (Figure 7-7). Figure 7-7 The broken link graphic tells you where the radar map should be located if the preference were set. How It Works The widget receives the removal event from Dashboard whenever you click in the close box of the wid- get or use the Widget Manager to remove it. With that, the onRemove() function is executed, which removes the preferences. Because you are removing all of the preferences, the WeatherMaps preferences file is removed. (The Weather widget’s preferences file isn’t removed because it left one key.) When you add WeatherMaps to Dashboard, it opens without any preferences at all; clicking each map link at the top of the widget presents you with the broken link graphic. 122 Chapter 7 12_778257 ch07.qxp 6/9/06 9:32 AM Page 122 You may remember that you are setting the radar map in the HTML file when you establish the <div> for the map. <! This URL sets the image so the widget comes up with a map the first time it is launched. > <div id=”theImages”></div> <img id=”mapImage” src=”http://image.weather.com/web/radar/us_mkc_closeradar_large_usen.jpg” width=”432” height=”290”></img> <div id=’flip’></div> </div> This default map is overridden by the execution your new onShow() function. Because you haven’t set the preference for the Radar map, you see only a broken link. The Weather widget defaulting to Austin makes a little more sense now; better to have the weather conditions of a random U.S. city than an empty widget. Setting Widget Focus In addition to activation and remove events, your widgets can also take advantage of events for setting the focus and for tracking drags in Dashboard. For instance, if you want to let the user know when your widget is the front-most widget in Dashboard, you can indicate this through the widget.focus and widget.blur properties. You can see this in use in Apple’s Calculator widget as well as the PCalc widget. Whenever Calculator has the focus, the screen becomes blue. If another widget is the front-most, the Calculator screen is grey. PCalc does something similar: its screen is a light tan when it has focus and a light grey when it doesn’t. If you look at the code in Calculator.js, you’ll see two statements that set the properties. window.onfocus = focus; window.onblur = blur; And here are the two functions that change the screen setting of the Calculator when it has focus. function focus() { document.getElementById(“lcd-backlight”).style.display = “block”; document.getElementById(“calcDisplay”).setAttribute(“class”, “backlightLCD”); } function blur() { document.getElementById(“lcd-backlight”).style.display = “”; document.getElementById(“calcDisplay”).setAttribute(“class”, “nobacklightLCD”); } PCalc does this in a slightly different fashion. It also contains functions for setting the widget’s focus and blur. However, it uses an image to indicate when the LCD has backlight and when the backlight is off. 123 Widget Events 12_778257 ch07.qxp 6/9/06 9:32 AM Page 123 In addition to showing when a widget has focus, these handlers can also be used for times when the widget doesn’t have focus. The Wimic widget uses the window.onfocus handler to minimize the wid- get when it doesn’t have focus (Figure 7-8). Figure 7-8 Because Wimic retrieves and displays cartoon strips from the Internet, it is rather large when it has focus (Figure 7-9) and minimizing it leaves more space for other widgets you may be running. Figure 7-9 Dragging a Widget You can also track your widget’s movements through the ondrag.start and ondrag.stop properties. The ondrag.start handler is called as the drag begins and the ondrag.stop handler is called when the drag finishes. Besides using these handlers to track the widget’s movements, you can also use them for other drag-dependent functions. The Flight Tracker widget, for instance, uses the ondrag.start to close any pop-up menus when the drag starts. The handler calls the dismissComboBoxes() function. function ondragstart() { dismissComboBoxes(); } The dismissComboBoxes function closes any pop-up menus when a drag starts. function dismissComboBoxes() { document.embeds[‘airlines-input’].dismissPopup(); document.embeds[‘departCity-input’].dismissPopup(); document.embeds[‘arriveCity-input’].dismissPopup(); } 124 Chapter 7 12_778257 ch07.qxp 6/9/06 9:32 AM Page 124 Control Regions While you’re looking at widget events, you should also look at the control regions that Dashboard brings to widgets. You can use the -apple-dashboard-region addition to style sheets to define different parts of your widget for controls. For instance, you can normally click any part of a widget and drag it around the screen. By contrast, application windows have specific regions defined for different func- tions. Typically, you mouse down on the title bar and drag the window to a new location on screen. Inside the window, however, mousing down and dragging selects the objects or text within the window. If you want to scroll the contents of a document, another region of the window is assigned for that behavior. You can see an example of the way control regions are used in the Calculator widget. Each of the buttons has a defined region that produces the effect of the buttons of a calculator. Click in one of those regions and you can click the button, but you can’t drag the widget. The To Do Tracker widget from Monkey Business Labs also has control regions defined that behave like an application. If you click one of the items in the to-do list, you are able to drag it to a new position in the list (Figure 7-10) rather than drag- ging the widget. If you want to drag the widget to a new location on screen, you— intuitively —grab the wire ring of the To Do Tracker. Figure 7-10 When you look in the To Do Tracker.css file, you’ll also notice that the previous and next arrows and the resize thumb are defined control regions. The functions for these control regions are apparently in the TDTPlugin and you can’t see them, but they could just as easily be created in JavaScript. The -apple-dashboard-region is a property you add to a CSS selector that specifies the control region for the style. This property takes the parameter dashboard-region(), which requires two parameters: label and geometry. Both of these parameters are required. Label specifies the type of region being defined, and control is the only possible parameter that it can take. As you can easily guess, geometry specifies the shape of the control region. Its parameters are either circle or rectangle. With just this information you can specify a control region. If you look in the To Do Tracker.css file, you see that the wire ring top of the widget is defined with the label control and the geometry rectangle. The area is specified within the style by the left, bottom, width, and height settings. 125 Widget Events 12_778257 ch07.qxp 6/9/06 9:32 AM Page 125 In addition to these parameters, you can also specify the boundary offsets in pixels for the control region using four parameters: offset-top, offset-right, offset-bottom, and offset-left. These are the offsets from the edge of the boundary that you have defined in the style. If you do not assign these offsets, Dashboard assumes 0 for all four. Be warned that you cannot specify a negative value for any of these offsets. The wire ring on the To Do Tracker widget is specified as a control region in the TopBar selector in the To Do Tracker.css file. If you added offsets to the TopBar style above, it might look like this. #TopBar { position:absolute; left:22px; bottom:222px; width:195px; height:25px; -apple-dashboard-region: dashboard-region(control rectangle 5px 5px 5px 5px); } Now that you see how control regions work, let’s add one to the WeatherMaps widget. Try it Out Adding a Control Region 1. Open the weathermaps.css file. 2. Create a <div> for a region on the map widget for the Weather.com logo and define it in the CSS file. It should look something like this: #wLogo { position: absolute; top:300px; right:20px; width:50px; bottom:30px; -apple-dashboard-region: dashboard-region(control rectangle, 0 0 0 0); } 3. Add the <div> id to the weathermaps.html file. <div id=”wLogo” onclick=’weatherLogo();’></div> 4. Add the function to the weathermaps.js file. function weatherLogo() { if (window.widget) { widget.openURL(‘http://www.weather.com/’); } } 5. Reload the Weathermaps widget if you have it installed. Now when you click the Weather.com logo on the map, it will open Safari and load the Weather.com website. 126 Chapter 7 12_778257 ch07.qxp 6/9/06 9:32 AM Page 126 [...]... position: absolute; top: 0px; left: 56 px; right: 56 px; bottom: 0px; background-image: url(“Images/top_center.png”); background-repeat: repeat -x; } #top_right { position: absolute; top: 0px; right: 0px; bottom: 0px; 137 Chapter 8 width: 56 px; background-image: url(“Images/top_right.png”); background-repeat: no-repeat; } #middle { position: absolute; top: 56 px; left: 0px; right: 0px; bottom: 56 px; text-align:... to the Widget Interface height: 170px; display: block; text-align: center; } #title { font: 12px “Helvetica Neue”; font-weight: bold; color: white; position: absolute; top: 10px; width: 100%; z-index: 1; text-align: center; } /* widget pieces */ #top { position: absolute; top: 0px; left: 0px; right: 0px; bottom: 56 px; } #top_left { position: absolute; top: 0px; left: 0px; bottom: 0px; width: 56 px; background-image:... } /* widget front */ #front { position: absolute; top: 0px; left: 0px; width: 170px; height: 170px; display: block; text-align: center; } #title { font: 12px “Helvetica Neue”; color: white; 147 Chapter 8 position: absolute; top: 10px; left: 65px; } #theImage { position: absolute; top: 30px; bottom: 48px; left: 15px; right: 15px; overflow: auto; } #scalerSlider { position: absolute; bottom: 28px; left:... to the Widget Interface top: 10px; left: 65px; } #resize { position: absolute; /*bottom: 22px; right: 18px;*/ bottom: 24px; right: 24px; width: 12px; height: 12px; z-index: 2; -apple -dashboard- region: dashboard- region(control rectangle 0px 0px 0px 0px); } /* widget back */ #back { display: none; } 4 Add the handlers to the JavaScript file for dealing with the user’s dragging of the resize box // tracks... #middle_left { position: absolute; top: 0px; bottom: 0px; left: 0px; width: 56 px; background-image: url(“Images/middle_left.png”); background-repeat: repeat-y; } #middle_center { position: absolute; top: 0px; bottom: 0px; left: 56 px; right: 56 px; background-image: url(“Images/middle_center.png”); background-repeat: repeat; } #middle_right { position: absolute; top: 0px; bottom: 0px; right: 0px; width: 56 px; background-image:... where the close box is situated 1 45 Chapter 8 The x and y in the method are the coordinates that you give Dashboard and place the close box relative to the top-left corner of the widget If, for example, you give it the values (0,0), Dashboard places the center of the close box over the widget s top-left corner Here is an example of the setCloseBoxOffset (x, y) method used in Apple’s Weather widget if (lastTopOffset... #bottom_left { position: absolute; left: 0px; bottom: 0px; width: 56 px; height: 56 px; background-image: url(“Images/bottom_left.png”); 138 Adding to the Widget Interface background-repeat: no-repeat; } #bottom_center { position: absolute; left: 56 px; right: 56 px; bottom: 0px; height: 56 px; background-image: url(“Images/bottom_center.png”); background-repeat: repeat -x; } #bottom_right { position: absolute;... absolute; right: 0px; bottom: 0px; width: 56 px; height: 56 px; background-image: url(“Images/bottom_right.png”); background-repeat: no-repeat; } #resize { position: absolute; bottom: 18px; right: 14px; -apple -dashboard- region: dashboard- region(control rectangle, 0 0 0 0); } /* widget back */ #back { display: none; position: absolute; top: 0px; left: 0px; width: 170px; height: 170px; background-image:... 48px; left: 15px; right: 15px; overflow: auto; } #scalerSlider { position: absolute; bottom: 28px; left: 15px; right: 15px; } #resize { position: absolute; bottom: 24px; right: 24px; width: 12px; height: 12px; z-index: 2; -apple -dashboard- region: dashboard- region(control rectangle 0px 0px 0px 0px); } /* widget back */ #back { display: none; } Notice that the image file content and the scalarSlider selectors... dueling close boxes As you try to close one, the other one will flash This may cause you to accidentally close the wrong widget — an annoying event that you want to avoid The improper placement of the close box can become even more pronounced when the widget is being resized As the widget s size changes, the placement of the close box may need to be moved Dashboard has a setCloseBoxOffset (x, y) method . look like this. #TopBar { position:absolute; left:22px; bottom:222px; width:195px; height:25px; -apple -dashboard- region: dashboard- region(control rectangle 5px 5px 5px 5px); } Now that you see how. onshow statements. 119 Widget Events 12_778 257 ch07.qxp 6/9/06 9:32 AM Page 119 if (window .widget) { widget. onremove = onremove; widget. onhide = onhide; widget. onshow = onshow; widget. onreceiverequest. file. It should look something like this: #wLogo { position: absolute; top:300px; right:20px; width :50 px; bottom:30px; -apple -dashboard- region: dashboard- region(control rectangle, 0 0 0 0); } 3.