class Checkbox(RPObject):
    """ This is a wrapper around DirectCheckBox, providing a simpler interface
    and better visuals """
    def __init__(self,
                 parent=None,
                 x=0,
                 y=0,
                 callback=None,
                 extra_args=None,
                 radio=False,
                 expand_width=100,
                 checked=False,
                 enabled=True):
        RPObject.__init__(self)

        prefix = "checkbox" if not radio else "radiobox"

        if enabled:
            checked_img = RPLoader.load_texture("/$$rp/data/gui/" + prefix +
                                                "_checked.png")
            unchecked_img = RPLoader.load_texture("/$$rp/data/gui/" + prefix +
                                                  "_default.png")
        else:
            checked_img = RPLoader.load_texture("/$$rp/data/gui/" + prefix +
                                                "_disabled.png")
            unchecked_img = checked_img

        # Set near filter, otherwise textures look like crap
        for tex in [checked_img, unchecked_img]:
            tex.set_minfilter(SamplerState.FT_linear)
            tex.set_magfilter(SamplerState.FT_linear)
            tex.set_wrap_u(SamplerState.WM_clamp)
            tex.set_wrap_v(SamplerState.WM_clamp)
            tex.set_anisotropic_degree(0)

        self._node = DirectCheckBox(parent=parent,
                                    pos=(x + 11, 1, -y - 8),
                                    scale=(10 / 2.0, 1, 10 / 2.0),
                                    checkedImage=checked_img,
                                    uncheckedImage=unchecked_img,
                                    image=unchecked_img,
                                    extraArgs=extra_args,
                                    state=DGG.NORMAL,
                                    relief=DGG.FLAT,
                                    command=self._update_status)

        self._node["frameColor"] = (0, 0, 0, 0)
        self._node["frameSize"] = (-2.6, 2 + expand_width / 7.5, -2.35, 2.5)
        self._node.set_transparency(TransparencyAttrib.M_alpha)

        self._callback = callback
        self._extra_args = extra_args
        self._collection = None

        if checked:
            self.set_checked(True, False)

    @property
    def collection(self):
        """ Returns a handle to the assigned checkbox collection, or None
        if no collection was assigned """
        return self._collection

    @collection.setter
    def collection(self, coll):
        """ Internal method to add a checkbox to a checkbox collection, this
        is used for radio-buttons """
        self._collection = coll

    @property
    def checked(self):
        """ Returns whether the node is currently checked """
        return self._node["isChecked"]

    @property
    def node(self):
        """ Returns a handle to the internally used node """
        return self._node

    def _update_status(self, status):
        """ Internal method when another checkbox in the same radio group
        changed it's value """

        if not status and self._collection:
            self._node.commandFunc(None)
            return

        if self._collection:
            if status:
                self._collection.on_checkbox_changed(self)
                # A radio box can't be unchecked
                # self._node["state"] = DGG.DISABLED

        if self._callback is not None:
            self._callback(*([status] + self._extra_args))

    def set_checked(self, val, do_callback=True):
        """ Internal method to check/uncheck the checkbox """
        self._node["isChecked"] = val

        if val:
            self._node["image"] = self._node["checkedImage"]
        else:
            self._node["image"] = self._node["uncheckedImage"]

        if do_callback and self._callback is not None:
            self._callback(*([val] + self._extra_args))
