Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a timer component #3

Open
samuelgrigolato opened this issue Nov 21, 2013 · 8 comments
Open

Add a timer component #3

samuelgrigolato opened this issue Nov 21, 2013 · 8 comments

Comments

@samuelgrigolato
Copy link
Collaborator

As suggested by previous dojos participants, it would be nice to have a Pomodoro like component built in dose.

I'm creating this issue to improve the requirements of the feature, before any coding. Following is my understanding as a starting point:

  • Add a timer positioned aside the semaphore;
  • Add a play/pause and a reset button (without the need to right click);
  • Add a "Timer duration" option inside the right click menu, allowing to change the default value (7 minutes).
@danilobellini
Copy link
Owner

I think such a timer should:

  1. Be near to the semaphore, in the same window (below? configurable?);
  2. Be possible to show/hide it (e.g. a new item for the popup menu);
  3. Have a digital "minutes:seconds" display with a monospaced font;
  4. Have a time-varying colored numbers/background (a colormap to let people know when time is almost over, without any need to "read" its written numbers);
  5. Warn the user when time is over (message box? audio? both?);
  6. Change accordingly the window shape (probably it won't be just a rounded rectangle anymore).

The timer duration can also be changed by [double] clicking over the numbers, what do you think?

@samuelgrigolato
Copy link
Collaborator Author

My cents:

1: configurable, below by default.
2: showing by default.
3: +1 monospaced, will ease the math and developers tend to prefer monospaced fonts anyway =].
4: nice feature!
5: Message box seems to be an annoying thing, I would prefer a change to the frame background color and an audio cue.

6: What did you mean with 'change accordingly window shape'? I would suggest that the new minimum frame size in pixels need to be the minimum value capable of presenting the time horizontally (suppressing the buttons). Implementing more complex shapes like an "L" or "T" seems not to be a necessary feature, people will most likely use the smallest rectangular version (IMHO).

About the mechanism to change the duration by double clicking the numbers: the value will change automatically (based on a set of pre-defined values) or an input popup will be displayed, allowing the user to type any value?

@danilobellini
Copy link
Owner

1: Configurations are "above" and "below". Making it available to the left or to the right would need a multirow representation, which can be done, but not in a first version.

2.1: I think it should be easy to show/hide it, even from command line (e.g. dose.py --timer 4:33 py.test would call py.test with the timer already set on 4 minutes and 33 seconds).

2.2: I agree there's a problem with the "hidden by default": people may not even know that a timer exists. But a "shown by default" should have a fast or a memoizable way to hide the timer. Perhaps it would be better to keep something like a ~/.doserc file to keep last used configuration (skip pattern, timer, size, position, etc.).

3: We can make an open font for that. =)

5.1: Instead of a message box, dose.py may "shake" itself, flicker, change its color/size in a "heartbeating"-like way, etc.. Even a message is ok, it just annoys when it changes the window that has the focus, and I think that's not needed (nor desired) at all.

5.2: Sound would add a new requirement for dose.py (e.g. PyAudio, PyGame, ...), besides the wave itself. To keep dose.py a "one-filer" project, the sound should be done by a synthesis algorithm. Also, a "tic-tac" with fade in for the last 30 seconds would be nice.

6.1: dose.py uses the rounded_rectangle_region() function to change the wx.Frame widget shape (i.e., the window shape itself), allowing rounded borders. If we add something below dose, its shape should be updated accordingly, perhaps with the small rounded borders making a small "cut" in the middle of the window.

6.2: Shapes like "L" or "T" might look nice, but I don't know if these shapes would give a better GUI experience for moving and resizing/reshaping, and these probably won't be done in a first implementation of a timer feature. But I don't think we need to keep only features that are "necessary", e.g., anyone can add an incrementing sequence memory game in dose.py as an easter egg.

Double clicking the number can be the same as a right click -> "Set timer interval" (or something like) in a input box popup. But this can also insert/show an edit box in place. or can show arrows up/down to allow changing the value by clicking. Or perhaps all of these.

@samuelgrigolato
Copy link
Collaborator Author

I'm thinking of implementing the following items as a first contribution:

  • Add config file support, defaulting to "~/.doserc". [which file format? python code?]
  • Add a timer box, below the semaphore by default, displaying the default value of 7 minutes, initially paused.
  • Add a play/pause button aside the timer.
  • Change the background color as the time decreases.
  • Shake and blink the frame, and beep a simple wave when the time runs out.
  • Store all options in the config file, and load them on startup.

New popup options:

  • Show/hide timer;
  • Timer position (below/above);
  • Enable/disable shake;
  • Enable/disable beep;
  • Change timer duration.

When I finish these we can go back and think about other cool things to add, like the open monospaced font, the heartbeat behavior and the inline editor controls.

@danilobellini
Copy link
Owner

Config file support might have "levels" of fallback (like git config). The config file would be:

  1. Local (a config for that specific project), os.curdir
  2. User, os.path.expanduser("~")
  3. Global, like "/etc"
  4. Default (e.g. hardcoded)

At first, two levels seem to be needed: home and default configuration. I think a global config isn't needed at all, unless it is the way the defaults are stored. Local config might be added afterwards. The other way around (storing config in the current dir instead of starting with an user config) would be as annoying as the Windows "Thumbs.db" files, and that's not something needed for coding dojos. So, after all, I don't even know if something else in a config file support is helpful.

The config file name might be ".dose.conf", ".doseconf", ".doserc", or something else. For example, Spyder uses "~/.spyder2/.spyder.ini" as its config file. I see no need for a subdirectory, and I liked ".doserc", but ending with ".ini" or ".conf" would help Windows users when finding an app to edit it (based on file extension).

File format would be a JSON, an INI-like with ConfigParser, a XML, an AST-parsed Python file (to ensure only assignments are done, or perhaps another Python syntax subset), etc..

I'm waiting for the pull request. =)

samuelgrigolato added a commit to samuelgrigolato/dose that referenced this issue Dec 3, 2013
…ini#3

Squashed commit of the following:

commit f6acb95
Author: Samuel Grigolato <[email protected]>
Date:   Mon Dec 2 21:21:04 2013 -0200

    Add config options: size, opacity and flip.

commit b90f01e
Author: Samuel Grigolato <[email protected]>
Date:   Fri Nov 29 01:57:17 2013 -0200

    Add user home config file support.
@samuelgrigolato
Copy link
Collaborator Author

Is there any way to make a wx.StaticText component "stretch" the text until it fills the parent panel? I did some research but had no luck (it works only the other way around, i.e., the component size matches the text width/height automatically). I'm almost biting the bullet and writing my own digit/colon drawer on top of wx.GraphicsContext.

@danilobellini
Copy link
Owner

Yes, there is. You can bind the resize event to change the font size. To find the font size, this script might help:

import wx

max_width = 10 # pixels
max_height = 20 # pixels

app = wx.App()
font = wx.FontFromPixelSize((max_width, max_height),
         family = wx.FONTFAMILY_DEFAULT,
         style = wx.FONTSTYLE_NORMAL,
         weight = wx.FONTWEIGHT_NORMAL,
       )
dc = wx.MemoryDC()
dc.SetFont(font)

print dc.GetTextExtent("Test") # => (29, 16)

@samuelgrigolato
Copy link
Collaborator Author

This script did the job well, thanks! =]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants