def _update_tabs(self) -> None: from ba.internal import (get_available_sale_time, get_available_purchase_count) if not self._root_widget: return for tab_name, tab_data in list( self._purchasable_count_widgets.items()): sale_time = get_available_sale_time(tab_name) if sale_time is not None: ba.textwidget(edit=tab_data['sale_title_text'], text=ba.Lstr(resource='store.saleText')) ba.textwidget(edit=tab_data['sale_time_text'], text=ba.timestring( sale_time, centi=False, timeformat=ba.TimeFormat.MILLISECONDS)) ba.imagewidget(edit=tab_data['sale_img'], opacity=1.0) count = 0 else: ba.textwidget(edit=tab_data['sale_title_text'], text='') ba.textwidget(edit=tab_data['sale_time_text'], text='') ba.imagewidget(edit=tab_data['sale_img'], opacity=0.0) count = get_available_purchase_count(tab_name) if count > 0: ba.textwidget(edit=tab_data['text'], text=str(count)) ba.imagewidget(edit=tab_data['img'], opacity=1.0) else: ba.textwidget(edit=tab_data['text'], text='') ba.imagewidget(edit=tab_data['img'], opacity=0.0)
def update_buttons(self) -> None: """Update our buttons.""" # pylint: disable=too-many-statements # pylint: disable=too-many-branches # pylint: disable=too-many-locals from ba.internal import have_pro, get_available_sale_time from ba import SpecialChar if not self._root_widget: return import datetime sales_raw = _ba.get_account_misc_read_val('sales', {}) sales = {} try: # Look at the current set of sales; filter any with time remaining. for sale_item, sale_info in list(sales_raw.items()): to_end = (datetime.datetime.utcfromtimestamp(sale_info['e']) - datetime.datetime.utcnow()).total_seconds() if to_end > 0: sales[sale_item] = { 'to_end': to_end, 'original_price': sale_info['op'] } except Exception: ba.print_exception('Error parsing sales.') assert self.button_infos is not None for b_type, b_info in self.button_infos.items(): if b_type in ['upgrades.pro', 'pro']: purchased = have_pro() else: purchased = _ba.get_purchased(b_type) sale_opacity = 0.0 sale_title_text: Union[str, ba.Lstr] = '' sale_time_text: Union[str, ba.Lstr] = '' if purchased: title_color = (0.8, 0.7, 0.9, 1.0) color = (0.63, 0.55, 0.78) extra_image_opacity = 0.5 call = ba.WeakCall(self._print_already_own, b_info['name']) price_text = '' price_text_left = '' price_text_right = '' show_purchase_check = True description_color: Sequence[float] = (0.4, 1.0, 0.4, 0.4) description_color2: Sequence[float] = (0.0, 0.0, 0.0, 0.0) price_color = (0.5, 1, 0.5, 0.3) else: title_color = (0.7, 0.9, 0.7, 1.0) color = (0.4, 0.8, 0.1) extra_image_opacity = 1.0 call = b_info['call'] if 'call' in b_info else None if b_type in ['upgrades.pro', 'pro']: sale_time = get_available_sale_time('extras') if sale_time is not None: priceraw = _ba.get_price('pro') price_text_left = (priceraw if priceraw is not None else '?') priceraw = _ba.get_price('pro_sale') price_text_right = (priceraw if priceraw is not None else '?') sale_opacity = 1.0 price_text = '' sale_title_text = ba.Lstr(resource='store.saleText') sale_time_text = ba.timestring( sale_time, centi=False, timeformat=ba.TimeFormat.MILLISECONDS) else: priceraw = _ba.get_price('pro') price_text = priceraw if priceraw is not None else '?' price_text_left = '' price_text_right = '' else: price = _ba.get_account_misc_read_val('price.' + b_type, 0) # Color the button differently if we cant afford this. if _ba.get_account_state() == 'signed_in': if _ba.get_account_ticket_count() < price: color = (0.6, 0.61, 0.6) price_text = ba.charstr(ba.SpecialChar.TICKET) + str( _ba.get_account_misc_read_val('price.' + b_type, '?')) price_text_left = '' price_text_right = '' # TESTING: if b_type in sales: sale_opacity = 1.0 price_text_left = ba.charstr(SpecialChar.TICKET) + str( sales[b_type]['original_price']) price_text_right = price_text price_text = '' sale_title_text = ba.Lstr(resource='store.saleText') sale_time_text = ba.timestring( int(sales[b_type]['to_end'] * 1000), centi=False, timeformat=ba.TimeFormat.MILLISECONDS) description_color = (0.5, 1.0, 0.5) description_color2 = (0.3, 1.0, 1.0) price_color = (0.2, 1, 0.2, 1.0) show_purchase_check = False if 'title_text' in b_info: ba.textwidget(edit=b_info['title_text'], color=title_color) if 'purchase_check' in b_info: ba.imagewidget(edit=b_info['purchase_check'], opacity=1.0 if show_purchase_check else 0.0) if 'price_widget' in b_info: ba.textwidget(edit=b_info['price_widget'], text=price_text, color=price_color) if 'price_widget_left' in b_info: ba.textwidget(edit=b_info['price_widget_left'], text=price_text_left) if 'price_widget_right' in b_info: ba.textwidget(edit=b_info['price_widget_right'], text=price_text_right) if 'price_slash_widget' in b_info: ba.imagewidget(edit=b_info['price_slash_widget'], opacity=sale_opacity) if 'sale_bg_widget' in b_info: ba.imagewidget(edit=b_info['sale_bg_widget'], opacity=sale_opacity) if 'sale_title_widget' in b_info: ba.textwidget(edit=b_info['sale_title_widget'], text=sale_title_text) if 'sale_time_widget' in b_info: ba.textwidget(edit=b_info['sale_time_widget'], text=sale_time_text) if 'button' in b_info: ba.buttonwidget(edit=b_info['button'], color=color, on_activate_call=call) if 'extra_backings' in b_info: for bck in b_info['extra_backings']: ba.imagewidget(edit=bck, color=color, opacity=extra_image_opacity) if 'extra_images' in b_info: for img in b_info['extra_images']: ba.imagewidget(edit=img, opacity=extra_image_opacity) if 'extra_texts' in b_info: for etxt in b_info['extra_texts']: ba.textwidget(edit=etxt, color=description_color) if 'extra_texts_2' in b_info: for etxt in b_info['extra_texts_2']: ba.textwidget(edit=etxt, color=description_color2) if 'descriptionText' in b_info: ba.textwidget(edit=b_info['descriptionText'], color=description_color)
def _update(self) -> None: # We may outlive our widgets. if not self.root_widget: return # If we've been foregrounded/backgrounded we need to re-grab data. if self._fg_state != ba.app.fg_state: self._fg_state = ba.app.fg_state self._have_valid_data = False # If we need to run another tournament query, do so. if not self._running_query and ( (self._last_query_time is None) or (not self._have_valid_data) or (ba.time(ba.TimeType.REAL) - self._last_query_time > 30.0)): _ba.tournament_query(args={ 'source': 'entry window' if self._tournament_activity is None else 'retry entry window' }, callback=ba.WeakCall( self._on_tournament_query_response)) self._last_query_time = ba.time(ba.TimeType.REAL) self._running_query = True # Grab the latest info on our tourney. self._tournament_info = ba.app.tournament_info[self._tournament_id] # If we don't have valid data always show a '-' for time. if not self._have_valid_data: ba.textwidget(edit=self._time_remaining_text, text='-') else: if self._seconds_remaining is not None: self._seconds_remaining = max(0, self._seconds_remaining - 1) ba.textwidget(edit=self._time_remaining_text, text=ba.timestring( self._seconds_remaining * 1000, centi=False, timeformat=ba.TimeFormat.MILLISECONDS)) # Keep price up-to-date and update the button with it. self._purchase_price = _ba.get_account_misc_read_val( self._purchase_price_name, None) ba.textwidget( edit=self._ticket_cost_text, text=(ba.Lstr(resource='getTicketsWindow.freeText') if self._purchase_price == 0 else ba.Lstr( resource='getTicketsWindow.ticketsText', subs=[('${COUNT}', str(self._purchase_price) if self._purchase_price is not None else '?')])), position=self._ticket_cost_text_position_free if self._purchase_price == 0 else self._ticket_cost_text_position, scale=1.0 if self._purchase_price == 0 else 0.6) ba.textwidget( edit=self._free_plays_remaining_text, text='' if (self._tournament_info['freeTriesRemaining'] in [None, 0] or self._purchase_price != 0) else '' + str(self._tournament_info['freeTriesRemaining'])) ba.imagewidget(edit=self._ticket_img, opacity=0.2 if self._purchase_price == 0 else 1.0, position=self._ticket_img_pos_free if self._purchase_price == 0 else self._ticket_img_pos) if self._do_ad_btn: enabled = _ba.have_incentivized_ad() have_ad_tries_remaining = ( self._tournament_info['adTriesRemaining'] is not None and self._tournament_info['adTriesRemaining'] > 0) ba.textwidget(edit=self._ad_text, position=self._ad_text_position_remaining if have_ad_tries_remaining else self._ad_text_position, color=(0, 1, 0) if enabled else (0.5, 0.5, 0.5)) ba.imagewidget(edit=self._pay_with_ad_img, opacity=1.0 if enabled else 0.2) ba.buttonwidget(edit=self._pay_with_ad_btn, color=(0.5, 0.7, 0.2) if enabled else (0.5, 0.5, 0.5)) ad_plays_remaining_text = ( '' if not have_ad_tries_remaining else '' + str(self._tournament_info['adTriesRemaining'])) ba.textwidget(edit=self._ad_plays_remaining_text, text=ad_plays_remaining_text, color=(0, 0.8, 0) if enabled else (0.4, 0.4, 0.4)) try: t_str = str(_ba.get_account_ticket_count()) except Exception: t_str = '?' if self._get_tickets_button is not None: ba.buttonwidget(edit=self._get_tickets_button, label=ba.charstr(ba.SpecialChar.TICKET) + t_str)
def _update(self) -> None: # pylint: disable=too-many-branches from ba import SpecialChar, TimeFormat from ba.internal import (get_available_sale_time, get_available_purchase_count) if not self._button: return # Our instance may outlive our UI objects. if self._ticket_text is not None: if _ba.get_account_state() == 'signed_in': sval = ba.charstr(SpecialChar.TICKET) + str( _ba.get_account_ticket_count()) else: sval = '-' ba.textwidget(edit=self._ticket_text, text=sval) available_purchases = get_available_purchase_count() # Old pro sale stuff.. sale_time = get_available_sale_time('extras') # ..also look for new style sales. if sale_time is None: import datetime sales_raw = _ba.get_account_misc_read_val('sales', {}) sale_times = [] try: # Look at the current set of sales; filter any with time # remaining that we don't own. for sale_item, sale_info in list(sales_raw.items()): if not _ba.get_purchased(sale_item): to_end = (datetime.datetime.utcfromtimestamp( sale_info['e']) - datetime.datetime.utcnow()).total_seconds() if to_end > 0: sale_times.append(to_end) except Exception: ba.print_exception('Error parsing sales') if sale_times: sale_time = int(min(sale_times) * 1000) if sale_time is not None: ba.textwidget(edit=self._sale_title_text, text=ba.Lstr(resource='store.saleText')) ba.textwidget(edit=self._sale_time_text, text=ba.timestring( sale_time, centi=False, timeformat=TimeFormat.MILLISECONDS)) ba.imagewidget(edit=self._sale_backing, opacity=1.0) ba.imagewidget(edit=self._available_purchase_backing, opacity=1.0) ba.textwidget(edit=self._available_purchase_text, text='') ba.imagewidget(edit=self._available_purchase_backing, opacity=0.0) else: ba.imagewidget(edit=self._sale_backing, opacity=0.0) ba.textwidget(edit=self._sale_time_text, text='') ba.textwidget(edit=self._sale_title_text, text='') if available_purchases > 0: ba.textwidget(edit=self._available_purchase_text, text=str(available_purchases)) ba.imagewidget(edit=self._available_purchase_backing, opacity=1.0) else: ba.textwidget(edit=self._available_purchase_text, text='') ba.imagewidget(edit=self._available_purchase_backing, opacity=0.0)
def _on_tournament_query_response(self, data: Optional[Dict[str, Any]]) -> None: if data is not None: # this used to be the whole payload data_t: List[Dict[str, Any]] = data['t'] # kill our loading text if we've got scores.. otherwise just # replace it with 'no scores yet' if data_t[0]['scores']: self._loading_text.delete() else: ba.textwidget(edit=self._loading_text, text=ba.Lstr(resource='noScoresYetText')) incr = 30 sub_width = self._width - 90 sub_height = 30 + len(data_t[0]['scores']) * incr self._subcontainer = ba.containerwidget(parent=self._scrollwidget, size=(sub_width, sub_height), background=False) for i, entry in enumerate(data_t[0]['scores']): ba.textwidget(parent=self._subcontainer, position=(sub_width * 0.1 - 5, sub_height - 20 - incr * i), maxwidth=20, scale=0.5, color=(0.6, 0.6, 0.7), flatness=1.0, shadow=0.0, text=str(i + 1), size=(0, 0), h_align='right', v_align='center') ba.textwidget( parent=self._subcontainer, position=(sub_width * 0.25 - 2, sub_height - 20 - incr * i), maxwidth=sub_width * 0.24, color=(0.9, 1.0, 0.9), flatness=1.0, shadow=0.0, scale=0.6, text=(ba.timestring(entry[0] * 10, centi=True, timeformat=ba.TimeFormat.MILLISECONDS) if data_t[0]['scoreType'] == 'time' else str( entry[0])), size=(0, 0), h_align='center', v_align='center') txt = ba.textwidget( parent=self._subcontainer, position=(sub_width * 0.25, sub_height - 20 - incr * i - (0.5 / 0.7) * incr), maxwidth=sub_width * 0.6, scale=0.7, flatness=1.0, shadow=0.0, text=ba.Lstr(value=entry[1]), selectable=True, click_activate=True, autoselect=True, extra_touch_border_scale=0.0, size=((sub_width * 0.6) / 0.7, incr / 0.7), h_align='left', v_align='center') ba.textwidget(edit=txt, on_activate_call=ba.Call(self._show_player_info, entry, txt)) if i == 0: ba.widget(edit=txt, up_widget=self._cancel_button)
def _update(self) -> None: import datetime # if we somehow get signed out, just die.. if _ba.get_account_state() != 'signed_in': self._back() return self._ticket_count = _ba.get_account_ticket_count() # update our incentivized ad button depending on whether ads are # available if self._ad_button is not None: next_reward_ad_time = _ba.get_account_misc_read_val_2( 'nextRewardAdTime', None) if next_reward_ad_time is not None: next_reward_ad_time = datetime.datetime.utcfromtimestamp( next_reward_ad_time) now = datetime.datetime.utcnow() if (_ba.have_incentivized_ad() and (next_reward_ad_time is None or next_reward_ad_time <= now)): self._ad_button_greyed = False ba.buttonwidget(edit=self._ad_button, color=(0.65, 0.5, 0.7)) ba.textwidget(edit=self._ad_label, color=(0.7, 0.9, 0.7, 1.0)) ba.textwidget(edit=self._ad_free_text, color=(1, 1, 0, 1)) ba.imagewidget(edit=self._ad_image, opacity=0.6) ba.textwidget(edit=self._ad_time_text, text='') else: self._ad_button_greyed = True ba.buttonwidget(edit=self._ad_button, color=(0.5, 0.5, 0.5)) ba.textwidget(edit=self._ad_label, color=(0.7, 0.9, 0.7, 0.2)) ba.textwidget(edit=self._ad_free_text, color=(1, 1, 0, 0.2)) ba.imagewidget(edit=self._ad_image, opacity=0.6 * 0.25) sval: Union[str, ba.Lstr] if (next_reward_ad_time is not None and next_reward_ad_time > now): sval = ba.timestring( (next_reward_ad_time - now).total_seconds() * 1000.0, centi=False, timeformat=ba.TimeFormat.MILLISECONDS) else: sval = '' ba.textwidget(edit=self._ad_time_text, text=sval) # if this is our first update, assign immediately; otherwise kick # off a smooth transition if the value has changed if self._smooth_ticket_count is None: self._smooth_ticket_count = float(self._ticket_count) self._smooth_update() # will set the text widget elif (self._ticket_count != int(self._smooth_ticket_count) and self._smooth_update_timer is None): self._smooth_update_timer = ba.Timer(0.05, ba.WeakCall( self._smooth_update), repeat=True, timetype=ba.TimeType.REAL) diff = abs(float(self._ticket_count) - self._smooth_ticket_count) self._smooth_increase_speed = (diff / 100.0 if diff >= 5000 else diff / 50.0 if diff >= 1500 else diff / 30.0 if diff >= 500 else diff / 15.0)