main.qml 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424
  1. import QtQuick 2.5
  2. import QtQuick.Controls 1.4
  3. import QtQuick.Controls.Styles 1.4
  4. import QtQuick.Dialogs 1.1
  5. import QtQuick.Window 2.2
  6. import "components" as Comps
  7. ApplicationWindow {
  8. property bool portrait: Screen.height > Screen.width ? true : false
  9. id: aw
  10. visible: true
  11. width: portrait ? 600 : 1280
  12. //height: portrait ? 960 : 720
  13. height: portrait ? 960 : Screen.height
  14. visibility: portrait ? "FullScreen" : "Windowed"
  15. color: "#fffffe"
  16. Comps.WebSocket {
  17. id: socket
  18. }
  19. property alias t_slides: socket.tot_slides
  20. Item {
  21. id: item1
  22. transformOrigin: Item.Center
  23. rotation: aw.portrait ? 90 : 0
  24. property alias mouseArea1: mouseArea1
  25. property int curImage: 1
  26. property variant pregs: []
  27. property string curPDF: "EBA"
  28. width: aw.portrait ? parent.height : parent.width
  29. height: aw.portrait ? parent.width : parent.height
  30. anchors.horizontalCenter: parent.horizontalCenter
  31. anchors.verticalCenter: parent.verticalCenter
  32. onCurPDFChanged: {
  33. canvas.change_image(curPDF, curImage)
  34. diapoStatus.text = qsTr("%1/%2 (%3 preg)").arg(curImage).arg(
  35. t_slides).arg(pregs.length)
  36. }
  37. onPregsChanged: {
  38. diapoStatus.text = qsTr("%1/%2 (%3 preg)").arg(curImage).arg(
  39. t_slides).arg(pregs.length)
  40. }
  41. onCurImageChanged: {
  42. canvas.change_image(curPDF, curImage)
  43. diapoStatus.text = qsTr("%1/%2 (%3 preg)").arg(curImage).arg(
  44. t_slides).arg(pregs.length)
  45. }
  46. function addPreg(p) {
  47. if (pregs.indexOf(p) !== -1) {
  48. return
  49. }
  50. pregs.push(p)
  51. curImageChanged();
  52. }
  53. Grid {
  54. id: grid1
  55. width: parent.width
  56. height: parent.height
  57. columns: 4
  58. spacing: 4
  59. Rectangle {
  60. id: canvasCol
  61. height: grid1.height
  62. //width: Screen.height > Screen.width ? grid1.width *3/4 : grid1.width/2
  63. width: Screen.height > Screen.width ? grid1.width *3/4 : Math.min(grid1.height * 4/3, grid1.width*3/4)
  64. color: "#333"
  65. smooth: false
  66. //aw.color
  67. Canvas {
  68. id: canvas
  69. antialiasing: false
  70. renderTarget: Canvas.Image
  71. renderStrategy: Canvas.Immediate
  72. property color strokeStyle: Qt.darker(fillStyle, 1.2)
  73. property color fillStyle: "#6400aa"
  74. property string curColor: "#ff0000"
  75. property real px: width / 2
  76. property real py: height / 2 + 10
  77. property real alpha: 1.0
  78. property variant points_array: []
  79. property string curImageUrl: "https://plataforma.especificosba.com.ar/diapo/EBA/1.png"
  80. property var ctx : null
  81. width: parent.width
  82. height: parent.height
  83. onPaint: full_repaint(region)
  84. onImageLoaded: {
  85. clean_path()
  86. if (ctx === null)
  87. ctx = canvas.getContext("2d");
  88. ctx.lineCap = 'square'
  89. ctx.lineWidth = 4
  90. requestPaint()
  91. }
  92. function clean_path() {
  93. points_array.length=0
  94. requestPaint()
  95. }
  96. function start_path() {
  97. points_array.push({
  98. points: [],
  99. color: curColor
  100. })
  101. }
  102. function normalizeTo800by600(point) {
  103. return {
  104. x: Math.round(
  105. point.x * 800 / canvas.width),
  106. y: Math.round(
  107. point.y * 600 / canvas.height)
  108. }
  109. }
  110. function change_image(pdf, number) {
  111. curImageUrl = "https://plataforma.especificosba.com.ar/diapo/"
  112. + pdf + "/" + number + ".png"
  113. canvas.loadImage(curImageUrl)
  114. }
  115. function add_point(p) {
  116. var pts = points_array[points_array.length - 1].points
  117. var lastpoint;
  118. if (pts.length>1)
  119. lastpoint = pts[pts.length-1];
  120. pts.push(p)
  121. socket.send_point(normalizeTo800by600(p));
  122. if (lastpoint) {
  123. markDirty(Qt.rect(Math.min(p.x,lastpoint.x),Math.min(p.y,lastpoint.y), Math.abs(p.x-lastpoint.x)+4, Math.abs(p.y-lastpoint.y)+4));
  124. }
  125. }
  126. function stroke(points, color) {
  127. if (points.length===0)
  128. return;
  129. if (ctx.strokeStyle !== color){
  130. ctx.strokeStyle = color;
  131. }
  132. ctx.beginPath()
  133. ctx.moveTo(points[0].x, points[0].y)
  134. var i = 0;
  135. for (i = 0; i < points.length - 1; i++) {
  136. ctx.moveTo(points[i].x, points[i].y)
  137. ctx.lineTo(points[i + 1].x, points[i + 1].y)
  138. }
  139. ctx.stroke()
  140. }
  141. function full_repaint(region){
  142. if (ctx === null )
  143. ctx = canvas.getContext("2d");
  144. if ( region === undefined || region.width > 350 || region.height > 350 ) {
  145. // console.log("FULL REPAINT");
  146. if (region)
  147. // console.log("W:", region.width, "H:", region.height);
  148. if (canvas.isImageLoaded(curImageUrl))
  149. ctx.drawImage(curImageUrl, 0, 0, canvas.width, canvas.height)
  150. var j = 0
  151. for (j = 0; j < points_array.length; j++) {
  152. if (points_array[j].points.length <= 1)
  153. continue
  154. stroke(points_array[j].points,points_array[j].color);
  155. }
  156. } else {
  157. //console.log("PARTIAL REPAINT");
  158. var lastLine = points_array[points_array.length-1];
  159. if (lastLine === undefined)
  160. return;
  161. stroke(lastLine.points, lastLine.color);
  162. }
  163. }
  164. }
  165. MouseArea {
  166. id: mouseArea1
  167. x: 0
  168. y:0
  169. width: canvas.width
  170. height: canvas.height
  171. property var last_point;
  172. onPressed: {
  173. if (!socket.isOpen)
  174. return
  175. canvas.start_path()
  176. last_point = { x: mouse.x, y: mouse.y }
  177. canvas.add_point(last_point)
  178. }
  179. onPositionChanged: {
  180. if (!socket.isOpen)
  181. return
  182. var point = { x: mouse.x, y: mouse.y }
  183. var dist = distance(last_point, point);
  184. if (dist <= 1000) //distance returns squared dsitance
  185. return;
  186. console.log("NEW POINT, DISTANCE:", dist)
  187. console.log(Screen.height, Screen.width);
  188. last_point = point
  189. canvas.add_point(point)
  190. }
  191. onReleased: {
  192. if (!socket.isOpen)
  193. return
  194. socket.finish_path()
  195. }
  196. function distance(p1,p2){
  197. return (p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y)
  198. }
  199. }
  200. }
  201. Item {
  202. id: spinnerCol
  203. width: parent.width - canvasCol.width - parent.spacing * 2
  204. height: parent.height
  205. visible: !socket.isOpen
  206. BusyIndicator {
  207. id: busy
  208. anchors { horizontalCenter: parent.horizontalCenter; verticalCenter: parent.verticalCenter }
  209. running: !socket.isOpen
  210. }
  211. Label {
  212. text: "Hubo un problema.. reconectando"
  213. anchors.horizontalCenter: parent.horizontalCenter
  214. anchors.top: busy.top + 20
  215. height: 80
  216. }
  217. }
  218. Column {
  219. id: columnLayout1
  220. spacing: 10
  221. width: parent.width - canvasCol.width - parent.spacing * 2
  222. height: parent.height
  223. visible: socket.isOpen
  224. Column {
  225. width: parent.width
  226. height: parent.height / 2 - 10
  227. Row {
  228. id: row2
  229. width: parent.width
  230. height: 120
  231. MouseArea {
  232. id: image1
  233. width: parent.width/2
  234. height: parent.height
  235. Image {
  236. anchors.centerIn: parent.Center
  237. source: "qrc:///images/back.png"
  238. height: parent.height
  239. fillMode: Image.PreserveAspectFit
  240. }
  241. enabled: socket.isOpen && (item1.curImage > 1)
  242. onClicked : socket.prev_diapo()
  243. }
  244. MouseArea {
  245. id: image2
  246. width: parent.width/2
  247. height: parent.height
  248. Image {
  249. anchors.centerIn: parent.Center
  250. height: parent.height
  251. source: "qrc:///images/fwd.png"
  252. fillMode: Image.PreserveAspectFit
  253. }
  254. enabled: socket.isOpen && (item1.curImage < t_slides)
  255. onClicked: socket.next_diapo()
  256. }
  257. }
  258. Row {
  259. id: row1
  260. width: parent.width
  261. height: 70
  262. Button {
  263. height: 70
  264. width: parent.width / 2
  265. id: preg
  266. text: qsTr("Preg")
  267. onClicked: {
  268. socket.set_preg()
  269. }
  270. }
  271. Button {
  272. height: 70
  273. width: parent.width / 2
  274. id: nopreg
  275. text: qsTr("No Preg")
  276. onClicked: {
  277. socket.unset_preg()
  278. }
  279. }
  280. }
  281. }
  282. Column {
  283. id: column1
  284. width: parent.width
  285. height: parent.height / 2 - 10
  286. spacing: 2
  287. Repeater{
  288. model: [ ["#0000ff", "#00ff00", "#ff0000"], ["#ffff00", "#00ffff", "#000000"] ]
  289. Row {
  290. width: parent.width
  291. height: 70
  292. Repeater {
  293. model: modelData
  294. Button {
  295. height: 70
  296. width: parent.width/3
  297. checkable: true
  298. checked: canvas.curColor === modelData
  299. onClicked: canvas.curColor = modelData
  300. style: ButtonStyle {
  301. background: Rectangle {
  302. implicitWidth: 100
  303. implicitHeight: 25
  304. border.width: 3
  305. border.color: canvas.curColor === modelData ?"#000":"#FFF"
  306. radius: 8
  307. gradient: Gradient {
  308. GradientStop { position: 0 ; color: modelData }
  309. GradientStop { position: 1 ; color: modelData }
  310. }
  311. }
  312. }
  313. }
  314. }
  315. }
  316. }
  317. Button {
  318. height: 70
  319. width: parent.width
  320. id: button3
  321. text: qsTr("Limpiar")
  322. enabled: socket.isOpen
  323. onClicked: {
  324. canvas.clean_path();
  325. socket.clear_path();
  326. }
  327. }
  328. Text {
  329. id: wsStatus
  330. text: qsTr("WS Status")
  331. }
  332. Text {
  333. id: diapoStatus
  334. text: qsTr("Diapo status")
  335. }
  336. Button {
  337. id: salir
  338. width: 40
  339. height: 20
  340. text: qsTr("Salir")
  341. onClicked: {
  342. messageDialog.visible = true;
  343. }
  344. }
  345. }
  346. }
  347. }
  348. }
  349. MessageDialog {
  350. id: messageDialog
  351. title: "Salir"
  352. text: "Seguro que desea salir?"
  353. standardButtons: StandardButton.Yes | StandardButton.No
  354. icon: StandardIcon.Warning
  355. onYes: {
  356. Qt.quit()
  357. }
  358. onNo: {
  359. visible = false
  360. }
  361. }
  362. /*
  363. Timer {
  364. id: messageSender
  365. repeat: true
  366. interval: 200
  367. running: true
  368. onTriggered: function() {
  369. }
  370. }
  371. */
  372. }