Package: jumpnbump Version: 1.60-3 Severity: wishlist Dear Maintainer,
the current version of jumpnbump-menu is written in python2 and use gtk2. Python2 will be in end of life in 2020 by the upstream. gtk2 will be removed in one or two releases. This is a draft (in attachments) for updating jumpnbump-menu to python3 and gtk3. The standalone mode and the options work, but there are still some problems: - server and client modes are not correctly selected - the windows are not translated - the about windows has a strange behavior when requested to close. I don't have currently the time to work on it but I plan to do it in the future. Stéphane
jumpnbump.glade
Description: application/glade
#!/usr/bin/python3 # Copyright (C) 2002 Martin Willemoes Hansen <m...@sysrq.dk> # Copyright (C) 2018 Stéphane Blondon # # Jump 'n Bump is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # Jump 'n Bump is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # Next two lines are a workaround for Debian bug 163794 import sys import gi gi.require_version("Gtk", "3.0") from gi.repository import Gtk from gi.repository import GObject import os import tempfile import shutil import gettext RESOURCE_DIR = '/usr/share/games/jumpnbump' BINARY_DIR = '/usr/games' UNPACK_BIN = '/usr/games/jnbunpack' application = "jumpnbump-menu" gettext.install(application) def populate_treeview(): levels = [] add_levels(levels, RESOURCE_DIR) add_levels(levels, os.path.expanduser("~/.jumpnbump/levels")) levels = sorted(levels, key=lambda level: level[0]) COLUMN_LEVEL = 0 COLUMN_DIR = 1 store = Gtk.ListStore(GObject.TYPE_STRING, GObject.TYPE_STRING) for level in levels: iter = store.append() store.set(iter, COLUMN_LEVEL, level[0], COLUMN_DIR, level[1]) treeview.set_model(store) renderer = Gtk.CellRendererText() treeview.append_column(Gtk.TreeViewColumn( _('Level'), renderer, text=COLUMN_LEVEL)) def add_levels(levels, dir): try: for file in os.listdir(dir): if (file.endswith('.dat') or file.endswith('.DAT')): levels.append((file, dir)) except OSError as err: print("%s not found (%s)." % (dir, str(err))) def standalone_mode(widget): disable_enable_level(1) disable_enable_server(0) num_clients.set_sensitive(0) nogore.set_sensitive(1) noflies.set_sensitive(1) def client_mode(widget): disable_enable_level(1) disable_enable_server(1) num_clients.set_sensitive(0) nogore.set_sensitive(1) noflies.set_sensitive(1) def server_mode(widget): disable_enable_level(1) disable_enable_server(0) num_clients.set_sensitive(1) nogore.set_sensitive(1) noflies.set_sensitive(1) def disable_enable_server(setting): server_entry.set_sensitive(setting) player_num.set_sensitive(setting) def disable_enable_level(setting): treeview.set_sensitive(setting) mirror.set_sensitive(setting) if (not setting): mirror.set_active(setting) def level_changed(widget): model, iter = treeview.get_selection().get_selected() global choosen_level choosen_level = '%s/%s' % (model.get_value(iter, 1), model.get_value(iter, 0)) unpackdir = None try: unpackdir = tempfile.mkdtemp("", "jumpnbump-menu-") os.chdir(unpackdir) os.spawnlp(os.P_WAIT, UNPACK_BIN, 'unpack', choosen_level) os.spawnlp(os.P_WAIT, 'convert', 'convert', '-scale', '50%', 'level.pcx', 'level_scaled.pcx') os.spawnlp(os.P_WAIT, 'convert', 'convert', 'level_scaled.pcx', 'level.png') image.set_from_file('level.png') except Exception as err: print(err) finally: if unpackdir != None: shutil.rmtree(unpackdir) image.show() def about(widget): global about_dialog if (not about_dialog): #gui = Gtk.glade.XML(gladefile, 'about', domain=application) #about_dialog = gui.get_widget('about') #gui.signal_connect('ok', about_close) gui = _get_builder() about_dialog = gui.get_object('about') about_dialog.show_all() gui.connect_signals({'ok': about_close}) def about_close(widget): global about_dialog about_dialog.destroy() about_dialog = None def run(widget): if (standalone.get_active()): execute(*get_level() + common_options()) elif (client.get_active()): execute('-player', str(player_num.get_value_as_int()), '-connect', server_entry.get_text(), *get_level() + common_options()) else: execute('-server', str(num_clients.get_value_as_int()), *get_level() + common_options()) def get_level(): level = [] if (mirror.get_active()): level.append('-mirror') else: level.append('-dat') level.append(choosen_level) return level def common_options(): options = [] if (fullscreen.get_active()): options.append('-fullscreen') if (nogore.get_active()): options.append('-nogore') if (double_res.get_active()): options.append('-scaleup') if (nosound.get_active()): options.append('-nosound') if (noflies.get_active()): options.append('-noflies') if (withmusic.get_active()): options.append('-musicnosound') if (mirror.get_active()): options.append('-mirror') return options def execute(*cmd): try: os.spawnl(os.P_NOWAIT, BINARY_DIR + '/jumpnbump', 'jumpnbump', *cmd) except Exception as err: print(err) def _get_builder(): global gladefile global_gladefile = RESOURCE_DIR + '/jumpnbump_menu.glade' local_gladefile = './jumpnbump_menu.glade' #if (os.access(global_gladefile, os.R_OK)): # gladefile = global_gladefile # del local_gladefile #elif (os.access(local_gladefile, os.R_OK)): # gladefile = local_gladefile # del global_gladefile #else: # print('Could not find the glade file') # return 0 #gui = Gtk.glade.XML(gladefile, 'main', domain=application) gui = Gtk.Builder() gladefile = local_gladefile gui.add_from_file(gladefile) return gui def main(): gui = _get_builder() global about_dialog, choosen_level, standalone, client, server, treeview, \ mirror, num_clients, server_entry, player_num, fullscreen, \ nogore, double_res, nosound, noflies, withmusic, image about_dialog = None choosen_level = '' standalone = gui.get_object('standalone') client = gui.get_object('client') server = gui.get_object('server') treeview = gui.get_object('level_treeview') populate_treeview() mirror = gui.get_object('mirror') num_clients = gui.get_object('num_of_clients') server_entry = gui.get_object('server_entry') player_num = gui.get_object('player_num') fullscreen = gui.get_object('fullscreen') nogore = gui.get_object('nogore') double_res = gui.get_object('double_res') nosound = gui.get_object('nosound') noflies = gui.get_object('noflies') withmusic = gui.get_object('withmusic') image = gui.get_object('image') #gui.signal_autoconnect({'standalone_mode': standalone_mode, # 'client_mode': client_mode, # 'server_mode': server_mode, # 'level_changed': level_changed, # 'quit': lambda *args: Gtk.main_quit(), # 'run': run, # 'about': about}) gui.connect_signals({'standalone_mode': standalone_mode, 'client_mode': client_mode, 'server_mode': server_mode, 'level_changed': level_changed, 'quit': Gtk.main_quit, 'run': run, 'about': about, }) Gtk.main() if __name__ == '__main__': main()