Skip to content

Commit

Permalink
Add config file support (pos, size, opac and flip options) danilobell…
Browse files Browse the repository at this point in the history
…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.
  • Loading branch information
samuelgrigolato committed Dec 2, 2013
1 parent 530b2c8 commit e072e46
Showing 1 changed file with 84 additions and 15 deletions.
99 changes: 84 additions & 15 deletions dose.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import os
import time
from fnmatch import fnmatch
import json

# Metadata (see setup.py for more information about these)
__version__ = "1.0.0"
Expand Down Expand Up @@ -75,6 +76,13 @@
".*"
])
TIME_BEFORE_CALL = 1.0 # seconds between event and the call action
CONFIG_FILE_NAME = ".dose.conf"
CONFIG_DEFAULT_OPTIONS = {
"position": (-1, -1), # by default let the win system decide
"size": (FIRST_WIDTH, FIRST_HEIGHT),
"opacity": FIRST_OPACITY,
"flipped": False
}

def rounded_rectangle_region(width, height, radius):
"""
Expand Down Expand Up @@ -112,23 +120,27 @@ class DoseGraphicalSemaphore(wx.Frame):
This class knows nothing about the led color meaning, and just print them
at the screen.
"""
def __init__(self, parent, leds=FIRST_LEDS,
width=FIRST_WIDTH, height=FIRST_HEIGHT,
opacity=FIRST_OPACITY, flip=False):
def __init__(self, parent, config, leds=FIRST_LEDS):
self._config = config
frame_style = (wx.FRAME_SHAPED | # Allows wx.SetShape
wx.FRAME_NO_TASKBAR |
wx.STAY_ON_TOP |
wx.NO_BORDER
)
super(DoseGraphicalSemaphore, self).__init__(parent, style=frame_style)
pos = config.get_option("position")
size = config.get_option("size")
opacity = config.get_option("opacity")
flip = config.get_option("flipped")
super(DoseGraphicalSemaphore, self).__init__(parent, style=frame_style,
pos=pos)
#self.BackgroundStyle = wx.BG_STYLE_CUSTOM # Avoids flicker
self.Bind(wx.EVT_ERASE_BACKGROUND, lambda evt: None)
self.Bind(wx.EVT_WINDOW_CREATE,
lambda evt: self.SetTransparent(FIRST_OPACITY)
) # Needed to at least have transparency on wxGTK
self._paint_width, self._paint_height = 0, 0 # Ensure update_sizes at
# first on_paint
self.ClientSize = (width, height)
self.ClientSize = size
self._flip = flip
self.opacity = opacity
self.Bind(wx.EVT_PAINT, self.on_paint)
Expand All @@ -152,6 +164,7 @@ def opacity(self):
@opacity.setter
def opacity(self, value):
self._opacity = value
self._config.set_option("opacity", value)
self.SetTransparent(self.opacity)

@property
Expand All @@ -162,6 +175,7 @@ def flip(self):
def flip(self, value):
if self._flip != value:
self._flip = value
self._config.set_option("flipped", value)
self.Refresh()

def on_paint(self, evt):
Expand Down Expand Up @@ -224,8 +238,9 @@ class DoseInteractiveSemaphore(DoseGraphicalSemaphore):
"""
Just a DojoGraphicalSemaphore, but now responsive to left click
"""
def __init__(self, parent):
super(DoseInteractiveSemaphore, self).__init__(parent)
def __init__(self, parent, config):
super(DoseInteractiveSemaphore, self).__init__(parent, config)
self._config = config
self._timer = wx.Timer(self)
self.Bind(wx.EVT_LEFT_DOWN, self.on_left_down)
self.Bind(wx.EVT_TIMER, self.on_timer, self._timer)
Expand All @@ -243,6 +258,7 @@ def on_timer(self, evt):
ctrl_is_down = wx.GetKeyState(wx.WXK_CONTROL)
shift_is_down = wx.GetKeyState(wx.WXK_SHIFT)
ms = wx.GetMouseState()
new_pos = None

# New initialization when keys pressed change
if self._key_state != (ctrl_is_down, shift_is_down):
Expand Down Expand Up @@ -286,21 +302,26 @@ def on_timer(self, evt):
new_h = max(MIN_HEIGHT, self._click_frame_height +
2 * delta_y * self._quad_signal_y
)
self.ClientSize = new_w, new_h
new_size = new_w, new_h
self.ClientSize = new_size
self._config.set_option("size", new_size)
self.SendSizeEvent() # Needed for wxGTK

# Center should be kept
center_x = self._click_frame_x + self._click_frame_width / 2
center_y = self._click_frame_y + self._click_frame_height / 2
self.Position = (center_x - new_w / 2,
center_y - new_h / 2)

self.Refresh()
new_pos = (center_x - new_w / 2,
center_y - new_h / 2)

# Move the window
if not (ctrl_is_down or shift_is_down):
self.Position = (self._click_frame_x + delta_x,
self._click_frame_y + delta_y)
new_pos = (self._click_frame_x + delta_x,
self._click_frame_y + delta_y)

if new_pos is not None:
self._config.set_option("position", new_pos)
self.Position = new_pos
self.Refresh()

# Since left button is kept down, there should be another one shot
# timer event again, without creating many timers like wx.CallLater
Expand Down Expand Up @@ -485,11 +506,58 @@ def stop(self):
self._watching = False


class DoseConfig:
"""
Handle load and storage of configuration options.
When dose starts, try to load configurations from
a file named ".dose.conf" in the following
locations:
1) Working directory (TODO!)
2) User home
If none of these files are present, dose
fallback to default values.
"""

def get_option(self, key):
return self._config.get(key, CONFIG_DEFAULT_OPTIONS[key])

def set_option(self, key, value):
self._config[key] = value

def _user_home_config_file_path(self):
user_home = os.path.expanduser("~")
path = os.path.join(user_home, CONFIG_FILE_NAME)
return path

def store_options(self):
"""
Store options in the user's home, only if
dose has not been launched with working
directory configs (TODO!).
"""
path = self._user_home_config_file_path()
config_file = open(path, "w")
json.dump(self._config, config_file, indent=4, separators=(',',': '))

def __init__(self):
path = self._user_home_config_file_path()
if os.path.exists(path):
config_file = open(path, "r")
self._config = json.load(config_file)
else:
self._config = CONFIG_DEFAULT_OPTIONS


class DoseMainWindow(DoseInteractiveSemaphore, DoseWatcher):

def __init__(self, parent):
DoseInteractiveSemaphore.__init__(self, parent)
config = DoseConfig()
DoseInteractiveSemaphore.__init__(self, parent, config)
DoseWatcher.__init__(self)
self._config = config
self.SetTitle("Disabled - dose") # Seen by the window manager
self.popmenu = {k:DosePopupMenu(self, k) for k in (True, False)}

Expand Down Expand Up @@ -568,6 +636,7 @@ def on_close(self, evt):
if evt.EventObject is not self: # Avoid deadlocks
self.Close() # wx.Frame
evt.Skip()
self._config.store_options()

def on_help_and_about(self, evt):
abinfo = wx.AboutDialogInfo()
Expand Down

0 comments on commit e072e46

Please sign in to comment.