Skip to content

Commit

Permalink
feat: add webcam function
Browse files Browse the repository at this point in the history
Signed-off-by: Iskander Sultanov <[email protected]>
  • Loading branch information
BigIskander committed Mar 5, 2024
1 parent eec2f06 commit 823e318
Show file tree
Hide file tree
Showing 6 changed files with 275 additions and 0 deletions.
5 changes: 5 additions & 0 deletions Constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,10 @@
GIMAGE = "mks_gimage"
IS_PREVIEW_ENCODED = "mks_is_preview_encoded"

#camera view parameters (experimental)
IS_CAMERA_VIEW = "mks_is_camera_view"
CAMERA_URL = "mks_camera_url"
CAMERA_VIDEO_ZOOM = "mks_camera_video_zoom"

# Errors
EXCEPTION_MESSAGE = "An exception occurred in network connection: %s"
29 changes: 29 additions & 0 deletions MKSOutputDevice.py
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,35 @@ def disconnect(self):

def getProperties(self):
return self._properties

#camera view (experimental), begining#
@pyqtProperty(bool)
def isCameraView(self):
global_container_stack = Application.getInstance().getGlobalContainerStack()
if global_container_stack:
meta_data = global_container_stack.getMetaData()
if Constants.IS_CAMERA_VIEW in meta_data:
return True
return False

@pyqtProperty(str)
def cameraUrl(self):
global_container_stack = Application.getInstance().getGlobalContainerStack()
if global_container_stack:
meta_data = global_container_stack.getMetaData()
if Constants.CAMERA_URL in meta_data:
return global_container_stack.getMetaDataEntry(Constants.CAMERA_URL)
return ""

@pyqtProperty(float)
def cameraVideoZoom(self):
global_container_stack = Application.getInstance().getGlobalContainerStack()
if global_container_stack:
meta_data = global_container_stack.getMetaData()
if Constants.CAMERA_VIDEO_ZOOM in meta_data:
return float(global_container_stack.getMetaDataEntry(Constants.CAMERA_VIDEO_ZOOM))
return 1.0
#camera view (experimental), end#

@pyqtSlot(str, result=str)
def getProperty(self, key):
Expand Down
59 changes: 59 additions & 0 deletions MachineConfig.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,65 @@ def __init__(self, parent=None):
printersChanged = pyqtSignal()
printersTryToConnect = pyqtSignal()

#camera view (experimental), begining#
@pyqtSlot(result=bool)
def isCameraViewEnabled(self):
global_container_stack = Application.getInstance().getGlobalContainerStack()
if global_container_stack:
meta_data = global_container_stack.getMetaData()
if Constants.IS_CAMERA_VIEW in meta_data:
return True
return False

@pyqtSlot(str)
def setCameraViewEnable(self, is_camera_view_enabled):
global_container_stack = Application.getInstance().getGlobalContainerStack()
if global_container_stack:
if is_camera_view_enabled == "true":
global_container_stack.setMetaDataEntry(Constants.IS_CAMERA_VIEW, is_camera_view_enabled)
else:
global_container_stack.setMetaDataEntry(Constants.IS_CAMERA_VIEW, None)
global_container_stack.removeMetaDataEntry(Constants.IS_CAMERA_VIEW)

@pyqtSlot(result=str)
def getCameraUrl(self):
global_container_stack = Application.getInstance().getGlobalContainerStack()
if global_container_stack:
meta_data = global_container_stack.getMetaData()
if Constants.CAMERA_URL in meta_data:
return global_container_stack.getMetaDataEntry(Constants.CAMERA_URL)
return "http://"

@pyqtSlot(str)
def setCameraUrl(self, camera_url):
global_container_stack = Application.getInstance().getGlobalContainerStack()
if global_container_stack:
if camera_url != "http://":
global_container_stack.setMetaDataEntry(Constants.CAMERA_URL, camera_url)
else:
global_container_stack.setMetaDataEntry(Constants.CAMERA_URL, None)
global_container_stack.removeMetaDataEntry(Constants.CAMERA_URL)

@pyqtSlot(result=str)
def getCameraVideoZoom(self):
global_container_stack = Application.getInstance().getGlobalContainerStack()
if global_container_stack:
meta_data = global_container_stack.getMetaData()
if Constants.CAMERA_VIDEO_ZOOM in meta_data:
return global_container_stack.getMetaDataEntry(Constants.CAMERA_VIDEO_ZOOM)
return "1.0"

@pyqtSlot(str)
def setCameraVideoZoom(self, camera_video_zoom):
global_container_stack = Application.getInstance().getGlobalContainerStack()
if global_container_stack:
if camera_video_zoom != "1.0":
global_container_stack.setMetaDataEntry(Constants.CAMERA_VIDEO_ZOOM, camera_video_zoom)
else:
global_container_stack.setMetaDataEntry(Constants.CAMERA_VIDEO_ZOOM, None)
global_container_stack.removeMetaDataEntry(Constants.CAMERA_VIDEO_ZOOM)
#camera view (experimental), end#

@pyqtProperty(str, constant=True)
def pluginVersion(self) -> str:
return self._plugin_version
Expand Down
17 changes: 17 additions & 0 deletions i18n/mksplugin.pot
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,23 @@ msgctxt "@label"
msgid "Switch to Monitor Tab after file upload"
msgstr ""

