# HG changeset patch # User DomtronVox # Date 1308358188 36000 # Node ID bf1dd9c24a7e01d43bff737dfc20cee3757d314b # Parent 06be71be07f1c42b072c91991479a1f90df0c3ac 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. diff -r 06be71be07f1 -r bf1dd9c24a7e gamescenecontroller.py --- 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,) diff -r 06be71be07f1 -r bf1dd9c24a7e gui/menus.py --- 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() diff -r 06be71be07f1 -r bf1dd9c24a7e settings.py --- 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\ """