Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

ui changes

  • Loading branch information...
commit 3b2ff9d907461f1057c05a9da31f9aecaa45e1ee 1 parent 2e35fc7
Michał Zieliński authored
2  android/info.sh
@@ -5,5 +5,5 @@ PKG_PACKAGE="pl.org.zielinscy.freeciv"
5 5 PKG_ARG="--orientation landscape --permission INTERNET --icon $BASE/freeciv-client.png --presplash $BASE/presplash.png"
6 6 # --presplash $GFX/splashscreen.png --icon $GFX/logo.png
7 7 RELEASE_VERSION="1.0.4"
8   -RELEASE_VERSION_ID="1004" # remember to change civsync.ua in sync.py:38
  8 +RELEASE_VERSION_ID="1005" # remember to change civsync.ua in sync.py:38
9 9 ANDROID_PATH="$HOME/apps/android-sdk-linux_x86/tools:$HOME/apps/android-ndk-r6b"
0  build.sh 100644 → 100755
File mode changed
2  lib/client/freeciv.py
@@ -68,7 +68,7 @@ def _callback(funname, *args):
68 68 else:
69 69 print 'no function named %s %s' % (name, args)
70 70 except:
71   - traceback.print_exc()
  71 + traceback.print_exc(limit=200)
72 72 print 'Abort.'
73 73 _end_callbacks()
74 74 if hard_exit:
7 lib/features.py
@@ -57,6 +57,9 @@ def parse_options():
57 57 args = sys.argv[1:]
58 58 unused = [sys.argv[0]]
59 59 for arg in args:
  60 + if arg == '-f:_list':
  61 + show_feature_list()
  62 + sys.exit(1)
60 63 if arg.startswith('-f:'):
61 64 arg = arg[len('-f:'):]
62 65 _parse_arg(arg)
@@ -64,6 +67,10 @@ def parse_options():
64 67 unused.append(arg)
65 68 sys.argv = unused
66 69
  70 +def show_feature_list():
  71 + for key in sorted(feature_types):
  72 + print '%s = [%s] %s' % (key.rjust(35), feature_types[key].__name__, str(features[key]).ljust(35))
  73 +
67 74 def _parse_arg(arg):
68 75 if '=' in arg:
69 76 key, val = arg.split('=', 1)
59 lib/main.py
@@ -35,12 +35,10 @@
35 35 import features
36 36 import monitor
37 37 import options
  38 +import menus
38 39
39 40 from sync import lzma
40 41
41   -def new_game():
42   - save.new_game()
43   -
44 42 features.add_feature('app.debug', default=True, type=bool)
45 43 features.add_feature('app.autoupdate', default=True, type=bool)
46 44 features.add_feature('app.forcesize')
@@ -60,24 +58,31 @@ def apply_hardexit(t):
60 58 pause_file = os.path.join(save.get_save_dir(), 'pause_options')
61 59
62 60 def client_main():
63   - action = sys.argv[1] if sys.argv[1:] else None
64 61 if try_resume():
65 62 ui.main()
66 63 return
67 64
  65 + ui.set(ui.Label('loading...'))
  66 + ui.execute_later.append(app_main)
  67 +
  68 + if features.get('app.profile'):
  69 + profile_main()
  70 + else:
  71 + ui.main()
  72 +
  73 +def app_main():
  74 + action = sys.argv[1] if sys.argv[1:] else None
  75 +
68 76 if action == 'load':
69 77 savename = sys.argv[2]
70 78 save.load_game(savename)
71 79 elif action == 'connect':
72 80 host, port = sys.argv[2:]
73 81 save.connect(host, int(port))
  82 + elif action == 'eval':
  83 + exec sys.argv[2]
74 84 else:
75   - show_main_menu()
76   -
77   - if features.get('app.profile'):
78   - profile_main()
79   - else:
80   - ui.main()
  85 + menus.main_menu()
