Skip to content

Commit

Permalink
Default now updates to the same value as Webcam & Timelapse stream au…
Browse files Browse the repository at this point in the history
…tomattically, cannot be changed/removed from the plugin. Buttons now become disabled when they are active. Added a reload notification after changing settings to manage issue with bindings after saving. Some debugging cleanup.
  • Loading branch information
mikedmor committed May 9, 2018
1 parent b83012a commit 833a5dc
Show file tree
Hide file tree
Showing 9 changed files with 124 additions and 29 deletions.
Binary file added Octoprint_MultiCam_Control.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Octoprint_MultiCam_Settings.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 10 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,10 @@
# OctoPrint_MultiCam
Extends the Control tab of OctoPrint, allowing the ability to switch between multiple webcam feeds.
# OctoPrint MultiCam
Extents the Control tab to include a webcam section with buttons that you can configure in the settings to switch between multiple webcam feeds.

Future updates will include the more options to show different types of streams, as well as the abilitly to show more than one stream at a time.

## Screenshots

![Control Preview][Octoprint_MultiCam_Control.png]

![Setting Preview][Octoprint_MultiCam_Settings.png]
11 changes: 6 additions & 5 deletions octoprint_multicam/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
class MultiCamPlugin(octoprint.plugin.StartupPlugin,
octoprint.plugin.TemplatePlugin,
octoprint.plugin.SettingsPlugin,
octoprint.plugin.AssetPlugin):
octoprint.plugin.AssetPlugin,
octoprint.plugin.ReloadNeedingPlugin):

def get_assets(self):
return dict(
Expand All @@ -18,7 +19,7 @@ def on_after_startup(self):
self._logger.info("MultiCam Loaded! (more: %s)" % self._settings.get(["multicamStream1"]))

def get_settings_defaults(self):
return dict(multicam_profiles=[{'name':'Default','URL':octoprint.settings.settings().get(["webcam","stream"])}])
return dict(multicam_profiles=[{'name':'Default','URL':octoprint.settings.settings().get(["webcam","stream"]), 'isButtonEnabled':'true'}])

def on_settings_save(self, data):
old_profiles = self._settings.get(["multicam_profiles"])
Expand All @@ -27,11 +28,11 @@ def on_settings_save(self, data):

new_profiles = self._settings.get(["multicam_profiles"])
if old_profiles != new_profiles:
self._logger.info("profiles changed from {old_profiles} to {new_profiles} reordering tabs.".format(**locals()))
self._logger.info("profiles changed from {old_profiles} to {new_profiles}".format(**locals()))
flattened_profiles = []
for profiles in new_profiles:
flattened_profiles.append(profiles["name"])
self._settings.global_set(["name","URL"],flattened_profiles)
flattened_profiles.append(profiles['name'])
self._settings.global_set(["name","URL","isButtonEnabled"],flattened_profiles)
self._plugin_manager.send_plugin_message(self._identifier, dict(reload=True))

def get_template_configs(self):
Expand Down
30 changes: 30 additions & 0 deletions octoprint_multicam/static/css/multicam.css
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,33 @@
color: #fff;
padding: 0;
}

