Bug#895858: jumpnbump: update jumpnbump-menu to gtk3 will be required in the future

Stéphane Blondon stephane.blondon at gmail.com
Mon Apr 16 23:32:19 BST 2018


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
-------------- next part --------------
A non-text attachment was scrubbed...
Name: jumpnbump.glade
Type: application/x-glade
Size: 33437 bytes
Desc: not available
URL: <http://alioth-lists.debian.net/pipermail/pkg-games-devel/attachments/20180417/48d5bd29/attachment-0001.bin>
-------------- next part --------------
#!/usr/bin/python3

# Copyright (C) 2002 Martin Willemoes Hansen <mwh at 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()


More information about the Pkg-games-devel mailing list