Skip to content

Commit

Permalink
SectionControlWidget - Added brightness slider.
Browse files Browse the repository at this point in the history
MaestroControlWidget - Removed brightness slider.
CanvasControlWidget - Fixed keyboard shortcuts not working due to
missing return.
PreferencesDialog - Added configurable event history size.
DeviceControlWidget - Fixed upload button not enabling after upload.
  • Loading branch information
8bitbuddhist committed Dec 4, 2018
1 parent b2c0a88 commit 5ee3921
Show file tree
Hide file tree
Showing 23 changed files with 282 additions and 240 deletions.
24 changes: 13 additions & 11 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ All notable changes to PixelMaestro Studio will be documented in this file.

The format is loosely based on [Keep a Changelog](http://keepachangelog.com/).

## [v0.40] - In Progress
## [v0.40] - 2018-12-03
### Added
- Main Window
- Added File > Merge, which loads a Cuefile on top of the current Maestro instead of replacing it.
- Added File > Queue, which loads a Cuefile into the Event History without affecting the running Maestro.
- Added `File > Open and Merge...`, which loads a Cuefile on top of the current Maestro instead of replacing it.
- Added `File > Open to Event History...`, which loads a Cuefile into the Event History without affecting the running Maestro.
- Added ability to resize sections of the interface.
- Added shortcut keys for Save, New, Open, etc.
- Added confirmation prompt when there are unsaved changes.
Expand All @@ -20,26 +20,28 @@ The format is loosely based on [Keep a Changelog](http://keepachangelog.com/).
- Added ability to click on a Section to make it the Active Section.
- Added "replace" tool for Canvases, which replaces a single color with another color.
- Added ability to re-select a Palette from the Palette drop-down. This lets you reapply a Palette after making changes.
- Added refresh button to Device tab.
- Added ability to map Sections on the Maestro to Sections on a device based on index.
- Added Maestro brightness slider.
- Added refresh button to Device tab, which scans for connected devices.
- Added ability to map Sections between the PC and a device to "translate" live updates to different Sections.
- Added Section brightness slider (brightness moved from Maestro-level to Section-level).
- Preferences
- Added ability to customize the max number of events stored in the Event History.

### Changed
- Main Window
- Added tooltips to several menu options.
- Renamed several file menu options to be more clear about their actions.
- Removed unnecessary Cues being saved to new Cuefiles.
- Renders now reflect changes to Maestro brightness.
- Viewport now reflects changes to Maestro brightness.
- Animation Editor
- Moved Maestro play/pause and lock controls from Show tab to the center of the window.
- Split MaestroControlWidget into individual subwidgets.
- Moved Maestro play/pause and lock controls from Show tab to the main window.
- Split MaestroControlWidget into subwidgets.
- Show timer now runs continuously instead of only when the Show is running.
- Renamed `Cue Interpreter` dialog to `Cue Previewer`.
- Renamed `Cue Interpreter` dialog to `Cue Preview`.
- Fixed memory leak when loading images into a Canvas.
- Fixed issue where Cues executed twice while loading.
- Fixed custom Palettes saving and loading even with session saving disabled.
- Fixed Palette colors regenerating when changing a Palette's name.
- `Enabled Show` now initializes and deletes the Show instead of pausing it.
- `Enable Show` now initializes and deletes the Show instead of just pausing it.
- Increased Event History to 200 events.
- Fixed issue where cancelling the Palette Editor dialog regenerated the color scheme anyway.
- Saved devices will now try to auto-connect even if they weren't auto-detected.
Expand Down
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,11 @@ PixelMaestro Studio is a desktop application for controlling LED displays using

## Features

- Design custom animations and patterns using a fully interactive, real-time, visual editing tool
- Design rich, full color animations using interactive real-time visual editing tools
- Control up to 256 independent, multi-layered drawing surfaces simultaneously
- Create beautiful, 24-bit color palettes with support for over 250 colors per palette
- Use powerful image editing tools to design your own still images and animations
- Upload your changes in real-time to Arduino and other devices over USB
- Save, load, and share your custom animations and configurations
- Set dynamic time-based animations and transitions using a powerful yet intuitive event scheduling system
- Upload your changes in real-time to devices connected via USB or serial port
- Save, load, and share your custom animations to and from your computer and other devices

## Usage

Expand All @@ -24,13 +22,15 @@ To learn more about the PixelMaestro library itself, [visit the repository](http

## Running PixelMaestro Studio

Download the latest version of PixelMaestro Studio from the [releases](https://github.com/8bitbuddhist/PixelMaestro-Studio/releases/) page.

### Windows

Download and run `PixelMaestro_Studio.exe`.

### Linux

Download `PixelMaestro_Studio`, mark it as executable, then run it.
Download `PixelMaestro_Studio`, make it executable, then run it.

```bash
$ wget https://github.com/8bitbuddhist/PixelMaestro-Studio/releases/download/{version tag}/PixelMaestro_Studio
Expand All @@ -54,7 +54,7 @@ $ ./PixelMaestro_Studio
$ git submodule init
$ git submodule update
```
4. Use `qmake` to build the project, or if you have the Qt Creator application installed, open the `PixelMaestro_Studio.pro` file.
4. Use `qmake` to build the project, or if you have Qt Creator installed, open the `PixelMaestro_Studio.pro` file.
```bash
qmake PixelMaestro-Studio.pro && make qmake_all
```
Expand Down
4 changes: 2 additions & 2 deletions src/controller/maestrocontroller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,6 @@ namespace PixelMaestroStudio {

// Maestro-specific Cues
if (save_handlers == nullptr || save_handlers->contains(CueController::Handler::MaestroCueHandler)) {
write_cue_to_stream(datastream, maestro_handler->set_brightness(maestro_->get_brightness()));
write_cue_to_stream(datastream, maestro_handler->set_timer(maestro_->get_timer()->get_interval()));
}

Expand Down Expand Up @@ -172,7 +171,8 @@ namespace PixelMaestroStudio {

SectionCueHandler* section_handler = dynamic_cast<SectionCueHandler*>(maestro_->get_cue_controller()->get_handler(CueController::Handler::SectionCueHandler));

// Dimensions
// Global Section settings
write_cue_to_stream(datastream, section_handler->set_brightness(section_id, layer_id, section->get_brightness()));
write_cue_to_stream(datastream, section_handler->set_dimensions(section_id, layer_id, section->get_dimensions()->x, section->get_dimensions()->y));

// Animation & Colors
Expand Down
14 changes: 6 additions & 8 deletions src/controller/serialdevicethreadcontroller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,17 @@ namespace PixelMaestroStudio {

emit progress_changed(0);
int current_index = 0;
int chunk_size = 64; // Size of each chunk in bytes
int sleep_period = 250; // Time in milliseconds between chunks

int chunk_index = CHUNK_SIZE;
try {
do {
QByteArray out_addr = output_.mid(current_index, chunk_size);
if (current_index + chunk_size > output_.size()) {
chunk_size = output_.size() - current_index;
QByteArray out_addr = output_.mid(current_index, chunk_index);
if (current_index + chunk_index > output_.size()) {
chunk_index = output_.size() - current_index;
}
serial_device_->get_device()->write(out_addr);
serial_device_->get_device()->flush();
current_index += chunk_size;
msleep(sleep_period);
current_index += chunk_index;
msleep(SLEEP_INTERVAL);
emit progress_changed((current_index / (float)output_.size()) * 100);
}
while (current_index < output_.size());
Expand Down
6 changes: 6 additions & 0 deletions src/controller/serialdevicethreadcontroller.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ namespace PixelMaestroStudio {
void progress_changed(int progress);

private:
/// Size of each chunk in bytes
const uint8_t CHUNK_SIZE = 64;

/// Time in milliseconds between chunks. Default is 250.
const uint8_t SLEEP_INTERVAL = 100;

SerialDeviceController* serial_device_ = nullptr;
QByteArray output_;
};
Expand Down
3 changes: 3 additions & 0 deletions src/dialog/preferencesdialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ namespace PixelMaestroStudio {
QString PreferencesDialog::output_enabled = QStringLiteral("Enabled");

// "Interface" section
QString PreferencesDialog::event_history_max = QStringLiteral("Interface/EventHistoryMax");
QString PreferencesDialog::pause_on_start = QStringLiteral("Interface/PauseOnStart");
QString PreferencesDialog::pixel_shape = QStringLiteral("Interface/Shape");
QString PreferencesDialog::save_session = QStringLiteral("Interface/SaveSessionOnClose");
Expand Down Expand Up @@ -54,6 +55,7 @@ namespace PixelMaestroStudio {
ui->setupUi(this);

// Interface settings
ui->eventHistorySizeSpinBox->setValue(settings_.value(event_history_max, 200).toInt());
ui->pixelShapeComboBox->setCurrentIndex(settings_.value(pixel_shape, 1).toInt()); // Default to square pixels
ui->saveSessionCheckBox->setChecked(settings_.value(save_session, true).toBool()); // Default to old session

Expand All @@ -74,6 +76,7 @@ namespace PixelMaestroStudio {
settings_.setValue(pause_on_start, ui->pauseOnStartCheckBox->isChecked());

// Save interface settings
settings_.setValue(event_history_max, ui->eventHistorySizeSpinBox->value());
settings_.setValue(pixel_shape, ui->pixelShapeComboBox->currentIndex());
settings_.setValue(save_session, ui->saveSessionCheckBox->isChecked());

Expand Down
1 change: 1 addition & 0 deletions src/dialog/preferencesdialog.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ namespace PixelMaestroStudio {
static QString device_port;
static QString devices;
static QString device_real_time_refresh;
static QString event_history_max;
static QString last_cuefile_directory;
static QString last_session;
static QString main_window_option;
Expand Down
23 changes: 23 additions & 0 deletions src/dialog/preferencesdialog.ui
Original file line number Diff line number Diff line change
Expand Up @@ -502,6 +502,29 @@
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Max Event History size</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QSpinBox" name="eventHistorySizeSpinBox">
<property name="toolTip">
<string>Maximum number of events to store in the Event History</string>
</property>
<property name="maximum">
<number>1000</number>
</property>
<property name="singleStep">
<number>10</number>
</property>
<property name="value">
<number>200</number>
</property>
</widget>
</item>
</layout>
</widget>
</item>
Expand Down
2 changes: 1 addition & 1 deletion src/dialog/sectionmapdialog.cpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
#include <QAbstractButton>
#include <QMessageBox>
#include <QSettings>
#include "sectionmapdialog.h"
#include "ui_sectionmapdialog.h"
#include "widget/devicecontrolwidget.h"
#include "widget/maestrocontrolwidget.h"

namespace PixelMaestroStudio {
SectionMapDialog::SectionMapDialog(SerialDeviceController* device, QWidget *parent) : QDialog(parent), ui(new Ui::SectionMapDialog) {
Expand Down
1 change: 1 addition & 0 deletions src/model/sectionmapmodel.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "sectionmapmodel.h"
#include <QList>
#include <QStandardItem>
#include <QStandardItemModel>

namespace PixelMaestroStudio {
Expand Down
8 changes: 5 additions & 3 deletions src/utility/cueinterpreter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ namespace PixelMaestroStudio {
"Set dimensions",
"Set layer",
"Set offset",
"Set scroll"});
"Set scroll",
"Set brightness"});

const QStringList CueInterpreter::ShowActions({"Set events",
"Set looping",
Expand Down Expand Up @@ -220,8 +221,6 @@ namespace PixelMaestroStudio {
result->append(": (" + QString::number(IntByteConvert::byte_to_int(&cue[(uint8_t)CanvasCueHandler::Byte::OptionsByte])) + ", ");
result->append(QString::number(IntByteConvert::byte_to_int(&cue[(uint8_t)CanvasCueHandler::Byte::OptionsByte + 2])) + ")");
break;
case CanvasCueHandler::Action::NextFrame:
break;
case CanvasCueHandler::Action::RemoveFrameTimer:
break;
case CanvasCueHandler::Action::SetCurrentFrameIndex:
Expand Down Expand Up @@ -285,6 +284,9 @@ namespace PixelMaestroStudio {
case SectionCueHandler::Action::SetAnimation:
result->append(": " + AnimationTypes.at(cue[(uint8_t)SectionCueHandler::Byte::OptionsByte]));
break;
case SectionCueHandler::Action::SetBrightness:
result->append(": " + QString::number(cue[(uint8_t)SectionCueHandler::Byte::OptionsByte]));
break;
case SectionCueHandler::Action::SetCanvas:
result->append(": " + QString::number(cue[(uint8_t)SectionCueHandler::Byte::OptionsByte]) + " frame(s)");
break;
Expand Down
4 changes: 2 additions & 2 deletions src/widget/canvascontrolwidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,12 @@ namespace PixelMaestroStudio {
if (maestro_control_widget_->section_control_widget_->get_active_section()->get_canvas() != nullptr) {
if (key_event->key() == Qt::Key_Left) {
on_playbackPreviousToolButton_clicked();
return true;
}
else if (key_event->key() == Qt::Key_Right) {
on_playbackNextToolButton_clicked();
return true;
}

return true;
}
}

Expand Down
10 changes: 7 additions & 3 deletions src/widget/devicecontrolwidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -279,8 +279,12 @@ namespace PixelMaestroStudio {
if (cell != nullptr) {
int remote_section_id = cell->text().toInt();
if (remote_section_id != target_section_id) {
// We have a match. Swap the values and reassmble the Cue.
// NOTE: This will change the Section for all future Cues, but in this case, I don't think there's any way around it.
/*
* We have a match. Swap the values and reassmble the Cue.
* NOTE: This will change the entire Cue for every device, but I don't think there's any way around it.
* Fortunately, we'll perform this check again for each device, so it will get replaced if it doesn't match.
* This assumes the device has a map, though.
*/
cue[(uint8_t)SectionCueHandler::Byte::SectionByte] = remote_section_id;
controller->assemble(size);
}
Expand Down Expand Up @@ -350,7 +354,7 @@ namespace PixelMaestroStudio {
void DeviceControlWidget::set_progress_bar(int val) {
ui->uploadProgressBar->setValue(val);
// Disable upload button while sending data
ui->uploadButton->setEnabled(val > 0 && val < 100);
ui->uploadButton->setEnabled(!(val > 0 && val < 100));
}

/**
Expand Down
1 change: 0 additions & 1 deletion src/widget/devicecontrolwidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@

#include <QBuffer>
#include <QSharedPointer>
#include <QThread>
#include <QVector>
#include <QWidget>
#include "controller/serialdevicecontroller.h"
Expand Down
29 changes: 0 additions & 29 deletions src/widget/maestrocontrolwidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,27 +102,6 @@ namespace PixelMaestroStudio {
set_maestro_modified(false);
}

void MaestroControlWidget::on_brightnessSlider_valueChanged(int value) {
ui->brightnessSpinBox->blockSignals(true);
ui->brightnessSpinBox->setValue(value);
ui->brightnessSpinBox->blockSignals(false);

run_cue(
maestro_handler->set_brightness(value)
);
}

void MaestroControlWidget::on_brightnessSpinBox_editingFinished() {
uint8_t brightness = ui->brightnessSpinBox->value();
ui->brightnessSlider->blockSignals(true);
ui->brightnessSlider->setValue(brightness);
ui->brightnessSlider->blockSignals(false);

run_cue(
maestro_handler->set_brightness(brightness)
);
}

/**
* Toggles the Maestro lock.
* @param checked If true, the Maestro is locked.
Expand Down Expand Up @@ -197,14 +176,6 @@ namespace PixelMaestroStudio {
void MaestroControlWidget::refresh_maestro_settings() {
show_control_widget_->refresh();
device_control_widget_->update_cuefile_size();

uint8_t brightness = maestro_controller_->get_maestro()->get_brightness();
ui->brightnessSlider->blockSignals(true);
ui->brightnessSpinBox->blockSignals(true);
ui->brightnessSlider->setValue(brightness);
ui->brightnessSpinBox->setValue(brightness);
ui->brightnessSlider->blockSignals(false);
ui->brightnessSpinBox->blockSignals(false);
}

/**
Expand Down
4 changes: 0 additions & 4 deletions src/widget/maestrocontrolwidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,6 @@ namespace PixelMaestroStudio {

void on_lockButton_toggled(bool checked);

void on_brightnessSpinBox_editingFinished();

void on_brightnessSlider_valueChanged(int value);

private:
Ui::MaestroControlWidget *ui;

Expand Down
Loading

0 comments on commit 5ee3921

Please sign in to comment.