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