changeset 4:bf1dd9c24a7e

Scrolling by keyboard is now possible. * Patch by DomtronVox. * Added scrolling with the arrow keys. * Added a slider bar in the settings menu to allow players to set the scrolling speed. * Fixed an error that occurred when the ok button in settings was pressed. * There is some kind of focus issue where opening the settings menu in-game causes scrolling to be disabled. Workaround is to change the scroll speed setting whenever you open the settings menu.
author DomtronVox
date Fri, 17 Jun 2011 14:49:48 -1000
parents 06be71be07f1
children bc88f7d5ca8b
files gamescenecontroller.py gui/menus.py settings.py
diffstat 3 files changed, 136 insertions(+), 39 deletions(-) [+]
line wrap: on
line diff
--- a/gamescenecontroller.py	Fri Jun 10 11:29:38 2011 -1000
+++ b/gamescenecontroller.py	Fri Jun 17 14:49:48 2011 -1000
@@ -82,11 +82,12 @@
         self.has_mouse_focus = True
         self.last_mousecoords = None
         self.mouse_callback = None
-        self.original_cursor_id = self.engine.getCursor().getId()        
-        self.scroll_direction = [0, 0]
-        self.scroll_timer = extensions.fife_timer.Timer(100,
-                                          lambda: self.view.moveCamera \
-                                                   (self.scroll_direction))    
+        self.original_cursor_id = self.engine.getCursor().getId()
+        self.scroll_data = {"mouse":[], "kb":[], "offset":[0,0]}
+        self.scroll_timer = extensions.fife_timer.Timer(
+            100,
+            lambda: self.view.moveCamera(self.scroll_data["offset"]),
+        )
         
         #this is temporary until we can set the native cursor
         self.resetMouseCursor()
@@ -180,8 +181,50 @@
             self.model.togglePause()
             self.pause(False)
         if(key_val == key.SPACE):
-            self.model.active_map.centerCameraOnPlayer() 
+            self.model.active_map.centerCameraOnPlayer()
+        
+        #alter scroll data if a directional key is hit
+        if(key_val == key.UP):
+            if not "up" in self.scroll_data["kb"]:
+                self.scroll_data["kb"].append("up")
+
+        if(key_val == key.RIGHT):
+            if not "right" in self.scroll_data["kb"]:
+                self.scroll_data["kb"].append("right")
+ 
+        if(key_val == key.DOWN): 
+            if not "down" in self.scroll_data["kb"]:
+                self.scroll_data["kb"].append("down")
+
+        if(key_val == key.LEFT):
+            if not "left" in self.scroll_data["kb"]:
+                self.scroll_data["kb"].append("left")
     
