Toolbar.qml 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. // Copyright (c) 2018 Ultimaker B.V.
  2. // Cura is released under the terms of the LGPLv3 or higher.
  3. import QtQuick 2.2
  4. import QtQuick.Controls 2.3
  5. import UM 1.5 as UM
  6. import Cura 1.7 as Cura
  7. Item
  8. {
  9. id: base
  10. width: buttons.width
  11. height: buttons.height
  12. property int activeY
  13. Item
  14. {
  15. id: buttons
  16. width: parent.visible ? toolButtons.width : 0
  17. height: childrenRect.height
  18. Behavior on width { NumberAnimation { duration: 100 } }
  19. // Used to create a rounded rectangle behind the toolButtons
  20. Rectangle
  21. {
  22. anchors
  23. {
  24. fill: toolButtons
  25. leftMargin: -radius - border.width // Removes border on left side
  26. }
  27. radius: UM.Theme.getSize("default_radius").width
  28. color: UM.Theme.getColor("toolbar_background")
  29. border.color: UM.Theme.getColor("lining")
  30. border.width: UM.Theme.getSize("default_lining").width
  31. }
  32. Column
  33. {
  34. id: toolButtons
  35. anchors.top: parent.top
  36. anchors.right: parent.right
  37. Repeater
  38. {
  39. id: repeat
  40. model: UM.ToolModel { id: toolsModel }
  41. width: childrenRect.width
  42. height: childrenRect.height
  43. delegate: UM.ToolbarButton
  44. {
  45. text: model.name + (model.shortcut ? ` ("${model.shortcut}")` : "")
  46. checkable: true
  47. checked: model.active
  48. enabled: model.enabled && UM.Selection.hasSelection && UM.Controller.toolsEnabled
  49. isTopElement: toolsModel.getItem(0).id == model.id
  50. isBottomElement: toolsModel.getItem(toolsModel.count - 1).id == model.id
  51. toolItem: UM.ColorImage
  52. {
  53. source: UM.Theme.getIcon(model.icon) != "" ? UM.Theme.getIcon(model.icon) : "file:///" + model.location + "/" + model.icon
  54. color: UM.Theme.getColor("icon")
  55. }
  56. onCheckedChanged:
  57. {
  58. if (checked)
  59. {
  60. base.activeY = y;
  61. }
  62. //Clear focus when tools change. This prevents the tool grabbing focus when activated.
  63. //Grabbing focus prevents items from being deleted.
  64. //Apparently this was only a problem on MacOS.
  65. forceActiveFocus();
  66. }
  67. //Workaround since using ToolButton's onClicked would break the binding of the checked property, instead
  68. //just catch the click so we do not trigger that behaviour.
  69. MouseArea
  70. {
  71. anchors.fill: parent;
  72. onClicked:
  73. {
  74. forceActiveFocus() //First grab focus, so all the text fields are updated
  75. if(parent.checked)
  76. {
  77. UM.Controller.setActiveTool(null);
  78. }
  79. else
  80. {
  81. UM.Controller.setActiveTool(model.id);
  82. }
  83. base.state = (index < toolsModel.count/2) ? "anchorAtTop" : "anchorAtBottom";
  84. }
  85. }
  86. }
  87. }
  88. }
  89. // Used to create a rounded rectangle behind the extruderButtons
  90. Rectangle
  91. {
  92. anchors
  93. {
  94. fill: extruderButtons
  95. leftMargin: -radius - border.width // Removes border on left side
  96. }
  97. radius: UM.Theme.getSize("default_radius").width
  98. color: UM.Theme.getColor("toolbar_background")
  99. border.color: UM.Theme.getColor("lining")
  100. border.width: UM.Theme.getSize("default_lining").width
  101. visible: extrudersModel.items.length > 1
  102. }
  103. Column
  104. {
  105. id: extruderButtons
  106. anchors.topMargin: UM.Theme.getSize("default_margin").height
  107. anchors.top: toolButtons.bottom
  108. anchors.right: parent.right
  109. Repeater
  110. {
  111. width: childrenRect.width
  112. height: childrenRect.height
  113. model: extrudersModel.items.length > 1 ? extrudersModel : 0
  114. delegate: Cura.ExtruderButton
  115. {
  116. extruder: model
  117. isTopElement: extrudersModel.getItem(0).id === model.id
  118. isBottomElement: extrudersModel.getItem(extrudersModel.rowCount() - 1).id === model.id
  119. text: catalog.i18ncp("@label %1 is filled in with the name of an extruder", "Print Selected Model with %1", "Print Selected Models with %1", UM.Selection.selectionCount).arg(extruder.name)
  120. checked: Cura.ExtruderManager.selectedObjectExtruders.indexOf(extruder.id) !== -1
  121. enabled: UM.Selection.hasSelection && extruder.stack.isEnabled
  122. font: UM.Theme.getFont("small_emphasis")
  123. onClicked:
  124. {
  125. forceActiveFocus() //First grab focus, so all the text fields are updated
  126. CuraActions.setExtruderForSelection(extruder.id)
  127. }
  128. }
  129. }
  130. }
  131. }
  132. property var extrudersModel: CuraApplication.getExtrudersModel()
  133. UM.PointingRectangle
  134. {
  135. id: panelBorder
  136. anchors.left: parent.right
  137. anchors.leftMargin: UM.Theme.getSize("default_margin").width
  138. anchors.top: base.top
  139. anchors.topMargin: base.activeY
  140. z: buttons.z - 1
  141. target: Qt.point(-1, base.activeY + Math.round(UM.Theme.getSize("button").height / 2))
  142. arrowSize: UM.Theme.getSize("default_arrow").width
  143. width:
  144. {
  145. if (panel.item && panel.width > 0)
  146. {
  147. return Math.max(panel.width + 2 * UM.Theme.getSize("default_margin").width)
  148. }
  149. else
  150. {
  151. return 0;
  152. }
  153. }
  154. height: panel.item ? panel.height + 2 * UM.Theme.getSize("default_margin").height : 0
  155. opacity: panel.item && panel.width > 0 ? 1 : 0
  156. Behavior on opacity { NumberAnimation { duration: 100 } }
  157. color: UM.Theme.getColor("tool_panel_background")
  158. borderColor: UM.Theme.getColor("lining")
  159. borderWidth: UM.Theme.getSize("default_lining").width
  160. MouseArea //Catch all mouse events (so scene doesn't handle them)
  161. {
  162. anchors.fill: parent
  163. acceptedButtons: Qt.AllButtons
  164. onWheel: wheel.accepted = true
  165. }
  166. Loader
  167. {
  168. id: panel
  169. x: UM.Theme.getSize("default_margin").width
  170. y: UM.Theme.getSize("default_margin").height
  171. source: UM.Controller.valid ? UM.Controller.activeToolPanel : ""
  172. enabled: UM.Controller.toolsEnabled
  173. }
  174. }
  175. // This rectangle displays the information about the current angle etc. when
  176. // dragging a tool handle.
  177. Rectangle
  178. {
  179. id: toolInfo
  180. x: visible ? -base.x + base.mouseX + UM.Theme.getSize("default_margin").width: 0
  181. y: visible ? -base.y + base.mouseY + UM.Theme.getSize("default_margin").height: 0
  182. width: toolHint.width + UM.Theme.getSize("default_margin").width
  183. height: toolHint.height;
  184. color: UM.Theme.getColor("tooltip")
  185. UM.Label
  186. {
  187. id: toolHint
  188. text: UM.Controller.properties.getValue("ToolHint") != undefined ? UM.ActiveTool.properties.getValue("ToolHint") : ""
  189. color: UM.Theme.getColor("tooltip_text")
  190. anchors.horizontalCenter: parent.horizontalCenter
  191. }
  192. visible: toolHint.text != ""
  193. }
  194. states: [
  195. State {
  196. name: "anchorAtTop"
  197. AnchorChanges {
  198. target: panelBorder
  199. anchors.top: base.top
  200. anchors.bottom: undefined
  201. }
  202. PropertyChanges {
  203. target: panelBorder
  204. anchors.topMargin: base.activeY
  205. }
  206. },
  207. State {
  208. name: "anchorAtBottom"
  209. AnchorChanges {
  210. target: panelBorder
  211. anchors.top: undefined
  212. anchors.bottom: base.top
  213. }
  214. PropertyChanges {
  215. target: panelBorder
  216. anchors.bottomMargin: {
  217. if (panelBorder.height > (base.activeY + UM.Theme.getSize("button").height)) {
  218. // panel is tall, align the top of the panel with the top of the first tool button
  219. return -panelBorder.height
  220. }
  221. // align the bottom of the panel with the bottom of the selected tool button
  222. return -(base.activeY + UM.Theme.getSize("button").height)
  223. }
  224. }
  225. }
  226. ]
  227. }