#include "SceneDialog.h" #include "SettingsDialog.h" #include "uic.h" #include <qcheckbox.h> #include <qcombobox.h> #include <qgroupbox.h> #include <qhbox.h> #include <qlabel.h> #include <qlayout.h> #include <qpushbutton.h> #include <qslider.h> #include <qspinbox.h> #include <qwhatsthis.h> SettingsDialog::SettingsDialog(void) { QVBoxLayout* v = new QVBoxLayout( this ); v->setSpacing( 5 ); QHBox* about = new QHBox( this ); about->setSpacing( 5 ); QLabel* logo = new QLabel( about ); logo->setPixmap( QPixmap( uic_findImage( "scenesaver.png" ) ) ); about->setStretchFactor( logo, 0 ); QWhatsThis::add(logo,"This is just a logo. It doesn't do anything except look pretty."); QLabel* blurb = new QLabel( about ); blurb->setText( "SceneSaver: the best slideshow screensaver ever.\nhttp://www.leadtogold.com" ); about->setStretchFactor( blurb, 1 ); QWhatsThis::add(blurb,"This is an explanatory blurb telling you what you're looking at."); v->addWidget( about ); QGroupBox* im = new QGroupBox (2, Horizontal, "Image properties", this ); QLabel* scene1 = new QLabel( "Click here to create a \"playlist\" ->", im ); QPushButton* scene2 = new QPushButton( "Choose Images...", im ); connect(scene2,SIGNAL(clicked()),this,SLOT(scenes())); QWhatsThis::add(scene1,"Clicking this button will open a dialog to select the images that SceneSaver will display."); QWhatsThis::add(scene2,"Clicking this button will open a dialog to select the images that SceneSaver will display."); QLabel* shuff1 = new QLabel( "Shuffle images", im ); QCheckBox* shuff2 = new QCheckBox( im ); 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."); QWhatsThis::add(shuff2,"If this option is checked, all the images after the first will be displayed in a random order."); QLabel* imag1 = new QLabel( "Rotate images after this many timesteps", im ); QSpinBox* imag2 = new QSpinBox(1, 1000000000, 100, im); 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."); QWhatsThis::add(imag2,"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."); diff_label = new QLabel( im ); QSlider* diff2 = new QSlider( 10, 100, 1, settings.diff, Horizontal, im ); connect(diff2,SIGNAL(valueChanged(int)),this,SLOT(diff(int))); connect(diff2,SIGNAL(valueChanged(int)),this,SLOT(diff_change(int))); diff_change(settings.diff); QWhatsThis::add(diff_label,"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."); QWhatsThis::add(diff2,"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."); v->addWidget( im ); 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." ); QWhatsThis::add(pop2,"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."); QWhatsThis::add(gmo2,"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(save2,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."); QWhatsThis::add(save2,"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.)"); QWhatsThis::add(fit2,"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." ); QWhatsThis::add(mut2,"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." ); 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."); QWhatsThis::add(rad2,"This is the maximum radius in pixels that any painter can be. Individual painters may be smaller than this, depending on their genotype."); QLabel* spe1 = new QLabel( "Maximum painter speed", pain ); QSlider* spe2 = new QSlider( 0, 100, 10, settings.maxspeed, Horizontal, pain ); connect(spe2,SIGNAL(valueChanged(int)),this,SLOT(maxspeed(int))); QWhatsThis::add(spe1,"This setting determines how fast the painters travel, proportionate to their size."); QWhatsThis::add(spe2,"This setting determines how fast the painters travel, proportionate to their size."); 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."); QWhatsThis::add(vis2,"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, 2550000, 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 25500 corresponding to the complete transformation of 1 pixel."); QWhatsThis::add(dig2,"This setting controls how much color each painter can transform per timestep, with 25500 corresponding to the complete transformation of 1 pixel."); smud_label = new QLabel( pain ); QSlider* smud2 = new QSlider( 0, 100, 10, settings.smudge, Horizontal, pain ); smud2->setTickmarks( QSlider::Above ); smud2->setTickInterval( 101 ); connect(smud2,SIGNAL(valueChanged(int)),this,SLOT(smudge(int))); connect(smud2,SIGNAL(valueChanged(int)),this,SLOT(smud_change(int))); smud_change( settings.smudge ); QWhatsThis::add(smud_label,"Painters can smudge the image behind them as they travel; this setting determines what percentage of the \"paint\" each painter smears with it."); QWhatsThis::add(smud2,"Painters can smudge the image behind them as they travel; this setting determines what percentage of the \"paint\" each painter smears with it."); dist_label = new QLabel( pain ); QSlider* dist2 = new QSlider(0, 200, 10, settings.smudgedist, Horizontal, pain); dist2->setTickmarks( QSlider::Above ); dist2->setTickInterval( 100 ); connect(dist2,SIGNAL(valueChanged(int)),this,SLOT(smudgedist(int))); connect(dist2,SIGNAL(valueChanged(int)),this,SLOT(dist_change(int))); dist_change( settings.smudgedist ); QWhatsThis::add(dist_label,"If smudging is enabled, this determines how far the painters \"push\" the paint that they're smearing."); QWhatsThis::add(dist2,"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); opac_label = new QLabel( "Opacity", view ); QSlider* draw2 = new QSlider( 0, 100, 10, settings.opacity_i, Horizontal, view ); connect(draw2,SIGNAL(valueChanged(int)),this,SLOT(opacity(int))); connect(draw2,SIGNAL(valueChanged(int)),this,SLOT(opac_change(int))); opac_change(settings.opacity_i); QWhatsThis::add(opac_label,"If this value is greater than 0, the painters will be visible as they paint over the image; otherwise only their trails will be visible."); QWhatsThis::add(draw2,"If this value is greater than 0, the painters will be visible as they paint over the image; otherwise only their trails will be visible."); QLabel* scale1 = new QLabel( "Image auto-scaling mode:", 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."); QWhatsThis::add(scale2,"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( "View mode", view ); QComboBox* cam2 = new QComboBox( view ); cam2->insertItem( "Image view" ); cam2->insertItem( "Chase-cam view" ); 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."); QWhatsThis::add(cam2,"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 ); QWhatsThis::add(bob,"This is just a blank space. It is not concealing anything important."); QPushButton* ok = new QPushButton( "OK", buttons ); connect(ok,SIGNAL(clicked()),this,SLOT(OK())); QWhatsThis::add(ok,"Push this button if you like the changes you've made to the settings and want to save them."); QPushButton* cancel = new QPushButton( "Cancel", buttons ); connect(cancel,SIGNAL(clicked()),this,SLOT(close())); QWhatsThis::add(cancel,"Push this button if you're filled with regret and want to forget the whole thing ever happened."); v->addWidget( buttons ); v->setMargin( 10 ); setFixedHeight( minimumHeight() ); ok->setFocus(); setIcon( uic_findImage( "scenesaver-small.png" ) ); 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 SettingsDialog::diff_change( int d ) { diff_label->setText( "Rotate image after painting " + QString::number( d ) + "% of it" ); } void SettingsDialog::smud_change( int s ) { smud_label->setText( "Smudging efficiency: " + QString::number( s ) + "%" ); } void SettingsDialog::dist_change( int d ) { dist_label->setText( "Smudging distance: " + QString::number( d ) + "%" ); } void SettingsDialog::opac_change( int o ) { QString opac; opac = QString::number( o ) + "%"; opac_label->setText( "Painter opacity: " + opac ); } void SettingsDialog::scenes() { SceneDialog* scene = new SceneDialog( this ); scene->exec(); } 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... |