81 86
82 87 def profile_main():
83 88 import cProfile
@@ -86,36 +91,18 @@ def profile_main():
86 91 p = pstats.Stats('profileout')
87 92 p.strip_dirs().sort_stats('time').print_stats()
88 93
89   -def show_main_menu():
90   - global main_menu
91   - main_menu = menu = ui.Menu()
92   -
93   - menu.add('New game', new_game)
94   - menu.add('Load game', save.load_dialog)
95   - menu.add('Feedback', feedback)
96   - menu.add('Options', options.show_options)
97   - if features.get('app.multiplayer'):
98   - menu.add('Connect', save.connect_dialog)
99   -
100   - ui.set(menu)
101   -
102   -def feedback():
103   - panel = ui.LinearLayoutWidget()
104   - panel.add(ui.Label('Leaving comments with logs will help me diagnose\npotential problems with game speed and\nunexpected behaviour.'))
105   - panel.add(ui.Button('Leave a comment with a log (preferred)', lambda: sync.comment(get_install_time(), True)))
106   - panel.add(ui.Button('Leave a comment without a log', lambda: sync.comment(get_install_time(), False)))
107   - ui.set(panel)
108   -
109 94 def start_autoupdate():
110 95 thread.start_new_thread(run_autoupdate, ())
111 96
112 97 def run_autoupdate():
113   - install_time = get_install_time()
  98 + install_time = sync.get_install_time()
114 99 try:
115 100 sync.client().updates(install_time)
116 101 except sync.civsync.UpdateRequiredError as err:
117 102 with ui.execute_later_lock:
118 103 ui.execute_later.append(lambda: notify_update(err.url))
  104 + except Exception as err:
  105 + print 'Failed to autoupdate:', err
