1# vim:fileencoding=utf-8
2# License: GPL v3 Copyright: 2015, Kovid Goyal <kovid at kovidgoyal.net>
3from __python__ import hash_literals
4
5from book_list.theme import get_color, get_font_size
6from dom import set_css, clear, create_keyframes, build_rule, svgicon, add_extra_css
7from elementmaker import E
8from gettext import gettext as _
9from session import get_interface_data
10
11bar_counter = 0
12CLASS_NAME = 'main-top-bar'
13SPACING = '0.75em'
14VSPACING = '0.5ex'
15THROBBER_NAME = 'top-bar-throbber'
16
17add_extra_css(def():
18    sel = '.' + CLASS_NAME + ' '
19    style = ''
20    style += create_keyframes(THROBBER_NAME, 'from { transform: scale(1); } 50% { transform: scale(0.5); } to { transform: scale(1); }')
21    style += build_rule(sel + 'a', display='inline-block', vertical_align='middle', overflow='hidden', cursor='pointer', color=get_color('bar-foreground'), background='none', padding_top=VSPACING, padding_bottom=VSPACING)
22    style += build_rule(sel + 'a:hover', transform='scale(1.5)')
23    style += build_rule(sel + 'a:active', transform='scale(2)')
24    style += build_rule(sel + 'a:focus', outline='none')
25    style += build_rule(sel + 'a.top-bar-title:hover', transform='scale(1)', color=get_color('bar-highlight'), font_style='italic')
26    style += build_rule(sel + 'a.top-bar-title:active', transform='scale(1)', color=get_color('bar-highlight'), font_style='italic')
27    return style
28)
29
30def create_markup(container):
31    for i in range(2):
32        bar = E.div(
33            class_=CLASS_NAME,
34            E.div(style="white-space:nowrap; overflow:hidden; text-overflow: ellipsis; padding-left: 0.5em;"),
35            E.div(style="white-space:nowrap; text-align:right; padding-right: 0.5em;")
36        )
37        if i is 0:
38            set_css(bar, position='fixed', left='0', top='0', z_index='1')
39        set_css(bar,
40            width='100%', display='flex', flex_direction='row', flex_wrap='wrap', justify_content='space-between',
41            font_size=get_font_size('title'), user_select='none',
42            color=get_color('bar-foreground'), background_color=get_color('bar-background')
43        )
44        container.appendChild(bar)
45
46def get_bars(container):
47    return container.getElementsByClassName(CLASS_NAME)
48
49def set_left_data(container, title='calibre', icon='heart', action=None, tooltip='', run_animation=False, title_action=None, title_tooltip=None):
50    bars = get_bars(container)
51    if icon is 'heart':
52        if not tooltip:
53            tooltip = _('Donate to support calibre development')
54    interface_data = get_interface_data()
55
56    for i, bar in enumerate(bars):
57        left = bar.firstChild
58        clear(left)
59        title_elem = 'a' if callable(title_action) else 'span'
60        left.appendChild(E.a(title=tooltip, svgicon(icon)))
61        left.appendChild(E(title_elem, title, title=title_tooltip, class_='top-bar-title',
62            style='margin-left: {0}; font-weight: bold; padding-top: {1}; padding-bottom: {1}; vertical-align: middle'.format(SPACING, VSPACING)))
63        if i is 0:
64            a = left.firstChild
65            if icon is 'heart':
66                set_css(a,
67                    animation_name=THROBBER_NAME, animation_duration='1s', animation_timing_function='ease-in-out',
68                    animation_iteration_count='5', animation_play_state='running' if run_animation else 'paused'
69                )
70                set_css(a.firstChild, color=get_color('heart'))
71                a.setAttribute('href', interface_data.donate_link)
72                a.setAttribute('target', 'donate-to-calibre')
73            if action is not None:
74                a.addEventListener('click', def(event):
75                    event.preventDefault()
76                    action.bind(event)()
77                )
78
79            if callable(title_action):
80                a = a.nextSibling
81                a.addEventListener('click', def(event):
82                    event.preventDefault()
83                    title_action.bind(event)()
84                )
85
86def set_title(container, text):
87    bars = get_bars(container)
88    for bar in bars:
89        bar.firstChild.firstChild.nextSibling.textContent = text
90
91
92def set_title_tooltip(container, text):
93    bars = get_bars(container)
94    for bar in bars:
95        bar.firstChild.firstChild.nextSibling.title = text
96
97
98def create_top_bar(container, **kw):
99    create_markup(container)
100    set_left_data(container, **kw)
101
102def add_button(container, icon, action=None, tooltip=''):
103    if not icon:
104        raise ValueError('An icon must be specified')
105    bars = get_bars(container)
106    for i, bar in enumerate(bars):
107        right = bar.firstChild.nextSibling
108        right.appendChild(E.a(
109            style="margin-left: " + SPACING,
110            title=tooltip, svgicon(icon),
111        ))
112        right.lastChild.dataset.buttonIcon = icon
113        if i is 0:
114            if action is not None:
115                right.lastChild.addEventListener('click', def(event):
116                    event.preventDefault(), action()
117                )
118
119def clear_buttons(container):
120    bars = get_bars(container)
121    for i, bar in enumerate(bars):
122        right = bar.firstChild.nextSibling
123        clear(right)
124
125
126def set_button_visibility(container, icon, visible):
127    for bar in get_bars(container):
128        right = bar.firstChild.nextSibling
129        elem = right.querySelector(f'[data-button-icon="{icon}"]')
130        if elem:
131            elem.style.display = 'inline-block' if visible else 'none'
132