1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 """sparse layout"""
22
23 from lib.xcairo import *
24 from lib.geom import *
25 import calendar
26 import optparse
27 import sys
28 from datetime import date, timedelta
29
30 import _base
31
33 """get the parser object for the layout command-line arguments
34
35 @param layout_name: corresponding python module (.py file)
36 @rtype: optparse.OptionParser
37 """
38 lname = layout_name.split(".")[1]
39 parser = optparse.OptionParser(usage="%prog (...) --layout " + lname + " [options] (...)",add_help_option=False)
40 parser.add_option("--rows", type="int", default=1, help="force grid rows [%default]")
41 parser.add_option("--cols", type="int", default=3,
42 help="force grid columns [%default]; if ROWS and COLS are both non-zero, "
43 "calendar will span multiple pages as needed; if one value is zero, it "
44 "will be computed automatically in order to fill exactly 1 page")
45 parser.add_option("--grid-order", choices=["row","column"],default="row",
46 help="either `row' or `column' to set grid placing order row-wise or column-wise [%default]")
47 parser.add_option("--z-order", choices=["auto", "increasing", "decreasing"], default="auto",
48 help="either `increasing' or `decreasing' to set whether next month (in grid order) "
49 "lies above or below the previously drawn month; this affects shadow casting, "
50 "since rendering is always performed in increasing z-order; specifying `auto' "
51 "selects increasing order if and only if sloppy boxes are enabled [%default]")
52 parser.add_option("--month-with-year", action="store_true", default=False,
53 help="displays year together with month name, e.g. January 1980; suppresses year from footer line")
54 parser.add_option("--no-footer", action="store_true", default=False,
55 help="disable footer line (with year and rendered-by message)")
56 parser.add_option("--symmetric", action="store_true", default=False,
57 help="force symmetric mode (equivalent to --geom-var=month.symmetric=1). "
58 "In symmetric mode, day cells are equally sized and all month boxes contain "
59 "the same number of (possibly empty) cells, independently of how many days or "
60 "weeks per month. In asymmetric mode, empty rows are eliminated, by slightly "
61 "resizing day cells, in order to have uniform month boxes.")
62 parser.add_option("--padding", type="float", default=None,
63 help="set month box padding (equivalent to --geom-var=month.padding=PADDING)")
64 parser.add_option("--no-shadow", action="store_true", default=None,
65 help="disable box shadows")
66 parser.add_option("--opaque", action="store_true", default=False,
67 help="make background opaque (white fill)")
68 parser.add_option("--swap-colors", action="store_true", default=None,
69 help="swap month colors for even/odd years")
70 return parser
71
72 parser = get_parser(__name__)
73
74 -def _draw_day_cell(cr, rect, day, header, footer, theme, show_day_name, text_height=None):
75 ds,G,L = theme
76 year, month, day_of_month, day_of_week = day
77 draw_box(cr, rect, ds.bg, ds.bg, mm_to_dots(ds.frame_thickness))
78
79 if day_of_month > 1:
80 x, y, w, h = rect
81 draw_line(cr, (x, y, w, 0), ds.frame, mm_to_dots(ds.frame_thickness))
82
83 if (text_height is not None) and (text_height > 0):
84 x, y, w, h = rect
85 h_diff = h - text_height
86 if h_diff > 0:
87 y += h_diff / 2
88 h = text_height
89 rect = (x, y, w, h)
90
91 x, y, w, h = rect
92 ww = h
93 Rleft = (x + 0.1 * h, y + 0.2 * h, ww - 0.2 * h, .6 * h)
94 Rmiddle = (x + h, y, ww, h)
95 Rmiddle_top = (x + h + 0.1 * h, y + 0.2 * h, ww, .18 * h)
96 bottom_h = .8 * h
97 Rmiddle_bottom = (x + h + 0.1 * h, y + h - bottom_h, ww, bottom_h - 0.2 * h)
98
99
100 Rright_header = (x + 2*h, y + 0.1 * h, w - 2 * ww - 0.2 * ww, 0.28 * h)
101 Rright_footer = (x + 2*h, y + 0.6 * h, w - 2 * ww - 0.2 * ww, 0.28 * h)
102 x, y, w, h = Rmiddle_bottom
103 hh = h
104 h = float(h) * 0.6
105 y += float(hh) - h
106 Rmiddle_bottom = (x, y, w, h)
107 valign = 0 if show_day_name else 2
108
109 draw_str(cr, text = str(day_of_month), rect = Rleft, scaling = -1, stroke_rgba = ds.fg,
110 align = (1,valign), font = ds.font, measure = "88")
111
112 if show_day_name:
113 draw_str(cr, text = L.day_name[day_of_week], rect = Rmiddle_bottom,
114 scaling = -1, stroke_rgba = ds.fg, align = (0,valign),
115 font = ds.font, measure = "Mo")
116
117 if day_of_week == 0 or (day_of_month == 1 and month == 1):
118 week_nr = date(year, month, day_of_month).isocalendar()[1]
119 draw_str(cr, text = "%s%d" % (L.week_of_year_prefix, week_nr), rect = Rmiddle_top,
120 scaling = -1, stroke_rgba = ds.fg, align = (0,valign),
121 font = ds.header_font, measure = "W88")
122
123 if header:
124 draw_str(cr, text = header, rect = Rright_header, scaling = -1,
125 stroke_rgba = ds.header, align = (1,1), font = ds.header_font,
126 measure='MgMgMgMgMgMgMgMgMg')
127 if footer:
128 draw_str(cr, text = footer, rect = Rright_footer, scaling = -1,
129 stroke_rgba = ds.footer, align = (1,1), font = ds.header_font,
130 measure='MgMgMgMgMgMgMgMgMg')
131
133 """sparse layout class"""
135 S,G,L = self.Theme
136 make_sloppy_rect(cr, rect, G.month.sloppy_dx, G.month.sloppy_dy, G.month.sloppy_rot)
137
138 day, span = calendar.monthrange(year, month)
139 wmeasure = 'A'*max(map(len,L.day_name))
140 mmeasure = 'A'*max(map(len,L.month_name))
141
142 rows = 31 if G.month.symmetric else span
143 grid = VLayout(rect_from_origin(rect), 32)
144 dom_grid = VLayout(grid.item_span(31,1), rows)
145
146
147 tmp_grid = VLayout(grid.item_span(31,1), 31)
148 text_height = tmp_grid.item(0)[3]
149
150
151 if S.month.box_shadow:
152 f = S.month.box_shadow_size
153 shad = (f,-f) if G.landscape else (f,f)
154 draw_shadow(cr, rect_from_origin(rect), shad)
155
156
157 for dom in range(1,span+1):
158 R = dom_grid.item(dom-1)
159 holiday_tuple = self.holiday_provider(year, month, dom, day)
160 day_style = holiday_tuple[2]
161 header = holiday_tuple[0]
162 footer = holiday_tuple[1]
163 _draw_day_cell(cr, rect = R, day = (year, month, dom, day),
164 header = header, footer = footer,
165 theme = (day_style, G.dom, L), show_day_name = True,
166 text_height = text_height)
167
168 day = (day + 1) % 7
169
170
171 mcolor = S.month.color_map_bg[year%2][month]
172 mcolor_fg = S.month.color_map_fg[year%2][month]
173 R_mb = grid.item(0)
174 R_text = rect_rel_scale(R_mb, 1, 0.5)
175 mshad = None
176 if S.month.text_shadow:
177 f = S.month.text_shadow_size
178 mshad = (f,-f) if G.landscape else (f,f)
179 draw_str(cr, text = L.month_name[month], rect = R_text, scaling = -1, stroke_rgba = mcolor_fg,
180 align = (2,0), font = S.month.font, measure = mmeasure, shadow = mshad)
181 cr.restore()
182