Example #2
0
class MainMenu(DirectObject):
    """This class represents the main menu as seen directly after the
    application has been started"""
    def __init__(self):

        # loading music
        self.menuMusic = loader.loadMusic("music/01Menu.mp3")
        self.menuMusic.setLoop(True)

        # create a main frame as big as the window
        self.frameMain = DirectFrame(
            # set framesize the same size as the window
            frameSize = (base.a2dLeft, base.a2dRight,
                         base.a2dTop, base.a2dBottom),
            # position center
            pos = (0, 0, 0),
            # set tramsparent background color
            frameColor = (0.15, 0.15, 0.15, 1))
        #self.frameMain.reparentTo(render2d)

        self.menuBackground = OnscreenImage(
            image = 'gui/Background.png',
            scale = (1.66, 1, 1),
            pos = (0, 0, 0))
        self.menuBackground.reparentTo(self.frameMain)

        self.defaultBtnMap = base.loader.loadModel("gui/button_map")
        self.buttonGeom = (
            self.defaultBtnMap.find("**/button_ready"),
            self.defaultBtnMap.find("**/button_click"),
            self.defaultBtnMap.find("**/button_rollover"),
            self.defaultBtnMap.find("**/button_disabled"))
        self.defaultTxtMap = base.loader.loadModel("gui/textbox_map")
        self.textboxGeom = self.defaultTxtMap.find("**/textbox")

        monospace = loader.loadFont('gui/DejaVuSansMono.ttf')
        defaultFont = loader.loadFont('gui/eufm10.ttf')

        # create the title
        self.textscale = 0.25
        self.title = DirectLabel(
            # scale and position
            scale = self.textscale,
            pos = (0.0, 0.0, base.a2dTop - self.textscale),
            # frame
            frameColor = (0, 0, 0, 0),
            # Text
            text = "Dungeon Crawler",
            text_align = TextNode.ACenter,
            text_fg = (0.82,0.85,0.87,1),
            text_shadow = (0, 0, 0, 1),
            text_shadowOffset = (-0.02, -0.02),
            text_font = defaultFont)
        self.title.setTransparency(1)
        self.title.reparentTo(self.frameMain)

        # create a host button
        self.btnHostPos = Vec3(0, 0, .45)
        self.btnHostScale = 0.25
        self.btnHost = DirectButton(
            # Scale and position
            scale = self.btnHostScale,
            pos = self.btnHostPos,
            # Text
            text = "Host",
            text_scale = 0.8,
            text_pos = (0, -0.2),
            text_fg = (0.82,0.85,0.87,1),
            text_shadow = (0, 0, 0, 1),
            text_shadowOffset = (-0.02, -0.02),
            text_font = defaultFont,
            # Frame
            geom = self.buttonGeom,
            frameColor = (0, 0, 0, 0),
            relief = 0,
            pressEffect = False,
            # Functionality
            command = self.host,
            rolloverSound = None,
            clickSound = None)
        self.btnHost.setTransparency(1)
        self.btnHost.reparentTo(self.frameMain)

        # create a join button
        self.btnJoinPos = Vec3(0, 0, 0)
        self.btnJoinScale = 0.25
        self.btnJoin = DirectButton(
            scale = self.btnJoinScale,
            pos = self.btnJoinPos,
            text = "Join",
            text_scale = 0.8,
            text_pos = (0, -0.2),
            text_fg = (0.82,0.85,0.87,1),
            text_shadow = (0, 0, 0, 1),
            text_shadowOffset = (-0.02, -0.02),
            text_font = defaultFont,
            geom = self.buttonGeom,
            frameColor = (0, 0, 0, 0),
            relief = 0,
            pressEffect = False,
            command = self.join,
            rolloverSound = None,
            clickSound = None)
        self.btnJoin.setTransparency(1)
        self.btnJoin.reparentTo(self.frameMain)

        # create the IP input field
        self.txtIPPos = Vec3(0, 0, -.30)
        self.txtIPScale = 0.25
        self.txtIPWidth = 9
        self.txtIP = DirectEntry(
            # scale and position
            pos = self.txtIPPos,
            scale = self.txtIPScale,
            width = self.txtIPWidth,
            # Text
            entryFont = monospace,
            text_align = TextNode.ACenter,
            text = "",
            text_scale = 0.5,
            text_pos = (0, -0.2),
            text_fg = (0.82,0.85,0.87,1),
            text_shadow = (0, 0, 0, 1),
            text_shadowOffset = (0.04, 0.04),
            initialText = "127.0.0.1",
            numLines = 1,
            # Frame
            geom = self.textboxGeom,
            frameColor = (0, 0, 0, 0),
            relief = 0,
            # Functionality
            command = self.join,
            focusInCommand = self.clearText)
        self.txtIP.reparentTo(self.frameMain)

        # create an exit button
        self.btnExitPos = Vec3(0, 0, -.75)
        self.btnExitScale = 0.25
        self.btnExit = DirectButton(
            scale = self.btnExitScale,
            pos = self.btnExitPos,
            text = "Exit",
            text_scale = 0.8,
            text_pos = (0, -0.2),
            text_fg = (0.82,0.85,0.87,1),
            text_shadow = (0, 0, 0, 1),
            text_shadowOffset = (-0.02, -0.02),
            text_font = defaultFont,
            geom = self.buttonGeom,
            frameColor = (0, 0, 0, 0),
            relief = 0,
            pressEffect = False,
            command = lambda: base.messenger.send("escape"),
            rolloverSound = None,
            clickSound = None)
        self.btnExit.setTransparency(1)
        self.btnExit.reparentTo(self.frameMain)

        # create a mute checkbox
        self.cbVolumeMute = DirectCheckBox(
            # set size
            scale = (0.1, 0.1, 0.1),
            frameSize = (-1, 1, 1, -1),
            # functionality and visuals
            command = self.cbVolumeMute_CheckedChanged,
            isChecked = True,
            checkedImage = "gui/SoundSwitch_off.png",
            uncheckedImage = "gui/SoundSwitch_on.png",
            # mouse behaviour
            relief = 0,
            pressEffect = False,
            rolloverSound = None,
            clickSound = None
            )
        self.cbVolumeMute.setTransparency(1)
        self.cbVolumeMute.reparentTo(self.frameMain)
        self.cbVolumeMute.commandFunc(None)

        # catch window resizes and recalculate the aspectration
        self.accept("window-event", self.recalcAspectRatio)
        self.accept("showerror", self.showError)

        # show the menu right away
        self.show()

    def host(self):
        """Function which will be called by pressing the host button"""
        self.hide()
        base.messenger.send("start_server")

    def join(self, ip=None):
        """Function which will be called by pressing the join button"""
        if ip == None: ip = self.txtIP.get(True)
        if ip == "": return
        self.hide()
        base.messenger.send("start_client", [ip])

    def showError(self, msg):
        self.show()
        self.dialog = OkDialog(
            dialogName="ErrorDialog",
            text="Error: {}".format(msg),
            command=self.closeDialog)

    def closeDialog(self, args):
        self.dialog.hide()

    def show(self):
        """Show the GUI"""
        self.frameMain.show()
        self.menuMusic.play()

    def hide(self):
        """Hide the GUI"""
        self.frameMain.hide()
        self.menuMusic.stop()

    def clearText(self):
        """Function to clear the text that was previously entered in the
        IP input field"""
        self.txtIP.enterText("")

    def cbVolumeMute_CheckedChanged(self, checked):
        if bool(checked):
            base.disableAllAudio()
        else:
            base.enableAllAudio()

    def recalcAspectRatio(self, window):
        """get the new aspect ratio to resize the mainframe"""
        # set the mainframe size to the window borders again
        self.frameMain["frameSize"] = (
            base.a2dLeft, base.a2dRight,
            base.a2dTop, base.a2dBottom)

        # calculate new aspec tratio
        wp = window.getProperties()
        aspX = 1.0
        aspY = 1.0
        wpXSize = wp.getXSize()
        wpYSize = wp.getYSize()
        if wpXSize > wpYSize:
            aspX = wpXSize / float(wpYSize)
        else:
            aspY = wpYSize / float(wpXSize)
        # calculate new position/size/whatever of the gui items
        self.title.setPos(0.0, 0.0, base.a2dTop - self.textscale)
        self.menuBackground.setScale(1.0 * aspX, 1.0, 1.0 * aspY)
        self.cbVolumeMute.setPos(base.a2dRight - 0.15, 0, base.a2dBottom + 0.15)
