Package arcmap :: Module dialogs
[hide private]
[frames] | no frames]

Source Code for Module arcmap.dialogs

  1  ################################################################################ 
  2  # Authors: Brian Schott (Sir Alaran) 
  3  # Copyright: Brian Schott (Sir Alaran) 
  4  # Date: Sep 29 2009 
  5  # License: 
  6  # 
  7  # This program is free software: you can redistribute it and/or modify 
  8  # it under the terms of the GNU General Public License as published by 
  9  # the Free Software Foundation, either version 3 of the License, or 
 10  # (at your option) any later version. 
 11  # 
 12  # This program is distributed in the hope that it will be useful, 
 13  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
 14  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
 15  # GNU General Public License for more details. 
 16  # 
 17  # You should have received a copy of the GNU General Public License 
 18  # along with this program.  If not, see <http://www.gnu.org/licenses/>. 
 19  ################################################################################ 
 20   
 21   
 22  """ 
 23  Define custom dialogs here to avoid cluttering up the rest of the code 
 24  """ 
 25   
 26  import os 
 27   
 28  import gtk 
 29  import cairo 
 30   
 31  import preferences 
 32  import visualwidget 
 33  import resizewidget 
 34  import parallax 
 35  import graphics 
 36  import tilemap 
 37   
 38   