119 106
120 107 def notify_update(url):
121 108 print 'update found at', url
@@ -164,16 +151,6 @@ def unpack_data():
164 151 os.remove('data.tgz')
165 152 progress.draw_frame('', 'starting...', 1)
166 153
167   -def get_install_time():
168   - path = os.path.join(save.get_save_dir(), 'install_time')
169   - try:
170   - return int(open(path).read())
171   - except (IOError, ValueError):
172   - install_time = int(time.time() * 1000)
173   - with open(path, 'w') as f:
174   - f.write('%d' % install_time)
175   - return install_time
176   -
177 154 def check_force_size():
178 155 if features.get('app.forcesize'):
179 156 return map(int, features.get('app.forcesize').split(','))
149 lib/menus.py
... ... @@ -0,0 +1,149 @@
  1 +# Copyright (C) 2011 Michal Zielinski (michal@zielinscy.org.pl)
  2 +#
  3 +# This program is free software; you can redistribute it and/or modify
  4 +# it under the terms of the GNU General Public License as published by
  5 +# the Free Software Foundation; either version 2, or (at your option)
  6 +# any later version.
  7 +#
  8 +# This program is distributed in the hope that it will be useful,
  9 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
  10 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11 +# GNU General Public License for more details.
  12 +
  13 +import ui
  14 +import pygame
  15 +
  16 +import sync
  17 +import save
  18 +import features
  19 +import options
  20 +
  21 +class SpacingLayoutWidget(ui.LayoutWidget):
  22 + def __init__(self, item1, item2, size):
  23 + ui.LayoutWidget.__init__(self)
  24 + self.item1 = item1
  25 + self.item2 = item2
  26 + self.items = (item1, item2)
  27 + self.size = (0,0)
  28 + self._asked_size = size
  29 +
  30 + def get_positions(self):
  31 + assert sum(map(lambda a:0 if a==0 else 1, self._asked_size)) == 1, 'exactly one value in tuple `size` should be zero'
  32 + is_horizontal = self._asked_size[1] == 0
  33 + if is_horizontal:
  34 + w = self._asked_size[0]
  35 + self.size = (w, max(self.item1.size[1], self.item2.size[1]))
  36 + yield (0, 0)
  37 + yield (w - self.item2.size[0], 0)
  38 + else:
  39 + h = self._asked_size[1]
  40 + self.size = (max(self.item1.size[0], self.item2.size[0]), h)
  41 + yield (0, 0)
  42 + yield (0, h - self.item2.size[1])
  43 +
  44 +def create_aligned_widget(widget, align, size=None):
  45 + if not size:
  46 + size = ui.screen_size
  47 + if align & ui.RIGHT:
  48 + widget = SpacingLayoutWidget(ui.Spacing(0,0), widget, (size[0], 0))
  49 + if align & ui.BOTTOM:
  50 + widget = SpacingLayoutWidget(ui.Spacing(0,0), widget, (0, size[1]))
  51 + return widget
  52 +
  53 +class PrettyMenu(ui.AbsoluteLayoutWidget):
  54 + def __init__(self):
  55 + ui.AbsoluteLayoutWidget.__init__(self)
  56 +
  57 + self.load_background()
  58 +
  59 + self.left = ui.HorizontalLayoutWidget(spacing=10)
  60 + self.left.add(ui.Spacing(0, 0))
  61 + self.right = ui.HorizontalLayoutWidget(spacing=10)
  62 + self.cont = SpacingLayoutWidget(self.left, self.right, (ui.screen_width, 0))
  63 + self.add(create_aligned_widget(self.cont, ui.BOTTOM, (0, ui.screen_height - 10)), (0,0))
  64 +
  65 + balloon_margin = 30
  66 +
  67 + def show_balloon(self, over, baloon):
  68 + self.update_layout()
  69 + baloon.update_layout()
  70 + pos = self.get_position_of(over)
  71 + self.add(baloon, (pos[0], pos[1] - baloon.size[1] - self.balloon_margin))
  72 +
  73 + def load_background(self):
  74 + img = ui.load_image('data/user/intro.jpg')
  75 + img_size = img.get_size()
  76 + surf_size = pygame.display.get_surface().get_size()
  77 + new_height = float(surf_size[0]) / img_size[0] * img_size[1]
  78 + self.background_margin_top = (new_height - surf_size[1]) / -2.5
  79 + self.background = pygame.transform.smoothscale(img, (surf_size[0], int(new_height)))
  80 +
  81 + def draw(self, surf, (x, y)):
  82 + surf.blit(self.background, (x, y + self.background_margin_top))
  83 + super(PrettyMenu, self).draw(surf, (x, y))
  84 +
  85 +class MenuButton(ui.Button):
  86 + active_bg = (255, 255, 200, 20)
  87 + bg = (150, 150, 50, 20)
  88 + fg = (150, 150, 50)
  89 +
  90 + def __init__(self, text, callback):
  91 + ui.Button.__init__(self, text, callback, force_width=100)
  92 +
  93 + def set_text(self, label):
  94 + if '\n' not in label:
  95 + label += '\n '
  96 + ui.Button.set_text(self, label)
  97 +
  98 +class Balloon(ui.AbsoluteLayoutWidget):
  99 + margin = 10
  100 +
  101 + def __init__(self):
  102 + ui.AbsoluteLayoutWidget.__init__(self)
  103 + self.content = ui.HorizontalLayoutWidget()
  104 + self.add(self.content, (self.margin, self.margin))
  105 +
  106 + def draw(self, surf, pos):
  107 + rect = pos + (self.content.size[0] + self.margin*2, self.content.size[1] + self.margin*2)
  108 + tpos = (pos[0] + 10, pos[1] + self.content.size[1] + self.margin*2 - 1)
  109 + tw = th = 18
  110 +
  111 + ui._round_rect(surf, (255,255,255,255), rect, 0, 10, 10)
  112 + pygame.gfxdraw.trigon(surf, tpos[0], tpos[1], tpos[0]+tw, tpos[1], tpos[0], tpos[1]+th, (255,255,255))
  113 + pygame.gfxdraw.filled_trigon(surf, tpos[0], tpos[1], tpos[0]+tw, tpos[1], tpos[0], tpos[1]+th, (255,255,255))
  114 + ui._round_rect(surf, (255,255,0,255), rect, 1, 10, 10)
  115 + ui.AbsoluteLayoutWidget.draw(self, surf, pos)
  116 +
  117 +class _D(ui.Label):
  118 + 'Label that prints its pos - for debugging'
  119 + def draw(self, surf, pos):
  120 + print pos, '(clip=%r)' % surf.get_clip()
  121 + ui.Label.draw(self, surf, pos)
  122 +
  123 +def main_menu():
  124 + menu = PrettyMenu()
  125 +
  126 + menu.left.add(MenuButton('New\ngame', save.new_game))
  127 + load_game_button = MenuButton('Load\ngame', save.load_dialog)
  128 + menu.left.add(load_game_button)
  129 + if features.get('app.multiplayer'):
  130 + menu.left.add(MenuButton('Connect', save.connect_dialog))
  131 +
  132 + menu.right.add(MenuButton('Feed\nback', feedback))
  133 + menu.right.add(MenuButton('Sett\nings', options.show_options))
  134 + menu.right.add(MenuButton('Exit', None))
  135 + menu.right.add(ui.Spacing(0, 0))
  136 +
  137 + #balloon = Balloon()
  138 + #balloon.content.add(ui.Label('hello'))
  139 + #menu.show_balloon(load_game_button, balloon)
  140 +
  141 + ui.replace(menu)
  142 +
  143 +
  144 +def feedback():
  145 + panel = ui.LinearLayoutWidget()
  146 + panel.add(ui.Label('Leaving comments with logs will help me diagnose\npotential problems with game speed and\nunexpected behaviour.'))
  147 + panel.add(ui.Button('Leave a comment with a log (preferred)', lambda: sync.comment(sync.get_install_time(), True)))
  148 + panel.add(ui.Button('Leave a comment without a log', lambda: sync.comment(sync.get_install_time(), False)))
  149 + ui.set(panel)
