Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make it possible to do some TextField-related actions #303

Open
wants to merge 6 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions demo/TextFieldDemo.qml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import QtQuick 2.0
import QtQuick.Layouts 1.1
import QtQuick.Controls 1.1 as Controls
import Material 0.1

Item {
Expand Down Expand Up @@ -35,6 +36,17 @@ Item {
anchors.horizontalCenter: parent.horizontalCenter
}

TextField {
placeholderText: "Text Field with Menu"
anchors.horizontalCenter: parent.horizontalCenter
menu: Controls.Menu {
Controls.MenuItem {
text: "Print \"awesome\""
onTriggered: console.log("awesome");
}
}
}

TextField {
id: passwordField
placeholderText: "Password"
Expand All @@ -50,5 +62,8 @@ Item {
}
}
}
TextArea {

}
}
}
2 changes: 1 addition & 1 deletion modules/Material/Button.qml
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ Controls.Button {
The context of the button, which is used to control special styling of
buttons in dialogs or snackbars.
*/
property string context: "default" // or "dialog" or "snackbar"
property string context: "default" // "dialog", "snackbar" or "editmenu"

/*!
Set to \c true if the button is on a dark background
Expand Down
4 changes: 2 additions & 2 deletions modules/Material/IconButton.qml
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ Item {

signal clicked

width: icon.width
height: icon.height
implicitWidth: icon.width
implicitHeight: icon.height
enabled: action ? action.enabled : true
opacity: enabled ? 1 : 0.6

Expand Down
37 changes: 37 additions & 0 deletions modules/Material/TextArea.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* QML Material - An application framework implementing Material Design.
* Copyright (C) 2014 Bogdan Cuza <[email protected]>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please put your own name here and use 2016 for the copyright.

* 2015 Ricardo Vieira <[email protected]>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 2.1 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

import QtQuick 2.4
import QtQuick.Controls 1.3 as Controls
import QtQuick.Controls.Styles.Material 0.1 as MaterialStyle
import Material 0.1

/*!
\qmltype TextArea
\inqmlmodule Material 0.1

\brief A text area input control.
*/
Controls.TextArea {

property color color: Theme.accentColor
property color errorColor: Palette.colors["red"]["500"]

style: MaterialStyle.TextAreaStyle {}
}
1 change: 1 addition & 0 deletions modules/Material/qmldir
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ Switch 0.1 Switch.qml
Tab 0.1 Tab.qml
TabBar 0.1 TabBar.qml
TabbedPage 0.1 TabbedPage.qml
TextArea 0.1 TextArea.qml
TextField 0.1 TextField.qml
ThinDivider 0.1 ThinDivider.qml
TimePicker 0.1 TimePicker.qml
Expand Down
1 change: 1 addition & 0 deletions modules/QtQuick/Controls/Styles/Material/ButtonStyle.qml
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ ButtonStyle {
implicitWidth: context == "dialog"
? Math.max(Units.dp(64), label.width + Units.dp(16))
: context == "snackbar" ? label.width + Units.dp(16)
: context == "editmenu" ? label.width
: Math.max(Units.dp(88), label.width + Units.dp(32))

Label {
Expand Down
178 changes: 178 additions & 0 deletions modules/QtQuick/Controls/Styles/Material/MaterialEditMenu.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
/*
* Copyright (C) 2015 by Aleix Pol Gonzalez <[email protected]>
* Copyright (C) 2015 by Marco Martin <[email protected]>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 2.010-1301, USA.
*/

import QtQuick 2.1
import QtQuick.Controls 1.1
import QtQuick.Controls.Styles 1.1
import QtQuick.Window 2.1
import QtQuick.Layouts 1.0
import Material 0.1

Item {
id: root
anchors.fill: parent
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assignments to existing properties should go under functions and above child objects.


property bool editing: true
onEditingChanged: {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The QML coding conventions doesn't specify the order of signal handlers, but I like to have signal listeners grouped together above functions and below properties.

updateCursorOpacity()
}
function updateCursorOpacity() {
var opacity = root.editing ? 0 : 1;
cursorHandle.opacity = opacity;
selectionHandle.opacity = opacity;
}
Component.onCompleted: updateCursorOpacity()

// https://www.google.com/design/spec/patterns/selection.html#selection-text-selection
Component {
id: editControls
Item {
id: popup
visible: input.activeFocus && !root.editing
z: 9999

Behavior on x { NumberAnimation { duration: 500; easing.type: Easing.InOutQuad } }

parent: Window.contentItem

function popup(startRect) {
var mapped = parent.mapFromItem(input, startRect.x, startRect.y);
var mapWidget = parent.mapFromItem(input.parent, input.x, input.y, input.width, input.height);

popup.x = Math.min(Math.max(mapWidget.x, mapped.x-bg.anchors.leftMargin), mapWidget.x+mapWidget.width-bg.width);
popup.y = Math.max(0, mapped.y - bg.height);

console.log("showing...", popup.x, popup.y, parent)
}

View {
id: bg
elevation: 1
anchors {
fill: buttons
topMargin: -Units.dp(12)
bottomMargin: -Units.dp(14)
leftMargin: -Units.dp(24)
rightMargin: -Units.dp(16)
}
}

RowLayout {
id: buttons
spacing: Units.dp(32)
Button {
text: qsTr("Cut")
visible: input.selectedText != ""
context: "editmenu"
onClicked: {
control.cut();
select(input.cursorPosition, input.cursorPosition);
}
}
Button {
text: qsTr("Copy")
visible: input.selectedText != ""
context: "editmenu"
onClicked: {
control.copy();
select(input.cursorPosition, input.cursorPosition);
}
}
Button {
text: qsTr("Paste")
visible: input.canPaste
context: "editmenu"
onClicked: {
control.paste();
}
}
Button {
text: qsTr("Select All")
visible: input.text != ""
context: "editmenu"
onClicked: {
control.selectAll();
}
}

IconButton {
iconName: "navigation/more_vert"
visible: control.menu !== null
onClicked: {
getMenuInstance().popup()
}
}
}
}
}

Connections {
target: mouseArea

onClicked: {
var pos = input.positionAt(mouse.x, mouse.y)
input.moveHandles(pos, pos)
input.activate()
}
onPressAndHold: {
root.editing = false;
var pos = input.positionAt(mouse.x, mouse.y)
input.moveHandles(pos, control.selectByMouse ? -1 : pos)
input.activate()
}
}

Connections {
target: input
onSelectionStartChanged: popupTimer.restart()
onSelectionEndChanged: popupTimer.restart()
onActiveFocusChanged: {
popupTimer.restart()
root.editing = true;
}
onTextChanged: root.editing = true;
}

Connections {
target: flickable
onMovingChanged: popupTimer.restart()
}

property Item editControlsInstance: null
function getEditControlsInstance() {
// Lazy load the view when first requested
if (!editControlsInstance) {
editControlsInstance = editControls.createObject(control);
}
return editControlsInstance;
}

Timer {
id: popupTimer
interval: 200
onTriggered: {
if (!root.editing && (input.canPaste || selectionStart !== selectionEnd)) {
var startRect = input.positionToRectangle(input.selectionStart);

getEditControlsInstance().popup(startRect);
}
}
}
}
Loading