mirror of
https://github.com/gryf/wmdocklib.git
synced 2025-12-19 20:38:03 +01:00
modified the fonts: they start from background colour (None or Black) and go to full intensity, which ought to be gray100 or white. the initialization procedure will spread all colour differences between the requested background and foreground proportionally to the intensity of the gray char pixel. most colour code clashes are resolved at initialization stage. there are only a few things you should not reuse, such as the space for transparency. just try out the result and make use of the 'debug' parameter which will cause the function to print the the generated xpm.
294 lines
10 KiB
Python
Executable File
294 lines
10 KiB
Python
Executable File
#!/usr/bin/env python
|
|
|
|
"""pywmdatetime.py
|
|
|
|
WindowMaker dockapp that displays time, date, weekday and week number.
|
|
|
|
Copyright (C) 2003 Kristoffer Erlandsson
|
|
|
|
Licensed under the GNU General Public License.
|
|
|
|
|
|
Changes:
|
|
2003-09-01 Kristoffer Erlandsson
|
|
Fixed a bug where the week didn't update if we used %q style week numbering.
|
|
|
|
2003-06-28 Kristoffer Erlandsson
|
|
Fixed a bug where a mouse click caused an infinite loop
|
|
|
|
2003-06-26 Kristoffer Erlandsson
|
|
Fixed bug when longer strings didn't get cleared when shorter ones where
|
|
painted. Now only repaint the strings when they have changed.
|
|
|
|
2003-06-24 Kristoffer Erlandsson
|
|
Added event handling for graceful shutdown
|
|
|
|
2003-06-16 Kristoffer Erlandsson
|
|
First workingish version
|
|
"""
|
|
usage = """pywmdatetime.py [options]
|
|
Available options are:
|
|
-h, --help print this help
|
|
-f, --foreground <color> set the foreground color
|
|
-b, --background <color> set the background color
|
|
-F, --font <file> set the font name
|
|
-t, --timeformat <format> set the time format
|
|
-d, --dateformat <format> set the date format
|
|
-y, --weekdayformat <format> set the weekday format
|
|
-e, --weekformat <format> set the week format
|
|
-r, --rgbfile <file> set the rgb file to get color codes from
|
|
-c, --configfile <file> set the config file to use
|
|
--debug shows the pixmap
|
|
|
|
The formats are the same as Python's strftime() accept. See the sample
|
|
rc-file for more information about this.
|
|
"""
|
|
|
|
import sys
|
|
import time
|
|
import getopt
|
|
import os
|
|
|
|
import wmdocklib
|
|
|
|
width = 64
|
|
height = 64
|
|
|
|
xOffset = 4
|
|
yOffset = 4
|
|
|
|
timeDefaultFormat = '%H:%M:%S'
|
|
dateDefaultFormat = '%d-%m-%y'
|
|
dayDefaultFormat = '%A'
|
|
weekDefaultFormat = 'wk %q' # %q added by Kristoffer for different week calculation.
|
|
|
|
defaultConfigFile = '~/.pywmdatetimerc'
|
|
maxCharsPerLine = None
|
|
|
|
def addString(s, x, y):
|
|
try:
|
|
wmdocklib.addString(s, x, y, xOffset, yOffset,
|
|
width, height)
|
|
except ValueError, e:
|
|
sys.stderr.write('Error when painting string:\n' + str(e) + '\n')
|
|
sys.stderr.write('test %s' % ((s, x, y, xOffset, yOffset,
|
|
width, height),))
|
|
raise
|
|
sys.exit(3)
|
|
|
|
def addTimeString(s, x, y):
|
|
for c in s:
|
|
charW = 7
|
|
charX = (ord(c) - ord('0')) * 7
|
|
charY = 64
|
|
if not c.isdigit():
|
|
charX = 70
|
|
charW = 3
|
|
wmdocklib.copyXPMArea(charX, charY, charW, 10, x+xOffset+1, y+yOffset)
|
|
x += charW
|
|
|
|
def clearLine(y):
|
|
'''Clear a line of text at position y.'''
|
|
wmdocklib.copyXPMArea(73, yOffset, width - 2 * xOffset, char_height,
|
|
xOffset, y + yOffset)
|
|
|
|
def getCenterStartPos(s):
|
|
return wmdocklib.getCenterStartPos(s, width, xOffset)
|
|
|
|
def getVertSpacing(numLines, margin):
|
|
return wmdocklib.getVertSpacing(numLines, margin-1, height, yOffset) + 1
|
|
|
|
def calculateWeek(localTime):
|
|
"""Calculate the week number as we do, for example in Sweden.
|
|
|
|
That is, add one to the %W format if the year didn't start on a monday."""
|
|
day = int(time.strftime('%j', localTime))
|
|
weekDay = int(time.strftime('%w')) - 1
|
|
if weekDay == -1:
|
|
weekDay = 6
|
|
lastMonday = day - weekDay
|
|
if lastMonday % 7 == 0:
|
|
return int(time.strftime('%W'))
|
|
return int(time.strftime('%W')) + 1
|
|
|
|
def parseCommandLine(argv):
|
|
"""Parse the commandline. Return a dictionary with options and values."""
|
|
shorts = 'hf:b:t:d:e:y:r:c:F:a'
|
|
longs = ['antialiased', 'help', 'foreground=', 'background=',
|
|
'timeformat=', 'dateformat=', 'debug',
|
|
'weekdayformat=', 'weekformat=', 'rgbfile=', 'configfile=', 'font=']
|
|
try:
|
|
opts, nonOptArgs = getopt.getopt(argv[1:], shorts, longs)
|
|
except getopt.GetoptError, e:
|
|
sys.stderr.write('Error when parsing commandline: ' + str(e) + '\n')
|
|
sys.stderr.write(usage)
|
|
sys.exit(2)
|
|
d = {}
|
|
|
|
for o, a in opts:
|
|
if o in ('-h', '--help'):
|
|
sys.stdout.write(usage)
|
|
sys.exit(0)
|
|
if o in ('-a', '--antialiased'):
|
|
d['antialiased'] = True
|
|
if o in ('-f', '--foreground'):
|
|
d['foreground'] = a
|
|
if o in ('-F', '--font'):
|
|
d['font'] = a
|
|
if o in ('-b', '--background'):
|
|
d['background'] = a
|
|
if o in ('-t', '--timeformat'):
|
|
d['timeformat'] = a
|
|
if o in ('-d', '--dateformat'):
|
|
d['dateformat'] = a
|
|
if o in ('-y', '--weekdayformat'):
|
|
d['weekdayformat'] = a
|
|
if o in ('-e', '--weekformat'):
|
|
d['weekformat'] = a
|
|
if o in ('-r', '--rgbfile'):
|
|
d['rgbfile'] = a
|
|
if o in ('-c', '--configfile'):
|
|
d['configfile'] = a
|
|
if o in ('--debug'):
|
|
d['debug'] = True
|
|
return d
|
|
|
|
def checkForEvents():
|
|
event = wmdocklib.getEvent()
|
|
while not event is None:
|
|
if event['type'] == 'destroynotify':
|
|
sys.exit(0)
|
|
event = wmdocklib.getEvent()
|
|
|
|
def mainLoop(timeFmt, dateFmt, dayFmt, weekFmt):
|
|
recalcWeek = weekFmt.find('%q') + 1 # True if we found %q.
|
|
newWeekFmt = weekFmt
|
|
counter = -1
|
|
lastStrs = [''] * 4
|
|
while 1:
|
|
counter += 1
|
|
checkForEvents()
|
|
lt = time.localtime()
|
|
timeStr = time.strftime(timeFmt, lt)[:maxCharsPerLine]
|
|
timeX = 3
|
|
if antialiased:
|
|
margin = 6
|
|
spacing = getVertSpacing(4, margin)
|
|
if lastStrs[0] != timeStr:
|
|
addTimeString(timeStr, timeX, margin-4)
|
|
margin += 3
|
|
else:
|
|
margin = 4
|
|
spacing = getVertSpacing(4, margin)
|
|
if lastStrs[0] != timeStr:
|
|
addString(timeStr, timeX, margin)
|
|
lastStrs[0] = timeStr
|
|
if counter % 100 == 0:
|
|
# We only perform the date/week checks/updates once every 100th
|
|
# iteration. We will maybe lag behind a couple of seconds when
|
|
# switching, but switching occurs seldom and it will be alot of
|
|
# unnecessary checks :).
|
|
dateStr = time.strftime(dateFmt, lt)[:maxCharsPerLine]
|
|
if recalcWeek:
|
|
week = calculateWeek(lt)
|
|
newWeekFmt = weekFmt.replace('%q', str(week))
|
|
weekStr = time.strftime(newWeekFmt, lt)[:maxCharsPerLine]
|
|
dayStr = time.strftime(dayFmt, lt)[:maxCharsPerLine]
|
|
dateX = getCenterStartPos(dateStr)
|
|
weekX = getCenterStartPos(weekStr)
|
|
dayX = getCenterStartPos(dayStr)
|
|
if lastStrs[1] != dateStr:
|
|
clearLine(margin + spacing + char_width)
|
|
addString(dateStr, dateX, margin + spacing + char_width)
|
|
lastStrs[1] = dateStr
|
|
if lastStrs[2] != dayStr:
|
|
clearLine(margin + 2 * (spacing + char_width))
|
|
addString(dayStr, dayX, margin + 2 * (spacing + char_width))
|
|
lastStrs[2] = dayStr
|
|
if lastStrs[3] != weekStr:
|
|
clearLine(margin + 3 * (spacing + char_width))
|
|
addString(weekStr, weekX, margin + 3 * (spacing + char_width))
|
|
lastStrs[3] = weekStr
|
|
if counter == 999999:
|
|
counter = -1
|
|
wmdocklib.redraw()
|
|
time.sleep(0.1)
|
|
|
|
patterns = [
|
|
".+@@+.....#@...#@@#...#@@#....$@%...@@@@+..+=@%..+@@@@@..%@@+...&@@#.....",
|
|
"$@==@$...+@@..&@--@&.*@--@&...#@%..*@-%%*.$==-@&.*%%%@=.#@-=@*.*@=-@&....",
|
|
"&@**@&..#@@@..&@$.@%.&-..@%..*@@%..+@+....+@*.%*....+@*.%@.+@+.%@$.-%.*+.",
|
|
"%@..@%..#+%@.....$@%....+@#..--@%..&@=@#..%@$+$.....--..&@&%@$.%@..%@.%@.",
|
|
"%@..@%....%@.....%@*...%@-..*@$@%..%@%=@*.%@=@@*...*@&...=@@#..&@%&@@.*+.",
|
|
"%@..@%....%@....+@%....&-@+.=#.@%...*.$@%.%@%&@-...#@...#@&%@*..=@@@@....",
|
|
"%@..@%....%@...+@=$......-@.@-%@=&.....@%.%@..%@...=-...@%..@%...+*%@.&%.",
|
|
"&@**@&....%@..$@=$...&-..-@.@@@@@%.--.*@#.+@$.-@...@%...@-.$@%.$#*.=%.%@.",
|
|
"$@==@$....%@..#@-%%&.+@--@#....@%..%@-=@$.$@=-@#..+@+...#@-=@*.$@=-@+....",
|
|
".+@@+.....%@..@@@@@%..#@@#.....@%..$-@=+...+=@%$..+@+...$#@@&...+@@#.....",
|
|
]
|
|
palette = {
|
|
".":"#181818",
|
|
"+":"#6E6E0F",
|
|
"@":"#FFFF00",
|
|
"#":"#A0A009",
|
|
"$":"#3B3B14",
|
|
"%":"#B9B907",
|
|
"&":"#87870C",
|
|
"*":"#545411",
|
|
"=":"#E6E602",
|
|
"-":"#CFCF04",
|
|
}
|
|
|
|
def main():
|
|
clConfig = parseCommandLine(sys.argv)
|
|
configFile = clConfig.get('configfile', defaultConfigFile)
|
|
configFile = os.path.expanduser(configFile)
|
|
fileConfig = wmdocklib.readConfigFile(configFile, sys.stderr)
|
|
# Merge the two configs, let the commandline options overwrite those in the
|
|
# configuration file.
|
|
config = fileConfig
|
|
for i in clConfig.iteritems():
|
|
config[i[0]] = i[1]
|
|
|
|
timeFmt = config.get('timeformat', timeDefaultFormat)
|
|
dateFmt = config.get('dateformat', dateDefaultFormat)
|
|
dayFmt = config.get('weekdayformat', dayDefaultFormat)
|
|
weekFmt = config.get('weekformat', weekDefaultFormat)
|
|
# openXwindow sets the window title to the program name. If we get the
|
|
# program name with a path, split it so we only name the window with the
|
|
# filename.
|
|
try:
|
|
programName = sys.argv[0].split(os.sep)[-1]
|
|
except IndexError: # Should only happen when using the interpreter.
|
|
programName = ''
|
|
sys.argv[0] = programName
|
|
|
|
palette[0] = clConfig.get('background', 'black')
|
|
palette[2] = clConfig.get('foreground', 'cyan3')
|
|
|
|
font = clConfig.get('font', '6x8orig')
|
|
|
|
if clConfig.get('antialiased'):
|
|
background = [((6,3),(57,19)),
|
|
((3,22),(60,60))]
|
|
else:
|
|
background = [((3,3),(59,60))]
|
|
|
|
debug = clConfig.get('debug')
|
|
|
|
global char_width, char_height, maxCharsPerLine, antialiased
|
|
char_width, char_height = wmdocklib.initPixmap(patterns=patterns,
|
|
font_name=font,
|
|
bg=0, fg=2, palette=palette,
|
|
background=background,
|
|
debug=debug)
|
|
maxCharsPerLine = (width-2*xOffset) / char_width
|
|
antialiased = clConfig.get('antialiased', False)
|
|
|
|
wmdocklib.openXwindow(sys.argv, width, height)
|
|
mainLoop(timeFmt, dateFmt, dayFmt, weekFmt)
|
|
|
|
if __name__ == '__main__':
|
|
main()
|
|
|