Example #3
0
class Checkbox(RPObject):

    """ This is a wrapper around DirectCheckBox, providing a simpler interface
    and better visuals """

    def __init__(self, parent=None, x=0, y=0, callback=None, extra_args=None,
                 radio=False, expand_width=100, checked=False, enabled=True):
        RPObject.__init__(self)

        prefix = "checkbox" if not radio else "radiobox"

        if enabled:
            checked_img = RPLoader.load_texture(
                "/$$rp/data/gui/" + prefix + "_checked.png")
            unchecked_img = RPLoader.load_texture(
                "/$$rp/data/gui/" + prefix + "_default.png")
        else:
            checked_img = RPLoader.load_texture(
                "/$$rp/data/gui/" + prefix + "_disabled.png")
            unchecked_img = checked_img

        # Set near filter, otherwise textures look like crap
        for tex in [checked_img, unchecked_img]:
            tex.set_minfilter(SamplerState.FT_linear)
            tex.set_magfilter(SamplerState.FT_linear)
            tex.set_wrap_u(SamplerState.WM_clamp)
            tex.set_wrap_v(SamplerState.WM_clamp)
            tex.set_anisotropic_degree(0)

        self._node = DirectCheckBox(
            parent=parent, pos=(x + 11, 1, -y - 8), scale=(10 / 2.0, 1, 10 / 2.0),
            checkedImage=checked_img, uncheckedImage=unchecked_img,
            image=unchecked_img, extraArgs=extra_args, state=DGG.NORMAL,
            relief=DGG.FLAT, command=self._update_status)

        self._node["frameColor"] = (0, 0, 0, 0)
        self._node["frameSize"] = (-2.6, 2 + expand_width / 7.5, -2.35, 2.5)
        self._node.set_transparency(TransparencyAttrib.M_alpha)

        self._callback = callback
        self._extra_args = extra_args
        self._collection = None

        if checked:
            self.set_checked(True, False)

    @property
    def collection(self):
        """ Returns a handle to the assigned checkbox collection, or None
        if no collection was assigned """
        return self._collection

    @collection.setter
    def collection(self, coll):
        """ Internal method to add a checkbox to a checkbox collection, this
        is used for radio-buttons """
        self._collection = coll

    @property
    def checked(self):
        """ Returns whether the node is currently checked """
        return self._node["isChecked"]

    @property
    def node(self):
        """ Returns a handle to the internally used node """
        return self._node

    def _update_status(self, status):
        """ Internal method when another checkbox in the same radio group
        changed it's value """

        if not status and self._collection:
            self._node.commandFunc(None)
            return

        if self._collection:
            if status:
                self._collection.on_checkbox_changed(self)
                # A radio box can't be unchecked
                # self._node["state"] = DGG.DISABLED

        if self._callback is not None:
            self._callback(*([status] + self._extra_args))

    def set_checked(self, val, do_callback=True):
        """ Internal method to check/uncheck the checkbox """
        self._node["isChecked"] = val

        if val:
            self._node["image"] = self._node["checkedImage"]
        else:
            self._node["image"] = self._node["uncheckedImage"]

        if do_callback and self._callback is not None:
            self._callback(*([val] + self._extra_args))