#camera view (experimental), begining#
#: qml/MachineConfig.qml:620
msgctxt "@label"
msgid "Camera view (experimental feature)"
msgstr ""

#: qml/MachineConfig.qml:646
msgctxt "@label"
msgid "Camera URL (MJPG-streamer stream URL)"
msgstr ""

#: qml/MachineConfig.qml:676
msgctxt "@label"
msgid "Camera video zoom (1.0 by default)"
msgstr ""
#camera view (experimental), end#

#: qml/MachineConfig.qml:631
msgctxt "@label"
msgid "MKS WiFi Plugin is active for this printer"
Expand Down
95 changes: 95 additions & 0 deletions qml/MachineConfig.qml
Original file line number Diff line number Diff line change
Expand Up @@ -604,6 +604,101 @@ Cura.MachineAction {
enabled: mksSupport.checked
}
}

//camera view (experimental), begining
Row {
anchors
{
left: parent.left
right: parent.right
}
UM.Label {
width: Math.round(parent.width * 0.5)
height: monitorTabAutoOpen.height
verticalAlignment: Text.AlignVCenter
wrapMode: Text.WordWrap
text: catalog.i18nc("@label", "Camera view (experimental feature)")

enabled: mksSupport.checked
}
UM.CheckBox {
id: isCameraView
checked: manager.isCameraViewEnabled()

onCheckedChanged: {
manager.setCameraViewEnable(isCameraView.checked)
}

enabled: mksSupport.checked
}
}
Row {
anchors
{
left: parent.left
right: parent.right
}
UM.Label {
width: Math.round(parent.width * 0.5)
height: monitorTabAutoOpen.height
verticalAlignment: Text.AlignVCenter
wrapMode: Text.WordWrap
text: catalog.i18nc("@label", "Camera URL (MJPG-streamer stream URL)")

enabled: isCameraView.checked
}
Cura.TextField {
id: cameraUrl
width: Math.round(parent.width * 0.5) - UM.Theme.getSize("default_margin").width
maximumLength: 1024
validator: RegularExpressionValidator
{
regularExpression: /^((?:http:\/\/)|(?:https:\/\/))\S{0,}$/
}

text: manager.getCameraUrl()

onEditingFinished: {
manager.setCameraUrl(cameraUrl.text)
}

enabled: isCameraView.checked
}
}
Row {
anchors
{
left: parent.left
right: parent.right
}
UM.Label {
width: Math.round(parent.width * 0.5)
height: monitorTabAutoOpen.height
verticalAlignment: Text.AlignVCenter
wrapMode: Text.WordWrap
text: catalog.i18nc("@label", "Camera video zoom (1.0 by default)")

enabled: isCameraView.checked
}
Cura.TextField {
id: cameraVideoZoom
width: Math.round(parent.width * 0.5) - UM.Theme.getSize("default_margin").width
maximumLength: 3
validator: RegularExpressionValidator
{
regularExpression: /^(?:[0-9]).(?:[0-9])$/
}

text: manager.getCameraVideoZoom()

onEditingFinished: {
manager.setCameraVideoZoom(cameraVideoZoom.text)
}

enabled: isCameraView.checked
}
}
//camera view (experimental), end
}
}
}
Expand Down
70 changes: 70 additions & 0 deletions qml/MonitorItem.qml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,76 @@ Component
UM.I18nCatalog { id: catalog; name:"mksplugin" }
UM.I18nCatalog { id: cura_catalog; name: "cura"}

//camera view (experimental), begining
Rectangle {
Cura.NetworkMJPGImage {
id: cameraImage

visible: OutputDevice.isCameraView
source: OutputDevice.cameraUrl //MJPG-streamer video stream URL
property real videoZoom: OutputDevice.cameraVideoZoom

property real videoWidth: Math.floor(imageWidth * videoZoom)
property real videoHeight: Math.floor(imageHeight * videoZoom)
property real modVideoWidth: Math.floor(videoWidth * (parent.height / videoHeight))
property real modVideoHeight: Math.floor(videoHeight * (parent.width / videoWidth))

width: {
if (videoWidth < parent.width) {
if (videoHeight < parent.height) {
return videoWidth
} else {
return modVideoWidth
}
} else {
if (modVideoWidth < parent.width) {
return modVideoWidth
} else {
return parent.width
}
}
}
height: {
if (videoHeight < parent.height) {
if (videoWidth < parent.width) {
return videoHeight
} else {
return modVideoHeight
}
} else {
if (modVideoHeight < parent.height) {
return modVideoHeight
} else {
return parent.height
}
}
}

anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter

Component.onCompleted: {
if (visible) {
start();
}
}
onVisibleChanged: {
if (visible) {
start();
} else {
stop();
}
}
}

color: UM.Theme.getColor("detail_background")
anchors.left: parent.left
width: parent.width - (Math.floor(parent.width * 0.35) - ((Math.floor(parent.width * 0.35) % 2) ? 0 : 1))
anchors.top: parent.top
anchors.bottom: parent.bottom
}
//camera view (experimental), end

Rectangle {
color: UM.Theme.getColor("main_background")

Expand Down

0 comments on commit 823e318

Please sign in to comment.