diff options
author | Jens Bache-Wiig <jens.bache-wiig@nokia.com> | 2011-02-21 10:52:17 +0100 |
---|---|---|
committer | Jens Bache-Wiig <jens.bache-wiig@nokia.com> | 2011-02-21 11:03:49 +0100 |
commit | 88f140ddd7f634ad4411f4d16cae51a93eb856b7 (patch) | |
tree | 97918777eb4be0e9da103ca431f43211e4454544 /src | |
parent | 9917d1d23cced9f3f91ec8a0504c2942e72adfc7 (diff) | |
download | qtquickcontrols-88f140ddd7f634ad4411f4d16cae51a93eb856b7.tar.gz |
Added widgets
Diffstat (limited to 'src')
46 files changed, 1984 insertions, 0 deletions
diff --git a/src/Button.qml b/src/Button.qml new file mode 100644 index 00000000..496d37df --- /dev/null +++ b/src/Button.qml @@ -0,0 +1,27 @@ +import QtQuick 1.0 +import "../../../components" as Components +import "../plugin" + +Components.Button { + id:button + + property int buttonHeight: Math.max(22, styleitem.sizeFromContents(100, 6).height) + height: buttonHeight + + QStyleItem { + id:styleitem + elementType:"button" + sunken: pressed + raised: !pressed + hover: containsMouse + enabled:button.enabled + text:button.text + } + + background: + QStyleBackground { + style:styleitem + anchors.fill:parent + } +} + diff --git a/src/ButtonRow.qml b/src/ButtonRow.qml new file mode 100644 index 00000000..623c5f44 --- /dev/null +++ b/src/ButtonRow.qml @@ -0,0 +1,5 @@ +import QtQuick 1.0 +import "../../../components" as Components + +Components.ButtonRow { +} diff --git a/src/CheckBox.qml b/src/CheckBox.qml new file mode 100644 index 00000000..632dce2d --- /dev/null +++ b/src/CheckBox.qml @@ -0,0 +1,26 @@ +import QtQuick 1.0 +import "../../../components" as Components +import "../plugin" + +// jb : Size should not depend on background, we should make it consistent + +Components.CheckBox{ + id:checkbox + property variant text + width:100 + height:18 + + background: QStyleBackground { + id:styleitem + style:QStyleItem { + elementType:"checkbox" + sunken:pressed + on:checked || pressed + hover:containsMouse + text:checkbox.text + enabled:checkbox.enabled + } + } + checkmark: null +} + diff --git a/src/ChoiceList.qml b/src/ChoiceList.qml new file mode 100644 index 00000000..5015fbef --- /dev/null +++ b/src/ChoiceList.qml @@ -0,0 +1,52 @@ +import QtQuick 1.0 +import "../../../components" as Components +import "../plugin" + +Components.ChoiceList { + id:choicelist + + property int buttonHeight: buttonitem.sizeFromContents(100, 18).height + QStyleItem { id:buttonitem; elementType:"combobox" } + height: buttonHeight + topMargin:4 + bottomMargin:4 + + QStyleItem { + id:styleitem + elementType: "combobox" + sunken: pressed + raised: !pressed + hover: containsMouse + enabled:choicelist.enabled + } + + background: QStyleBackground { + anchors.fill:parent + style: styleitem + } + + listItem: Item { + id:item + + height:22 + anchors.left:parent.left + width:choicelist.width + QStyleBackground { + anchors.fill:parent + style: QStyleItem { + elementType: "menuitem" + text: choicelist.model.get(index).text + selected: highlighted + } + } + } + + popupFrame: QStyleBackground { + property int fw: styleitem.pixelMetric("menupanelwidth"); + anchors.leftMargin: styleitem.pixelMetric("menuhmargin") + fw + anchors.rightMargin: styleitem.pixelMetric("menuhmargin") + fw + anchors.topMargin: styleitem.pixelMetric("menuvmargin") + fw + anchors.bottomMargin: styleitem.pixelMetric("menuvmargin") + fw + style:QStyleItem{elementType:"menu"} + } +} diff --git a/src/GroupBox.qml b/src/GroupBox.qml new file mode 100644 index 00000000..0d45810d --- /dev/null +++ b/src/GroupBox.qml @@ -0,0 +1,27 @@ +import QtQuick 1.0 +import "../../../components" as Components +import "../plugin" + +Item { + width:200 + height:46 + + property alias text: styleitem.text + default property alias children: content.children + property bool checkable: false + + QStyleBackground { + anchors.fill:parent + style: QStyleItem{ + id:styleitem + elementType:"groupbox" + } + + Item { + id:content + anchors.topMargin:22 + anchors.leftMargin:6 + anchors.fill:parent + } + } +} diff --git a/src/ProgressBar.qml b/src/ProgressBar.qml new file mode 100644 index 00000000..bf29bcac --- /dev/null +++ b/src/ProgressBar.qml @@ -0,0 +1,31 @@ +import QtQuick 1.0 +import "../../../components" as Components +import "../plugin" + +Components.ProgressBar { + id:progressbar + + // Align with button + property int buttonHeight: buttonitem.sizeFromContents(100, 15).height + QStyleItem { id:buttonitem; elementType:"button" } + height: buttonHeight + + background: QStyleBackground{ + anchors.fill:parent + style: QStyleItem { + elementType:"progressbar" + + // XXX: since desktop uses int instead of real, the progressbar + // range [0..1] must be stretched to a good precision + property int factor : 1000000 + + value: progressbar.value * factor + minimum: indeterminate ? 0 : progressbar.minimumValue * factor + maximum: indeterminate ? 0 : progressbar.maximumValue * factor + enabled: progressbar.enabled + } + } + indeterminateProgress:null + progress: null +} + diff --git a/src/RadioButton.qml b/src/RadioButton.qml new file mode 100644 index 00000000..3c2c3e54 --- /dev/null +++ b/src/RadioButton.qml @@ -0,0 +1,26 @@ +import QtQuick 1.0 +import "../../../components" as Components +import "../plugin" + +// jb : Size should not depend on background, we should make it consistent + +Components.RadioButton{ + id:radiobutton + property variant text + width:110 + height:18 + + background: QStyleBackground { + + style: QStyleItem{ + elementType:"radiobutton" + sunken:pressed + on:checked || pressed + hover:containsMouse + text:radiobutton.text + enabled:radiobutton.enabled + } + } + checkmark: null +} + diff --git a/src/ScrollArea.qml b/src/ScrollArea.qml new file mode 100644 index 00000000..3a904dde --- /dev/null +++ b/src/ScrollArea.qml @@ -0,0 +1,103 @@ +import QtQuick 1.0 +import "../../../components" as Components +import "../plugin" + +FocusScope { + id:scrollarea + width: 100 + height: 100 + + property int contentMargin: 1 + property int __scrollbarExtent : styleitem.pixelMetric("scrollbarExtent"); + property int frameWidth: styleitem.pixelMetric("defaultframewidth"); + property int contentHeight : content.childrenRect.height + property int contentWidth: content.childrenRect.width + property alias color: flickable.color + property bool frame: true + property bool highlightOnFocus: false + + default property alias children: content.children + + property int contentY + property int contentX + + property bool frameAroundContents: styleitem.styleHint("framearoundcontents") + + onContentYChanged: { + vscrollbar.value = contentY + } + + onContentXChanged: { + hscrollbar.value = contentX + } + + QStyleBackground { + style: QStyleItem{ + id:styleitem + elementType: frame ? "frame" : "" + sunken: true + } + anchors.fill: parent + anchors.rightMargin: (frameAroundContents && vscrollbar.visible) ? vscrollbar.width + 4 : -frameWidth + anchors.bottomMargin: (frameAroundContents && hscrollbar.visible) ? hscrollbar.height + 4 : -frameWidth + anchors.topMargin: (frameAroundContents && hscrollbar.visible) ? hscrollbar.height + 4 : -frameWidth + + Rectangle { + id:flickable + color: "transparent" + anchors.fill: parent + anchors.margins: frame ? 2 : 0 + clip: true + + Item { + id: docmargins + anchors.fill:parent + anchors.margins:contentMargin + Item { + id: content + x: -scrollarea.contentX + y: -scrollarea.contentY + } + } + } + } + + ScrollBar { + id: hscrollbar + orientation: Qt.Horizontal + visible: contentWidth > flickable.width + maximumValue: contentWidth > flickable.width ? scrollarea.contentWidth - flickable.width : 0 + minimumValue: 0 + anchors.bottom: parent.bottom + anchors.left: parent.left + anchors.right: parent.right + anchors.rightMargin: { return (frame ? 1 : 0) + ( vscrollbar.visible ? __scrollbarExtent : 0) } + onValueChanged: contentX = value + } + + ScrollBar { + id: vscrollbar + orientation: Qt.Vertical + visible: contentHeight > flickable.height + maximumValue: contentHeight > flickable.height ? scrollarea.contentHeight - flickable.height : 0 + minimumValue: 0 + anchors.right: parent.right + anchors.top: parent.top + anchors.bottom: parent.bottom + anchors.bottomMargin: { return (frame ? 1 : 0) + (hscrollbar.visible ? __scrollbarExtent : 0) } + onValueChanged: contentY = value + } + + QStyleBackground { + z:2 + anchors.fill:parent + anchors.margins:-2 + anchors.rightMargin:-4 + anchors.bottomMargin:-4 + visible: highlightOnFocus && parent.activeFocus && styleitem.styleHint("focuswidget") + style: QStyleItem { + id:framestyle + elementType:"focusframe" + } + } +} diff --git a/src/ScrollBar.qml b/src/ScrollBar.qml new file mode 100644 index 00000000..ea822b62 --- /dev/null +++ b/src/ScrollBar.qml @@ -0,0 +1,109 @@ +import QtQuick 1.1 +import "../../../components" as Components +import "../plugin" + +MouseArea { + id:scrollbar + property int __scrollbarExtent : styleitem.pixelMetric("scrollbarExtent"); + implicitWidth:orientation == Qt.Horizontal ? 200 : __scrollbarExtent; + implicitHeight:orientation == Qt.Horizontal ? __scrollbarExtent : 200 + + property int orientation : Qt.Horizontal + property alias minimumValue: slider.minimumValue + property alias maximumValue: slider.maximumValue + property alias value: slider.value + + property bool upPressed; + property bool downPressed; + property bool __autoincrement: false + + // Update hover item + onEntered: styleitem.activeControl = bgitem.hitTest(mouseX, mouseY) + onExited: styleitem.activeControl = "none" + onMouseXChanged: styleitem.activeControl = bgitem.hitTest(mouseX, mouseY) + hoverEnabled:true + + Timer { running: upPressed || downPressed; interval: 350 ; onTriggered: __autoincrement = true } + Timer { running: __autoincrement; interval: 60 ; repeat: true ; + onTriggered: upPressed ? decrement() : increment() } + + onPressed: { + var control = bgitem.hitTest(mouseX,mouseY) + if (control == "up") { + upPressed = true + } else if (control == "down") { + downPressed = true + } + } + + onReleased: { + __autoincrement = false; + if (upPressed) { + upPressed = false; + decrement() + } else if (downPressed) { + increment() + downPressed = false; + } + } + + function increment() { + value += 30 + if (value > maximumValue) + value = maximumValue + } + + function decrement() { + value -= 30 + if (value < minimumValue) + value = minimumValue + } + + QStyleBackground { + id:bgitem + anchors.fill:parent + style: QStyleItem { + id:styleitem + elementType: "scrollbar" + hover: activeControl != "none" + activeControl: "none" + sunken: upPressed | downPressed + minimum: slider.minimumValue + maximum: slider.maximumValue + value: slider.value + horizontal: orientation == Qt.Horizontal + enabled: parent.enabled + } + } + + property variant handleRect + function updateHandle() { + handleRect = bgitem.subControlRect("handle") + var grooveRect = bgitem.subControlRect("groove"); + var extra = 0 + if (orientation == Qt.Vertical) { + slider.anchors.topMargin = grooveRect.y + extra + slider.anchors.bottomMargin = height - grooveRect.y - grooveRect.height + extra + } else { + slider.anchors.leftMargin = grooveRect.x + extra + slider.anchors.rightMargin = width - grooveRect.x - grooveRect.width + extra + } + } + + onValueChanged: updateHandle() + onMaximumValueChanged: updateHandle() + onMinimumValueChanged: updateHandle() + Component.onCompleted: updateHandle() + Components.Slider { + id:slider + anchors.fill:parent + orientation:scrollbar.orientation + leftMargin: (orientation === Qt.Horizontal) ? handleRect.width/2 : handleRect.height/2 + rightMargin:leftMargin + handle: Item { width:orientation == Qt.Vertical ? handleRect.height : handleRect.width; + height:orientation == Qt.Vertical ? handleRect.width : handleRect.height} + groove:null + valueIndicator:null + inverted:orientation != Qt.Horizontal + } +} diff --git a/src/Slider.qml b/src/Slider.qml new file mode 100644 index 00000000..c6b9c915 --- /dev/null +++ b/src/Slider.qml @@ -0,0 +1,31 @@ +import QtQuick 1.0 +import "../../../components" as Components +import "../plugin" + +// jens: ContainsMouse breaks drag functionality + +Components.Slider{ + id:slider + minimumWidth:200 + + // Align with button + property int buttonHeight: buttonitem.sizeFromContents(100, 15).height + QStyleItem { id:buttonitem; elementType:"button" } + height: buttonHeight + + groove: QStyleBackground { + anchors.fill:parent + style: QStyleItem{ + elementType:"slider" + sunken: pressed + maximum:slider.maximumValue + minimum:slider.minimumValue + value:slider.value + horizontal:slider.orientation == Qt.Horizontal + enabled:slider.enabled + } + } + + handle: null + valueIndicator: null +} diff --git a/src/SpinBox.qml b/src/SpinBox.qml new file mode 100644 index 00000000..2db428ce --- /dev/null +++ b/src/SpinBox.qml @@ -0,0 +1,91 @@ +import QtQuick 1.0 +import "../../../components" as Components +import "../plugin" + +Components.SpinBox { + id:spinbox + + property variant __upRect; + property variant __downRect; + property int __margin: (height -16)/2 + + // Align height with button + topMargin:__margin + bottomMargin:__margin + + property int buttonHeight: edititem.sizeFromContents(100, 20).height + QStyleItem { id:edititem; elementType:"edit" } + height: buttonHeight + clip:false + + background: + Item { + anchors.fill: parent + property variant __editRect + + Rectangle { + id:editBackground + x: __editRect.x - 1 + y: __editRect.y + width: __editRect.width + height: __editRect.height + } + + Item { + id:focusFrame + anchors.fill: editBackground + visible:framestyle.styleHint("focuswidget") + QStyleBackground{ + anchors.margins: -6 + anchors.leftMargin: -5 + anchors.fill: parent + visible:spinbox.activeFocus + style: QStyleItem { + id:framestyle + elementType:"focusframe" + } + } + } + + function updateRect() { + __upRect = spinboxbg.subControlRect("up"); + __downRect = spinboxbg.subControlRect("down"); + __editRect = spinboxbg.subControlRect("edit"); + } + + Component.onCompleted:updateRect() + onWidthChanged:updateRect() + onHeightChanged:updateRect() + + QStyleBackground { + id:spinboxbg + anchors.fill:parent + style: QStyleItem { + id: styleitem + elementType: "spinbox" + sunken: downPressed | upPressed + hover: containsMouse + focus: spinbox.activeFocus + enabled: spinbox.enabled + value: (upPressed? 1 : 0) | + (downPressed== 1 ? 1<<1 : 0) | + (upEnabled? (1<<2) : 0) | + (downEnabled == 1 ? (1<<3) : 0) + } + } + } + + up: Item { + x: __upRect.x + y: __upRect.y + width: __upRect.width + height: __upRect.height + } + + down: Item { + x: __downRect.x + y: __downRect.y + width: __downRect.width + height: __downRect.height + } +} diff --git a/src/Switch.qml b/src/Switch.qml new file mode 100644 index 00000000..b82817c9 --- /dev/null +++ b/src/Switch.qml @@ -0,0 +1,22 @@ +import QtQuick 1.0 +import "../../../components" as Components +import "../plugin" + +Components.Switch { + id:widget + minimumWidth:100 + minimumHeight:30 + + groove:QStyleItem { + elementType:"edit" + sunken: true + } + + handle: QStyleItem { + elementType:"button" + width:widget.width/2 + height:widget.height-4 + hover:containsMouse + } +} + diff --git a/src/Tab.qml b/src/Tab.qml new file mode 100644 index 00000000..e258185b --- /dev/null +++ b/src/Tab.qml @@ -0,0 +1,7 @@ +import Qt 4.7 + +Item { + id:tab + anchors.fill:parent + property string title +} diff --git a/src/TabBar.qml b/src/TabBar.qml new file mode 100644 index 00000000..2d891256 --- /dev/null +++ b/src/TabBar.qml @@ -0,0 +1,90 @@ +import QtQuick 1.0 +import "../../../components" as Components +import "../plugin" + + +Item { + id: tabbar + property int tabHeight: styleitem.sizeFromContents(100, 24).height + height: tabHeight + + property Item tabFrame + onTabFrameChanged:parent = tabFrame + visible: tabFrame ? tabFrame.tabsVisible : true + property int __overlap : styleitem.pixelMetric("tabvshift"); + property string position: tabFrame ? tabFrame.position : "North" + property string tabBarAlignment: styleitem.styleHint("tabbaralignment"); + property int tabOverlap: styleitem.pixelMetric("taboverlap"); + + function tab(index) { + for (var i = 0; i < tabrow.children.length; ++i) { + if (tabrow.children[i].tabindex == index) { + return tabrow.children[i] + } + } + return null; + } + + QStyleItem { + id:styleitem + elementType: "tab" + text: "generic" + } + + Row { + id:tabrow + states: + State { + when: tabBarAlignment == "center" + name: "centered" + AnchorChanges { + target:tabrow + anchors.horizontalCenter: tabbar.horizontalCenter + } + } + Repeater { + id:repeater + model: tabFrame ? tabFrame.tabs.length : null + delegate: Item { + id:tab + property int tabindex: index + property bool selected : tabFrame.current == index + width: textitem.width + 42 + height: tabHeight + z: selected ? 1 : -1 + + QStyleBackground { + style: QStyleItem { + id:style + elementType: "tab" + selected: tab.selected + text: tabbar.position + + activeControl: tabFrame.count == 1 ? + "only" : + index == 0 ? "beginning" : + index == tabFrame.count-1 ? "end" : "middle" + } + anchors.leftMargin: -tabOverlap + (style.text == "North" && (style.activeControl == "middle" || style.activeControl == "end") + && tab.selected ? -__overlap : 0) + + anchors.rightMargin: -tabOverlap + (style.text == "North" && (style.activeControl == "middle" || style.activeControl == "beginning") + && tab.selected ? -__overlap : 0) + anchors.fill:parent + } + + Text { + id:textitem + anchors.centerIn:parent + text: tabFrame.tabs[index].title + elide: Text.ElideRight + } + + MouseArea { + anchors.fill: parent + onPressed: tabFrame.current = index + } + } + } + } +} diff --git a/src/TabFrame.qml b/src/TabFrame.qml new file mode 100644 index 00000000..01896e75 --- /dev/null +++ b/src/TabFrame.qml @@ -0,0 +1,72 @@ +import QtQuick 1.0 +import "../../../components" as Components +import "../plugin" + +Item{ + id: tabWidget + width:100 + height:100 + property TabBar tabbar + property int current: 0 + property int count: stack.children.length + property bool frame:true + property bool tabsVisible: true + property string position: "North" + default property alias tabs : stack.children + + onCurrentChanged: __setOpacities() + Component.onCompleted: __setOpacities() + onTabbarChanged: { + tabbar.tabFrame = tabWidget + tabbar.anchors.top = tabWidget.top + tabbar.anchors.left = tabWidget.left + tabbar.anchors.right = tabWidget.right + } + + property int __baseOverlap : style.pixelMetric("tabbaseoverlap"); + function __setOpacities() { + for (var i = 0; i < stack.children.length; ++i) { + stack.children[i].opacity = (i == current ? 1 : 0) + } + } + + QStyleBackground { + id: frame + z:-1 + style: QStyleItem { + id:style + elementType: "tabframe" + text: position + value: tabbar && tabsVisible && tabbar.tab(current) ? tabbar.tab(current).x : 0 + minimum: tabbar && tabsVisible && tabbar.tab(current) ? tabbar.tab(current).width : 0 + } + anchors.fill:parent + Item { + id:stack + anchors.fill:parent + anchors.margins: frame ? 2 : 0 + } + anchors.topMargin: tabbar && tabsVisible && position == "North" ? tabbar.height - __baseOverlap : 0 + + states: [ + State { + name: "South" + when: position == "South" && tabbar!= undefined + PropertyChanges { + target: frame + anchors.topMargin: 0 + anchors.bottomMargin: tabbar ? tabbar.height - __baseOverlap: 0 + } + PropertyChanges { + target: tabbar + anchors.topMargin: -__baseOverlap + } + AnchorChanges { + target: tabbar + anchors.top: frame.bottom + anchors.bottom: undefined + } + } + ] + } +} diff --git a/src/TextArea.qml b/src/TextArea.qml new file mode 100644 index 00000000..93ad8f3d --- /dev/null +++ b/src/TextArea.qml @@ -0,0 +1,44 @@ +import QtQuick 1.0 +import "../../../components" as Components +import "../plugin" + +Components.TextArea { + id:textarea + leftMargin:12 + rightMargin:12 + minimumWidth:200 + desktopBehavior:true + placeholderText:"" + clip:false + // Align with button + property int buttonHeight: buttonitem.sizeFromContents(100, 14).height + QStyleItem { id:buttonitem; elementType:"button" } + minimumHeight: buttonHeight + + background: QStyleBackground { + anchors.fill:parent + style: QStyleItem{ + elementType:"edit" + sunken:true + focus:textarea.activeFocus + } + } + + Item{ + id:focusFrame + anchors.fill: textarea + parent:textarea.parent + visible:framestyle.styleHint("focuswidget") + QStyleBackground{ + anchors.margins: -2 + anchors.rightMargin:-4 + anchors.bottomMargin:-4 + anchors.fill: parent + visible:textarea.activeFocus + style: QStyleItem { + id:framestyle + elementType:"focusframe" + } + } + } +} diff --git a/src/TextField.qml b/src/TextField.qml new file mode 100644 index 00000000..260584e9 --- /dev/null +++ b/src/TextField.qml @@ -0,0 +1,52 @@ +import QtQuick 1.0 +import "../../../components" as Components +import "../plugin" + +Components.TextField { + id:textfield + minimumWidth:200 + desktopBehavior:true + placeholderText:"" + topMargin:2 + bottomMargin:2 + leftMargin:6 + rightMargin:6 + width:200 + height: editItem.sizeFromContents(100, 20).height + clip:false + + QStyleItem { + id:editItem + elementType:"edit" + sunken:true + focus:textfield.activeFocus + hover:containsMouse + } + + background: QStyleBackground { + anchors.fill:parent + style: QStyleItem{ + elementType:"edit" + sunken:true + focus:textfield.activeFocus + } + } + + Item{ + id:focusFrame + anchors.fill: textfield + parent:textfield + visible:framestyle.styleHint("focuswidget") + QStyleBackground{ + anchors.margins: -2 + anchors.rightMargin:-4 + anchors.bottomMargin:-4 + anchors.fill: parent + visible:textfield.activeFocus + style: QStyleItem { + id:framestyle + elementType:"focusframe" + } + } + } +} diff --git a/src/TextScrollArea.qml b/src/TextScrollArea.qml new file mode 100644 index 00000000..2a7deab6 --- /dev/null +++ b/src/TextScrollArea.qml @@ -0,0 +1,31 @@ +import QtQuick 1.0 +import "../../../components" as Components +import "../plugin" + +ScrollArea { + id:area + color: "white" + width: 280 + height: 120 + contentWidth: 200 + + property alias text: edit.text + property alias wrapMode: edit.wrapMode + highlightOnFocus: true + + TextEdit { + id: edit + text: loremIpsum + loremIpsum; + wrapMode: TextEdit.WordWrap; + width: area.contentWidth + selectByMouse:true + + // keep textcursor within scrollarea + onCursorRectangleChanged: + if (cursorRectangle.y >= area.contentY + area.height - 1.5*cursorRectangle.height) + area.contentY = cursorRectangle.y - area.height + 1.5*cursorRectangle.height + else if (cursorRectangle.y < area.contentY) + area.contentY = cursorRectangle.y + + } +} diff --git a/src/ToolBar.qml b/src/ToolBar.qml new file mode 100644 index 00000000..ce61382e --- /dev/null +++ b/src/ToolBar.qml @@ -0,0 +1,12 @@ +import QtQuick 1.0 +import "../../../components" as Components +import "../plugin" + +QStyleBackground { + id:styleitem + width:200 + height:60 + + style: QStyleItem{elementType:"toolbar"} +} + diff --git a/src/ToolButton.qml b/src/ToolButton.qml new file mode 100644 index 00000000..98b2dfeb --- /dev/null +++ b/src/ToolButton.qml @@ -0,0 +1,18 @@ +import QtQuick 1.0 +import "../../../components" as Components +import "../plugin" + +Components.Button { + id:button + minimumWidth:30 + background: QStyleBackground { + anchors.fill:parent + style: QStyleItem { + elementType: "toolbutton" + on: pressed | checked + sunken: pressed + raised: containsMouse + hover: containsMouse + } + } +} diff --git a/src/components/ButtonGroup.js b/src/components/ButtonGroup.js new file mode 100644 index 00000000..f2d00002 --- /dev/null +++ b/src/components/ButtonGroup.js @@ -0,0 +1,127 @@ +var self; +var clickHandlers = []; +var visibleButtons = []; +var nonVisibleButtons = []; +var direction; +var exclusive; + +function create(that, options) { + self = that; + direction = options.direction || Qt.Horizontal; + exclusive = self.exclusive|| options.exclusive; + self.childrenChanged.connect(rebuild); +// self.widthChanged.connect(resizeChildren); + build(); +} + +function isButton(item) { + if (item && item["__position"] !== undefined) + return true; + return false; +} + +function hasChecked(item) { + if (item && item["checked"] !== undefined) + return true; + return false; +} + +function destroy() { + self.childrenChanged.disconnect(rebuild); +// self.widthChanged.disconnect(resizeChildren); + cleanup(); +} + +function build() { + visibleButtons = []; + nonVisibleButtons = []; + + for (var i = 0, item; (item = self.children[i]); i++) { + if (!hasChecked(item)) + continue; + + item.visibleChanged.connect(rebuild); // Not optimal, but hardly a bottleneck in your app + if (!item.visible) { + nonVisibleButtons.push(item); + continue; + } + visibleButtons.push(item); + + if (exclusive && hasChecked(item)) { + if (item["checkable"]!==undefined) { + item.checkable = true; + } + clickHandlers[i] = checkExclusive(item); + item.clicked.connect(clickHandlers[i]); + } + } + + if (self.checkedButton && !self.checkedButton.visible) + self.checkedButton = undefined; + + var nrButtons = visibleButtons.length; + if (nrButtons == 0) + return; + + if (nrButtons == 1) { + finishButton(visibleButtons[0], "only"); + } else { + finishButton(visibleButtons[0], direction == Qt.Horizontal ? "leftmost" : "top"); + for (var i = 1; i < nrButtons - 1; i++) + finishButton(visibleButtons[i], direction == Qt.Horizontal ? "h_middle": "v_middle"); + finishButton(visibleButtons[nrButtons - 1], direction == Qt.Horizontal ? "rightmost" : "bottom"); + } +} + +function finishButton(button, position) { + if (isButton(button)) { + button.__position = position; + if (direction == Qt.Vertical) { + button.anchors.left = self.left + button.anchors.right = self.right + } + } +} + +function cleanup() { + visibleButtons.forEach(function(item, i) { + if (clickHandlers[i]) + item.clicked.disconnect(clickHandlers[i]); + item.visibleChanged.disconnect(rebuild); + }); + clickHandlers = []; + + nonVisibleButtons.forEach(function(item, i) { + item.visibleChanged.disconnect(rebuild); + }); +} + +function rebuild() { + cleanup(); + build(); +} + +function resizeChildren() { + if (direction != Qt.Horizontal) + return; + + var extraPixels = self.width % visibleButtons; + var buttonSize = (self.width - extraPixels) / visibleButtons; + visibleButtons.forEach(function(item, i) { + if (!item || !item.visible) + return; + item.width = buttonSize + (extraPixels > 0 ? 1 : 0); + if (extraPixels > 0) + extraPixels--; + }); +} + +function checkExclusive(item) { + var button = item; + return function() { + for (var i = 0, ref; (ref = visibleButtons[i]); i++) { + ref.checked = button === ref; + } + self.checkedButton = button; + } +} diff --git a/src/components/components.pro b/src/components/components.pro new file mode 100644 index 00000000..be0663d7 --- /dev/null +++ b/src/components/components.pro @@ -0,0 +1,49 @@ +TEMPLATE = subdirs # XXX: Avoid call the linker +TARGETPATH = Qt/labs/components/custom + +symbian { + INSTALL_IMPORTS = /resource/qt/imports +} else { + INSTALL_IMPORTS = $$[QT_INSTALL_IMPORTS] +} + +QML_FILES = \ + qmldir \ + BasicButton.qml \ + BusyIndicator.qml \ + ButtonBlock.qml \ + ButtonColumn.qml \ + ButtonRow.qml \ + ButtonGroup.js \ + Button.qml \ + CheckBox.qml \ + ChoiceList.qml \ + ProgressBar.qml \ + RadioButton.qml \ + ScrollDecorator.qml \ + ScrollIndicator.qml \ + Slider.qml \ + SpinBox.qml \ + Switch.qml \ + TextArea.qml \ + TextField.qml + +QML_DIRS = \ + behaviors \ + private \ + styles \ + visuals + +qmlfiles.files = $$QML_FILES +qmlfiles.sources = $$QML_FILES +qmlfiles.path = $$INSTALL_IMPORTS/$$TARGETPATH + +qmldirs.files = $$QML_DIRS +qmldirs.sources = $$QML_DIRS +qmldirs.path = $$INSTALL_IMPORTS/$$TARGETPATH + +INSTALLS += qmlfiles qmldirs + +symbian { + DEPLOYMENT += qmlfiles qmldirs +} diff --git a/src/components/qmldir b/src/components/qmldir new file mode 100644 index 00000000..6e256a81 --- /dev/null +++ b/src/components/qmldir @@ -0,0 +1,17 @@ +BasicButton 1.0 BasicButton.qml +BusyIndicator 1.0 BusyIndicator.qml +ButtonBlock 1.0 ButtonBlock.qml +Button 1.0 Button.qml +ButtonColumn 1.0 ButtonColumn.qml +ButtonRow 1.0 ButtonRow.qml +CheckBox 1.0 CheckBox.qml +ChoiceList 1.0 ChoiceList.qml +ProgressBar 1.0 ProgressBar.qml +RadioButton 1.0 RadioButton.qml +ScrollDecorator 1.0 ScrollDecorator.qml +ScrollIndicator 1.0 ScrollIndicator.qml +Slider 1.0 Slider.qml +SpinBox 1.0 SpinBox.qml +Switch 1.0 Switch.qml +TextArea 1.0 TextArea.qml +TextField 1.0 TextField.qml diff --git a/src/images/folder_new.png b/src/images/folder_new.png Binary files differnew file mode 100644 index 00000000..8d8bb9bd --- /dev/null +++ b/src/images/folder_new.png diff --git a/src/plugin/qmldir b/src/plugin/qmldir new file mode 100644 index 00000000..e8452efd --- /dev/null +++ b/src/plugin/qmldir @@ -0,0 +1 @@ +plugin styleplugin diff --git a/src/styleitem/styleitem.pro b/src/styleitem/styleitem.pro new file mode 100644 index 00000000..b254cd1e --- /dev/null +++ b/src/styleitem/styleitem.pro @@ -0,0 +1,38 @@ +TEMPLATE = lib +CONFIG += qt plugin +QT += declarative +QT += script + +TARGET = styleplugin + +DESTDIR = ..\\plugin +OBJECTS_DIR = tmp +MOC_DIR = tmp + +HEADERS += qstyleplugin.h \ + qstyleitem.h + +SOURCES += qstyleplugin.cpp \ + qstyleitem.cpp + + +OTHER_FILES += \ + ../widgets/Button.qml \ + ../widgets/CheckBox.qml \ + ../widgets/ChoiceList.qml \ + ../widgets/GroupBox.qml \ + ../widgets/ProgressBar.qml \ + ../widgets/RadioButton.qml \ + ../widgets/ScrollArea.qml \ + ../widgets/ScrollBar.qml \ + ../widgets/Slider.qml \ + ../widgets/SpinBox.qml \ + ../widgets/Switch.qml \ + ../widgets/TextArea.qml \ + ../widgets/TextField.qml \ + ../widgets/ToolBar.qml \ + ../widgets/ToolButton.qml \ + ../gallery.qml \ + ../widgets/Tab.qml \ + ../widgets/TabBar.qml \ + ../widgets/TabFrame.qml diff --git a/src/widgets/Button.qml b/src/widgets/Button.qml new file mode 100644 index 00000000..496d37df --- /dev/null +++ b/src/widgets/Button.qml @@ -0,0 +1,27 @@ +import QtQuick 1.0 +import "../../../components" as Components +import "../plugin" + +Components.Button { + id:button + + property int buttonHeight: Math.max(22, styleitem.sizeFromContents(100, 6).height) + height: buttonHeight + + QStyleItem { + id:styleitem + elementType:"button" + sunken: pressed + raised: !pressed + hover: containsMouse + enabled:button.enabled + text:button.text + } + + background: + QStyleBackground { + style:styleitem + anchors.fill:parent + } +} + diff --git a/src/widgets/ButtonRow.qml b/src/widgets/ButtonRow.qml new file mode 100644 index 00000000..623c5f44 --- /dev/null +++ b/src/widgets/ButtonRow.qml @@ -0,0 +1,5 @@ +import QtQuick 1.0 +import "../../../components" as Components + +Components.ButtonRow { +} diff --git a/src/widgets/CheckBox.qml b/src/widgets/CheckBox.qml new file mode 100644 index 00000000..632dce2d --- /dev/null +++ b/src/widgets/CheckBox.qml @@ -0,0 +1,26 @@ +import QtQuick 1.0 +import "../../../components" as Components +import "../plugin" + +// jb : Size should not depend on background, we should make it consistent + +Components.CheckBox{ + id:checkbox + property variant text + width:100 + height:18 + + background: QStyleBackground { + id:styleitem + style:QStyleItem { + elementType:"checkbox" + sunken:pressed + on:checked || pressed + hover:containsMouse + text:checkbox.text + enabled:checkbox.enabled + } + } + checkmark: null +} + diff --git a/src/widgets/ChoiceList.qml b/src/widgets/ChoiceList.qml new file mode 100644 index 00000000..5015fbef --- /dev/null +++ b/src/widgets/ChoiceList.qml @@ -0,0 +1,52 @@ +import QtQuick 1.0 +import "../../../components" as Components +import "../plugin" + +Components.ChoiceList { + id:choicelist + + property int buttonHeight: buttonitem.sizeFromContents(100, 18).height + QStyleItem { id:buttonitem; elementType:"combobox" } + height: buttonHeight + topMargin:4 + bottomMargin:4 + + QStyleItem { + id:styleitem + elementType: "combobox" + sunken: pressed + raised: !pressed + hover: containsMouse + enabled:choicelist.enabled + } + + background: QStyleBackground { + anchors.fill:parent + style: styleitem + } + + listItem: Item { + id:item + + height:22 + anchors.left:parent.left + width:choicelist.width + QStyleBackground { + anchors.fill:parent + style: QStyleItem { + elementType: "menuitem" + text: choicelist.model.get(index).text + selected: highlighted + } + } + } + + popupFrame: QStyleBackground { + property int fw: styleitem.pixelMetric("menupanelwidth"); + anchors.leftMargin: styleitem.pixelMetric("menuhmargin") + fw + anchors.rightMargin: styleitem.pixelMetric("menuhmargin") + fw + anchors.topMargin: styleitem.pixelMetric("menuvmargin") + fw + anchors.bottomMargin: styleitem.pixelMetric("menuvmargin") + fw + style:QStyleItem{elementType:"menu"} + } +} diff --git a/src/widgets/GroupBox.qml b/src/widgets/GroupBox.qml new file mode 100644 index 00000000..0d45810d --- /dev/null +++ b/src/widgets/GroupBox.qml @@ -0,0 +1,27 @@ +import QtQuick 1.0 +import "../../../components" as Components +import "../plugin" + +Item { + width:200 + height:46 + + property alias text: styleitem.text + default property alias children: content.children + property bool checkable: false + + QStyleBackground { + anchors.fill:parent + style: QStyleItem{ + id:styleitem + elementType:"groupbox" + } + + Item { + id:content + anchors.topMargin:22 + anchors.leftMargin:6 + anchors.fill:parent + } + } +} diff --git a/src/widgets/ProgressBar.qml b/src/widgets/ProgressBar.qml new file mode 100644 index 00000000..bf29bcac --- /dev/null +++ b/src/widgets/ProgressBar.qml @@ -0,0 +1,31 @@ +import QtQuick 1.0 +import "../../../components" as Components +import "../plugin" + +Components.ProgressBar { + id:progressbar + + // Align with button + property int buttonHeight: buttonitem.sizeFromContents(100, 15).height + QStyleItem { id:buttonitem; elementType:"button" } + height: buttonHeight + + background: QStyleBackground{ + anchors.fill:parent + style: QStyleItem { + elementType:"progressbar" + + // XXX: since desktop uses int instead of real, the progressbar + // range [0..1] must be stretched to a good precision + property int factor : 1000000 + + value: progressbar.value * factor + minimum: indeterminate ? 0 : progressbar.minimumValue * factor + maximum: indeterminate ? 0 : progressbar.maximumValue * factor + enabled: progressbar.enabled + } + } + indeterminateProgress:null + progress: null +} + diff --git a/src/widgets/RadioButton.qml b/src/widgets/RadioButton.qml new file mode 100644 index 00000000..3c2c3e54 --- /dev/null +++ b/src/widgets/RadioButton.qml @@ -0,0 +1,26 @@ +import QtQuick 1.0 +import "../../../components" as Components +import "../plugin" + +// jb : Size should not depend on background, we should make it consistent + +Components.RadioButton{ + id:radiobutton + property variant text + width:110 + height:18 + + background: QStyleBackground { + + style: QStyleItem{ + elementType:"radiobutton" + sunken:pressed + on:checked || pressed + hover:containsMouse + text:radiobutton.text + enabled:radiobutton.enabled + } + } + checkmark: null +} + diff --git a/src/widgets/ScrollArea.qml b/src/widgets/ScrollArea.qml new file mode 100644 index 00000000..3a904dde --- /dev/null +++ b/src/widgets/ScrollArea.qml @@ -0,0 +1,103 @@ +import QtQuick 1.0 +import "../../../components" as Components +import "../plugin" + +FocusScope { + id:scrollarea + width: 100 + height: 100 + + property int contentMargin: 1 + property int __scrollbarExtent : styleitem.pixelMetric("scrollbarExtent"); + property int frameWidth: styleitem.pixelMetric("defaultframewidth"); + property int contentHeight : content.childrenRect.height + property int contentWidth: content.childrenRect.width + property alias color: flickable.color + property bool frame: true + property bool highlightOnFocus: false + + default property alias children: content.children + + property int contentY + property int contentX + + property bool frameAroundContents: styleitem.styleHint("framearoundcontents") + + onContentYChanged: { + vscrollbar.value = contentY + } + + onContentXChanged: { + hscrollbar.value = contentX + } + + QStyleBackground { + style: QStyleItem{ + id:styleitem + elementType: frame ? "frame" : "" + sunken: true + } + anchors.fill: parent + anchors.rightMargin: (frameAroundContents && vscrollbar.visible) ? vscrollbar.width + 4 : -frameWidth + anchors.bottomMargin: (frameAroundContents && hscrollbar.visible) ? hscrollbar.height + 4 : -frameWidth + anchors.topMargin: (frameAroundContents && hscrollbar.visible) ? hscrollbar.height + 4 : -frameWidth + + Rectangle { + id:flickable + color: "transparent" + anchors.fill: parent + anchors.margins: frame ? 2 : 0 + clip: true + + Item { + id: docmargins + anchors.fill:parent + anchors.margins:contentMargin + Item { + id: content + x: -scrollarea.contentX + y: -scrollarea.contentY + } + } + } + } + + ScrollBar { + id: hscrollbar + orientation: Qt.Horizontal + visible: contentWidth > flickable.width + maximumValue: contentWidth > flickable.width ? scrollarea.contentWidth - flickable.width : 0 + minimumValue: 0 + anchors.bottom: parent.bottom + anchors.left: parent.left + anchors.right: parent.right + anchors.rightMargin: { return (frame ? 1 : 0) + ( vscrollbar.visible ? __scrollbarExtent : 0) } + onValueChanged: contentX = value + } + + ScrollBar { + id: vscrollbar + orientation: Qt.Vertical + visible: contentHeight > flickable.height + maximumValue: contentHeight > flickable.height ? scrollarea.contentHeight - flickable.height : 0 + minimumValue: 0 + anchors.right: parent.right + anchors.top: parent.top + anchors.bottom: parent.bottom + anchors.bottomMargin: { return (frame ? 1 : 0) + (hscrollbar.visible ? __scrollbarExtent : 0) } + onValueChanged: contentY = value + } + + QStyleBackground { + z:2 + anchors.fill:parent + anchors.margins:-2 + anchors.rightMargin:-4 + anchors.bottomMargin:-4 + visible: highlightOnFocus && parent.activeFocus && styleitem.styleHint("focuswidget") + style: QStyleItem { + id:framestyle + elementType:"focusframe" + } + } +} diff --git a/src/widgets/ScrollBar.qml b/src/widgets/ScrollBar.qml new file mode 100644 index 00000000..ea822b62 --- /dev/null +++ b/src/widgets/ScrollBar.qml @@ -0,0 +1,109 @@ +import QtQuick 1.1 +import "../../../components" as Components +import "../plugin" + +MouseArea { + id:scrollbar + property int __scrollbarExtent : styleitem.pixelMetric("scrollbarExtent"); + implicitWidth:orientation == Qt.Horizontal ? 200 : __scrollbarExtent; + implicitHeight:orientation == Qt.Horizontal ? __scrollbarExtent : 200 + + property int orientation : Qt.Horizontal + property alias minimumValue: slider.minimumValue + property alias maximumValue: slider.maximumValue + property alias value: slider.value + + property bool upPressed; + property bool downPressed; + property bool __autoincrement: false + + // Update hover item + onEntered: styleitem.activeControl = bgitem.hitTest(mouseX, mouseY) + onExited: styleitem.activeControl = "none" + onMouseXChanged: styleitem.activeControl = bgitem.hitTest(mouseX, mouseY) + hoverEnabled:true + + Timer { running: upPressed || downPressed; interval: 350 ; onTriggered: __autoincrement = true } + Timer { running: __autoincrement; interval: 60 ; repeat: true ; + onTriggered: upPressed ? decrement() : increment() } + + onPressed: { + var control = bgitem.hitTest(mouseX,mouseY) + if (control == "up") { + upPressed = true + } else if (control == "down") { + downPressed = true + } + } + + onReleased: { + __autoincrement = false; + if (upPressed) { + upPressed = false; + decrement() + } else if (downPressed) { + increment() + downPressed = false; + } + } + + function increment() { + value += 30 + if (value > maximumValue) + value = maximumValue + } + + function decrement() { + value -= 30 + if (value < minimumValue) + value = minimumValue + } + + QStyleBackground { + id:bgitem + anchors.fill:parent + style: QStyleItem { + id:styleitem + elementType: "scrollbar" + hover: activeControl != "none" + activeControl: "none" + sunken: upPressed | downPressed + minimum: slider.minimumValue + maximum: slider.maximumValue + value: slider.value + horizontal: orientation == Qt.Horizontal + enabled: parent.enabled + } + } + + property variant handleRect + function updateHandle() { + handleRect = bgitem.subControlRect("handle") + var grooveRect = bgitem.subControlRect("groove"); + var extra = 0 + if (orientation == Qt.Vertical) { + slider.anchors.topMargin = grooveRect.y + extra + slider.anchors.bottomMargin = height - grooveRect.y - grooveRect.height + extra + } else { + slider.anchors.leftMargin = grooveRect.x + extra + slider.anchors.rightMargin = width - grooveRect.x - grooveRect.width + extra + } + } + + onValueChanged: updateHandle() + onMaximumValueChanged: updateHandle() + onMinimumValueChanged: updateHandle() + Component.onCompleted: updateHandle() + Components.Slider { + id:slider + anchors.fill:parent + orientation:scrollbar.orientation + leftMargin: (orientation === Qt.Horizontal) ? handleRect.width/2 : handleRect.height/2 + rightMargin:leftMargin + handle: Item { width:orientation == Qt.Vertical ? handleRect.height : handleRect.width; + height:orientation == Qt.Vertical ? handleRect.width : handleRect.height} + groove:null + valueIndicator:null + inverted:orientation != Qt.Horizontal + } +} diff --git a/src/widgets/Slider.qml b/src/widgets/Slider.qml new file mode 100644 index 00000000..c6b9c915 --- /dev/null +++ b/src/widgets/Slider.qml @@ -0,0 +1,31 @@ +import QtQuick 1.0 +import "../../../components" as Components +import "../plugin" + +// jens: ContainsMouse breaks drag functionality + +Components.Slider{ + id:slider + minimumWidth:200 + + // Align with button + property int buttonHeight: buttonitem.sizeFromContents(100, 15).height + QStyleItem { id:buttonitem; elementType:"button" } + height: buttonHeight + + groove: QStyleBackground { + anchors.fill:parent + style: QStyleItem{ + elementType:"slider" + sunken: pressed + maximum:slider.maximumValue + minimum:slider.minimumValue + value:slider.value + horizontal:slider.orientation == Qt.Horizontal + enabled:slider.enabled + } + } + + handle: null + valueIndicator: null +} diff --git a/src/widgets/SpinBox.qml b/src/widgets/SpinBox.qml new file mode 100644 index 00000000..2db428ce --- /dev/null +++ b/src/widgets/SpinBox.qml @@ -0,0 +1,91 @@ +import QtQuick 1.0 +import "../../../components" as Components +import "../plugin" + +Components.SpinBox { + id:spinbox + + property variant __upRect; + property variant __downRect; + property int __margin: (height -16)/2 + + // Align height with button + topMargin:__margin + bottomMargin:__margin + + property int buttonHeight: edititem.sizeFromContents(100, 20).height + QStyleItem { id:edititem; elementType:"edit" } + height: buttonHeight + clip:false + + background: + Item { + anchors.fill: parent + property variant __editRect + + Rectangle { + id:editBackground + x: __editRect.x - 1 + y: __editRect.y + width: __editRect.width + height: __editRect.height + } + + Item { + id:focusFrame + anchors.fill: editBackground + visible:framestyle.styleHint("focuswidget") + QStyleBackground{ + anchors.margins: -6 + anchors.leftMargin: -5 + anchors.fill: parent + visible:spinbox.activeFocus + style: QStyleItem { + id:framestyle + elementType:"focusframe" + } + } + } + + function updateRect() { + __upRect = spinboxbg.subControlRect("up"); + __downRect = spinboxbg.subControlRect("down"); + __editRect = spinboxbg.subControlRect("edit"); + } + + Component.onCompleted:updateRect() + onWidthChanged:updateRect() + onHeightChanged:updateRect() + + QStyleBackground { + id:spinboxbg + anchors.fill:parent + style: QStyleItem { + id: styleitem + elementType: "spinbox" + sunken: downPressed | upPressed + hover: containsMouse + focus: spinbox.activeFocus + enabled: spinbox.enabled + value: (upPressed? 1 : 0) | + (downPressed== 1 ? 1<<1 : 0) | + (upEnabled? (1<<2) : 0) | + (downEnabled == 1 ? (1<<3) : 0) + } + } + } + + up: Item { + x: __upRect.x + y: __upRect.y + width: __upRect.width + height: __upRect.height + } + + down: Item { + x: __downRect.x + y: __downRect.y + width: __downRect.width + height: __downRect.height + } +} diff --git a/src/widgets/Switch.qml b/src/widgets/Switch.qml new file mode 100644 index 00000000..b82817c9 --- /dev/null +++ b/src/widgets/Switch.qml @@ -0,0 +1,22 @@ +import QtQuick 1.0 +import "../../../components" as Components +import "../plugin" + +Components.Switch { + id:widget + minimumWidth:100 + minimumHeight:30 + + groove:QStyleItem { + elementType:"edit" + sunken: true + } + + handle: QStyleItem { + elementType:"button" + width:widget.width/2 + height:widget.height-4 + hover:containsMouse + } +} + diff --git a/src/widgets/Tab.qml b/src/widgets/Tab.qml new file mode 100644 index 00000000..e258185b --- /dev/null +++ b/src/widgets/Tab.qml @@ -0,0 +1,7 @@ +import Qt 4.7 + +Item { + id:tab + anchors.fill:parent + property string title +} diff --git a/src/widgets/TabBar.qml b/src/widgets/TabBar.qml new file mode 100644 index 00000000..2d891256 --- /dev/null +++ b/src/widgets/TabBar.qml @@ -0,0 +1,90 @@ +import QtQuick 1.0 +import "../../../components" as Components +import "../plugin" + + +Item { + id: tabbar + property int tabHeight: styleitem.sizeFromContents(100, 24).height + height: tabHeight + + property Item tabFrame + onTabFrameChanged:parent = tabFrame + visible: tabFrame ? tabFrame.tabsVisible : true + property int __overlap : styleitem.pixelMetric("tabvshift"); + property string position: tabFrame ? tabFrame.position : "North" + property string tabBarAlignment: styleitem.styleHint("tabbaralignment"); + property int tabOverlap: styleitem.pixelMetric("taboverlap"); + + function tab(index) { + for (var i = 0; i < tabrow.children.length; ++i) { + if (tabrow.children[i].tabindex == index) { + return tabrow.children[i] + } + } + return null; + } + + QStyleItem { + id:styleitem + elementType: "tab" + text: "generic" + } + + Row { + id:tabrow + states: + State { + when: tabBarAlignment == "center" + name: "centered" + AnchorChanges { + target:tabrow + anchors.horizontalCenter: tabbar.horizontalCenter + } + } + Repeater { + id:repeater + model: tabFrame ? tabFrame.tabs.length : null + delegate: Item { + id:tab + property int tabindex: index + property bool selected : tabFrame.current == index + width: textitem.width + 42 + height: tabHeight + z: selected ? 1 : -1 + + QStyleBackground { + style: QStyleItem { + id:style + elementType: "tab" + selected: tab.selected + text: tabbar.position + + activeControl: tabFrame.count == 1 ? + "only" : + index == 0 ? "beginning" : + index == tabFrame.count-1 ? "end" : "middle" + } + anchors.leftMargin: -tabOverlap + (style.text == "North" && (style.activeControl == "middle" || style.activeControl == "end") + && tab.selected ? -__overlap : 0) + + anchors.rightMargin: -tabOverlap + (style.text == "North" && (style.activeControl == "middle" || style.activeControl == "beginning") + && tab.selected ? -__overlap : 0) + anchors.fill:parent + } + + Text { + id:textitem + anchors.centerIn:parent + text: tabFrame.tabs[index].title + elide: Text.ElideRight + } + + MouseArea { + anchors.fill: parent + onPressed: tabFrame.current = index + } + } + } + } +} diff --git a/src/widgets/TabFrame.qml b/src/widgets/TabFrame.qml new file mode 100644 index 00000000..01896e75 --- /dev/null +++ b/src/widgets/TabFrame.qml @@ -0,0 +1,72 @@ +import QtQuick 1.0 +import "../../../components" as Components +import "../plugin" + +Item{ + id: tabWidget + width:100 + height:100 + property TabBar tabbar + property int current: 0 + property int count: stack.children.length + property bool frame:true + property bool tabsVisible: true + property string position: "North" + default property alias tabs : stack.children + + onCurrentChanged: __setOpacities() + Component.onCompleted: __setOpacities() + onTabbarChanged: { + tabbar.tabFrame = tabWidget + tabbar.anchors.top = tabWidget.top + tabbar.anchors.left = tabWidget.left + tabbar.anchors.right = tabWidget.right + } + + property int __baseOverlap : style.pixelMetric("tabbaseoverlap"); + function __setOpacities() { + for (var i = 0; i < stack.children.length; ++i) { + stack.children[i].opacity = (i == current ? 1 : 0) + } + } + + QStyleBackground { + id: frame + z:-1 + style: QStyleItem { + id:style + elementType: "tabframe" + text: position + value: tabbar && tabsVisible && tabbar.tab(current) ? tabbar.tab(current).x : 0 + minimum: tabbar && tabsVisible && tabbar.tab(current) ? tabbar.tab(current).width : 0 + } + anchors.fill:parent + Item { + id:stack + anchors.fill:parent + anchors.margins: frame ? 2 : 0 + } + anchors.topMargin: tabbar && tabsVisible && position == "North" ? tabbar.height - __baseOverlap : 0 + + states: [ + State { + name: "South" + when: position == "South" && tabbar!= undefined + PropertyChanges { + target: frame + anchors.topMargin: 0 + anchors.bottomMargin: tabbar ? tabbar.height - __baseOverlap: 0 + } + PropertyChanges { + target: tabbar + anchors.topMargin: -__baseOverlap + } + AnchorChanges { + target: tabbar + anchors.top: frame.bottom + anchors.bottom: undefined + } + } + ] + } +} diff --git a/src/widgets/TextArea.qml b/src/widgets/TextArea.qml new file mode 100644 index 00000000..93ad8f3d --- /dev/null +++ b/src/widgets/TextArea.qml @@ -0,0 +1,44 @@ +import QtQuick 1.0 +import "../../../components" as Components +import "../plugin" + +Components.TextArea { + id:textarea + leftMargin:12 + rightMargin:12 + minimumWidth:200 + desktopBehavior:true + placeholderText:"" + clip:false + // Align with button + property int buttonHeight: buttonitem.sizeFromContents(100, 14).height + QStyleItem { id:buttonitem; elementType:"button" } + minimumHeight: buttonHeight + + background: QStyleBackground { + anchors.fill:parent + style: QStyleItem{ + elementType:"edit" + sunken:true + focus:textarea.activeFocus + } + } + + Item{ + id:focusFrame + anchors.fill: textarea + parent:textarea.parent + visible:framestyle.styleHint("focuswidget") + QStyleBackground{ + anchors.margins: -2 + anchors.rightMargin:-4 + anchors.bottomMargin:-4 + anchors.fill: parent + visible:textarea.activeFocus + style: QStyleItem { + id:framestyle + elementType:"focusframe" + } + } + } +} diff --git a/src/widgets/TextField.qml b/src/widgets/TextField.qml new file mode 100644 index 00000000..260584e9 --- /dev/null +++ b/src/widgets/TextField.qml @@ -0,0 +1,52 @@ +import QtQuick 1.0 +import "../../../components" as Components +import "../plugin" + +Components.TextField { + id:textfield + minimumWidth:200 + desktopBehavior:true + placeholderText:"" + topMargin:2 + bottomMargin:2 + leftMargin:6 + rightMargin:6 + width:200 + height: editItem.sizeFromContents(100, 20).height + clip:false + + QStyleItem { + id:editItem + elementType:"edit" + sunken:true + focus:textfield.activeFocus + hover:containsMouse + } + + background: QStyleBackground { + anchors.fill:parent + style: QStyleItem{ + elementType:"edit" + sunken:true + focus:textfield.activeFocus + } + } + + Item{ + id:focusFrame + anchors.fill: textfield + parent:textfield + visible:framestyle.styleHint("focuswidget") + QStyleBackground{ + anchors.margins: -2 + anchors.rightMargin:-4 + anchors.bottomMargin:-4 + anchors.fill: parent + visible:textfield.activeFocus + style: QStyleItem { + id:framestyle + elementType:"focusframe" + } + } + } +} diff --git a/src/widgets/TextScrollArea.qml b/src/widgets/TextScrollArea.qml new file mode 100644 index 00000000..2a7deab6 --- /dev/null +++ b/src/widgets/TextScrollArea.qml @@ -0,0 +1,31 @@ +import QtQuick 1.0 +import "../../../components" as Components +import "../plugin" + +ScrollArea { + id:area + color: "white" + width: 280 + height: 120 + contentWidth: 200 + + property alias text: edit.text + property alias wrapMode: edit.wrapMode + highlightOnFocus: true + + TextEdit { + id: edit + text: loremIpsum + loremIpsum; + wrapMode: TextEdit.WordWrap; + width: area.contentWidth + selectByMouse:true + + // keep textcursor within scrollarea + onCursorRectangleChanged: + if (cursorRectangle.y >= area.contentY + area.height - 1.5*cursorRectangle.height) + area.contentY = cursorRectangle.y - area.height + 1.5*cursorRectangle.height + else if (cursorRectangle.y < area.contentY) + area.contentY = cursorRectangle.y + + } +} diff --git a/src/widgets/ToolBar.qml b/src/widgets/ToolBar.qml new file mode 100644 index 00000000..ce61382e --- /dev/null +++ b/src/widgets/ToolBar.qml @@ -0,0 +1,12 @@ +import QtQuick 1.0 +import "../../../components" as Components +import "../plugin" + +QStyleBackground { + id:styleitem + width:200 + height:60 + + style: QStyleItem{elementType:"toolbar"} +} + diff --git a/src/widgets/ToolButton.qml b/src/widgets/ToolButton.qml new file mode 100644 index 00000000..98b2dfeb --- /dev/null +++ b/src/widgets/ToolButton.qml @@ -0,0 +1,18 @@ +import QtQuick 1.0 +import "../../../components" as Components +import "../plugin" + +Components.Button { + id:button + minimumWidth:30 + background: QStyleBackground { + anchors.fill:parent + style: QStyleItem { + elementType: "toolbutton" + on: pressed | checked + sunken: pressed + raised: containsMouse + hover: containsMouse + } + } +} |