13 lib/sync.py
@@ -33,7 +33,7 @@ def apply_user_agent_change(ua):
33 33 civsync.USER_AGENT = ua
34 34
35 35 features.set_applier('civsync.ua', apply_user_agent_change)
36   -features.set('civsync.ua', 'CivSyncAndroid/1004')
  36 +features.set('civsync.ua', 'CivSyncAndroid/1005')
37 37 features.add_feature('civsync.enable', False, type=bool)
38 38
39 39 session = None
@@ -219,5 +219,14 @@ def sync_request(callback, name, args, kwargs):
219 219 with ui.execute_later_lock:
220 220 ui.execute_later.append(lambda: callback(result))
221 221
222   -#ui.execute_later.append()
  222 +
  223 +def get_install_time():
  224 + path = os.path.join(save.get_save_dir(), 'install_time')
  225 + try:
  226 + return int(open(path).read())
  227 + except (IOError, ValueError):
  228 + install_time = int(time.time() * 1000)
  229 + with open(path, 'w') as f:
  230 + f.write('%d' % install_time)
  231 + return install_time
223 232
25 lib/test_glue.py
... ... @@ -0,0 +1,25 @@
  1 +import sys, os
  2 +
  3 +sys.path.append(os.path.join(os.path.dirname(__file__), '../src'))
  4 +
  5 +import freecivclient
  6 +import glob
  7 +
  8 +def callback(funname, *args):
  9 + if funname == 'add_function':
  10 + name, i = args
  11 + functions[name] = i
  12 + return
  13 + if funname == 'set_const':
  14 + return
  15 + return (5,)
  16 +
  17 +def call(name, *args):
  18 + freecivclient.call_f(functions[name], args)
  19 +
  20 +functions = {}
  21 +
  22 +freecivclient.set_callback(callback)
  23 +
  24 +while True:
  25 + call('call_callback', 5)
49 lib/ui.py
@@ -33,13 +33,17 @@ def set_show_fps(val):
33 33 show_fps = val
34 34
35 35 features.set_applier('ui.showfps', set_show_fps, type=bool, default=False)
  36 +features.add_feature('ui.enable_anim', type=bool, default=True)
36 37
37 38 def replace(new_screen):
38 39 global screen
39 40 screen = new_screen
40 41
41 42 def replace_anim(new_screen, direction=1):
42   - replace(Animation(screen, new_screen, direction))
  43 + if features.get('ui.enable_anim'):
  44 + replace(Animation(screen, new_screen, direction))
  45 + else:
  46 + replace(new_screen)
43 47
44 48 def set(new_screen, anim=True):
45 49 if screen:
@@ -263,6 +267,17 @@ def event(self, event):
263 267 elif self.items:
264 268 self.items[0].event(event)
265 269
  270 + def get_position_of(self, item):
  271 + if item in self.items:
  272 + return self.positions[self.items.index(item)]
  273 + for child in self.items:
  274 + if hasattr(child, 'get_position_of'):
  275 + child_pos = self.positions[self.items.index(child)]
  276 + rel_pos = child.get_position_of(item)
  277 + if rel_pos:
  278 + return rel_pos[0] + child_pos[0], rel_pos[1] + child_pos[1]
  279 + return None
  280 +
266 281 def get_items_at(self, evpos, yield_this=None):
267 282 if yield_this:
268 283 yield yield_this
@@ -626,6 +641,7 @@ def gfx_rect(surf, color, rect, width):
626 641
627 642 def _round_rect(surface, color, rect, width, xr, yr):
628 643 clip = surface.get_clip()
  644 + rect = pygame.Rect(rect)