.ui-pnotify.multicam-reloadneeded .ui-pnotify-container {
background-color: #404040 !important;
background-image: none !important;
border: none !important;
-moz-border-radius: 10px;
-webkit-border-radius: 10px;
border-radius: 10px;
}
.ui-pnotify.multicam-reloadneeded .ui-pnotify-title, .ui-pnotify.multicam-reloadneeded .ui-pnotify-text {
color: #FFF !important;
}
.ui-pnotify.multicam-reloadneeded .ui-pnotify-title {
font-weight: bold;
margin-bottom: 10px;
padding-bottom: 10px;
border-bottom: 1px solid #FFF;
text-indent: -60px;
}
.ui-pnotify.multicam-reloadneeded .ui-pnotify-icon {
margin-top: 40px;
float: left;
}
.ui-pnotify.multicam-reloadneeded .icon {
margin: 10px;
width: 40px;
height: 40px;
font-size: 40px;
color: #FFF;
}
90 changes: 73 additions & 17 deletions octoprint_multicam/static/js/multicam.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,52 +4,108 @@ $(function() {

var camViewPort = $('#webcam_image');

var currentStream = ""; //camViewPort.attr('src').substr(0, camViewPort.attr('src').indexOf('?'));

self.settings = parameters[0];

self.multicam_profiles = ko.observableArray();

self.enabled_buttons = ko.observableArray();

self.onBeforeBinding = function() {
self.multicam_profiles(self.settings.settings.plugins.multicam.multicam_profiles());
};

self.onSettingsBeforeSave = function() {
ko.utils.arrayForEach(self.multicam_profiles(), function (item, index) {
if(index == 0 && item.URL != $('#settings-webcamStreamUrl').val()) {
console.log("Changes Detected in Webcam & Timelaspse URL");
item.URL($('#settings-webcamStreamUrl').val());
}
});
self.onAfterTabChange();
};

self.onEventSettingsUpdated = function(payload) {
self.multicam_profiles(self.settings.settings.plugins.multicam.multicam_profiles());
//self.multicam_profiles(self.settings.settings.plugins.multicam.multicam_profiles());
self.settings.settings.plugins.multicam.multicam_profiles(self.multicam_profiles.slice(0));
};

self.addMultiCamProfile = function() {
//console.log("Adding New profile for Webcam "+self.multicam_profiles().length);
self.settings.settings.plugins.multicam.multicam_profiles.push({name: ko.observable('Webcam '+self.multicam_profiles().length), URL: ko.observable('http://')});
//console.log("Updating local multicam_profiles variable");
self.settings.settings.plugins.multicam.multicam_profiles.push({name: ko.observable('Webcam '+self.multicam_profiles().length), URL: ko.observable('http://'), isButtonEnabled: ko.observable(true)});
self.multicam_profiles(self.settings.settings.plugins.multicam.multicam_profiles());
};

self.removeMultiCamProfile = function(profile) {
//console.log("Removing profile");
self.settings.settings.plugins.multicam.multicam_profiles.remove(profile);
//console.log("Updating local multicam_profiles variable");
self.multicam_profiles(self.settings.settings.plugins.multicam.multicam_profiles());
};

//TODO: get binding working with: enable: $parent.currentLoaded(URL)
self.currentLoaded = function(URL) {
return URL != currentStream;
}.bind(MultiCamViewModel);

self.loadWebcam = function(profile, event) {
console.log("CurrentStream:"+currentStream);
console.log("Changing stream to: "+ko.toJS(profile).URL);
camViewPort.attr('src',ko.toJS(profile).URL);
currentStream = ko.toJS(profile).URL;
//console.log(ko.toJS(self.multicam_profiles()));
ko.utils.arrayForEach(self.multicam_profiles(), function (item) {
item.isButtonEnabled(true);
});
profile.isButtonEnabled(false);
//console.log(ko.toJS(self.multicam_profiles()));
};

self.onAfterBinding = function() {
var camControl = $('#camControl');
var container = $('#control-jog-general');

// Inserts the control after the general settings under Control Tab
camControl.insertAfter(container);
camControl.css('display', '');
};

self.onAfterTabChange = function(current, previous) {
ko.utils.arrayForEach(self.multicam_profiles(), function (item, index) {
if(index == 0) {
item.isButtonEnabled(false);
} else {
item.isButtonEnabled(true);
}
});
};

//Saving the buttons seems to effect the databinding, until the bug is fixed a reload of the ui is required!
self.onDataUpdaterPluginMessage = function(plugin, data) {
if (plugin != "multicam") {
return;
}
if (data.reload) {
new PNotify({
title: 'Reload Required',
text: 'MultiCam has changed and a reload of the web interface is required.\n\n<span class="label label-important">After the save operation is complete<\/span> press the <span class="label">F5<\/span> key.\n',
hide: false,
icon: 'icon icon-refresh',
addclass: 'multicam-reloadneeded',
confirm: {
confirm: true,
buttons: [{
text: 'Ok',
addClass: 'btn',
click: function(notice) {
notice.remove();
}
},
{
text: 'Cancel',
addClass: 'hidden',
click: function(notice) {
notice.remove();
}
},
]
},
buttons: {
closer: false,
sticker: false
},
history: {
history: false
}
});
};
};

}
Expand Down
4 changes: 2 additions & 2 deletions octoprint_multicam/templates/multicam.jinja2
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<!-- ko allowBindings: true -->
<div class="jog-panel" id="camControl">
<div class="jog-panel" id="camControl" style="display: none;">
<h1>Webcams</h1>
<div data-bind="foreach: settings.settings.plugins.multicam.multicam_profiles">
<button class="btn btn-block control-box" data-bind="click: $parent.loadWebcam, text: name">Default (before bind)</button>
<button class="btn btn-block control-box" data-bind="click: $parent.loadWebcam, text: name, enable: isButtonEnabled">Default (before bind)</button>
</div>
</div>
<!-- /ko -->
4 changes: 2 additions & 2 deletions octoprint_multicam/templates/multicam_settings.jinja2
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@
<input type="text" class="span12 text-right" data-bind="value: name">
</div>
<div class="input-append span5">
<input type="text" class="span12 text-right" data-bind="value: URL">
<input type="text" class="span12 text-right" data-bind="value: URL, enable: $index()!==0, attr: { 'title': $index()!==0 ? 'URL of stream' : 'Edit this field in the Webcam & Timelapse tab (Applies after Save)' }">
</div>
<div class="span2">
<button title="Remove Webcam" class="btn btn-danger" data-bind="click: $parent.removeMultiCamProfile"><i class="fa fa-trash-o"></i></button>
<button title="Remove Webcam" class="btn btn-danger" data-bind="click: $parent.removeMultiCamProfile, enable: $index()!==0, attr: { 'title': $index()!==0 ? 'Remove Webcam' : 'Default Webcam cannot be removed!' }"><i class="fa fa-trash-o"></i></button>
</div>
</div>
</div>
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
plugin_name = "OctoPrint-MultiCam"

# The plugin's version. Can be overwritten within OctoPrint's internal data via __plugin_version__ in the plugin module
plugin_version = "0.1.0"
plugin_version = "0.2.0"

# The plugin's description. Can be overwritten within OctoPrint's internal data via __plugin_description__ in the plugin
# module
Expand Down

0 comments on commit 833a5dc

Please sign in to comment.