android/GlueIOIOPort: fix spurious errors after IOIO baud rate change
[xcsoar.git] / src / Renderer / MapItemListRenderer.cpp
blobcc7ee95edc764dc1f9dd4438a2eebcd3453637a9
1 /*
2 Copyright_License {
4 XCSoar Glide Computer - http://www.xcsoar.org/
5 Copyright (C) 2000-2013 The XCSoar Project
6 A detailed list of copyright holders can be found in the file "AUTHORS".
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License
10 as published by the Free Software Foundation; either version 2
11 of the License, or (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 #include "MapItemListRenderer.hpp"
25 #include "Screen/Canvas.hpp"
26 #include "Screen/Layout.hpp"
27 #include "MapWindow/Items/MapItem.hpp"
28 #include "Look/DialogLook.hpp"
29 #include "Look/MapLook.hpp"
30 #include "Renderer/AircraftRenderer.hpp"
31 #include "Renderer/AirspaceListRenderer.hpp"
32 #include "Renderer/WaypointListRenderer.hpp"
33 #include "Engine/Waypoint/Waypoint.hpp"
34 #include "Formatter/UserUnits.hpp"
35 #include "Formatter/UserGeoPointFormatter.hpp"
36 #include "Formatter/TimeFormatter.hpp"
37 #include "Formatter/LocalTimeFormatter.hpp"
38 #include "Formatter/AngleFormatter.hpp"
39 #include "Dialogs/Task/dlgTaskHelpers.hpp"
40 #include "Renderer/OZPreviewRenderer.hpp"
41 #include "Language/Language.hpp"
42 #include "Util/StringUtil.hpp"
43 #include "Util/Macros.hpp"
44 #include "Util/StaticString.hpp"
45 #include "Terrain/RasterBuffer.hpp"
46 #include "MapSettings.hpp"
47 #include "Math/Screen.hpp"
48 #include "Look/TrafficLook.hpp"
49 #include "Look/FinalGlideBarLook.hpp"
50 #include "Renderer/TrafficRenderer.hpp"
51 #include "FLARM/FlarmDetails.hpp"
52 #include "FLARM/FlarmNetRecord.hpp"
53 #include "Weather/Features.hpp"
54 #include "FLARM/List.hpp"
55 #include "Time/RoughTime.hpp"
57 #ifdef HAVE_NOAA
58 #include "Renderer/NOAAListRenderer.hpp"
59 #endif
61 #include <cstdio>
63 namespace MapItemListRenderer
65 void Draw(Canvas &canvas, const PixelRect rc, const LocationMapItem &item,
66 const DialogLook &dialog_look);
68 void Draw(Canvas &canvas, const PixelRect rc,
69 const ArrivalAltitudeMapItem &item,
70 const DialogLook &dialog_look, const FinalGlideBarLook &look);
72 void Draw(Canvas &canvas, const PixelRect rc, const SelfMapItem &item,
73 const DialogLook &dialog_look,
74 const AircraftLook &look, const MapSettings &settings);
76 void Draw(Canvas &canvas, const PixelRect rc, const AirspaceMapItem &item,
77 const DialogLook &dialog_look, const AirspaceLook &look,
78 const AirspaceRendererSettings &renderer_settings);
80 void Draw(Canvas &canvas, const PixelRect rc, const WaypointMapItem &item,
81 const DialogLook &dialog_look, const WaypointLook &look,
82 const WaypointRendererSettings &renderer_settings);
84 void Draw(Canvas &canvas, const PixelRect rc, const MarkerMapItem &item,
85 RoughTimeDelta utc_offset,
86 const DialogLook &dialog_look, const MarkerLook &look);
88 #ifdef HAVE_NOAA
89 void Draw(Canvas &canvas, const PixelRect rc, const WeatherStationMapItem &item,
90 const DialogLook &dialog_look, const NOAALook &look);
91 #endif
93 void Draw(Canvas &canvas, const PixelRect rc, const TaskOZMapItem &item,
94 const DialogLook &dialog_look,
95 const TaskLook &look, const AirspaceLook &airspace_look,
96 const AirspaceRendererSettings &airspace_settings);
98 void Draw(Canvas &canvas, const PixelRect rc, const TrafficMapItem &item,
99 const DialogLook &dialog_look, const TrafficLook &traffic_look,
100 const TrafficList *traffic_list);
102 void Draw(Canvas &canvas, const PixelRect rc, const ThermalMapItem &item,
103 RoughTimeDelta utc_offset,
104 const DialogLook &dialog_look, const MapLook &look);
107 void
108 MapItemListRenderer::Draw(Canvas &canvas, const PixelRect rc,
109 const LocationMapItem &item,
110 const DialogLook &dialog_look)
112 const Font &name_font = *dialog_look.list.font_bold;
113 const Font &small_font = *dialog_look.small_font;
115 const unsigned text_padding = Layout::GetTextPadding();
116 int left = rc.left + text_padding;
118 TCHAR info_buffer[256], distance_buffer[32], direction_buffer[32];
119 if (item.vector.IsValid()) {
120 FormatUserDistanceSmart(item.vector.distance, distance_buffer, 32);
121 FormatBearing(direction_buffer, ARRAY_SIZE(direction_buffer),
122 item.vector.bearing);
123 _stprintf(info_buffer, _T("%s: %s, %s: %s"),
124 _("Distance"), distance_buffer,
125 _("Direction"), direction_buffer);
126 } else {
127 _stprintf(info_buffer, _T("%s: %s, %s: %s"),
128 _("Distance"), _T("???"), _("Direction"), _T("???"));
131 canvas.Select(name_font);
133 canvas.DrawClippedText(left, rc.top + text_padding, rc, info_buffer);
136 TCHAR elevation_buffer[32];
137 if (!RasterBuffer::IsSpecial(item.elevation)) {
138 FormatUserAltitude(fixed(item.elevation), elevation_buffer, 32);
139 _stprintf(info_buffer, _T("%s: %s"), _("Elevation"), elevation_buffer);
140 } else {
141 _stprintf(info_buffer, _T("%s: %s"), _("Elevation"), _T("???"));
144 canvas.Select(small_font);
145 canvas.DrawClippedText(left,
146 rc.top + name_font.GetHeight() + 2 * text_padding,
147 rc, info_buffer);
150 void
151 MapItemListRenderer::Draw(Canvas &canvas, const PixelRect rc,
152 const ArrivalAltitudeMapItem &item,
153 const DialogLook &dialog_look,
154 const FinalGlideBarLook &look)
156 const UPixelScalar line_height = rc.bottom - rc.top;
158 bool elevation_available =
159 !RasterBuffer::IsSpecial((short)item.elevation);
161 bool reach_relevant = item.reach.IsReachRelevant();
163 RoughAltitude arrival_altitude =
164 item.reach.terrain_valid == ReachResult::Validity::VALID
165 ? item.reach.terrain
166 : item.reach.direct;
167 if (elevation_available)
168 arrival_altitude -= item.elevation;
170 bool reachable =
171 item.reach.terrain_valid != ReachResult::Validity::UNREACHABLE &&
172 arrival_altitude.IsPositive();
174 // Draw final glide arrow icon
176 RasterPoint pt = { (PixelScalar)(rc.left + line_height / 2),
177 (PixelScalar)(rc.top + line_height / 2) };
179 RasterPoint arrow[] = {
180 { -7, -3 }, { 0, 4 }, { 7, -3 }
183 Angle arrow_angle = reachable ? Angle::HalfCircle() : Angle::Zero();
184 PolygonRotateShift(arrow, ARRAY_SIZE(arrow), pt.x, pt.y, arrow_angle, 100);
186 if (reachable) {
187 canvas.Select(look.brush_above);
188 canvas.Select(look.pen_above);
189 } else {
190 canvas.Select(look.brush_below);
191 canvas.Select(look.pen_below);
193 canvas.DrawPolygon(arrow, ARRAY_SIZE(arrow));
196 const Font &name_font = *dialog_look.list.font_bold;
197 const Font &small_font = *dialog_look.small_font;
199 const unsigned text_padding = Layout::GetTextPadding();
200 int left = rc.left + line_height + text_padding;
203 // Format title row
205 TCHAR altitude_buffer[32];
206 StaticString<256> buffer;
207 buffer.clear();
209 if (elevation_available) {
210 RoughAltitude relative_arrival_altitude =
211 item.reach.direct - item.elevation;
213 FormatRelativeUserAltitude(fixed((short)relative_arrival_altitude),
214 altitude_buffer, ARRAY_SIZE(altitude_buffer));
216 buffer.AppendFormat(_T("%s %s, "), altitude_buffer, _("AGL"));
219 FormatUserAltitude(fixed(item.reach.direct),
220 altitude_buffer, ARRAY_SIZE(altitude_buffer));
222 buffer.AppendFormat(_T("%s %s"), altitude_buffer, _("MSL"));
224 // Draw title row
226 canvas.Select(name_font);
227 canvas.DrawClippedText(left, rc.top + text_padding, rc, buffer);
229 // Format comment row
231 if (reach_relevant) {
232 buffer.Format(_T("%s: "), _("around terrain"));
234 if (elevation_available) {
235 RoughAltitude relative_arrival_altitude =
236 item.reach.terrain - item.elevation;
238 FormatRelativeUserAltitude(fixed((short)relative_arrival_altitude),
239 altitude_buffer, ARRAY_SIZE(altitude_buffer));
241 buffer.AppendFormat(_T("%s %s, "), altitude_buffer, _("AGL"));
244 FormatUserAltitude(fixed(item.reach.terrain),
245 altitude_buffer, ARRAY_SIZE(altitude_buffer));
247 buffer.AppendFormat(_T("%s %s, "), altitude_buffer, _("MSL"));
248 } else if (elevation_available &&
249 (int)item.reach.direct >= (int)item.elevation &&
250 item.reach.terrain_valid == ReachResult::Validity::UNREACHABLE) {
251 buffer.UnsafeFormat(_T("%s "), _("Unreachable due to terrain."));
252 } else {
253 buffer.clear();
256 buffer += _("Arrival altitude incl. safety height");
258 // Draw comment row
260 canvas.Select(small_font);
261 canvas.DrawClippedText(left,
262 rc.top + name_font.GetHeight() + 2 * text_padding,
263 rc, buffer);
266 void
267 MapItemListRenderer::Draw(Canvas &canvas, const PixelRect rc,
268 const SelfMapItem &item,
269 const DialogLook &dialog_look,
270 const AircraftLook &look,
271 const MapSettings &settings)
273 const unsigned line_height = rc.bottom - rc.top;
274 const unsigned text_padding = Layout::GetTextPadding();
276 const Font &name_font = *dialog_look.list.font_bold;
277 const Font &small_font = *dialog_look.small_font;
279 int left = rc.left + line_height + text_padding;
280 canvas.Select(name_font);
281 canvas.DrawClippedText(left, rc.top + text_padding, rc,
282 _("Your Position"));
284 TCHAR buffer[128];
285 FormatGeoPoint(item.location, buffer, 128);
287 canvas.Select(small_font);
288 canvas.DrawClippedText(left,
289 rc.top + name_font.GetHeight() + 2 * text_padding,
290 rc, buffer);
292 RasterPoint pt = { (PixelScalar)(rc.left + line_height / 2),
293 (PixelScalar)(rc.top + line_height / 2) };
294 AircraftRenderer::Draw(canvas, settings, look, item.bearing, pt);
297 void
298 MapItemListRenderer::Draw(Canvas &canvas, const PixelRect rc,
299 const AirspaceMapItem &item,
300 const DialogLook &dialog_look,
301 const AirspaceLook &look,
302 const AirspaceRendererSettings &renderer_settings)
304 AirspaceListRenderer::Draw(canvas, rc, *item.airspace, dialog_look, look,
305 renderer_settings);
308 void
309 MapItemListRenderer::Draw(Canvas &canvas, const PixelRect rc,
310 const WaypointMapItem &item,
311 const DialogLook &dialog_look,
312 const WaypointLook &look,
313 const WaypointRendererSettings &renderer_settings)
315 WaypointListRenderer::Draw(canvas, rc, item.waypoint,
316 dialog_look, look, renderer_settings);
319 void
320 MapItemListRenderer::Draw(Canvas &canvas, const PixelRect rc,
321 const MarkerMapItem &item, RoughTimeDelta utc_offset,
322 const DialogLook &dialog_look,
323 const MarkerLook &look)
325 const unsigned line_height = rc.bottom - rc.top;
326 const unsigned text_padding = Layout::GetTextPadding();
328 const Marker &marker = item.marker;
330 const RasterPoint pt(rc.left + line_height / 2,
331 rc.top + line_height / 2);
333 look.icon.Draw(canvas, pt);
335 const Font &name_font = *dialog_look.list.font_bold;
336 const Font &small_font = *dialog_look.small_font;
338 int left = rc.left + line_height + text_padding;
340 StaticString<256> buffer;
341 buffer.Format(_T("%s #%d"), _("Marker"), item.id + 1);
342 canvas.Select(name_font);
343 canvas.DrawClippedText(left, rc.top + text_padding, rc, buffer);
345 TCHAR time_buffer[32], timespan_buffer[32];
346 FormatLocalTimeHHMM(time_buffer, marker.time.GetSecondOfDay(), utc_offset);
347 FormatTimespanSmart(timespan_buffer, BrokenDateTime::NowUTC() - marker.time);
348 buffer.Format(_("dropped %s ago"), timespan_buffer);
349 buffer.AppendFormat(_T(" (%s)"), time_buffer);
350 canvas.Select(small_font);
351 canvas.DrawClippedText(left,
352 rc.top + name_font.GetHeight() + 2 * text_padding,
353 rc, buffer);
356 #ifdef HAVE_NOAA
357 void
358 MapItemListRenderer::Draw(Canvas &canvas, const PixelRect rc,
359 const WeatherStationMapItem &item,
360 const DialogLook &dialog_look,
361 const NOAALook &look)
363 const NOAAStore::Item &station = *item.station;
364 NOAAListRenderer::Draw(canvas, rc, station, look, dialog_look);
366 #endif
368 void
369 MapItemListRenderer::Draw(Canvas &canvas, const PixelRect rc,
370 const ThermalMapItem &item,
371 RoughTimeDelta utc_offset,
372 const DialogLook &dialog_look,
373 const MapLook &look)
375 const unsigned line_height = rc.bottom - rc.top;
376 const unsigned text_padding = Layout::GetTextPadding();
378 const ThermalSource &thermal = item.thermal;
380 const RasterPoint pt(rc.left + line_height / 2,
381 rc.top + line_height / 2);
383 look.thermal_source_icon.Draw(canvas, pt);
385 const Font &name_font = *dialog_look.list.font_bold;
386 const Font &small_font = *dialog_look.small_font;
388 int left = rc.left + line_height + text_padding;
390 canvas.Select(name_font);
391 canvas.DrawClippedText(left, rc.top + text_padding,
392 rc, _("Thermal"));
394 StaticString<256> buffer;
395 TCHAR lift_buffer[32], time_buffer[32], timespan_buffer[32];
396 FormatUserVerticalSpeed(thermal.lift_rate, lift_buffer, 32);
397 FormatLocalTimeHHMM(time_buffer, (int)thermal.time, utc_offset);
399 int timespan = BrokenDateTime::NowUTC().GetSecondOfDay() - (int)thermal.time;
400 if (timespan < 0)
401 timespan += 24 * 60 * 60;
403 FormatTimespanSmart(timespan_buffer, timespan);
405 buffer.Format(_T("%s: %s"), _("Avg. lift"), lift_buffer);
406 buffer.append(_T(" - "));
407 buffer.AppendFormat(_("left %s ago"), timespan_buffer);
408 buffer.AppendFormat(_T(" (%s)"), time_buffer);
409 canvas.Select(small_font);
410 canvas.DrawClippedText(left,
411 rc.top + name_font.GetHeight() + 2 * text_padding,
412 rc, buffer);
415 void
416 MapItemListRenderer::Draw(Canvas &canvas, const PixelRect rc,
417 const TaskOZMapItem &item,
418 const DialogLook &dialog_look,
419 const TaskLook &look, const AirspaceLook &airspace_look,
420 const AirspaceRendererSettings &airspace_settings)
422 const unsigned line_height = rc.bottom - rc.top;
423 const unsigned text_padding = Layout::GetTextPadding();
425 const ObservationZonePoint &oz = *item.oz;
426 const Waypoint &waypoint = item.waypoint;
428 const Font &name_font = *dialog_look.list.font_bold;
429 const Font &small_font = *dialog_look.small_font;
431 TCHAR buffer[256];
433 // Y-Coordinate of the second row
434 int top2 = rc.top + name_font.GetHeight() + 2 * text_padding;
436 // Use small font for details
437 canvas.Select(small_font);
439 // Draw details line
440 UPixelScalar left = rc.left + line_height + text_padding;
441 OrderedTaskPointRadiusLabel(*item.oz, buffer);
442 if (!StringIsEmpty(buffer))
443 canvas.DrawClippedText(left, top2, rc.right - left, buffer);
445 // Draw waypoint name
446 canvas.Select(name_font);
447 OrderedTaskPointLabel(item.tp_type, waypoint.name.c_str(),
448 item.index, buffer);
449 canvas.DrawClippedText(left, rc.top + text_padding,
450 rc.right - left, buffer);
452 const RasterPoint pt(rc.left + line_height / 2,
453 rc.top + line_height / 2);
454 PixelScalar radius = std::min(PixelScalar(line_height / 2
455 - 2 * text_padding),
456 Layout::FastScale(10));
457 OZPreviewRenderer::Draw(canvas, oz, pt, radius, look,
458 airspace_settings, airspace_look);
462 void
463 MapItemListRenderer::Draw(Canvas &canvas, const PixelRect rc,
464 const TrafficMapItem &item,
465 const DialogLook &dialog_look,
466 const TrafficLook &traffic_look,
467 const TrafficList *traffic_list)
469 const unsigned line_height = rc.bottom - rc.top;
470 const unsigned text_padding = Layout::GetTextPadding();
472 const FlarmTraffic *traffic = traffic_list == NULL ? NULL :
473 traffic_list->FindTraffic(item.id);
475 // Now render the text information
476 const Font &name_font = *dialog_look.list.font_bold;
477 const Font &small_font = *dialog_look.small_font;
478 int left = rc.left + line_height + text_padding;
480 const FlarmNetRecord *record = FlarmDetails::LookupRecord(item.id);
482 StaticString<256> title_string;
483 if (record && !StringIsEmpty(record->pilot))
484 title_string = record->pilot.c_str();
485 else
486 title_string = _("FLARM Traffic");
488 // Append name to the title, if it exists
489 const TCHAR *callsign = FlarmDetails::LookupCallsign(item.id);
490 if (callsign != NULL && !StringIsEmpty(callsign)) {
491 title_string.append(_T(", "));
492 title_string.append(callsign);
495 canvas.Select(name_font);
496 canvas.DrawClippedText(left, rc.top + text_padding,
497 rc, title_string);
499 StaticString<256> info_string;
500 if (record && !StringIsEmpty(record->plane_type))
501 info_string = record->plane_type;
502 else if (traffic != NULL)
503 info_string = FlarmTraffic::GetTypeString(traffic->type);
504 else
505 info_string = _("Unknown");
507 // Generate the line of info about the target, if it's available
508 if (traffic != NULL) {
509 if (traffic->altitude_available) {
510 TCHAR tmp[15];
511 FormatUserAltitude(traffic->altitude, tmp, 15);
512 info_string.AppendFormat(_T(", %s: %s"), _("Altitude"), tmp);
514 if (traffic->climb_rate_avg30s_available) {
515 TCHAR tmp[15];
516 FormatUserVerticalSpeed(traffic->climb_rate_avg30s, tmp, 15);
517 info_string.AppendFormat(_T(", %s: %s"), _("Vario"), tmp);
520 canvas.Select(small_font);
521 canvas.DrawClippedText(left,
522 rc.top + name_font.GetHeight() + 2 * text_padding,
523 rc, info_string);
525 RasterPoint pt = { (PixelScalar)(rc.left + line_height / 2),
526 (PixelScalar)(rc.top + line_height / 2) };
528 // Render the representation of the traffic icon
529 if (traffic != NULL)
530 TrafficRenderer::Draw(canvas, traffic_look, *traffic, traffic->track,
531 item.color, pt);
534 #ifdef HAVE_SKYLINES_TRACKING_HANDLER
537 * Calculate how many minutes have passed since #past_ms.
539 gcc_const
540 static unsigned
541 SinceInMinutes(fixed now_s, uint32_t past_ms)
543 const unsigned day_minutes = 24 * 60;
544 unsigned now_minutes = uint32_t(now_s / 60) % day_minutes;
545 unsigned past_minutes = (past_ms / 60000) % day_minutes;
547 if (past_minutes >= 20 * 60 && now_minutes < 4 * 60)
548 /* midnight rollover */
549 now_minutes += day_minutes;
551 if (past_minutes > now_minutes)
552 return 0;
554 return now_minutes - past_minutes;
557 #include "Interface.hpp"
559 static void
560 Draw(Canvas &canvas, const PixelRect rc,
561 const SkyLinesTrafficMapItem &item,
562 const DialogLook &dialog_look)
564 const Font &name_font = *dialog_look.list.font_bold;
565 const Font &small_font = *dialog_look.small_font;
567 const unsigned line_height = rc.bottom - rc.top;
568 const unsigned text_padding = Layout::GetTextPadding();
569 const int left = rc.left + line_height + text_padding;
570 const int top = rc.top + text_padding;
572 canvas.Select(name_font);
573 canvas.DrawText(left, top, item.name);
575 if (CommonInterface::Basic().time_available) {
576 canvas.Select(small_font);
578 StaticString<64> buffer;
579 buffer.UnsafeFormat(_("%u minutes ago"),
580 SinceInMinutes(CommonInterface::Basic().time,
581 item.time_of_day_ms));
583 canvas.DrawText(left, rc.top + name_font.GetHeight() + 2 * text_padding,
584 buffer);
588 #endif /* HAVE_SKYLINES_TRACKING_HANDLER */
590 void
591 MapItemListRenderer::Draw(Canvas &canvas, const PixelRect rc,
592 const MapItem &item,
593 const DialogLook &dialog_look, const MapLook &look,
594 const TrafficLook &traffic_look,
595 const FinalGlideBarLook &final_glide_look,
596 const MapSettings &settings,
597 RoughTimeDelta utc_offset,
598 const TrafficList *traffic_list)
600 switch (item.type) {
601 case MapItem::LOCATION:
602 Draw(canvas, rc, (const LocationMapItem &)item, dialog_look);
603 break;
604 case MapItem::ARRIVAL_ALTITUDE:
605 Draw(canvas, rc, (const ArrivalAltitudeMapItem &)item,
606 dialog_look, final_glide_look);
607 break;
608 case MapItem::SELF:
609 Draw(canvas, rc, (const SelfMapItem &)item,
610 dialog_look, look.aircraft, settings);
611 break;
612 case MapItem::AIRSPACE:
613 Draw(canvas, rc, (const AirspaceMapItem &)item,
614 dialog_look, look.airspace,
615 settings.airspace);
616 break;
617 case MapItem::WAYPOINT:
618 Draw(canvas, rc, (const WaypointMapItem &)item,
619 dialog_look, look.waypoint,
620 settings.waypoint);
621 break;
622 case MapItem::TASK_OZ:
623 Draw(canvas, rc, (const TaskOZMapItem &)item,
624 dialog_look, look.task, look.airspace,
625 settings.airspace);
626 break;
627 case MapItem::MARKER:
628 Draw(canvas, rc, (const MarkerMapItem &)item, utc_offset,
629 dialog_look, look.marker);
630 break;
632 #ifdef HAVE_NOAA
633 case MapItem::WEATHER:
634 Draw(canvas, rc, (const WeatherStationMapItem &)item, dialog_look, look.noaa);
635 break;
636 #endif
638 case MapItem::TRAFFIC:
639 Draw(canvas, rc, (const TrafficMapItem &)item,
640 dialog_look, traffic_look, traffic_list);
641 break;
643 #ifdef HAVE_SKYLINES_TRACKING_HANDLER
644 case MapItem::SKYLINES_TRAFFIC:
645 ::Draw(canvas, rc, (const SkyLinesTrafficMapItem &)item, dialog_look);
646 break;
647 #endif
649 case MapItem::THERMAL:
650 Draw(canvas, rc, (const ThermalMapItem &)item, utc_offset,
651 dialog_look, look);
652 break;