629 645
630 646 # left and right
631 647 surface.set_clip(clip.clip(rect.inflate(0, 5-yr*2)))
@@ -635,26 +651,26 @@ def _round_rect(surface, color, rect, width, xr, yr):
635 651 surface.set_clip(clip.clip(rect.inflate(5-xr*2, 0)))
636 652 if width != 0:
637 653 gfx_rect(surface, color, rect.inflate(0, 1-width), width)
638   - else:
  654 + else: # fill
639 655 x, y, w, h = rect
640   - gfx_rect(surface, color, (x, y, w, yr - 2), width)
641   - gfx_rect(surface, color, (x, y + h - yr + 1, w, yr - 1), width)
  656 + gfx_rect(surface, color, (x, y, w, yr - 3), width)
  657 + gfx_rect(surface, color, (x, y + h - yr + 2, w, yr - 1), width)
642 658
643 659 # top left corner
644   - surface.set_clip(clip.clip(rect.left, rect.top, xr, yr))
  660 + surface.set_clip(clip.clip(rect.left, rect.top, xr-3, yr-3))
645 661 gfx_ellipse(surface, color, pygame.Rect(rect.left, rect.top, 2*xr, 2*yr), width)
646 662
647 663 # top right corner
648   - surface.set_clip(clip.clip(rect.right-xr, rect.top, xr, yr))
  664 + surface.set_clip(clip.clip(rect.right-xr+2, rect.top, xr, yr-3))
649 665 gfx_ellipse(surface, color, pygame.Rect(rect.right-2*xr, rect.top, 2*xr, 2*yr), width)
650 666
651 667 # bottom left
652   - surface.set_clip(clip.clip(rect.left, rect.bottom-yr, xr, yr))
  668 + surface.set_clip(clip.clip(rect.left, rect.bottom-yr+2, xr-3, yr))
653 669 gfx_ellipse(surface, color, pygame.Rect(rect.left, rect.bottom-2*yr, 2*xr, 2*yr), width)
654 670
655 671 # bottom right
656   - surface.set_clip(clip.clip(rect.right-xr, rect.bottom-yr, xr, yr))
657   - gfx_ellipse(surface, color, pygame.Rect(rect.right-2*xr, rect.bottom-2*yr, 2*xr, 2*yr), width)
  672 + surface.set_clip(clip.clip(rect.right-xr+2, rect.bottom-yr+2, xr, yr))
  673 + gfx_ellipse(surface, color, pygame.Rect(rect.right-2*xr-1, rect.bottom-2*yr-1, 2*xr, 2*yr), width)
658 674
659 675 surface.set_clip(clip)
660 676
@@ -664,16 +680,20 @@ def round_rect(surf, bg, fg, rect, round=10):
664 680 _round_rect(surf, fg, rect, 1, round, round)
665 681
666 682 class Button(WithText):
667   - def __init__(self, label, callback, font=None, color=None, force_width=None):
  683 + active_bg = (255, 255, 200, 150)
  684 + bg = (130, 100, 0, 90)
  685 + fg = (150, 150, 50)
  686 +
  687 + def __init__(self, label, callback, font=None, color=None, force_width=None, force_height=None):
668 688 WithText.__init__(self, label, callback, font, color, padding=4, force_width=force_width)
669 689 self.active = False
670 690
671 691 def draw(self, surf, pos):
672 692 if self.active:
673   - color = (255, 255, 200, 20)
  693 + color = self.active_bg
674 694 else:
675   - color = (150, 150, 50, 20)
676   - round_rect(surf, color, (150, 150, 50), pos + self.size)
  695 + color = self.bg
  696 + round_rect(surf, color, self.fg, pos + self.size)
677 697 WithText.draw(self, surf, pos)
678 698
679 699 def unhover(self):
@@ -775,6 +795,9 @@ def yes():
775 795 def load_font(name, size):
776 796 return pygame.font.Font('fonts/ProcionoTT.ttf', size)
777 797
  798 +def load_image(name):
  799 + return pygame.image.load(name).convert_alpha()
  800 +
778 801 def init():
779 802 global font, smallfont, bigfont, mediumfont, consolefont
780 803 pygame.init()

0 comments on commit 3b2ff9d

Please sign in to comment.
Something went wrong with that request. Please try again.