#include "SettingsDialog.h" #include <qcheckbox.h> #include <qcombobox.h> #include <qgroupbox.h> #include <qhbox.h> #include <qlabel.h> #include <qlayout.h> #include <qpushbutton.h> #include <qspinbox.h> #include <qwhatsthis.h> SettingsDialog::SettingsDialog(void) { QVBoxLayout* v = new QVBoxLayout( this ); v->setSpacing( 5 ); QGroupBox* sim = new QGroupBox (2, Horizontal, "Simulation properties", this); QLabel* pop1 = new QLabel( "Number of painters in the world", sim ); QSpinBox* pop2 = new QSpinBox(2, 999, 1, sim); connect(pop2,SIGNAL(valueChanged(int)),this,SLOT(pop(int))); pop2->setValue(settings.pop); QWhatsThis::add(pop1,"Little creatures called \"painters\" are responsible for transitioning between images in SceneSaver. There is a fixed number of painters at any given time, which you can set here. Painters compete with each other to improve, so you need to have at least two. Having too many painters will cause SceneSaver to run slowly." ); QLabel* gmo1 = new QLabel( "Seed with engineered painters", sim ); QCheckBox* gmo2 = new QCheckBox( sim ); connect(gmo2,SIGNAL(toggled(bool)),this,SLOT(gmo(bool))); gmo2->setChecked(settings.gmo); QWhatsThis::add(gmo1,"By default, when a painter needs to be created from scratch (such as after you increase the population), they are seeded randomly. By checking this option you can instead use pre-built painters that have some modicum of intelligence."); QLabel* save1 = new QLabel( "Save painter genotypes on exit", sim ); QCheckBox* save2 = new QCheckBox( sim ); connect(save1,SIGNAL(toggled(bool)),this,SLOT(save(bool))); save2->setChecked(settings.save); QWhatsThis::add(save1,"If this option is checked, whenever you exit the screensaver the current crop of painters will be saved for next time. Painters are saved in the SceneGenes.txt file in your SceneSaver directory."); QLabel* fit1 = new QLabel( "Number of timesteps between fitness rankings", sim ); QSpinBox* fit2 = new QSpinBox(100, 1000000000, 100, sim); connect(fit2,SIGNAL(valueChanged(int)),this,SLOT(fitness(int))); fit2->setValue(settings.fitness); QWhatsThis::add(fit1,"Painters compete to see which is the most \"fit\" at painting over images. This number determines how often they get ranked; at each ranking, the least fit painter is replaced with a mutated copy of the most fit. (A \"timestep\" is a single frame of animation, usually a small fraction of a second.)"); QLabel* mut1 = new QLabel( "Number of mutations at each fitness ranking", sim ); QSpinBox* mut2 = new QSpinBox(0, 1000, 1, sim); connect(mut2,SIGNAL(valueChanged(int)),this,SLOT(mutate(int))); mut2->setValue(settings.mutate); QWhatsThis::add(mut1,"This is the number of \"genes\" that will be randomly mutated at each fitness ranking. More mutations can lead to faster progress, but having too many can halt it by creating inviable genotypes." ); QLabel* imag1 = new QLabel( "Maximum number of timesteps before image is rotated", sim ); QSpinBox* imag2 = new QSpinBox(100, 1000000000, 100, sim); connect(imag2,SIGNAL(valueChanged(int)),this,SLOT(image(int))); imag2->setValue(settings.image); QWhatsThis::add(imag1,"After this number of timesteps, the background image will automatically be swapped out, regardless of how much or how little progress the painters have made."); QLabel* diff1 = new QLabel( "Maximum percentage of painter progress before image is rotated", sim ); QSpinBox* diff2 = new QSpinBox(1, 100, 1, sim); connect(diff2,SIGNAL(valueChanged(int)),this,SLOT(diff(int))); diff2->setValue(settings.diff); QWhatsThis::add(diff1,"After this percentage of the image has been painted, the background image will automatically be swapped out, regardless of how much or how little time has passed."); QLabel* shuff1 = new QLabel( "Shuffle images", sim ); QCheckBox* shuff2 = new QCheckBox( sim ); connect(shuff2,SIGNAL(toggled(bool)),this,SLOT(shuffle(bool))); shuff2->setChecked(settings.shuffle); QWhatsThis::add(shuff1,"If this option is checked, all the images after the first will be displayed in a random order."); v->addWidget( sim ); QGroupBox* pain = new QGroupBox (2, Horizontal, "Painter properties", this); QLabel* rad1 = new QLabel( "Maximum painter radius in pixels", pain ); QSpinBox* rad2 = new QSpinBox(1, 1000, 1, pain); connect(rad2,SIGNAL(valueChanged(int)),this,SLOT(radius(int))); rad2->setValue(settings.radius); QWhatsThis::add(rad1,"This is the maximum radius in pixels that any painter can be. Individual painters may be smaller than this, depending on their genotype."); QLabel* vis1 = new QLabel( "Visual range of each painter in pixels", pain ); QSpinBox* vis2 = new QSpinBox(0, 1000, 1, pain); connect(vis2,SIGNAL(valueChanged(int)),this,SLOT(vision(int))); vis2->setValue(settings.vision); QWhatsThis::add(vis1,"This is the radius within which any given painter can perceive unpainted pixels (measured from the center of its body). Increasing this number makes painters more efficient but also makes SceneSaver run slower."); QLabel* dig1 = new QLabel( "Painting efficiency", pain ); QSpinBox* dig2 = new QSpinBox(1, 25500, 1, pain); connect(dig2,SIGNAL(valueChanged(int)),this,SLOT(digest(int))); dig2->setValue(settings.digest); QWhatsThis::add(dig1,"This setting controls how much color each painter can transform per timestep, with 255 corresponding to the complete transformation of 1 pixel."); QLabel* smud1 = new QLabel( "Smudging efficiency", pain ); QSpinBox* smud2 = new QSpinBox(0, 100, 1, pain); connect(smud2,SIGNAL(valueChanged(int)),this,SLOT(smudge(int))); smud2->setValue(settings.smudge); QWhatsThis::add(smud1,"Painters can smudge the image behind them as they travel; this setting determines what percentage of the \"paint\" each painter smears with it."); QLabel* dist1 = new QLabel( "Smudging distance", pain ); QSpinBox* dist2 = new QSpinBox(0, 200, 1, pain); connect(dist2,SIGNAL(valueChanged(int)),this,SLOT(smudgedist(int))); dist2->setValue(settings.smudgedist); QWhatsThis::add(dist1,"If smudging is enabled, this determines how far the painters \"push\" the paint that they're smearing."); v->addWidget( pain ); QGroupBox* view = new QGroupBox (2, Horizontal, "View properties", this); QLabel* draw1 = new QLabel( "Show painters in world view", view ); QCheckBox* draw2 = new QCheckBox( view ); connect(draw2,SIGNAL(toggled(bool)),this,SLOT(visible(bool))); draw2->setChecked(settings.visible); QWhatsThis::add(draw1,"If this option is checked, the painters will be visible in SceneSaver; otherwise only their trails will be visible."); QLabel* scale1 = new QLabel( "Image auto-scaling", view ); QComboBox* scale2 = new QComboBox( view ); scale2->insertItem( "No scaling" ); scale2->insertItem( "Stretch to fit" ); scale2->insertItem( "Letterbox to preserve aspect ratio" ); scale2->insertItem( "Zoom to preserve aspect ratio" ); connect(scale2,SIGNAL(activated(int)),this,SLOT(autoscale(int))); switch(settings.autoscale) { default: case 'N': scale2->setCurrentItem(0); break; case 'S': scale2->setCurrentItem(1); break; case 'L': scale2->setCurrentItem(2); break; case 'M': scale2->setCurrentItem(3); break; } QWhatsThis::add(scale1,"If the images don't match the dimensions of your screen, this setting determines how they will be made to fit."); QLabel* cam1 = new QLabel( "Camera mode", view ); QComboBox* cam2 = new QComboBox( view ); cam2->insertItem( "Image view" ); cam2->insertItem( "Chase-cam" ); connect(cam2,SIGNAL(activated(int)),this,SLOT(camera(int))); switch(settings.camera) { default: case 'W': cam2->setCurrentItem(0); break; case 'C': cam2->setCurrentItem(1); break; } QWhatsThis::add(cam1,"This determines what you will see when SceneSaver is running. In image view mode, you will see the entire image that the painters are drawing; in chase-cam mode you will follow a single painter and see what it sees."); v->addWidget( view ); QHBox* buttons = new QHBox( this ); QWidget* bob = new QWidget( buttons ); buttons->setStretchFactor( bob, 2 ); buttons->setSpacing( 5 ); QPushButton* ok = new QPushButton( "OK", buttons ); connect(ok,SIGNAL(clicked()),this,SLOT(OK())); QPushButton* cancel = new QPushButton( "Cancel", buttons ); connect(cancel,SIGNAL(clicked()),this,SLOT(close())); v->addWidget( buttons ); setFixedHeight( minimumHeight() ); ok->setFocus(); setCaption( "SceneSaver settings" ); } SettingsDialog::~SettingsDialog(void) { } void SettingsDialog::autoscale( int opt ) { switch( opt ) { case 0: default: settings.autoscale = 'N'; break; case 1: settings.autoscale = 'S'; break; case 2: settings.autoscale = 'L'; break; case 3: settings.autoscale = 'M'; break; } } void SettingsDialog::camera( int opt ) { switch( opt ) { case 0: default: settings.camera = 'W'; break; case 1: settings.camera = 'C'; break; } } void savesettings(); //defined in settings.cpp void SettingsDialog::OK() { savesettings(); close(); }
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#6 | 5890 | Sam Stafford |
Increased granularity of "digestion" setting so that lower values can be set. (This change is backwards-compatible with old settings files.) |
||
#5 | 5818 | Sam Stafford | Configurable painter opacity. | ||
#4 | 5589 | Sam Stafford | Make painter speed configurable. | ||
#3 | 5299 | Sam Stafford |
A second pass for usability - tightened up some terminology and extended some of the "What's This?" help blurbs. |
||
#2 | 5296 | Sam Stafford |
Cleaned up config dialog a little, added scenes dialog and a couple of icons. |
||
#1 | 5293 | Sam Stafford |
Quick and dirty configuration dialog to edit SceneSaver.cfg. Slightly friendlier than the Notepad gizmo. Still need to write something to help people set up Scenes.txt... |