?? xclock.pro
字號:
;+
; NAME:
; XCLOCK
;
; PURPOSE:
;
; This widget program simulates a simple analog clock.
;
; AUTHOR:
;
; Robert M. Dimeo, Ph.D.
; NIST Center for Neutron Research
; 100 Bureau Drive
; Gaithersburg, MD 20899
; Phone: (301) 975-8135
; E-mail: robert.dimeo@nist.gov
; http://www.ncnr.nist.gov/staff/dimeo
;
; CATEGORY:
;
; Widgets
;
; CALLING SEQUENCE:
;
; XCLOCK
;
; INPUT FIELDS:
;
; NONE
;
; KEYWORD PARAMETERS:
;
; ANALOG: This keyword, when set, causes the display to appear like a
; clock face.
;
; DIGITAL: This keyword, when set, causes the display to show a text output
; of the date and time.
;
; DISCLAIMER
;
; This software is provided as is without any warranty whatsoever.
; Permission to use, copy, modify, and distribute modified or
; unmodified copies is granted, provided this disclaimer
; is included unchanged.
;
; MODIFICATION HISTORY:
;
; Written by Rob Dimeo, November 10, 2002.
; -November 14, 2002: Added ANALOG and DIGITAL keyword parameters.
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
PRO Xclockcleanup,tlb
COMPILE_OPT idl2,hidden
WIDGET_CONTROL,tlb,/clear_events
WIDGET_CONTROL,tlb,get_uvalue = pState
WDELETE,(*pState).winPix
PTR_FREE,pState
END
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
PRO Xclockquit,event
COMPILE_OPT idl2,hidden
; We simply destroy the top-level base here and then the cleanup routine is
; executed.
WIDGET_CONTROL,event.top,/destroy
END
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
PRO Xclock_showdigital,event
COMPILE_OPT idl2,hidden
WIDGET_CONTROL,event.top,get_uvalue = pState
xrange = [-1.0,1.0]
yrange = xrange
PLOT,xrange,yrange,/nodata,xrange = xrange,yrange = yrange, $
xstyle = 4,ystyle = 4,background = (*pState).backColor,xmargin = [0,0], $
ymargin = [0,0]
XYOUTS,0.5,0.5,SYSTIME(),color = (*pState).foreColor,/normal,alignment = 0.5, $
charsize = 1.5
END
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
PRO Xclock_showface,event
COMPILE_OPT idl2,hidden
WIDGET_CONTROL,event.top,get_uvalue = pState
xrange = [-1.0,1.0]
yrange = xrange
PLOT,xrange,yrange,/nodata,xrange = xrange,yrange = yrange, $
xstyle = 4,ystyle = 4,background = (*pState).backColor,xmargin = [0,0], $
ymargin = [0,0]
; Plot the clock face
th = 90.0-(360./12)-(360.0/12.0)*FINDGEN(12)
r = 0.75
xt = r*COS(th*!dtor)
yt = r*SIN(th*!dtor)
XYOUTS,xt,yt,STRTRIM(STRING(1+INDGEN(12)),2),/data,alignment = 0.5, $
color = (*pState).foreColor,charsize = 1.25
ncircle = 50
rc = 0.85
thc = (360./(ncircle - 1))*FINDGEN(ncircle)
xc = rc*COS(thc*!dtor)
yc = rc*SIN(thc*!dtor)
PLOTS,xc,yc,/data, thick = 2.0,color = (*pState).foreColor
END
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
PRO Xclock_draw,event
COMPILE_OPT idl2,hidden
WIDGET_CONTROL,event.top,get_uvalue = pState
Caldat,SYSTIME(/julian),month,day,year,hour,minute,second
IF hour GT 12 THEN hour = hour MOD 12
; Calculate the second hand
ths = 90.0-(360.0/60.)*second
rs = 0.80
xs = rs*COS(ths*!dtor) & ys = rs*SIN(ths*!dtor)
; Calculate the minute hand
thm = 90.0-(360.0/60.)*minute
rm = 0.65
xm = rm*COS(thm*!dtor) & ym = rm*SIN(thm*!dtor)
; Calculate the hour hand
; Note that we will provide a contribution from the
; minutes value so that the hour hand changes every
; minute rather than abruptly once every hour.
rh = 0.5
thh = 90.0-(360.0/12.)*(hour+FLOAT(minute)/60.0)
xh = rh*COS(thh*!dtor) & yh = rh*SIN(thh*!dtor)
; Draw the seconds hand
PLOTS,[0.0,xs],[0.0,ys],/data,thick = 1,color = (*pState).foreColor
; Draw the minutes hand
PLOTS,[0.0,xm],[0.0,ym],/data, thick = 2,color = (*pState).foreColor
; Draw the hour hand
PLOTS,[0.0,xh],[0.0,yh],/data, thick = 4,color = (*pState).foreColor
END
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
PRO Xclock_resize,event
COMPILE_OPT idl2,hidden
WIDGET_CONTROL,event.top,get_uvalue = pState
newsize = event.x > event.y ; pick the larger of the two dimensions
xsize = newsize & ysize = newsize
; Delete the existing pixmap and create a new one of the appropriate size.
WDELETE,(*pState).winPix
WINDOW,/free,/pixmap,xsize = xsize,ysize = ysize
WIDGET_CONTROL,(*pState).win,draw_xsize = xsize,draw_ysize = ysize
; Fire the timer immediately so that the resizing looks seamless.
WIDGET_CONTROL,(*pState).timer,time = 0.0
END
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
PRO Xclock_event,event
COMPILE_OPT idl2,hidden
WIDGET_CONTROL,event.top,get_uvalue = pState
IF TAG_NAMES(event,/structure_name) EQ 'WIDGET_BASE' THEN BEGIN
Xclock_resize,event
RETURN
ENDIF
WSET,(*pState).winPix
IF (*pState).type EQ 0 THEN BEGIN
Xclock_showface,event
Xclock_draw,event
ENDIF ELSE BEGIN
Xclock_showdigital,event
ENDELSE
WSET,(*pState).winVis
DEVICE,copy = [0,0,!d.x_size,!d.y_size,0,0,(*pState).winPix]
; Fire off the timer every once per second
WIDGET_CONTROL,(*pState).timer,time = (*pState).duration
END
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
PRO Xclock,group_leader = group_leader,analog = analog,digital = digital
COMPILE_OPT idl2,hidden
; Turn color decomposition off so that we can use simple color indexing for
; plot and annotation commands.
DEVICE,decomposed = 0
; Load the black & white color table
Loadct,0,/silent
type = 0
IF KEYWORD_SET(analog) THEN type = 0
IF KEYWORD_SET(digital) THEN type = 1
title = 'XCLOCK'
IF N_ELEMENTS(group_leader) NE 0 THEN BEGIN
tlb = WIDGET_BASE(/col,group_leader = group_leader,title = title, $
/tlb_size_events)
ENDIF ELSE BEGIN
tlb = WIDGET_BASE(/col,title = title,/tlb_size_events)
ENDELSE
IF type EQ 0 THEN BEGIN
xsize = 300 & ysize = xsize
ENDIF ELSE BEGIN
xsize = 300 & ysize = 100
ENDELSE
win = WIDGET_DRAW(tlb,xsize = xsize,ysize = ysize)
timer = WIDGET_BASE(tlb)
WIDGET_CONTROL,tlb,/realize
WIDGET_CONTROL,win,get_value = winVis
WINDOW,/free,/pixmap,xsize = xsize,ysize = ysize
winPix = !d.window
; Define the state structure
state = { win:win, $
winVis:winVis, $
winPix:winPix, $
duration:1.0, $
foreColor:0, $
backColor:255, $
type:type, $
timer:timer $
}
; Create a pointer to the state structure
pState = PTR_NEW(state,/no_copy)
; Stuff the (pointer to the) state structure into the user-value
; of the top-level base.
WIDGET_CONTROL,tlb,set_uvalue = pState
; Fire off the timer immediately so that the clock face
; is displayed at once. After this we fire off the timer
; only once every (*pState).duration (or 1 second).
WIDGET_CONTROL,(*pState).timer,time = 0.0
; Start the event loop by calling XMANAGER
Xmanager,'xClock',tlb,/no_block,cleanup = 'xClockCleanup'
END
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -