Register forum user name Search FAQ

Gammon Forum

Notice: Any messages purporting to come from this site telling you that your password has expired, or that you need to verify your details, confirm your email, resolve issues, making threats, or asking for money, are spam. We do not email users with any such messages. If you have lost your password you can obtain a new one by using the password reset link.

Due to spam on this forum, all posts now need moderator approval.

 Entire forum ➜ MUSHclient ➜ Plugins ➜ Stopwatch plugin

Stopwatch plugin

It is now over 60 days since the last post. This thread is closed.     Refresh page


Posted by Nick Gammon   Australia  (23,133 posts)  Bio   Forum Administrator
Date Wed 15 Sep 2010 04:12 AM (UTC)

Amended on Wed 15 Sep 2010 11:23 PM (UTC) by Nick Gammon

Message
The plugin below implements a small "stopwatch" miniwindow.

When installed you see the stopwatch window, initially paused. You can click on the "start" button to start it counting up. You can pause it, or reset it. There are various aliases to accomplish the same thing via the keyboard. You could make macros to assign the aliases to keys if you wanted (eg. F5: stopwatch start, F6: stopwatch pause).

This could be used in situations where you want to time how long something takes (eg. how long it takes you to finish a quest).



Template:saveplugin=Stopwatch To save and install the Stopwatch plugin do this:
  1. Copy between the lines below (to the Clipboard)
  2. Open a text editor (such as Notepad) and paste the plugin into it
  3. Save to disk on your PC, preferably in your plugins directory, as Stopwatch.xml
  4. Go to the MUSHclient File menu -> Plugins
  5. Click "Add"
  6. Choose the file Stopwatch.xml (which you just saved in step 3) as a plugin
  7. Click "Close"



<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE muclient>

<muclient>
<plugin
   name="Stopwatch"
   author="Nick Gammon"
   id="84f927265b7fed69c7ada8be"
   language="Lua"
   purpose="Shows a stopwatch"
   date_written="2010-09-15 10:22"
   save_state="y"
   requires="4.60"
   version="1.2"
   >
   
<description trim="y">
<![CDATA[
Shows a stopwatch.

ALIASES:

stopwatch start:  Start the stopwatch
stopwatch pause:  Pause the stopwatch
stopwatch reset:  Reset the stopwatch to zero
stopwatch hide:   Hide the stopwatch window (it still runs if started)
stopwatch show:   Make the stopwatch window visible again

]]>
</description>
</plugin>

<!--  Aliases  -->

<aliases>
  <alias
   script="stopwatch_start"
   name="stopwatch_start"
   match="stopwatch start"
   enabled="y"
   sequence="100"
  >
  </alias>
  
 <alias
   script="stopwatch_pause"
   name="stopwatch_pause"
   match="stopwatch pause"
   enabled="y"
   sequence="100"
  >
  </alias>
    
 <alias
   script="stopwatch_reset"
   name="stopwatch_reset"
   match="stopwatch reset"
   enabled="y"
   sequence="100"
  >
  </alias>
    
 <alias
   script="stopwatch_hide"
   name="stopwatch_hide"
   match="stopwatch hide"
   enabled="y"
   sequence="100"
  >
  </alias>

      
 <alias
   script="stopwatch_show"
   name="stopwatch_show"
   match="stopwatch show"
   enabled="y"
   sequence="100"
  >
  </alias>
      
 <alias
   script="stopwatch_help"
   name="stopwatch_help"
   match="stopwatch *"
   enabled="y"
   sequence="110"
  >
  </alias>
    
</aliases>


<!--  Timers  -->

<timers>
  <timer
     second="0.5" 
     script="tick"
     active_closed="y"
     name="tick_timer"
>
  </timer>
</timers>


<!--  Script  -->


<script>
<![CDATA[

require "movewindow"  -- load the movewindow.lua module

-- configuration

-- window title
local title = "Stopwatch"

-- just to make it more readable

local function time_now ()
  return GetInfo (232)
end -- time_now

-- EXPOSED FUNCTIONS

-- hide window on removal
function OnPluginClose ()
  WindowShow (win,  false)  -- hide it
end -- OnPluginClose

-- hide window on disable
function OnPluginDisable ()
  WindowShow (win,  false)  -- hide it
end -- OnPluginDisable

-- show window on enable
function OnPluginEnable ()
  WindowShow (win,  true)  -- show it
  if not paused then
    EnableTimer ("tick_timer", true) 
  end -- if
  tick ()
end -- OnPluginEnable

function OnPluginSaveState ()
  -- save window current location for next time  
  movewindow.save_state (win)
end -- function OnPluginSaveState

-- Reset button clicked
function reset_mouseup (flags, hotspot_id)
  elapsed_time = 0
  start_time = time_now ()
  tick ()
end -- reset_mouseup

-- Pause/Run button clicked
function pause_mouseup (flags, hotspot_id)
  if paused then
    start_time = time_now ()  -- start timing from now
    paused = false  
    EnableTimer ("tick_timer", true) 
  else
    -- remember how much we have done so far
    elapsed_time = elapsed_time + time_now () - start_time
    paused = true
    EnableTimer ("tick_timer", false) 
  end -- if
  
  tick ()
end -- pause_mouseup

-- Close button clicked
function close_mouseup (flags, hotspot_id)
  EnableTimer ("tick_timer", false) 
  WindowShow (win,  false)  -- hide it
end -- function

-- here each second
function tick (name)

  background_colour = 0x222222

  -- Clear the part we draw the time into
  WindowCircleOp (win, miniwin.circle_round_rectangle, -- round rectangle
                  2, font_height_title + 2, -2, -2,              
                  ColourNameToRGB ("gray"), miniwin.pen_solid + miniwin.pen_join_miter, 2,      
                  background_colour, miniwin.brush_solid,  -- brush
                  10,   -- width of the ellipse used to draw the rounded corner
                  10)   -- height of the ellipse used to draw the rounded corner

  -- if paused we use elapsed time until pause
  if paused then
    elapsed = elapsed_time
  else
    -- otherwise calculate time difference and add in previous times (when we paused)
    elapsed = time_now () - start_time + elapsed_time
  end -- if
    
  -- work out hours:mins:secs
  secs = math.floor (elapsed % 60)
  mins = math.floor ((elapsed / 60) % 60)
  hours = math.floor ((elapsed / (60 * 60)) % 24)
  
  -- draw the time
  width = WindowText (win, "fn", string.format ("%02i:%02i:%02i", hours, mins, secs), 
            6, font_height_title + 5, 0, 0, 
            ColourNameToRGB ("white"))

  -- pause button - calculate once
  if not pause_left then
    pause_left  = width + 14
    pause_top   = font_height_title + 5  
    button_colour = 0x08b3c7
    button_size = 14
  end -- if
      
  -- draw the pause button
  WindowCircleOp (win, miniwin.circle_round_rectangle, -- round rectangle
                  pause_left, pause_top, pause_left + button_size, pause_top + button_size,     
                  button_colour, miniwin.pen_solid + miniwin.pen_join_round, 1,   
                  background_colour, miniwin.brush_solid,  -- brush
                  5,   -- width of the ellipse used to draw the rounded corner
                  5)   -- height of the ellipse used to draw the rounded corner
           
  if paused then
    -- draw the triangle which is the "run" button
    local points = string.format ("%i,%i,%i,%i,%i,%i", 
                    pause_left + 4, pause_top + 3,
                    pause_left + 11, pause_top + 7,
                    pause_left + 4, pause_top + 11)
                    
    -- draw play icon
    WindowPolygon (win, points,
                    0,   miniwin.pen_null, 0, -- no pen
                    button_colour, miniwin.brush_solid,    -- brush (solid)
                    true,    -- fill
                    false)   -- alternate fill

  else 
    -- draw pause icon (two vertical bars)
    WindowRectOp (win, miniwin.rect_fill, pause_left + 4, pause_top + 4, pause_left + 6, pause_top + 10, 
                  button_colour)
    WindowRectOp (win, miniwin.rect_fill, pause_left + 8, pause_top + 4, pause_left + 10, pause_top + 10, 
                  button_colour)
  end -- if
                    
  -- only add hotspot once - otherwise mouseups may fail
  if not WindowHotspotInfo (win, "pause", 1) then
    WindowAddHotspot(win, "pause",  
                    pause_left, pause_top, pause_left + button_size, pause_top + button_size, 
                   "", -- mouseover
                   "", -- cancelmouseover
                   "", -- mousedown
                   "", -- cancelmousedown
                   "pause_mouseup", 
                   "Stop/start",  -- tooltip text
                   miniwin.cursor_hand, 0)  -- hand cursor
  end -- if doesn't exist yet
         
  -- fix up tooltip text      
  if paused then
    WindowHotspotTooltip (win, "pause", "Run")   
  else
    WindowHotspotTooltip (win, "pause", "Pause")   
  end -- if
    
  -- reset button
  reset_left  = pause_left + button_size + 4
  reset_top   = pause_top  
  
  -- reset button
  WindowCircleOp (win, miniwin.circle_round_rectangle, -- round rectangle
                  reset_left, reset_top, reset_left + button_size, reset_top + button_size,     
                  button_colour, miniwin.pen_solid + miniwin.pen_join_round, 1,   
                  background_colour, miniwin.brush_solid,  -- brush
                  5,   -- width of the ellipse used to draw the rounded corner
                  5)   -- height of the ellipse used to draw the rounded corner
            
  -- with little circle in the middle
  WindowCircleOp (win, miniwin.circle_ellipse,  -- ellipse
                reset_left + 3, reset_top + 3, reset_left + 12, reset_top + 12, 
                0, miniwin.pen_null, 0, 
                button_colour, miniwin.brush_solid)     -- brush

  -- only add hotspot once
  if not WindowHotspotInfo (win, "reset", 1) then
    WindowAddHotspot(win, "reset",  
                    reset_left, reset_top, reset_left + button_size, reset_top + button_size, 
                   "", -- mouseover
                   "", -- cancelmouseover
                   "", -- mousedown
                   "", -- cancelmousedown
                   "reset_mouseup", 
                   "Reset to zero",  -- tooltip text
                   miniwin.cursor_hand, 0)  -- hand cursor
  end -- if doesn't exist yet
                 
  Redraw ()  -- ensure screen refreshes
end -- tick

-- they typed: stopwatch start
function stopwatch_start (name, line, wildcards)
  if paused then
    pause_mouseup () -- start it
    ColourNote ("cyan", "", "Stopwatch started")
  else
    ColourNote ("orange", "", "Stopwatch already running")
  end -- if
end -- stopwatch_start

-- they typed: stopwatch pause
function stopwatch_pause (name, line, wildcards)
  if not paused then
    pause_mouseup () -- start it
    ColourNote ("cyan", "", "Stopwatch paused")
  else
    ColourNote ("orange", "", "Stopwatch not running")
  end -- if
end -- stopwatch_pause

-- they typed: stopwatch reset
function stopwatch_reset (name, line, wildcards)
  reset_mouseup () -- start it
  ColourNote ("cyan", "", "Stopwatch reset to zero")
end -- stopwatch_reset

-- they typed: stopwatch hide
function stopwatch_hide (name, line, wildcards)
  close_mouseup () -- start it
  ColourNote ("cyan", "", "Stopwatch hidden. Type 'stopwatch show' to see it again.")
end -- stopwatch_hide

-- they typed: stopwatch show
function stopwatch_show (name, line, wildcards)
  OnPluginEnable () -- basically shows it
  ColourNote ("cyan", "", "Stopwatch shown")
end -- stopwatch_show

-- they typed: stopwatch (something)
function stopwatch_help (name, line, wildcards)
  ColourNote ("cyan", "", GetPluginInfo (GetPluginID (), 3))
end -- stopwatch_help

--------------------------------------------------------------------------------
--   START EXECUTION HERE
--------------------------------------------------------------------------------
-- startup stuff - create window, find font characteristics

win = "Stopwatch_" .. GetPluginID ()  -- get a unique name


fonts = utils.getfontfamilies ()

if not fonts.Dina then
  AddFont (GetInfo (66) .. "\\Dina.fon")
end -- if Dina not installed

font_name = "Dina"    

-- make the window
WindowCreate (win, 0, 0, 1, 1, miniwin.pos_top_right, 0, 0)  -- create window
               
-- grab a font or two
WindowFont (win, "ft", font_name, 8) -- define font (title)
WindowFont (win, "fn", font_name, 10) -- define font (numbers)

-- work out how high and wide it is
font_height_title = WindowFontInfo (win, "ft", 1)   -- height of the title font  
font_height_digits = WindowFontInfo (win, "fn", 1)   -- height of the numbers font  

window_width = 10 + WindowTextWidth (win, "fn", "99:99:99") + 45
window_height = font_height_title + font_height_digits + 9

-- install the window movement handler, get back the window position
windowinfo = movewindow.install (win, WINDOW_POSITION)
 
-- remake the window with the correct width
WindowCreate (win, 
               windowinfo.window_left, 
               windowinfo.window_top, 
               window_width, window_height,              
               windowinfo.window_mode,   
               windowinfo.window_flags,
               0) 

-- add the drag handler so they can move the window around
movewindow.add_drag_handler (win, 0, 0, 0, font_height_title)

-- draw drag bar rectangle
WindowRectOp (win, miniwin.rect_fill, 0, 0, 0, font_height_title + 2, 0x222222)

-- draw title
local sz = WindowTextWidth (win, "ft", title)
WindowText (win, "ft", title, (window_width - sz) / 2, 1, window_width, 0, 
            ColourNameToRGB ("yellow"))

-- close box
local box_left, box_top, box_right, box_bottom = 
         window_width - font_height_title + 2, 2, 
         window_width - 2, font_height_title - 2
           
-- square box                 
WindowCircleOp (win, miniwin.circle_rectangle, 
                   box_left, box_top, box_right + 1, box_bottom + 1, 
                   0x808080, miniwin.pen_solid + miniwin.pen_join_bevel, 1,
                   0, miniwin.brush_null)
             
-- with two lines to make an X                         
WindowLine (win, box_left, box_top, box_right, box_bottom, 0x808080, 0, 1)
WindowLine (win, box_left, box_bottom, box_right, box_top, 0x808080, 0, 1)
         
-- hotspot if they click on close box
WindowAddHotspot(win, "close",  
                  box_left, box_top, box_right, box_bottom, 
                 "", -- mouseover
                 "", -- cancelmouseover
                 "", -- mousedown
                 "", -- cancelmousedown
                 "close_mouseup", 
                 "Close",  -- tooltip text
                 miniwin.cursor_hand, 0)  -- hand cursor
                 
-- start paused                      
paused = true
    
-- reset to zero       
reset_mouseup ()

-- show stopwatch
WindowShow (win, true)
            
]]>
</script>

</muclient>


[EDIT] Fixed bug where time would be shown wrongly after an hour (like: 1:61:00).

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

The dates and times for posts above are shown in Universal Co-ordinated Time (UTC).

To show them in your local time you can join the forum, and then set the 'time correction' field in your profile to the number of hours difference between your location and UTC time.


7,535 views.

It is now over 60 days since the last post. This thread is closed.     Refresh page

Go to topic:           Search the forum


[Go to top] top

Information and images on this site are licensed under the Creative Commons Attribution 3.0 Australia License unless stated otherwise.