39 -class HIGTableBuilder(object):
40 """Builds table layouts for HIG-compliant dialogs"""
41 - def __init__(self):
42 self.cols = 3 43 self.row = 1 44 self.table = gtk.Table(self.row, self.cols, False) 45 self.table.set_col_spacing(0, 12) 46 self.table.set_border_width(12)
47
48 - def updateSize(self):
49 self.row = self.row + 1; 50 self.table.resize(self.row, self.cols)
51
52 - def addSectionHeader(self, labelText):
53 self.updateSize() 54 label = gtk.Label("<b>" + labelText + "</b>") 55 label.set_use_markup(True) 56 label.set_alignment(0, 0.5) 57 self.table.attach(label, 0, 2, self.row - 1, self.row)
58
59 - def addWidget(self, widget):
60 self.updateSize() 61 self.table.attach(widget, 1, 3, self.row - 1, self.row, xpadding=6, 62 ypadding=6)
63
64 - def addLabeledWidget(self, labelText, widget):
65 self.updateSize() 66 label = gtk.Label(labelText) 67 label.set_use_underline(True) 68 label.set_mnemonic_widget(widget) 69 label.set_alignment(0, 0.5) 70 self.table.attach(label, 1, 2, self.row - 1, self.row, xpadding=6, 71 ypadding=6) 72 self.table.attach(widget, 2, 3, self.row - 1, self.row, xpadding=6, 73 ypadding=6) 74 widget.connect("state-changed", self.__stateChangedCB, label)
75
76 - def __stateChangedCB(self, widget, state, label):
77 # This is here so that the label will become insensitive if the 78 # widget is set to be insensitive 79 label.set_sensitive(widget.get_property("sensitive"))
80
81 - def getTable(self):
82 return self.table
83 84
85 -def UnsavedDialog(window, hasFileName = True):
86 dialog = gtk.Dialog("", window, gtk.DIALOG_MODAL | 87 gtk.DIALOG_DESTROY_WITH_PARENT, None) 88 dialog.add_button("Close _Without Saving", gtk.RESPONSE_CLOSE) 89 dialog.add_button(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL) 90 dialog.set_border_width(6) 91 dialog.set_has_separator(False) 92 dialog.set_resizable(False) 93 dialog.vbox.set_spacing(12) 94 dialog.vbox.set_border_width(6) 95 hbox = gtk.HBox() 96 hbox.set_spacing(12) 97 hbox.set_border_width(6) 98 image = gtk.Image() 99 image.set_from_stock(gtk.STOCK_DIALOG_WARNING, gtk.ICON_SIZE_DIALOG) 100 hbox.pack_start(image, False, False, 0) 101 hbox.pack_end(gtk.Label("Save the changes to the map before closing?")) 102 dialog.vbox.pack_start(hbox, False, False, 0) 103 dialog.show_all() 104 if hasFileName == True: 105 dialog.add_button(gtk.STOCK_SAVE, gtk.RESPONSE_ACCEPT) 106 else: 107 dialog.add_button(gtk.STOCK_SAVE_AS, gtk.RESPONSE_ACCEPT) 108 109 response = dialog.run() 110 dialog.destroy() 111 return response
112 113
114 -class PropertiesDialog(gtk.Dialog):
115 """ Dialog for File->Properties """ 116
117 - def __init__(self, parent, controller):
118 """ 119 parent = the dialog's parent window 120 map = the map whose properties will be displayed 121 """ 122 gtk.Dialog.__init__(self, "", parent, 123 gtk.DIALOG_DESTROY_WITH_PARENT, (gtk.STOCK_CANCEL, 124 gtk.RESPONSE_REJECTgtk.STOCK_OK, gtk.RESPONSE_ACCEPT))
125 126
127 -class StaticShapePropertiesDialog(gtk.Dialog):
128 - def __init__(self, parent, shape):
129 gtk.Dialog.__init__(self, "Shape Properties", parent, 130 gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, 131 (gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT, gtk.STOCK_APPLY, 132 gtk.RESPONSE_ACCEPT)) 133 134 builder = HIGTableBuilder() 135 136 builder.addSectionHeader("Physics") 137 138 frictionAdjustment = gtk.Adjustment(shape.friction, 0.0, 1.0, 0.1) 139 self.frictionSpin = gtk.SpinButton(frictionAdjustment, 1.0, 4) 140 builder.addLabeledWidget("Coefficient of _Friction:", self.frictionSpin) 141 142 restitutionAdjustment = gtk.Adjustment(shape.restitution, 0.0, 20.0, 0.1) 143 self.restitutionSpin = gtk.SpinButton(restitutionAdjustment, 1.0, 4) 144 builder.addLabeledWidget("Coefficient of _Restitution:", 145 self.restitutionSpin) 146 147 builder.addSectionHeader("Damage") 148 149 damageAdjustment = gtk.Adjustment(shape.damage, 0.0, 32000.0, 1.0) 150 self.damageSpin = gtk.SpinButton(damageAdjustment, 1.0, 4) 151 builder.addLabeledWidget("_Damage per second:", self.damageSpin) 152 153 self.vbox.pack_start(builder.getTable(), True, False, 0) 154 self.vbox.show_all() 155 self.set_resizable(False) 156 self.set_default_response(gtk.RESPONSE_ACCEPT)
157
158 - def getFriction(self):
159 return self.frictionSpin.get_value()
160
161 - def getRestitution(self):
162 return self.restitutionSpin.get_value()
163
164 - def getDamage(self):
165 return self.damageSpin.get_value()
166 167
168 -class NewDialog(gtk.Dialog):
169 """ Dialog for File->New """
170 - def __init__(self, parent):
171 """ parent = the dialog's parent window """ 172 gtk.Dialog.__init__(self, "New Map", parent, 173 gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, 174 (gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT, gtk.STOCK_OK, 175 gtk.RESPONSE_ACCEPT)) 176 177 builder = HIGTableBuilder() 178 179 widthAdjustment = gtk.Adjustment(20, 1, 65535, 1, 10, 0) 180 self.widthSpinButton = gtk.SpinButton(widthAdjustment, 1.0, 0) 181 self.widthSpinButton.set_snap_to_ticks(True) 182 self.widthSpinButton.set_numeric(True) 183 self.widthSpinButton.set_alignment(1.0) 184 builder.addLabeledWidget("_Width:", self.widthSpinButton) 185 186 heightAdjustment = gtk.Adjustment(15, 1, 65535, 1, 10, 0) 187 self.heightSpinButton = gtk.SpinButton(heightAdjustment, 1.0, 0) 188 self.heightSpinButton.set_snap_to_ticks(True) 189 self.heightSpinButton.set_numeric(True) 190 self.heightSpinButton.set_alignment(1.0) 191 builder.addLabeledWidget("_Height:", self.heightSpinButton) 192 193 tileAdjustment = gtk.Adjustment(32, 10, 128, 1, 1, 0) 194 self.tileSpinButton = gtk.SpinButton(tileAdjustment, 1.0, 0) 195 self.tileSpinButton.set_snap_to_ticks(True) 196 self.tileSpinButton.set_numeric(True) 197 self.tileSpinButton.set_alignment(1.0) 198 builder.addLabeledWidget("_Tile Size:", self.tileSpinButton) 199 200 self.vbox.add(builder.getTable()) 201 self.vbox.show_all() 202 self.set_resizable(False) 203 self.set_default_response(gtk.RESPONSE_ACCEPT)
204
205 - def getWidth(self):
206 return self.widthSpinButton.get_value_as_int()
207
208 - def getHeight(self):
209 return self.heightSpinButton.get_value_as_int()
210
211 - def getTileSize(self):
212 return self.tileSpinButton.get_value_as_int()
213 214
215 -class ResizeDialog(gtk.Dialog):
216 """ Dialog for resizing the map """
217 - def __init__(self, parent, currentWidth, currentHeight, thumbnail):
218 gtk.Dialog.__init__(self, "Resize Map", parent, 219 gtk.DIALOG_DESTROY_WITH_PARENT, 220 (gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT, gtk.STOCK_APPLY, 221 gtk.RESPONSE_ACCEPT)) 222 223 # This needs to be here so that the gtk.gdk.Window is valid for the 224 # thumbnail code below 225 self.show_all() 226 227 builder = HIGTableBuilder() 228 229 builder.addSectionHeader("Dimentions") 230 builder.addLabeledWidget("Current Width:", 231 gtk.Label(str(currentWidth))) 232 builder.addLabeledWidget("Current Height:", 233 gtk.Label(str(currentHeight))) 234 235 self.currentWidth = currentWidth 236 self.currentHeight = currentHeight 237 self.newWidthLabel = gtk.Label(str(currentWidth)) 238 builder.addLabeledWidget("New Width:", self.newWidthLabel) 239 self.newHeightLabel = gtk.Label(str(currentHeight)) 240 builder.addLabeledWidget("New Height:", self.newHeightLabel) 241 242 builder.addSectionHeader("Adjustment") 243 negLabel = gtk.Label("Negative values will cause tiles to be\n" 244 +"removed from the specified edge") 245 negLabel.set_alignment(0.0, 0.0) 246 builder.addWidget(negLabel) 247 248 rightAdjustment = gtk.Adjustment(0, -(currentWidth - 1), 65535, 1, 10, 0) 249 self.rightSpinButton = gtk.SpinButton(rightAdjustment, 1.0, 0) 250 self.rightSpinButton.set_snap_to_ticks(True) 251 self.rightSpinButton.set_numeric(True) 252 self.rightSpinButton.set_alignment(1.0) 253 self.rightSpinButton.connect("value-changed", self.rightChangedCB) 254 255 leftAdjustment = gtk.Adjustment(0, -(currentWidth - 1), 65535, 1, 10, 0) 256 self.leftSpinButton = gtk.SpinButton(leftAdjustment, 1.0, 0) 257 self.leftSpinButton.set_snap_to_ticks(True) 258 self.leftSpinButton.set_numeric(True) 259 self.leftSpinButton.set_alignment(1.0) 260 self.leftSpinButton.connect("value-changed", self.leftChangedCB) 261 262 topAdjustment = gtk.Adjustment(0, -(currentHeight - 1), 65535, 1, 10, 0) 263 self.topSpinButton = gtk.SpinButton(topAdjustment, 1.0, 0) 264 self.topSpinButton.set_snap_to_ticks(True) 265 self.topSpinButton.set_numeric(True) 266 self.topSpinButton.set_alignment(1.0) 267 self.topSpinButton.connect("value-changed", self.topChangedCB) 268 269 bottomAdjustment = gtk.Adjustment(0, -(currentHeight - 1), 65535, 1, 10, 0) 270 self.bottomSpinButton = gtk.SpinButton(bottomAdjustment, 1.0, 0) 271 self.bottomSpinButton.set_snap_to_ticks(True) 272 self.bottomSpinButton.set_numeric(True) 273 self.bottomSpinButton.set_alignment(1.0) 274 self.bottomSpinButton.connect("value-changed", self.bottomChangedCB) 275 276 self.__r = resizewidget.ResizeView(currentWidth, currentHeight, 277 thumbnail) 278 279 # The boxes are here to force the cell allocated to the resize widget 280 # to remain a certain width and height. They are invisible on the dialog 281 # and serve no real purpose other than a hack. 282 size = int(max(thumbnail.get_width(), thumbnail.get_height())) 283 hBox = gtk.HBox() 284 hBox.set_size_request(size, 1) 285 vBox = gtk.VBox() 286 vBox.set_size_request(1, size) 287 288 table = gtk.Table(4, 4, False) 289 table.attach(self.leftSpinButton, 0, 1, 1, 2, xpadding=6, ypadding=6) 290 table.attach(self.rightSpinButton, 2, 3, 1, 2, xpadding=6, ypadding=6) 291 table.attach(self.topSpinButton, 1, 2, 0, 1, xpadding=6, ypadding=6) 292 table.attach(self.bottomSpinButton, 1, 2, 2, 3, xpadding=6, ypadding=6) 293 table.attach(self.__r, 1, 2, 1, 2, xoptions=gtk.EXPAND, yoptions=gtk.EXPAND, xpadding=6, ypadding=6) 294 table.attach(vBox, 3, 4, 1, 2, xpadding=0, ypadding=6) 295 table.attach(hBox, 1, 2, 3, 4, xpadding=6, ypadding=0) 296 builder.addWidget(table) 297 298 self.vbox.add(builder.getTable()) 299 self.vbox.show_all() 300 self.set_resizable(False) 301 self.set_default_response(gtk.RESPONSE_ACCEPT)
302
303 - def leftChangedCB(self, widget):
304 r = self.rightSpinButton.get_value_as_int() 305 l = self.leftSpinButton.get_value_as_int() 306 nw = r + l + self.currentWidth 307 self.newWidthLabel.set_text(str(nw)) 308 self.rightSpinButton.get_adjustment().lower = -(self.currentWidth + l - 1) 309 self.__r.setLeft(l)
310
311 - def rightChangedCB(self, widget):
312 r = self.rightSpinButton.get_value_as_int() 313 l = self.leftSpinButton.get_value_as_int() 314 nw = r + l + self.currentWidth 315 self.newWidthLabel.set_text(str(nw)) 316 self.leftSpinButton.get_adjustment().lower = -(self.currentWidth + r - 1) 317 self.__r.setRight(r)
318
319 - def topChangedCB(self, widget):
320 t = self.topSpinButton.get_value_as_int() 321 b = self.bottomSpinButton.get_value_as_int() 322 nh = t + b + self.currentHeight 323 self.newHeightLabel.set_text(str(nh)) 324 self.bottomSpinButton.get_adjustment().lower = -(self.currentHeight + t - 1) 325 self.__r.setTop(t)
326
327 - def bottomChangedCB(self, widget):
328 t = self.topSpinButton.get_value_as_int() 329 b = self.bottomSpinButton.get_value_as_int() 330 nh = t + b + self.currentHeight 331 self.newHeightLabel.set_text(str(nh)) 332 self.topSpinButton.get_adjustment().lower = -(self.currentWidth + b - 1) 333 self.__r.setBottom(b)
334
335 - def getWidth(self):
336 r = self.rightSpinButton.get_value_as_int() 337 l = self.leftSpinButton.get_value_as_int() 338 return r + l + self.currentWidth
339
340 - def getHeight(self):
341 t = self.topSpinButton.get_value_as_int() 342 b = self.bottomSpinButton.get_value_as_int() 343 return t + b + self.currentHeight
344
345 - def getXOffset(self):
346 return self.leftSpinButton.get_value_as_int()
347
348 - def getYOffset(self):
349 return self.topSpinButton.get_value_as_int()
350 351
352 -class BackgroundLayerDialog(gtk.Dialog):
353 - def __init__(self, parent, parallax):
354 355 if parallax != None: 356 self.parallax = parallax 357 else: 358 self.parallax = tilemap.Parallax() 359 360 if self.parallax.fileName == None: 361 fileName = "New Background" 362 else: 363 fileName = self.parallax.fileName 364 365 gtk.Dialog.__init__(self, os.path.basename(fileName), parent, 366 gtk.DIALOG_DESTROY_WITH_PARENT, 367 (gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT, gtk.STOCK_APPLY, 368 gtk.RESPONSE_ACCEPT)) 369 370 builder = HIGTableBuilder() 371 372 builder.addSectionHeader("Appearance") 373 374 fFilter = graphics.getFileFilter() 375 self.fileChooser = gtk.FileChooserDialog("Choose Background Image", 376 self, gtk.FILE_CHOOSER_ACTION_OPEN, 377 (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, 378 gtk.STOCK_OPEN, gtk.RESPONSE_ACCEPT)) 379 self.fileChooser.add_filter(fFilter) 380 self.fileButton = gtk.FileChooserButton(self.fileChooser) 381 if self.parallax.fileName != None: 382 self.fileChooser.set_filename(self.parallax.fileName) 383 self.fileButton.set_width_chars(6) 384 builder.addLabeledWidget("_Image", self.fileButton) 385 386 builder.addSectionHeader("Repeat") 387 388 self.tileHorizontally = gtk.CheckButton("Repeat Horizontally", True) 389 self.tileHorizontally.set_active(self.parallax.hTile) 390 builder.addWidget(self.tileHorizontally) 391 392 self.tileVertically = gtk.CheckButton("Repeat Vertically", True) 393 self.tileVertically.set_active(self.parallax.vTile) 394 builder.addWidget(self.tileVertically) 395 396 builder.addSectionHeader("Scrolling") 397 398 self.scrollHorizontally = gtk.CheckButton("Scroll Horizontally", True) 399 self.scrollHorizontally.connect("toggled", 400 self.scrollHorizontallyChanged) 401 builder.addWidget(self.scrollHorizontally) 402 403 self.scrollHorizontallySpeed = gtk.SpinButton( 404 gtk.Adjustment(self.parallax.hScrollSpeed, 0, 20.0, 0.1, 1.0, 405 0.0), 0.1, 2) 406 builder.addLabeledWidget("Horizontal Scroll Speed", 407 self.scrollHorizontallySpeed) 408 409 self.scrollVertically = gtk.CheckButton("Scroll Vertically", True) 410 self.scrollVertically.connect("toggled", 411 self.scrollVerticallyChanged) 412 builder.addWidget(self.scrollVertically) 413 414 self.scrollVerticallySpeed = gtk.SpinButton( 415 gtk.Adjustment(self.parallax.vScrollSpeed, 0, 20.0, 0.1, 1.0, 416 0.0), 0.1, 2) 417 builder.addLabeledWidget("Vertical Scroll Speed", 418 self.scrollVerticallySpeed) 419 420 421 self.scrollHorizontally.set_active(self.parallax.hScroll) 422 self.scrollHorizontallySpeed.set_sensitive(self.parallax.hScroll) 423 self.scrollVertically.set_active(self.parallax.vScroll) 424 self.scrollVerticallySpeed.set_sensitive(self.parallax.vScroll) 425 426 self.vbox.add(builder.getTable()) 427 self.show_all() 428 self.set_resizable(False)
429
430 - def scrollHorizontallyChanged(self, button):
431 self.scrollHorizontallySpeed.set_sensitive(button.get_active())
432
433 - def scrollVerticallyChanged(self, button):
434 self.scrollVerticallySpeed.set_sensitive(button.get_active())
435
436 -class BackgroundDialog(gtk.Dialog):
437 - def __init__(self, parent, parallaxes, bgColor):
438 gtk.Dialog.__init__(self, "Backgrounds", parent, 439 gtk.DIALOG_DESTROY_WITH_PARENT, 440 (gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT, gtk.STOCK_APPLY, 441 gtk.RESPONSE_ACCEPT)) 442 443 self.bgColor = bgColor 444 self.parallaxes = parallaxes 445 446 # Default width and height. 447 # TODO: tweak this so that it works on the netbook 448 previewWidth = 640 449 previewHeight = 480 450 previewScale = 0.75 451 452 # Left side of dialog: contains the preview and sliders 453 vs = gtk.VScale(gtk.Adjustment(0, -1000, 1000, 1, 10, 10)) 454 vs.set_digits(0) 455 vs.set_draw_value(False) 456 hs = gtk.HScale(gtk.Adjustment(0, -1000, 1000, 1, 10, 10)) 457 hs.set_draw_value(False) 458 hs.set_digits(0) 459 t = gtk.Table(2, 2) 460 self.__preview = parallax.ParallaxViewer(previewWidth, previewHeight, 461 previewScale) 462 vs.connect("value-changed", self.previewYChanged) 463 hs.connect("value-changed", self.previewXChanged) 464 t.attach(self.__preview, 0, 1, 0, 1) 465 t.attach(vs, 1, 2, 0, 1) 466 t.attach(hs, 0, 1, 1, 2) 467 468 # Right side of dialog: contains preview size spin buttons, background 469 # color selector, and list of layers. 470 471 # Top portion 472 builder = HIGTableBuilder() 473 builder.addSectionHeader("Background") 474 self.colorButton = gtk.ColorButton(self.bgColor.getGdk()) 475 self.colorButton.connect("color-set", self.colorSet) 476 builder.addLabeledWidget("Color:", self.colorButton) 477 self.__preview.setColor(self.bgColor) 478 479 builder.addSectionHeader("Preview") 480 previewWSpin = gtk.SpinButton(gtk.Adjustment(previewWidth, 0, 1024, 1, 481 10, 0), 10, 0) 482 previewWSpin.connect("value-changed", self.previewWidthChanged) 483 builder.addLabeledWidget("Width:", previewWSpin) 484 485 previewHSpin = gtk.SpinButton(gtk.Adjustment(previewHeight, 0, 768, 1, 486 10, 0), 10, 0) 487 previewHSpin.connect("value-changed", self.previewHeightChanged) 488 builder.addLabeledWidget("Height:", previewHSpin) 489 490 previewScale = gtk.SpinButton(gtk.Adjustment(previewScale, 0.1, 2.0, 491 0.1, 0.0), 10, 2) 492 previewScale.connect("value-changed", self.previewScaleChanged) 493 builder.addLabeledWidget("Zoom", previewScale) 494 495 # List view 496 self.treeModel = gtk.ListStore(bool, str) 497 self.treeView = gtk.TreeView(self.treeModel) 498 cto = gtk.CellRendererToggle() 499 cto.set_property("activatable", True) 500 cto.connect("toggled", self.visibilityToggle) 501 self.treeView.append_column(gtk.TreeViewColumn("Visible", cto, active=0)) 502 cte = gtk.CellRendererText() 503 self.treeView.append_column(gtk.TreeViewColumn("Background", cte, 504 text=1)) 505 506 # Add current parallax information to the tree view 507 for p in self.parallaxes: 508 self.treeModel.prepend([p.visible, os.path.basename(p.fileName)]) 509 self.__preview.addBackground(p) 510 511 # This has the same effect as clicking the edit button 512 self.treeView.connect("row-activated", self.rowActivated) 513 514 toolbar = gtk.Toolbar() 515 toolbar.set_orientation(gtk.ORIENTATION_HORIZONTAL) 516 toolbar.set_style(gtk.TOOLBAR_ICONS) 517 toolbar.set_show_arrow(False) 518 519 newButton = gtk.ToolButton(gtk.STOCK_NEW) 520 newButton.connect("clicked", self.newClicked) 521 toolbar.insert(newButton, -1) 522 523 deleteButton = gtk.ToolButton(gtk.STOCK_DELETE) 524 deleteButton.connect("clicked", self.deleteClicked) 525 toolbar.insert(deleteButton, -1) 526 527 upButton = gtk.ToolButton(gtk.STOCK_GO_UP) 528 upButton.connect("clicked", self.upClicked) 529 toolbar.insert(upButton, -1) 530 531 downButton = gtk.ToolButton(gtk.STOCK_GO_DOWN) 532 downButton.connect("clicked", self.downClicked) 533 toolbar.insert(downButton, -1) 534 535 editButton = gtk.ToolButton(gtk.STOCK_EDIT) 536 editButton.connect("clicked", self.editClicked) 537 toolbar.insert(editButton, -1) 538 539 vBox = gtk.VBox() 540 vBox.pack_start(builder.getTable(), False, False) 541 vBox.pack_end(toolbar, False, True) 542 vBox.pack_end(self.treeView) 543 544 hBox = gtk.HBox() 545 hBox.pack_start(t) 546 hBox.pack_end(vBox) 547 self.vbox.add(hBox) 548 self.set_resizable(False) 549 self.show_all()
550
551 - def previewWidthChanged(self, adjustment):
552 self.__preview.setWidth(int(adjustment.get_value()))
553
554 - def previewHeightChanged(self, adjustment):
555 self.__preview.setHeight(int(adjustment.get_value()))
556
557 - def previewScaleChanged(self, adjustment):
558 self.__preview.setScale(adjustment.get_value())
559
560 - def previewXChanged(self, adjustment):
561 self.__preview.setX(int(adjustment.get_value()))
562
563 - def previewYChanged(self, adjustment):
564 self.__preview.setY(int(adjustment.get_value()))
565
566 - def colorSet(self, colorButton):
567 self.bgColor = graphics.RGBA() 568 self.bgColor.setGdk(colorButton.get_color()) 569 self.__preview.setColor(self.bgColor)
570
571 - def getCurrent(self):
572 """ 573 @rtype: gtk.TreeIter 574 @return: an iterator associated with the currently selected layer 575 """ 576 selection = self.treeView.get_selection() 577 if selection != None: 578 return selection.get_selected()[1] 579 else: 580 return None
581
582 - def comIndex(self, index):
583 return len(self.treeModel) - index - 1
584
585 - def newClicked(self, button):
586 p = self.__showEditDialog(None) 587 if p != None and p.fileName != None: 588 self.parallaxes.append(p) 589 self.treeModel.prepend([True, os.path.basename(p.fileName)]) 590 self.__preview.addBackground(p)
591
592 - def deleteClicked(self, button):
593 iter = self.getCurrent() 594 if iter == None: 595 return 596 # Remove the current layer 597 index = self.treeModel.get_path(iter)[0] 598 self.__preview.deleteLayer(self.comIndex(index)) 599 self.treeModel.remove(iter) 600 del self.parallaxes[self.comIndex(index)]
601
602 - def upClicked(self, button):
603 cIter = self.getCurrent() 604 if cIter == None or int(self.treeModel.get_path(cIter)[0]) == 0: 605 return 606 else: 607 current = self.treeModel.get_path(cIter)[0] 608 pIter = self.treeModel.get_iter(int(current) - 1) 609 previous = self.treeModel.get_path(pIter)[0] 610 self.treeModel.swap(cIter, pIter) 611 self.__preview.swapLayers(self.comIndex(int(current)), 612 self.comIndex(int(previous)))
613
614 - def downClicked(self, button):
615 iter = self.getCurrent() 616 if iter == None: 617 return 618 else: 619 next = self.treeModel.iter_next(iter) 620 if next != None: 621 index = self.treeModel.get_path(iter)[0] 622 nextIndex = self.treeModel.get_path(next)[0] 623 self.treeModel.swap(iter, next) 624 self.__preview.swapLayers(self.comIndex(index), 625 self.comIndex(int(nextIndex)))
626
627 - def editClicked(self, button):
628 iter = self.getCurrent() 629 if iter == None: 630 return 631 else: 632 index = self.treeModel.get_path(iter)[0] 633 self.__showEditDialog(self.parallaxes[self.comIndex(index)])
634
635 - def rowActivated(self, treeview, path, column):
636 self.__showEditDialog(self.parallaxes[self.comIndex(path[0])])
637
638 - def visibilityToggle(self, cell, path):
639 p = int(path) 640 self.treeModel[p][0] = not self.treeModel[p][0] 641 self.__preview.setVisible(self.comIndex(p), self.treeModel[p][0])
642
643 - def __showEditDialog(self, parallax):
644 d = BackgroundLayerDialog(self, parallax) 645 result = d.run() 646 if result == gtk.RESPONSE_ACCEPT: 647 parallax = d.parallax 648 parallax.hScroll = d.scrollHorizontally.get_active() 649 parallax.vScroll = d.scrollVertically.get_active() 650 parallax.hTile = d.tileHorizontally.get_active() 651 parallax.vTile = d.tileVertically.get_active() 652 parallax.vScrollSpeed = d.scrollVerticallySpeed.get_value() 653 parallax.hScrollSpeed = d.scrollHorizontallySpeed.get_value() 654 parallax.fileName = d.fileChooser.get_filename() 655 d.destroy() 656 return parallax 657 else: 658 d.destroy() 659 return None
660 661
662 -class PreferencesDialog(gtk.Dialog):
663 - def __init__(self, parent):
664 gtk.Dialog.__init__(self, "Preferences", parent, 665 gtk.DIALOG_DESTROY_WITH_PARENT, (gtk.STOCK_OK, gtk.RESPONSE_ACCEPT)) 666 667 self.notebook = gtk.Notebook() 668 self.notebook.set_scrollable(True) 669 670 self.createVisualTab() 671 self.createFilesTab() 672 self.createPhysicsTab() 673 self.vbox.add(self.notebook) 674 self.show_all() 675 self.set_resizable(False)
676 677
678 - def createVisualTab(self):
679 builder = HIGTableBuilder() 680 builder.addSectionHeader("Grid") 681 682 self.lengthSpin = gtk.SpinButton(gtk.Adjustment( 683 preferences.visual["stipple_length"], 0, 50, 1, 684 1, 0), 1, 0) 685 self.lengthSpin.connect("value-changed", self.visualSpinChange, 686 "stipple_length") 687 builder.addLabeledWidget("_Line length:", self.lengthSpin) 688 689 self.gapSpin = gtk.SpinButton(gtk.Adjustment( 690 preferences.visual["stipple_gap"], 0, 50, 1, 691 1, 0), 1, 0) 692 self.gapSpin.connect("value-changed", self.visualSpinChange, 693 "stipple_gap") 694 builder.addLabeledWidget("_Gap length:", self.gapSpin) 695 696 builder.addSectionHeader("Shapes") 697 698 self.handleSpin = gtk.SpinButton(gtk.Adjustment( 699 preferences.visual["handle_size"], 6, 20, 1, 1, 0), 1, 0) 700 self.handleSpin.connect("value-changed", self.visualSpinChange, 701 "handle_size") 702 builder.addLabeledWidget("Handle _Size:", self.handleSpin) 703 704 ioColor = graphics.RGBA() 705 ioColor.fromU32(preferences.visual["invalid_outline"]) 706 ioButton = gtk.ColorButton(ioColor.getGdk()) 707 ioButton.set_use_alpha(True) 708 ioButton.set_alpha(int(ioColor.a * 65535)) # convert to unsigned 16-bit 709 ioButton.connect("color-set", self.colorSet, "invalid_outline") 710 builder.addLabeledWidget("_Invalid Shape Outline Color:", ioButton) 711 712 ifColor = graphics.RGBA() 713 ifColor.fromU32(preferences.visual["invalid_fill"]) 714 ifButton = gtk.ColorButton(ifColor.getGdk()) 715 ifButton.set_use_alpha(True) 716 ifButton.set_alpha(int(ifColor.a * 65535)) 717 ifButton.connect("color-set", self.colorSet, "invalid_fill") 718 builder.addLabeledWidget("I_nvalid Shape Fill Color:", ifButton) 719 720 voColor = graphics.RGBA() 721 voColor.fromU32(preferences.visual["valid_outline"]) 722 voButton = gtk.ColorButton(voColor.getGdk()) 723 voButton.set_use_alpha(True) 724 voButton.set_alpha(int(voColor.a * 65535)) 725 voButton.connect("color-set", self.colorSet, "valid_outline") 726 builder.addLabeledWidget("_Valid Shape Outline Color:", voButton) 727 728 vfColor = graphics.RGBA() 729 vfColor.fromU32(preferences.visual["valid_fill"]) 730 vfButton = gtk.ColorButton(vfColor.getGdk()) 731 vfButton.set_use_alpha(True) 732 vfButton.set_alpha(int(vfColor.a * 65535)) 733 vfButton.connect("color-set", self.colorSet, "valid_fill") 734 builder.addLabeledWidget("V_alid Shape Fill Color:", vfButton) 735 736 builder.addSectionHeader("Preview") 737 self.visualWidget = visualwidget.VisualWidget() 738 builder.addWidget(self.visualWidget) 739 740 vbox = gtk.VBox() 741 vbox.set_border_width(0) 742 vbox.pack_start(builder.table, False, False) 743 self.notebook.append_page(vbox, gtk.Label("Visual"))
744
745 - def colorSet(self, colorButton, key):
746 color = graphics.RGBA() 747 color.setGdk(colorButton.get_color()) 748 color.a = colorButton.get_alpha() / 65535.0 749 preferences.visual[key] = color.toU32() 750 self.visualWidget.update()
751 # Add something about updating the preview here. 752
753 - def visualSpinChange(self, adjustment, key):
754 preferences.visual[key] = adjustment.get_value_as_int() 755 self.visualWidget.update()
756
757 - def createFilesTab(self):
758 builder = HIGTableBuilder() 759 builder.addSectionHeader("File location settings") 760 761 self.usePrefixes = gtk.CheckButton("Use Prefixes") 762 self.usePrefixes.set_active(preferences.files["use_prefixes"]) 763 self.usePrefixes.connect("toggled", self.prefixToggled) 764 builder.addWidget(self.usePrefixes) 765 766 self.tilesetEntry = gtk.Entry() 767 self.tilesetEntry.set_text(preferences.files["tileset_prefix"]) 768 self.tilesetEntry.connect("changed", self.entryEdited, "tileset_prefix") 769 builder.addLabeledWidget("Tileset Prefix:", self.tilesetEntry) 770 771 self.parallaxEntry = gtk.Entry() 772 self.parallaxEntry.set_text(preferences.files["parallax_prefix"]) 773 self.parallaxEntry.connect("changed", self.entryEdited, 774 "parallax_prefix") 775 builder.addLabeledWidget("Parallax Prefix:", self.parallaxEntry) 776 777 self.dataDirEntry = gtk.Entry() 778 self.dataDirEntry.set_text(preferences.files["data_prefix"]) 779 self.dataDirEntry.connect("changed", self.entryEdited, "data_prefix") 780 builder.addLabeledWidget("Default Data Directory:", self.dataDirEntry) 781 782 builder.addSectionHeader("Preview (Save):") 783 784 self.tilePreviewSave = gtk.Entry() 785 self.tilePreviewSave.set_editable(False) 786 self.parallaxPreviewSave = gtk.Entry() 787 self.parallaxPreviewSave.set_editable(False) 788 builder.addWidget(self.tilePreviewSave) 789 builder.addWidget(self.parallaxPreviewSave) 790 791 builder.addSectionHeader("Preview (Load):") 792 793 self.tilePreviewLoad = gtk.Entry() 794 self.tilePreviewLoad.set_editable(False) 795 self.parallaxPreviewLoad = gtk.Entry() 796 self.parallaxPreviewLoad.set_editable(False) 797 builder.addWidget(self.tilePreviewLoad) 798 builder.addWidget(self.parallaxPreviewLoad) 799 800 # Call the update functions manually to set up the dialog 801 self.prefixToggled(self.usePrefixes) 802 self.entryEdited(self.parallaxEntry, "parallax_prefix") 803 804 vbox = gtk.VBox() 805 vbox.set_border_width(0) 806 vbox.pack_start(builder.table, False, False) 807 self.notebook.append_page(vbox, gtk.Label("Files"))
808
809 - def prefixToggled(self, button):
810 self.tilesetEntry.set_sensitive(button.get_active()) 811 self.parallaxEntry.set_sensitive(button.get_active()) 812 self.dataDirEntry.set_sensitive(button.get_active()) 813 self.tilePreviewSave.set_sensitive(button.get_active()) 814 self.tilePreviewLoad.set_sensitive(button.get_active()) 815 self.parallaxPreviewSave.set_sensitive(button.get_active()) 816 self.parallaxPreviewLoad.set_sensitive(button.get_active()) 817 preferences.files["use_prefixes"] = button.get_active()
818
819 - def entryEdited(self, entry, key):
820 preferences.files[key] = entry.get_text() 821 self.setPreviewText()
822
823 - def setPreviewText(self):
824 self.tilePreviewSave.set_text(os.path.join( 825 preferences.files["tileset_prefix"], 826 "tiles.png")) 827 self.parallaxPreviewSave.set_text(os.path.join( 828 preferences.files["parallax_prefix"], 829 "parallax.png")) 830 self.tilePreviewLoad.set_text(os.path.join( 831 preferences.files["data_prefix"], 832 preferences.files["tileset_prefix"], 833 "tiles.png")) 834 self.parallaxPreviewLoad.set_text(os.path.join( 835 preferences.files["data_prefix"], 836 preferences.files["parallax_prefix"], 837 "parallax.png"))
838
839 - def createPhysicsTab(self):
840 builder = HIGTableBuilder() 841 builder.addSectionHeader("Default Physics Parameters") 842 843 frictionAdjustment = gtk.Adjustment( 844 preferences.physics["default_friction"], 0.0, 1.0, 0.1) 845 frictionSpin = gtk.SpinButton(frictionAdjustment, 1.0, 4) 846 frictionSpin.connect("value-changed", self.physicsSpinChange, 847 "default_friction") 848 builder.addLabeledWidget("Coefficient of _Friction:", frictionSpin) 849 850 restitutionAdjustment = gtk.Adjustment( 851 preferences.physics["default_restitution"], 0.0, 20.0, 0.1) 852 restitutionSpin = gtk.SpinButton(restitutionAdjustment, 1.0, 4) 853 restitutionSpin.connect("value-changed", self.physicsSpinChange, 854 "default_restitution") 855 builder.addLabeledWidget("Coefficient of _Restitution:", 856 restitutionSpin) 857 858 vbox = gtk.VBox() 859 vbox.set_border_width(0) 860 vbox.pack_start(builder.table, False, False) 861 self.notebook.append_page(vbox, gtk.Label("Physics"))
862
863 - def physicsSpinChange(self, adjustment, key):
864 preferences.physics[key] = adjustment.get_value()
865