Example #4
0
class MenuOptions(Menu):

    def __init__(self, _engine):
        """
        This function will initialise the main screen of the options
        and prepare the tabs with the various settings
        """
        Menu.__init__(self)

        # Engine
        self.engine = _engine

        self.initGeneralTab()
        self.initControlTab()

        self.currentTab = [0]

        self.tabGroup = [
            DirectRadioButton(
                text = _("General"),
                variable = self.currentTab,
                value = [0],
                scale = 0.05,
                pos = (-0.6, 0, 0.65),
                command = self.showGeneralTab),
            DirectRadioButton(
                text = _("Controls"),
                variable = self.currentTab,
                value = [1],
                scale = 0.05,
                pos = (0.6, 0, 0.65),
                command = self.showControlTab)
            ]

        for tab in self.tabGroup:
            tab.reparentTo(self.frameMain)
            tab.setOthers(self.tabGroup)

        # set the text of all GUI elements
        self.setText()

        self.hideBase()

    def initGeneralTab(self):
        """
        This function will set up the content of the
        general tab
        """
        self.frameGeneral = DirectFrame(
            # size of the frame
            frameSize = (base.a2dLeft, base.a2dRight,
                         -0.6, 0.6),
            # position of the frame
            pos = (0, 0, 0),
            # tramsparent bg color
            frameColor = (0, 0, 0, 0.5))

        yPos = 0.45
        shiftY = 0.25

        self.lblLanguage = DirectLabel(
            text = _("Language"),
            scale = 0.15,
            pos = (base.a2dLeft + 0.25, 0, yPos),
            frameColor = (0,0,0,0),
            text_fg = (1,1,1,1),
            #text_font = self.defaultFont,
            text_align = TextNode.ALeft)

        self.cmbLanguage = DirectOptionMenu(
            text = "languages",
            scale = 0.15,
            pos = (base.a2dRight - 1.5, 0, 0.45),
            items = ["Deutsch","English","русский", "français"],
            initialitem = 0,
            highlightColor = (0.65,0.65,0.65,1),
            #text_font = self.defaultFontRegular,
            #item_text_font = self.defaultFontRegular,
            command = self.cmbLanguage_SelectionChanged)

        yPos -= shiftY

        self.lblResolution = DirectLabel(
            text = _("Screen resolution"),
            scale = 0.15,
            pos = (base.a2dLeft + 0.25, 0, yPos),
            frameColor = (0,0,0,0),
            text_fg = (1,1,1,1),
            #text_font = self.defaultFont,
            text_align = TextNode.ALeft)

        # get the display resolutions
        di = base.pipe.getDisplayInformation()
        sizes = []
        for index in range(di.getTotalDisplayModes()):
            tmptext = "{0}x{1}".format(
                di.getDisplayModeWidth(index),
                di.getDisplayModeHeight(index))
            if not tmptext in sizes:
                sizes.append(tmptext)

        self.cmbResolution = DirectOptionMenu(
            text = "resolutions",
            scale = 0.15,
            pos = (base.a2dRight - 1.5, 0, yPos),
            items = sizes,
            initialitem = 0,
            highlightColor = (0.65, 0.65, 0.65, 1),
            #text_font = self.defaultFontRegular,
            #item_text_font = self.defaultFontRegular,
            command = self.cmbResolution_SelectionChanged)

        yPos -= shiftY

        self.lblGraphicQuality = DirectLabel(
            text = _("Graphic quality"),
            scale = 0.15,
            pos = (base.a2dLeft + 0.25, 0, yPos),
            frameColor = (0,0,0,0),
            text_fg = (1,1,1,1),
            #text_font = self.defaultFont,
            text_align = TextNode.ALeft)

        self.graphicqualityTextMap = {
            0:_("Low"),
            1:_("Medium"),
            2:_("High")}
        self.sliderGraphicQuality = DirectSlider(
            scale = 0.5,
            pos = (base.a2dRight - 1, 0, yPos + 0.05),
            range = (0,2),
            scrollSize = 1,
            text = self.graphicqualityTextMap[self.engine.settings.graphicquality],
            text_scale = 0.25,
            text_align = TextNode.ALeft,
            text_pos = (1.1, -0.1),
            text_fg = (1,1,1,1),
            #text_font = self.defaultFont,
            value = self.engine.settings.graphicquality,
            command = self.sliderGraphicQuality_ValueChanged)

        yPos -= shiftY

        self.lblVolume = DirectLabel(
            text = _("Volume"),
            scale = 0.15,
            pos = (base.a2dLeft + 0.25, 0, yPos),
            frameColor = (0,0,0,0),
            text_fg = (1,1,1,1),
            #text_font = self.defaultFont,
            text_align = TextNode.ALeft)

        self.sliderVolume = DirectSlider(
            scale = 0.5,
            pos = (base.a2dRight - 1, 0, yPos + 0.05),
            range = (0,1),
            scrollSize = 0.01,
            text = str(int(self.engine.settings.volume * 100)) + "%",
            text_scale = 0.25,
            text_align = TextNode.ALeft,
            text_pos = (1.1, -0.1),
            text_fg = (1,1,1,1),
            #text_font = self.defaultFont,
            value = self.engine.settings.volume,
            command = self.sliderVolume_ValueChanged)

        yPos -= shiftY

        self.lblVolumeMute = DirectLabel(
            text = _("Mute"),
            scale = 0.15,
            pos = (base.a2dLeft + 0.25, 0, yPos),
            frameColor = (0,0,0,0),
            text_fg = (1,1,1,1),
            #text_font = self.defaultFont,
            text_align = TextNode.ALeft)

        self.cbVolumeMute = DirectCheckBox(
            text = "X",
            pos = (base.a2dRight - 1, 0, yPos),
            scale = (0.25, 0.25, 0.25),
            command = self.cbVolumeMute_CheckedChanged,
            rolloverSound = None,
            clickSound = None,
            relief = 0,
            pressEffect = False,
            #frameColor = (0,0,0,0),
            checkedImage = "gui/buttons/options/SoundSwitch_off.png",
            uncheckedImage = "gui/buttons/options/SoundSwitch_on.png"
            )
        self.cbVolumeMute.setTransparency(1)
        self.cbVolumeMute.setImage()
        self.cbVolumeMute["image_scale"] = 0.25
        self.cbVolumeMute["text"] = ""

        self.createBackButton(self.btnBack_Click)

        self.lblLanguage.reparentTo(self.frameGeneral)
        self.cmbLanguage.reparentTo(self.frameGeneral)
        self.lblResolution.reparentTo(self.frameGeneral)
        self.cmbResolution.reparentTo(self.frameGeneral)
        self.lblGraphicQuality.reparentTo(self.frameGeneral)
        self.sliderGraphicQuality.reparentTo(self.frameGeneral)
        self.lblVolume.reparentTo(self.frameGeneral)
        self.sliderVolume.reparentTo(self.frameGeneral)
        self.lblVolumeMute.reparentTo(self.frameGeneral)
        self.cbVolumeMute.reparentTo(self.frameGeneral)

        self.frameGeneral.reparentTo(self.frameMain)

        self.accept("LanguageChanged", self.setText)

    def initControlTab(self):
        """
        This function will set up the content of the
        control tab
        """
        self.frameControl = DirectFrame(
            # size of the frame
            frameSize = (base.a2dLeft, base.a2dRight,
                         -0.6, 0.6),
            # position of the frame
            pos = (0, 0, 0),
            # tramsparent bg color
            frameColor = (0, 0, 0, 0.5))

        numItemsVisible = 9
        itemHeight = 0.10

        # the list field for the keyboard maping to the actions
        self.controlsList = DirectScrolledList(
            decButton_pos= (0, 0, -0.05),
            decButton_text = _("up"),
            decButton_text_scale = 0.04,
            decButton_borderWidth = (0.005, 0.005),

            incButton_pos= (0, 0, -1.05),
            incButton_text = _("down"),
            incButton_text_scale = 0.04,
            incButton_borderWidth = (0.005, 0.005),

            frameSize = (-1, 1, -1.1, 0.0),
            frameColor = (0,0,0,0.5),
            pos = (0, 0, 0.6),
            numItemsVisible = numItemsVisible,
            forceHeight = itemHeight,
            itemFrame_frameSize = (-0.9, 0.9, -0.9, 0),
            itemFrame_pos = (0, 0, -0.1),
            )

        self.fillControlsList()

        self.controlsList.reparentTo(self.frameControl)
        self.frameControl.reparentTo(self.frameMain)

    def fillControlsList(self):
        for key, value in sorted(self.engine.settings.playerKeys.items()):
            # the base frame of any item in the list
            itemFrame = DirectFrame(
                frameSize = (-0.9, 0.9, -0.09, 0),
                frameColor = (0, 1, 0, 0))

            def changeKey(key, value):
                # all possible keyboard keys to set for a specific action
                keyboard = [
                    "escape",
                    "f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9", "f10",
                    "f11", "f12",

                    "print_screen", "scroll_lock", "pause", "num_lock",
                    "insert", "delete", "home", "end", "page_up", "page_down",

                    "tab", "caps_lock", "shift", "rcontrol", "lcontrol", "ralt",
                    "lalt", "space", "backspace", "enter",

                    "arrow_left", "arrow_up", "arrow_down", "arrow_right",

                    "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l",
                    "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x",
                    "y", "z",

                    "ä", "ö", "ü",

                    ",", ";", ".", ":", "_", "-", "#", "'", "+", "*", "~", "'",
                    "`", "!", "\"", "§", "$", "%", "&", "/", "(", ")", "=", "?",
                    "{", "}", "[", "]", "\\", "^", "°"
                    ]

                def setKey(arg):
                    """
                    This function will set the chosen key for the given action
                    """
                    # ignore all keyboard inputs again
                    for keyboardKey in keyboard:
                        self.ignore(keyboardKey)
                    if arg == 1:
                        # if the dialog was closed with OK
                        # set the settings to the new value
                        self.engine.settings.playerKeys[key][0] = self.selectedKey
                        if len(self.engine.settings.playerKeys[key]) > 1:
                            # just set the run key value if it is possible
                            newKey = self.engine.settings.playerKeys["run"][0] + "-" + self.selectedKey
                            self.engine.settings.playerKeys[key][1] = newKey
                    # refresh the controls list
                    self.controlsList.removeAllItems()
                    self.fillControlsList()
                    # finaly close the dialog
                    self.keySelectDialog.hide()
                    self.keySelectDialog = None

                # this variable will store the selected key for the given action
                self.selectedKey = value[0]
                def setSelectedKey(selkey):
                    """
                    set the pressed key as the selected one and actualise the text
                    on the dialog
                    """
                    self.selectedKey = selkey
                    self.keySelectDialog["text"] = "{0}: {1}".format(key, self.selectedKey)

                # accept all keyboard keys
                for keyboardKey in keyboard:
                    self.accept(
                        keyboardKey,
                        setSelectedKey,
                        [keyboardKey])

                # set up a dialog wich will ask for the new key for the chosen action
                self.keySelectDialog = OkCancelDialog(
                    dialogName = "OkCancelDialog",
                    text = "{0}: {1}".format(key, value[0]),
                    fadeScreen = 1,
                    command = setKey
                    )
                # show the dialog
                self.keySelectDialog.show()

            # add the change button to change the key of the action
            itemBtnChange = DirectButton(
                text = _("change"),
                scale = 0.05,
                pos = (0.5, 0, -0.05),
                command = changeKey,
                extraArgs = [key, value]
                )
            itemBtnChange.reparentTo(itemFrame)
            # add the label wich will show the name and key of the action
            itemText = DirectLabel(
                text = "{0} - {1}".format(key, value[0]),
                text_scale = 0.06,
                text_align = TextNode.ALeft,
                pos = (-0.88, 0, -0.06))
            itemText.reparentTo(itemFrame)

            # finaly add the item to the list
            self.controlsList.addItem(itemFrame)


    def show(self):
        self.setText()
        self.showBase()

    def showGeneralTab(self):
        # set the selected language in the textbox
        if self.engine.settings.selectedLanguage == "de-DE":
            self.cmbLanguage.set(0, False)
        elif self.engine.settings.selectedLanguage == "ru-RU":
            self.cmbLanguage.set(2, False)
        elif self.engine.settings.selectedLanguage == "fr-FR":
            self.cmbLanguage.set(3, False)
        else:
            self.cmbLanguage.set(1, False)


        res = str(self.engine.settings.windowSize[0]) + "x" + str(self.engine.settings.windowSize[1])
        i = 0
        for item in self.cmbResolution["items"]:
            if item == res:
                self.cmbResolution.set(i, False)
            i += 1

        self.sliderGraphicQuality["value"] = self.engine.settings.graphicquality

        self.sliderVolume["value"] = self.engine.settings.volume

        #self.cbVolumeMute["indicatorValue"] = settings.muted
        self.cbVolumeMute["isChecked"] = not self.engine.settings.muted
        self.cbVolumeMute.commandFunc(None)
        #self.cbVolumeMute.setIndicatorValue()

        self.frameGeneral.show()
        self.hideControlTab()

    def showControlTab(self):
        self.frameControl.show()
        self.hideGeneralTab()

    def hide(self):
        self.hideBase()

    def hideGeneralTab(self):
        self.frameGeneral.hide()

    def hideControlTab(self):
        self.frameControl.hide()

    def setText(self):
        self.title["text"] = _("Options")
        self.btnBack["text"] = _("Back")
        self.lblLanguage["text"] = _("Language")
        self.lblResolution["text"] = _("Screen resolution")
        self.lblGraphicQuality["text"] = _("Graphic quality")
        self.graphicqualityTextMap = {
            0:_("Low"),
            1:_("Medium"),
            2:_("High")}
        self.sliderGraphicQuality["text"] = self.graphicqualityTextMap[
            self.engine.settings.graphicquality]
        self.lblVolume["text"] = _("Volume")
        self.lblVolumeMute["text"] = _("Mute")


    def cmbLanguage_SelectionChanged(self, arg):
        # TODO: get available languages and maping from language class!
        if arg == "Deutsch":
            self.engine.lng.changeLanguage("de-DE")
            self.engine.settings.selectedLanguage = "de-DE"
        elif arg == "русский":
            self.engine.lng.changeLanguage("ru-RU")
            self.engine.settings.selectedLanguage = "ru-RU"
        elif arg == "français":
            self.engine.lng.changeLanguage("fr-FR")
            self.engine.settings.selectedLanguage = "fr-FR"
        else:
            self.engine.lng.changeLanguage("en-US")
            self.engine.settings.selectedLanguage = "en-US"

    def cmbResolution_SelectionChanged(self, arg):
        resx = int(arg.split("x")[0])
        resy = int(arg.split("x")[1])
        self.engine.settings.windowSize = [resx, resy]
        self.engine.graphicMgr.setResolution(resx, resy)

    def sliderGraphicQuality_ValueChanged(self):
        val = int(round(self.sliderGraphicQuality["value"], 0))
        self.sliderGraphicQuality["text"] = self.graphicqualityTextMap[val]
        if val != self.engine.settings.graphicquality:
            self.engine.settings.graphicquality = val
            self.engine.graphicMgr.setGraphicQuality(self.engine.settings.graphicquality)

    def sliderVolume_ValueChanged(self):
        val = round(self.sliderVolume["value"], 2)
        self.sliderVolume["text"] = str(int(val * 100)) + "%"
        self.engine.settings.volume = val
        self.engine.audioMgr.setVolume(self.engine.settings.volume)

    def cbVolumeMute_CheckedChanged(self, checked):
        self.cbVolumeMute["image_scale"] = 0.35
        self.cbVolumeMute["image_pos"] = (0.05,0,0.25)
        self.engine.settings.muted = bool(checked)
        self.engine.audioMgr.mute(self.engine.settings.muted)

    def btnBack_Click(self):
        base.messenger.send("OptMenu_back")