+    def keyReleased(self, evt):
+        """Whenever a key is pressed, fife calls this routine.
+           @type evt: fife.event
+           @param evt: The event that fife caught
+           @return: None"""
+        key = evt.getKey()
+        key_val = key.getValue()
+
+        #alter scroll data if a directional key is released
+        if(key_val == key.UP):
+            if "up" in self.scroll_data["kb"]:
+                self.scroll_data["kb"].remove("up")
+
+        if(key_val == key.RIGHT):
+            if "right" in self.scroll_data["kb"]:
+                self.scroll_data["kb"].remove("right")
+ 
+        if(key_val == key.DOWN): 
+            if "down" in self.scroll_data["kb"]:
+                self.scroll_data["kb"].remove("down")
+
+        if(key_val == key.LEFT):
+            if "left" in self.scroll_data["kb"]:
+                self.scroll_data["kb"].remove("left")
+        
     def mouseReleased(self, evt):
         """If a mouse button is released, fife calls this routine.
            We want to wait until the button is released, because otherwise
@@ -235,9 +278,8 @@
         #this can be helpful for IDEs code analysis
         if False:
             assert(isinstance(cursor, fife.Cursor))
-        self.last_mousecoords = fife.ScreenPoint(cursor.getX(), 
-                                                 cursor.getY())        
-        self.view.highlightFrontObject(self.last_mousecoords)       
+        self.last_mousecoords = fife.ScreenPoint(cursor.getX(), cursor.getY())
+        self.view.highlightFrontObject(self.last_mousecoords)
         
         #set the trigger area in pixles
         pixle_edge = 20
@@ -252,33 +294,29 @@
         
         
         #edge logic
-        self.scroll_direction = [0, 0]
         if self.has_mouse_focus:
-            direction = self.scroll_direction
+            direction = self.scroll_data["mouse"] = []
+            
             #up
-            if mouse_y <= pixle_edge: 
-                direction[0] += 1
-                direction[1] -= 1
+            if mouse_y <= pixle_edge:
+                direction.append("up")
                 image = '/'.join(['gui/cursors', settings.parpg.CursorUp])
                 
             #right
             if mouse_x >= screen_width - pixle_edge:
-                direction[0] += 1
-                direction[1] += 1
+                direction.append("right")
                 image = '/'.join(['gui/cursors', settings.parpg.CursorRight])
                 
             #down
             if mouse_y >= screen_height - pixle_edge:
-                direction[0] -= 1
-                direction[1] += 1
+                direction.append("down")
                 image = '/'.join(['gui/cursors', settings.parpg.CursorDown])
                 
             #left
             if mouse_x <= pixle_edge:
-                direction[0] -= 1
-                direction[1] -= 1
+                direction.append("left")
                 image = '/'.join(['gui/cursors', settings.parpg.CursorLeft])
-            
+                
             if image is not None and not data_drag.dragging:
                 self.setMouseCursor(image, image)
        
@@ -318,6 +356,50 @@
             self.view.hud.initializeInventory()         
             self.pause(False)
 
+    def handleScrolling(self):
+        """
+        Merge kb and mouse related scroll data, limit the speed and
+        move the camera.
+        """
+        #this is how many pxls the camera is moved in one time frame
+        scroll_offset = self.scroll_data["offset"] = [0,0]
+ 
+        mouse = self.scroll_data["mouse"]
+        keyboard = self.scroll_data["kb"]
+        speed = self.model.settings.parpg.ScrollSpeed
+
+        #adds a value to the offset depending on the contents of each
+        #  of the controllers: set() removes doubles
+        scroll_direction = set(mouse+keyboard)
+        for direction in scroll_direction:
+            if direction == "up":
+                scroll_offset[0] +=1
+                scroll_offset[1] -=1
+            elif direction == "right":
+                scroll_offset[0] +=1
+                scroll_offset[1] +=1
+            elif direction == "down":
+                scroll_offset[0] -=1
+                scroll_offset[1] +=1
+            elif direction == "left":
+                scroll_offset[0] -=1
+                scroll_offset[1] -=1
+
+        #keep the speed within bounds
+        if scroll_offset[0] > 0: scroll_offset[0] = speed
+        if scroll_offset[0] < 0: scroll_offset[0] = -speed
+        
+        if scroll_offset[1] > 0: scroll_offset[1] = speed
+        if scroll_offset[1] < 0: scroll_offset[1] = -speed
+        
+        #de/activate scrolling
+        if scroll_offset != [0, 0]:
+            self.scroll_timer.start()
+        else: 
+            self.scroll_timer.stop()
+            if not data_drag.dragging:
+                self.resetMouseCursor()
+
     def nullFunc(self, userdata):
         """Sample callback for the context menus."""
         logger.info(userdata)
@@ -433,7 +515,7 @@
             self.has_mouse_focus = True
         elif(command.getCommandType() == fife.CMD_MOUSE_FOCUS_LOST):
             self.has_mouse_focus = False
-      
+   
     def pump(self):
         """Routine called during each frame. Our main loop is in ./run.py"""
         # uncomment to instrument
@@ -444,12 +526,6 @@
         if self.model.active_map:
             self.view.highlightFrontObject(self.last_mousecoords)
             self.view.refreshTopLayerTransparencies()
-            if self.scroll_direction != [0, 0]:
-                self.scroll_timer.start()
-            else: 
-                self.scroll_timer.stop()
-                if not data_drag.dragging:
-                    self.resetMouseCursor()
-                
+            self.handleScrolling()
         self.handleCommands()
         # print "%05f" % (time.time()-t0,)
--- a/gui/menus.py	Fri Jun 10 11:29:38 2011 -1000
+++ b/gui/menus.py	Fri Jun 17 14:49:48 2011 -1000
@@ -96,20 +96,24 @@
         self.lighting_model = self.settings.fife.Lighting
         self.fullscreen = self.settings.fife.FullScreen
         self.sound = self.settings.fife.EnableSound
+        self.scroll_speed = self.settings.parpg.ScrollSpeed
         
         xml_file = vfs.VFS.open('gui/settings_menu.xml')
         self.window = pychan.loadXML(xml_file)
         self.restart_dialog = RestartDialog(self.settings)
         self.window.mapEvents({'okButton': self.save,
                                'cancelButton': self.hide,
-                               'defaultButton': self.reset})
+                               'defaultButton': self.reset,
+                               'scroll_speed': self.update})
         self.initializeWidgets()
         self.fillWidgets()
 
     def initializeWidgets(self):
+        scroll_speed = unicode(self.scroll_speed)
         initial_data = {'screen_resolution': self.resolutions,
                         'render_backend': self.render_backends,
-                        'lighting_model': self.lighting_models}
+                        'lighting_model': self.lighting_models,
+                        'scroll_speed_value': scroll_speed}
 
         self.window.distributeInitialData(initial_data)
 
@@ -118,13 +122,26 @@
         resolution = self.resolutions.index(self.resolution)
         backend = self.render_backends.index(self.render_backend)
         lighting = self.lighting_models.index(self.lighting_model)
-
+        
         self.window.distributeData({'screen_resolution': resolution,
                                     'render_backend': backend,
                                     'lighting_model': lighting,
                                     'enable_fullscreen': self.fullscreen,
                                     'enable_sound': self.sound})
 
+    def update(self):
+        """updates lables to show realtime data"""
+        #collects the data from the widgets
+        (scroll_speed) = self.window.collectData('scroll_speed')
+
+        #alter the data note:pychan insists that all lables be given
+        #  unicode text
+        #the slice rounds the number displayed
+        scroll_speed = unicode(scroll_speed)[:3]
+
+        #adds the data to the proper widgets
+        self.window.distributeInitialData({'scroll_speed_value': scroll_speed})
+
     def show(self):
         self.window.show()
 
@@ -136,13 +153,11 @@
         self.fillWidgets()
 
     def save(self):
-        (resolution, backend, lighting,
-         fullscreen, sound) = self.window.collectData('screen_resolution',
-                                                      'render_backend',
-                                                      'lighting_model', 
-                                                      'enable_fullscreen',
-                                                      'enable_sound')
-
+        (resolution, backend, lighting, fullscreen, sound, scroll_speed) = \
+            self.window.collectData('screen_resolution', 'render_backend',
+                                    'lighting_model', 'enable_fullscreen',
+                                    'enable_sound', 'scroll_speed')
+        
         width, height = self.resolutions[resolution].split('x')
         self.settings.fife.ScreenWidth = width
         self.settings.fife.ScreenHeight = height
@@ -150,6 +165,7 @@
         self.settings.fife.Lighting = self.lighting_models[lighting]
         self.settings.fife.FullScreen = fullscreen
         self.settings.fife.EnableSound = sound
+        self.settings.parpg.ScrollSpeed = scroll_speed
         self.settings.write()
        
         self.restart_dialog.show()
--- a/settings.py	Fri Jun 10 11:29:38 2011 -1000
+++ b/settings.py	Fri Jun 17 14:49:48 2011 -1000
@@ -267,6 +267,7 @@
                                     'user{0}'.format(self.suffix))
 
         for section in self.sections:
+
             if '[{0}]\n'.format(section) not in self.settings_file:
                 self.settings_file.append('\n[{0}]\n'.format(section))
                 for option, value in getattr(self, section).options.iteritems():
@@ -309,6 +310,7 @@
         sections.pop(sections.index('settings_file'))
         sections.pop(sections.index('paths'))
         sections.pop(sections.index('suffix'))
+        sections.pop(sections.index('filename'))
         
         return sections
 
@@ -452,6 +454,9 @@
 # File to use for left cursor (filename)
 CursorLeft = cursor_left.png
 
+# how many pixles to move the camera per time frame (digit)
+ScrollSpeed = 1.0
+
 # Player walk speed (digit)
 PCSpeed = 3\
 """