Showing preview only (278K chars total). Download the full file or copy to clipboard to get everything.
Repository: GDPURJYFS/WellChat
Branch: master
Commit: a861ddfd961b
Files: 97
Total size: 248.8 KB
Directory structure:
gitextract_f1fzdbi7/
├── .gitignore
├── LICENSE
├── README.md
├── Sparrow/
│ ├── Sparrow.pri
│ ├── keyboard.cpp
│ ├── keyboard.h
│ ├── qmlnetworkaccessmanagerfactory.cpp
│ ├── qmlnetworkaccessmanagerfactory.h
│ ├── qtbridgingandroid.cpp
│ ├── qtbridgingandroid.h
│ └── sparrow_global.h
├── WellChat.pro
├── android/
│ ├── AndroidManifest.xml
│ ├── assets/
│ │ └── font/
│ │ └── NotoSansHans-DemiLight.otf
│ ├── build.gradle
│ ├── gradle/
│ │ └── wrapper/
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradlew
│ ├── gradlew.bat
│ ├── res/
│ │ └── values/
│ │ └── libs.xml
│ └── src/
│ └── org/
│ └── gdpurjyfs/
│ ├── sparrow/
│ │ └── QtBridgingAndroid.java
│ └── wellchat/
│ └── WellChatActivity.java
├── deployment.pri
├── desktop.qrc
├── doc/
│ └── weixin-ui-analyse.md
├── main.cpp
├── qml/
│ └── WellChat/
│ ├── BussinessPage/
│ │ ├── Chat/
│ │ │ ├── ChatPage.qml
│ │ │ ├── Heartbeat.qml
│ │ │ ├── Lazy.qml
│ │ │ ├── Tuling123.js
│ │ │ └── heart.js
│ │ ├── ChatsView.qml
│ │ ├── Contacts/
│ │ │ └── ContactsListView.qml
│ │ ├── ContactsView.qml
│ │ ├── Discover/
│ │ │ └── MomentsPage/
│ │ │ └── MomentsPage.qml
│ │ ├── DiscoverPage.qml
│ │ ├── Personal/
│ │ │ ├── FavoritesPage.qml
│ │ │ ├── MyPostsPage.qml
│ │ │ ├── Settings/
│ │ │ │ ├── AboutPage.qml
│ │ │ │ ├── ChatSettingsPage.qml
│ │ │ │ ├── DoNotDisturbSettingsPage.qml
│ │ │ │ ├── GeneralSettingsPage.qml
│ │ │ │ ├── MyAccountSettingsPage.qml
│ │ │ │ ├── NotificationsSettingsPage.qml
│ │ │ │ ├── PrivacySettingsPage.qml
│ │ │ │ └── SettingsGroup.qml
│ │ │ └── SettingsPage.qml
│ │ ├── PersonalPage.qml
│ │ ├── ProfilePage.qml
│ │ ├── R.qml
│ │ └── qmldir
│ ├── Component/
│ │ ├── +android/
│ │ │ └── UI.js
│ │ ├── Constant.qml
│ │ ├── Icon.qml
│ │ ├── IconButton.qml
│ │ ├── IconLabel.qml
│ │ ├── MainListView.qml
│ │ ├── SampleTextArea.qml
│ │ ├── ScrollBar.qml
│ │ ├── Separator.qml
│ │ └── UI.js
│ ├── MainView.qml
│ ├── Sparrow/
│ │ ├── +android/
│ │ │ ├── UI.js
│ │ │ └── WebPage.qml
│ │ ├── BottomBar.qml
│ │ ├── ClickedShaderEffect.qml
│ │ ├── GeneralSettings.qml
│ │ ├── Page.qml
│ │ ├── PageStackWindow.qml
│ │ ├── PopupLayer/
│ │ │ ├── Delegate/
│ │ │ │ ├── PopupLayerBottomMenuDelegate.qml
│ │ │ │ ├── PopupLayerDialogDelegate.qml
│ │ │ │ ├── PopupLayerSideMenuDelegate.qml
│ │ │ │ └── qmldir
│ │ │ ├── PopupLayer.qml
│ │ │ ├── PopupLayerDelegate.qml
│ │ │ ├── PopupLayerTransition.qml
│ │ │ ├── qmldir
│ │ │ └── readme.md
│ │ ├── QObject.qml
│ │ ├── SampleButton.qml
│ │ ├── SampleIcon.qml
│ │ ├── SampleLabel.qml
│ │ ├── SampleTextField.qml
│ │ ├── TopBar.qml
│ │ ├── Tracker.qml
│ │ ├── UI.js
│ │ ├── WebPage.qml
│ │ ├── qmldir
│ │ └── resources/
│ │ ├── NotoSansHans-DemiLight.otf
│ │ └── readme.md
│ ├── WellChat.qmlproject
│ ├── main.qml
│ └── resource/
│ ├── R.qml
│ └── qmldir
├── qml.qrc
└── src/
└── wellchat/
├── collectionsmodel.cpp
└── collectionsmodel.h
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
WellChat.pro.user
*.user
================================================
FILE: LICENSE
================================================
The MIT License (MIT)
Copyright (c) 2015 GDPURJYFS
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: README.md
================================================
# WellChat
WellChat is a Application that is a WeChat-like APP by qml.
> best tool vesion:
> Qt version >= 5.5.0
> Android SDK APi >= 19
> Android 5.0 or new
使用 qml 来仿制安卓微信的 Qt 程序,可以运行在安卓上。
## 界面展示
### 480 * 800
微信界面

仿制界面




### 1080P
微信界面








植入图灵聊天机器人的聊天界面

## QML开发安卓应用的局限
`QtQuick.Control` 这个模块是专门为桌面平台准备的,对移动平台支持并不完善。不能很好地动态切换不同的 `ToolBar` 和 `StatusBar` 来适配不同的页面。
如何设计一个简单的页面栈呢?查看[简单易用的页面栈框架](https://github.com/GDPURJYFS/Sparrow)
## 剖析界面
微信界面的主要操作交互逻辑有首界面的四个可以切换的分页,以及一个页面栈。查看[微信界面剖析](doc/weixin-ui-analyse.md)
---
***images and protocol Copyright (C) by [Tencent] (http://weixin.qq.com/)***
***图片、协议版权归[腾讯] (http://weixin.qq.com/) 所有!***
================================================
FILE: Sparrow/Sparrow.pri
================================================
QT += core network sql qml
android {
QT += androidextras
}
HEADERS += \
#$$PWD/qmlnetworkaccessmanagerfactory.h \
#$$PWD/notificationclient.h \
$$PWD/keyboard.h \
$$PWD/sparrow_global.h \
#$$PWD/qtnativeforandroid.h \
$$PWD/qtbridgingandroid.h
SOURCES += \
#$$PWD/qmlnetworkaccessmanagerfactory.cpp \
#$$PWD/notificationclient.cpp \
$$PWD/keyboard.cpp \
#$$PWD/qtnativeforandroid.cpp \
$$PWD/qtbridgingandroid.cpp
OTHER_FILES += $$PWD/../android/src/org/gdpurjyfs/sparrow/QtBridgingAndroid.java
# $$PWD/../android/src/org/gdpurjyfs/sparrow/QtNativeForAndroid.java \
DISTFILES +=
================================================
FILE: Sparrow/keyboard.cpp
================================================
#include "keyboard.h"
#include <QGuiApplication>
#include <QInputMethod>
#include "sparrow_global.h"
Keyboard::Keyboard(QObject *parent) :
QObject(parent),
m_inputMethod (QGuiApplication::inputMethod())
{
connect(m_inputMethod, SIGNAL(visibleChanged()), this, SIGNAL(visibleChanged()));
#ifndef Q_OS_ANDROID
connect(this, SIGNAL(visibleChanged()), this, SLOT(onVisibleChangedChanged()));
#endif
}
bool Keyboard::visible() const
{
return m_inputMethod->isVisible();
}
void Keyboard::setVisible(bool v)
{
if(v) {
m_inputMethod->show();
} else {
m_inputMethod->hide();
}
}
QRectF Keyboard::keyboardRectangle() const
{
return this->m_keyboardRectangle;
}
Keyboard *Keyboard::singleton()
{
static Keyboard* keyboard = new Keyboard(QCoreApplication::instance());
return keyboard;
}
void Keyboard::setKeyboardRectangle(const QRectF &keyboardRectangle)
{
if(this->keyboardRectangle() != keyboardRectangle) {
this->m_keyboardRectangle = keyboardRectangle;
emit keyboardRectangleChanged(this->m_keyboardRectangle);
}
}
void Keyboard::onVisibleChangedChanged()
{
#ifndef Q_OS_ANDROID
this->setKeyboardRectangle(m_inputMethod->keyboardRectangle());
#endif
}
================================================
FILE: Sparrow/keyboard.h
================================================
#ifndef VIRTUALKEYBOARD_H
#define VIRTUALKEYBOARD_H
#include <QObject>
#include <QRectF>
class QtBridgingAndroid;
class QtNativeForAndroid;
class QInputMethod;
class Keyboard : public QObject
{
Q_OBJECT
Q_PROPERTY(bool visible READ visible WRITE setVisible NOTIFY visibleChanged)
Q_PROPERTY(QRectF keyboardRectangle READ keyboardRectangle NOTIFY keyboardRectangleChanged)
public:
explicit Keyboard(QObject *parent = 0);
bool visible()const;
void setVisible(bool v);
QRectF keyboardRectangle()const;
static Keyboard *singleton();
signals:
void visibleChanged();
void keyboardRectangleChanged(const QRectF& keyboardRectangle);
protected slots:
void setKeyboardRectangle(const QRectF& keyboardRectangle);
private slots:
void onVisibleChangedChanged();
private:
QInputMethod* m_inputMethod;
QRectF m_keyboardRectangle;
friend class QtNativeForAndroid;
friend class QtBridgingAndroid;
};
#endif // VIRTUALKEYBOARD_H
================================================
FILE: Sparrow/qmlnetworkaccessmanagerfactory.cpp
================================================
#include "qmlnetworkaccessmanagerfactory.h"
#include <QDir>
#include <QDebug>
#include <QNetworkAccessManager>
#include <QNetworkDiskCache>
#include <QStandardPaths>
QmlNetworkAccessManagerFactory::QmlNetworkAccessManagerFactory()
{
#ifdef QT_DEBUG
qDebug() << QStandardPaths::writableLocation(QStandardPaths::CacheLocation);
#endif
}
QmlNetworkAccessManagerFactory::~QmlNetworkAccessManagerFactory()
{
#ifdef QT_DEBUG
qDebug() << "~QmlNetworkAccessManagerFactory";
#endif
}
QNetworkAccessManager *QmlNetworkAccessManagerFactory::create(QObject *parent)
{
QNetworkAccessManager* manager = new QNetworkAccessManager(parent);
QString cachePath = QStandardPaths::writableLocation(QStandardPaths::CacheLocation);
if(QDir().mkpath(cachePath)) {
QNetworkDiskCache* diskCache = new QNetworkDiskCache(manager);
diskCache->setCacheDirectory(cachePath);
diskCache->setMaximumCacheSize(10*1024*1024);
manager->setCache(diskCache);
}
return manager;
}
================================================
FILE: Sparrow/qmlnetworkaccessmanagerfactory.h
================================================
#ifndef QMLNETWORKACCESSMANAGERFACTORY_H
#define QMLNETWORKACCESSMANAGERFACTORY_H
#include <QQmlNetworkAccessManagerFactory>
class QmlNetworkAccessManagerFactory : public QQmlNetworkAccessManagerFactory
{
public:
QmlNetworkAccessManagerFactory();
~QmlNetworkAccessManagerFactory();
QNetworkAccessManager *create(QObject *parent);
};
#endif // QMLNETWORKACCESSMANAGERFACTORY_H
================================================
FILE: Sparrow/qtbridgingandroid.cpp
================================================
#include "qtbridgingandroid.h"
#include "keyboard.h"
#include <QRect>
#include <QRectF>
#include <QGuiApplication>
QtBridgingAndroid::QtBridgingAndroid(QObject *parent)
: QObject(parent)
{
}
void QtBridgingAndroid::sendNotification(const QString ¬ifyString)
{
#ifdef Q_OS_ANDROID
#ifdef QT_DEBUG
qDebug() << "sending... ";
#endif
QAndroidJniObject javaNotification = QAndroidJniObject::fromString(notifyString);
// org/gdpurjyfs/wellchat/NotificationClient
// org/gdpurjyfs/wellchat/QtBridgingAndroid
// org/gdpurjyfs/sparrow/QtBridgingAndroid
QAndroidJniObject::callStaticMethod<void>("org/gdpurjyfs/sparrow/QtBridgingAndroid",
"notify",
"(Ljava/lang/String;)V",
javaNotification.object<jstring>()
);
Q_SAFE_CALL_JAVA
#endif
#ifndef Q_OS_ANDROID
Q_UNUSED(notifyString)
qDebug() << "not allow to use the QtAndroidExtras";
#endif
}
void QtBridgingAndroid::setStatusBarColor(const QColor &color)
{
#ifdef Q_OS_ANDROID
QString colorString = color.name(QColor::HexRgb);
QAndroidJniObject javaColorString = QAndroidJniObject::fromString(colorString);
#ifdef QT_DEBUG
qDebug() << "colorString" << colorString;
#endif
// org/gdpurjyfs/wellchat/QtBridgingAndroid
// org/gdpurjyfs/sparrow/QtBridgingAndroid
QAndroidJniObject::callStaticMethod<void>("org/gdpurjyfs/sparrow/QtBridgingAndroid",
"setStatusBarColor",
"(Ljava/lang/String;)V",
javaColorString.object<jstring>()
);
Q_SAFE_CALL_JAVA
#else
Q_UNUSED(color)
#endif
#ifndef Q_OS_ANDROID
qDebug() << "not allow to use the QtAndroidExtras";
#endif
}
#ifdef Q_OS_ANDROID
// 在 Java 中被调用
void QtBridgingAndroid::notifiedKeyboardRectangle(JNIEnv *env, jobject thiz,
jint x, jint y, jint width, jint height)
{
Q_UNUSED(env)
Q_UNUSED(thiz)
if(QGuiApplication::applicationState() != Qt::ApplicationHidden) {
#ifdef QT_DEBUG
qDebug() << "invoke method notifiedKeyboardRectangle: " <<
#endif
QMetaObject::invokeMethod(Keyboard::singleton(),
"setKeyboardRectangle",
Qt::AutoConnection,
Q_ARG(QRectF, QRect(x, y, width, height))) ;
}
}
bool QtBridgingAndroid::registerNativeMethodForJava()
{
JNINativeMethod methods[] = {
{
"notifiedKeyboardRectangle",
"(IIII)V",
(void*)&(QtBridgingAndroid::notifiedKeyboardRectangle)
}
};
// org/gdpurjyfs/wellchat/QtBridgingAndroid
// "org/gdpurjyfs/sparrow/qtnativeforandroid" // 包名
// const char * classname = "org/gdpurjyfs/sparrow/QtNativeForAndroid";
const char * classname = "org/gdpurjyfs/sparrow/QtBridgingAndroid";
jclass clazz;
QAndroidJniEnvironment env;
QAndroidJniObject javaClass(classname);
clazz = env->GetObjectClass(javaClass.object<jobject>());
Q_SAFE_CALL_JAVA
bool result = false;
if(clazz) {
jint ret = env->RegisterNatives(clazz,
methods,
sizeof(methods) / sizeof(methods[0]));
//! [bug] env->DeleteGlobalRef(clazz);
result = (ret >= 0);
} else {
#ifdef QT_DEBUG
qDebug() << "can't find java class" << classname;
#endif
}
Q_SAFE_CALL_JAVA
return result;
}
void QtBridgingAndroid::installListener()
{
#ifdef Q_OS_ANDROID
// org/gdpurjyfs/wellchat/NotificationClient
// org/gdpurjyfs/wellchat/QtBridgingAndroid
// org/gdpurjyfs/sparrow/QtBridgingAndroid
QAndroidJniObject::callStaticMethod<void>("org/gdpurjyfs/sparrow/QtBridgingAndroid",
"listenKeyboardHeight");
Q_SAFE_CALL_JAVA
#endif
}
#endif
================================================
FILE: Sparrow/qtbridgingandroid.h
================================================
#ifndef QTBRIDGINGANDROID_H
#define QTBRIDGINGANDROID_H
#include <QObject>
#include <QColor>
#include "sparrow_global.h"
class QtBridgingAndroid : public QObject
{
Q_OBJECT
public:
explicit QtBridgingAndroid(QObject *parent = 0);
// Java Method
Q_INVOKABLE void sendNotification(const QString& notifyString);
// Java Method
Q_INVOKABLE void setStatusBarColor(const QColor& color);
public:
#ifdef Q_OS_ANDROID
static void notifiedKeyboardRectangle(JNIEnv * env, jobject thiz,
jint x, jint y, jint width, jint height);
static bool registerNativeMethodForJava();
static void installListener();
#endif
};
#endif // QTBRIDGINGANDROID_H
================================================
FILE: Sparrow/sparrow_global.h
================================================
#ifndef GLOBAL
#define GLOBAL
#include <QDebug>
#ifdef Q_OS_ANDROID
#include <QtAndroidExtras/QAndroidJniObject>
#include <QtAndroidExtras/QAndroidJniEnvironment>
#define Q_SAFE_CALL_JAVA { \
QAndroidJniEnvironment env; \
if(env->ExceptionCheck()) { \
qDebug() << "have a java exception"; \
env->ExceptionClear(); \
} \
}
#endif
#endif // GLOBAL
================================================
FILE: WellChat.pro
================================================
TEMPLATE = app
QT += qml quick widgets
SOURCES += main.cpp \
src/wellchat/collectionsmodel.cpp
RESOURCES += \
qml.qrc
# Additional import path used to resolve QML modules in Qt Creator's code model
QML_IMPORT_PATH =
# Default rules for deployment.
include(deployment.pri)
include(Sparrow/Sparrow.pri)
DISTFILES += \
android/AndroidManifest.xml \
android/gradle/wrapper/gradle-wrapper.jar \
android/gradlew \
android/res/values/libs.xml \
android/build.gradle \
android/gradle/wrapper/gradle-wrapper.properties \
android/gradlew.bat
ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android
OTHER_FILES += android/src/org/gdpurjyfs/wellchat/WellChatActivity.java
# android/src/org/gdpurjyfs/wellchat/QtBridgingAndroid.java \
HEADERS += \
src/wellchat/collectionsmodel.h
================================================
FILE: android/AndroidManifest.xml
================================================
<?xml version="1.0"?>
<manifest package="org.gdpurjyfs.wellchat" xmlns:android="http://schemas.android.com/apk/res/android" android:versionName="0.0.1" android:versionCode="1" android:installLocation="auto">
<application android:icon="@drawable/icon" android:name="org.qtproject.qt5.android.bindings.QtApplication" android:label="@string/app_name">
<activity android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|locale|fontScale|keyboard|keyboardHidden|navigation" android:name="org.gdpurjyfs.wellchat.WellChatActivity" android:label="WellChat" android:screenOrientation="unspecified" android:windowSoftInputMode="adjustPan">
<!-- android:windowSoftInputMode = "adjustUnspecified" -->
<!-- android:windowSoftInputMode = "adjustPan" -->
<!-- android:theme="@android:style/Theme.NoTitleBar.Fullscreen" -->
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
<meta-data android:name="android.app.lib_name" android:value="-- %%INSERT_APP_LIB_NAME%% --"/>
<meta-data android:name="android.app.qt_sources_resource_id" android:resource="@array/qt_sources"/>
<meta-data android:name="android.app.repository" android:value="default"/>
<meta-data android:name="android.app.qt_libs_resource_id" android:resource="@array/qt_libs"/>
<meta-data android:name="android.app.bundled_libs_resource_id" android:resource="@array/bundled_libs"/>
<!-- Deploy Qt libs as part of package -->
<meta-data android:name="android.app.bundle_local_qt_libs" android:value="-- %%BUNDLE_LOCAL_QT_LIBS%% --"/>
<meta-data android:name="android.app.bundled_in_lib_resource_id" android:resource="@array/bundled_in_lib"/>
<meta-data android:name="android.app.bundled_in_assets_resource_id" android:resource="@array/bundled_in_assets"/>
<!-- Run with local libs -->
<meta-data android:name="android.app.use_local_qt_libs" android:value="-- %%USE_LOCAL_QT_LIBS%% --"/>
<meta-data android:name="android.app.libs_prefix" android:value="/data/local/tmp/qt/"/>
<meta-data android:name="android.app.load_local_libs" android:value="-- %%INSERT_LOCAL_LIBS%% --"/>
<meta-data android:name="android.app.load_local_jars" android:value="-- %%INSERT_LOCAL_JARS%% --"/>
<meta-data android:name="android.app.static_init_classes" android:value="-- %%INSERT_INIT_CLASSES%% --"/>
<!-- Messages maps -->
<meta-data android:value="@string/ministro_not_found_msg" android:name="android.app.ministro_not_found_msg"/>
<meta-data android:value="@string/ministro_needed_msg" android:name="android.app.ministro_needed_msg"/>
<meta-data android:value="@string/fatal_error_msg" android:name="android.app.fatal_error_msg"/>
<!-- Messages maps -->
<!-- Splash screen -->
<!--
<meta-data android:name="android.app.splash_screen_drawable" android:resource="@drawable/logo"/>
-->
<!-- Splash screen -->
<!-- Background running -->
<!-- Warning: changing this value to true may cause unexpected crashes if the
application still try to draw after
"applicationStateChanged(Qt::ApplicationSuspended)"
signal is sent! -->
<meta-data android:name="android.app.background_running" android:value="true"/>
<!--
qt start: 11:58:35
qt died: 12:13:58
这个方法不稳定,因为在QtCreator不能继续跟踪打印。
-->
<!-- Background running -->
</activity>
</application>
<uses-sdk android:minSdkVersion="9" android:targetSdkVersion="14"/>
<supports-screens android:largeScreens="true" android:normalScreens="true" android:anyDensity="true" android:smallScreens="true"/>
<!-- %%INSERT_PERMISSIONS -->
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<!-- %%INSERT_FEATURES -->
</manifest>
================================================
FILE: android/build.gradle
================================================
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:1.1.0'
}
}
allprojects {
repositories {
jcenter()
}
}
apply plugin: 'com.android.application'
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
}
android {
/*******************************************************
* The following variables:
* - androidBuildToolsVersion,
* - androidCompileSdkVersion
* - qt5AndroidDir - holds the path to qt android files
* needed to build any Qt application
* on Android.
*
* are defined in gradle.properties file. This file is
* updated by QtCreator and androiddeployqt tools.
* Changing them manually might break the compilation!
*******************************************************/
compileSdkVersion androidCompileSdkVersion.toInteger()
buildToolsVersion androidBuildToolsVersion
sourceSets {
main {
manifest.srcFile 'AndroidManifest.xml'
java.srcDirs = [qt5AndroidDir + '/src', 'src', 'java']
aidl.srcDirs = [qt5AndroidDir + '/src', 'src', 'aidl']
res.srcDirs = [qt5AndroidDir + '/res', 'res']
resources.srcDirs = ['src']
renderscript.srcDirs = ['src']
assets.srcDirs = ['assets']
jniLibs.srcDirs = ['libs']
}
}
lintOptions {
abortOnError false
}
}
================================================
FILE: android/gradle/wrapper/gradle-wrapper.properties
================================================
#Wed Apr 10 15:27:10 PDT 2013
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=http\://services.gradle.org/distributions/gradle-1.12-all.zip
================================================
FILE: android/gradlew
================================================
#!/usr/bin/env bash
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn ( ) {
echo "$*"
}
die ( ) {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
esac
# For Cygwin, ensure paths are in UNIX format before anything is touched.
if $cygwin ; then
[ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
fi
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >&-
APP_HOME="`pwd -P`"
cd "$SAVED" >&-
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
JVM_OPTS=("$@")
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
================================================
FILE: android/gradlew.bat
================================================
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windowz variants
if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
goto execute
:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
================================================
FILE: android/res/values/libs.xml
================================================
<?xml version='1.0' encoding='utf-8'?>
<resources>
<array name="qt_sources">
<item>https://download.qt-project.org/ministro/android/qt5/qt-5.4</item>
</array>
<!-- The following is handled automatically by the deployment tool. It should
not be edited manually. -->
<array name="bundled_libs">
<!-- %%INSERT_EXTRA_LIBS%% -->
</array>
<array name="qt_libs">
<!-- %%INSERT_QT_LIBS%% -->
</array>
<array name="bundled_in_lib">
<!-- %%INSERT_BUNDLED_IN_LIB%% -->
</array>
<array name="bundled_in_assets">
<!-- %%INSERT_BUNDLED_IN_ASSETS%% -->
</array>
</resources>
================================================
FILE: android/src/org/gdpurjyfs/sparrow/QtBridgingAndroid.java
================================================
/*
* Copyright (c) <2015> <copyright qyvlik>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
/*!
* Activity 先于 Qt 加载
* 1. 在 Activity OnCreate 中调用 QtBridgingAndroid::Init,然后进入Qt::main
* 2. 在 Qt::main 中注册 Java 的 native 函数 QtBridgingAndroid::notifiedKeyboardRectangle
* 3. 在 Qt::main 通过调用 Java::QtBridgingAndroid::listenKeyboardHeight 注入监听键盘事件
* 4. 在 Qt::main 加载 QML。
*/
package org.gdpurjyfs.sparrow;
import android.app.Notification;
import android.app.NotificationManager;
import android.content.Context;
import android.app.Activity;
import android.os.Bundle;
import android.graphics.Color;
import android.app.Activity;
import android.view.Window;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.widget.RelativeLayout;
import android.view.ViewTreeObserver;
import android.graphics.Rect;
import android.view.ViewGroup;
import java.lang.Thread;
//! http://blog.csdn.net/foruok/article/details/46323129
class SetStatusBarColorRunnable implements Runnable
{
private Activity m_activity;
private int m_color;
public SetStatusBarColorRunnable(Activity activity, int color) {
m_activity = activity;
m_color = color;
}
// this method is called on Android Ui Thread
@Override
public void run() {
m_activity.getWindow().setStatusBarColor(m_color);
}
}
public class QtBridgingAndroid
{
public static Activity instanceActivity;
private static NotificationManager notificationManager;
private static Notification.Builder builder;
private static Rect keyboardRectangle;
private static boolean hasListenVirtualKeyboard = false;
// allow Qt call this static function
// api 19
// @TargetApi(Build.VERSION_CODES.LOLLIPOP)
// android.view.ViewRootImpl$CalledFromWrongThreadException
//! http://daydayup1989.iteye.com/blog/784831
public static void setStatusBarColor(String colorString) {
if(instanceActivity != null) {
try {
System.out.println("colorString: " + colorString);
int color = Color.parseColor(colorString);
System.out.println("color: " + color);
instanceActivity.runOnUiThread(new SetStatusBarColorRunnable(instanceActivity,
color));
} catch(IllegalArgumentException e) {
e.printStackTrace();
} catch(Exception e1) {
e1.printStackTrace();
}
}
}
// allow Qt call this static function
public static void notify(String notifyText)
{
if (notificationManager == null) {
notificationManager = (NotificationManager)instanceActivity.getSystemService(Context.NOTIFICATION_SERVICE);
builder = new Notification.Builder(instanceActivity);
builder.setSmallIcon(org.gdpurjyfs.wellchat.R.drawable.icon);
builder.setContentTitle("WellChat");
}
System.out.println("set setContentText");
builder.setContentText(notifyText);
notificationManager.notify(1, builder.build());
}
private static View getRootView(Activity context)
{
return ((ViewGroup)context.findViewById(android.R.id.content)).getChildAt(0);
}
// 确保Qt调用时,只注入一次键盘监听事件
public static void listenKeyboardHeight() {
if(!hasListenVirtualKeyboard) {
final View myRootView = getRootView(instanceActivity);
myRootView.getViewTreeObserver().addOnGlobalLayoutListener(
new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
Rect outRect = new Rect();
instanceActivity.getWindow().getDecorView().getWindowVisibleDisplayFrame(outRect);
keyboardRectangle = new Rect();
myRootView.getWindowVisibleDisplayFrame(keyboardRectangle);
int screenHeight = myRootView.getRootView().getHeight();
// 小于100 就不行了
// 这里还要减去状态栏的高度
// 魔幻数字
// android:windowSoftInputMode="adjustPan" magic = 0
// 其他情况为 5
int magic = 0;
int virtualKeyboardHeight = screenHeight - (keyboardRectangle.bottom - keyboardRectangle.top)
- outRect.top - magic;
if( virtualKeyboardHeight < 100 ) {
virtualKeyboardHeight = 0;
}
// java 通知 Qt 键盘改变了
System.out.println("try to call native method");
notifiedKeyboardRectangle(
keyboardRectangle.centerX(),
keyboardRectangle.centerY(),
keyboardRectangle.width(),
virtualKeyboardHeight);
}
});
hasListenVirtualKeyboard = true;
}
}
// allow java call this native method
public static native void notifiedKeyboardRectangle(int x, int y,
int width, int height);
// Java call this method and init this static Bridge Class
public static void Init(Activity instanceActivity) {
QtBridgingAndroid.instanceActivity = instanceActivity;
System.out.println("QtBridgingAndroid::Init");
}
}
================================================
FILE: android/src/org/gdpurjyfs/wellchat/WellChatActivity.java
================================================
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the QtAndroidExtras module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL21$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see http://www.qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** As a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** $QT_END_LICENSE$
**
****************************************************************************/
package org.gdpurjyfs.wellchat;
import android.app.Notification;
import android.app.NotificationManager;
import android.content.Context;
import android.app.Activity;
import android.view.Window;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.widget.RelativeLayout;
import android.view.ViewTreeObserver;
import android.graphics.Rect;
import android.view.ViewGroup;
import android.os.Bundle;
//import org.gdpurjyfs.sparrow;
public class WellChatActivity extends org.qtproject.qt5.android.bindings.QtActivity
{
// @Override
// public void onCreate (Bundle savedInstanceState){
// System.out.println("这里竟然不能有其他复杂的函数操作,会闪退的。");
// super.onCreate(savedInstanceState);
// org.gdpurjyfs.sparrow.QtBridgingAndroid.Init(this);
// }
public WellChatActivity()
{
org.gdpurjyfs.sparrow.QtBridgingAndroid.Init(this);
}
}
================================================
FILE: deployment.pri
================================================
android-no-sdk {
target.path = /data/user/qt
export(target.path)
INSTALLS += target
} else:android {
QT += androidextras
x86 {
target.path = /libs/x86
} else: armeabi-v7a {
target.path = /libs/armeabi-v7a
} else {
target.path = /libs/armeabi
}
export(target.path)
INSTALLS += target
} else:unix {
isEmpty(target.path) {
qnx {
target.path = /tmp/$${TARGET}/bin
} else {
target.path = /opt/$${TARGET}/bin
}
export(target.path)
}
INSTALLS += target
}
win32 {
RESOURCES += \
desktop.qrc
}
export(INSTALLS)
================================================
FILE: desktop.qrc
================================================
<RCC>
<qresource prefix="/">
<file>qml/WellChat/Sparrow/resources/NotoSansHans-DemiLight.otf</file>
</qresource>
</RCC>
================================================
FILE: doc/weixin-ui-analyse.md
================================================
# 微信界面剖析
微信界面剖析分为:首界面,单个界面,字体大小,素材等。
## 首界面
可以先查看[简单易用的页面栈框架](readme.md)。
先看看微信的首界面。有四个分页,`BottomBar` 可以显示当前页面的以及进行切换。`TopBar` 显示微信的应用名称和两个按钮。所以首页面的实现可以使用一个横向的 `ListView` 来实现,内部有四个不同的页面,使用 `VisualItemModel` 进行加载。

现在取其中的聊天界面为例子。

在点开一个联系人进行聊天时,会将一个聊天页面压入页面栈。

先不管聊天界面是如何实现的。就讲讲页面压栈要注意的问题。
先回到首界面的 `Chats`。里面有若干个联系人,在点击某一个联系人之后,触发一个函数,将聊天页面压入栈。一般是由 `MouseArea` 触发 `clicked` 信号,然后触发页面入栈的函数。
问题来了,由于页面入栈的实现问题,`StackView` 将一个页面推入栈顶是需要时间的,所以 `StackView` 会产生一个过渡,来提高用户体验,如果你的手速够快的话,双击某个联系人,会不会触发两次点击事件呢?答案是,会的。所以在触发页面入栈的函数中应该添加一个处理语句,在当前页面 A 要将页面 B 入栈时,在处理函数中添加一句 `A.enable = false;`,在 B 页面弹出后,设置 `A.enable = true;`。就不会因为点击过快,触发两次函数,向页面栈压入两个页面了。
> ps: 后来在微信上,拼手速,以极快速度点击**设置**,确实会压入两个或两个以上的**设置**页面。不同安卓机,有不同响应,版本为 **6.2.4**。看来是通病啊。在当前页面压入另一个页面时,是需要时间的,在这个处理过程中,当前页面不做屏蔽处理的话,是十分麻烦的。当然,这种误操作只会有程序猿才能发现。
> 这个 `enable` 属性为真时,允许处理键盘和鼠标事件。详细查看 `Item::enable`。
## 字体大小
字体大小,以及安卓各个硬件上差异,进行适配就有些问题了。如何进行字体大小适配?
直接查看 [Sparrow](https://github.com/GDPURJYFS/Sparrow) 中 `UI.js` 的字体设置大小。使用了 `pointSize` 这个计量单位可以很好的工作在不同屏幕下。可以按照自己需求改动 `UI.js` 中的字体大小值。
## 单个界面
要注意微信在各个屏幕分辨率下,每个可选项的高度,其实是根据字体大小来决定的。例如上下的留白是根据字体的高度。
## 素材
素材获取来源互联网,所有权归腾讯公司所有。
## Model/View
随着研究的深入,我发现,QtQuick 本身提供的 ListModel 不能很好的适应类似于微信这样的界面业务。必须要从 `C++` 中重写对应的逻辑模型。
**TODO**
---
> 查看 [Sparrow 框架](https://github.com/GDPURJYFS/Sparrow)
> 查看[一周 app 计划](https://github.com/GDPURJYFS/A-week-to-develop-android-app-plan)可以了解到更多的安卓开发的问题。
================================================
FILE: main.cpp
================================================
/*!
* Activity 先于 Qt 加载
* 1. 在 Activity OnCreate 中调用 QtBridgingAndroid::Init,然后进入Qt::main
* 2. 在 Qt::main 中注册 Java 的 native 函数 QtBridgingAndroid::notifiedKeyboardRectangle
* 3. 在 Qt::main 通过调用 Java::QtBridgingAndroid::listenKeyboardHeight 注入监听键盘事件
* 4. 在 Qt::main 加载 QML。
*/
#include <QApplication>
#include <QQmlApplicationEngine>
#include <qqml.h>
#include <QQmlContext>
#include "Sparrow/qtbridgingandroid.h"
#include "Sparrow/keyboard.h"
#include "src/wellchat/collectionsmodel.h"
int main(int argc, char *argv[])
{
//! [java register native function]
#ifdef Q_OS_ANDROID
qDebug() << "QtNative::registerNativeMethod : "
<< QtBridgingAndroid::registerNativeMethodForJava();
#endif
//! [java register native function]
QApplication app(argc, argv);
//! [0]
app.setApplicationName("WellChat");
app.setOrganizationDomain("github.com/GDPURJYFS");
app.setOrganizationName("GDPURJYFS");
app.setApplicationVersion("0.0.1");
//! [0]
QQmlApplicationEngine engine;
//! [2] register qml type
qmlRegisterType<CollectionsModel>("WellChat", 1, 0, "CollectionsModel");
//! [2]
//! [3]
//! import path or imoprt plugin
engine.addImportPath("qrc:/qml/WellChat");
//! [3]
//! [4]
//! load qml file
engine.load(QUrl(QStringLiteral("qrc:/qml/WellChat/main.qml")));
//! [4]
//! [5]
QtBridgingAndroid *BridgingAndroid = new QtBridgingAndroid(&engine);
QQmlContext *context = engine.rootContext();
context->setContextProperty("BridgingAndroid", BridgingAndroid);
#ifdef Q_OS_ANDROID
//! [1] 向java安装事件监听,需要在 QApplication 示例化之后
QtBridgingAndroid::installListener();
// QQmlEngine: Illegal attempt to connect to Keyboard(0xe20036a0)
// that is in a different thread than the QML engine
// QQmlApplicationEngine(0xe0fa1924.
//! [1]
#endif
context->setContextProperty("Keyboard", Keyboard::singleton());
//! [5]
return app.exec();
}
================================================
FILE: qml/WellChat/BussinessPage/Chat/ChatPage.qml
================================================
import Resource 1.0 as R
import QtQuick 2.5
import QtQuick.Controls 1.4
import QtQuick.Window 2.0
import QtQuick.Layouts 1.1
import QtQuick.Dialogs 1.2
import Sparrow 1.0
import Sparrow.PopupLayer 1.0
import "./Tuling123.js" as Tuling123
import "../../Component"
Page {
id: chatPage
property string username
focus: true
Keys.onBackPressed: {
event.accepted = true;
stackView.pop();
Qt.inputMethod.hide();
}
topBar: TopBar {
id: topBar
RowLayout {
anchors.fill: parent
spacing: 10
Item { width: topBar.height - 2; height: width }
SampleIcon {
iconSize: Qt.size( topBar.height - 2, topBar.height - 2)
anchors.verticalCenter: parent.verticalCenter
iconSource: R.R.activeIconBack
// iconSource: constant.backActiveIcon
onClicked: {
Qt.inputMethod.hide();
stackView.pop();
}
Separator {
color: "black"
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
}
}
}
// such as menuBar
Row {
parent: topBar
anchors.left: parent.left
anchors.leftMargin: (topBar.height - 2) * 1.5
anchors.fill: parent
SampleLabel {
text: username
// Layout.alignment: Qt.AlignRight
color: "white"
anchors.verticalCenter: parent.verticalCenter
}
SampleIcon {
iconSource: R.R.labelIconSettings
iconSize: Qt.size( topBar.height - 2, topBar.height - 2)
anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right
onClicked: {
if(Qt.inputMethod.visible === false) {
inputYourNicoName.changeYourNicoName()
} else {
Qt.inputMethod.visible = false;
inputYourNicoName.changeYourNicoName()
}
}
}
}
}
///////////////////////////////////////////////////////////////////////////////////
property string chatContentBuffer: ""
Lazy {
id: lazy
}
property int readKeyboardHeight: Keyboard.keyboardRectangle.height
onReadKeyboardHeightChanged: {
// console.log("onReadKeyboardHeightChanged, readKeyboardHeight:",
// readKeyboardHeight);
if(readKeyboardHeight != 0) {
keyboardHeight = Keyboard.keyboardRectangle.height;
// console.log("onReadKeyboardHeightChanged, keyboardHeight:",
// keyboardHeight)
}
}
property int keyboardHeight: 0
onKeyboardHeightChanged: {
if(Qt.platform.os === "android") {
if(keyboardHeight != 0) {
upAnimation.to = keyboardHeight;
upAnimation.start();
}
}
}
NumberAnimation {
id: upAnimation
target: chatPage.bottomBarArea
duration: 50
from: 0
properties: "anchors.bottomMargin"
}
function inputMethodShowHelper() {
// 如果是安卓
if(Qt.platform.os === "android") {
// 第一次打开
if(keyboardHeight == 0) {
Qt.inputMethod.visibleChanged.connect(function() {
if(Qt.inputMethod.visible) {
Qt.inputMethod.visibleChanged.disconnect(arguments.callee);
lazy.startCallback(50, function() {
// 动态生成TextArea
loader_input.sourceComponent = component_input;
loader_input.item.focus = true;
});
}
});
Qt.inputMethod.show();
} else {
upAnimation.to = keyboardHeight;
upAnimation.start();
lazy.startCallback(50, function() {
// 动态生成TextArea
loader_input.sourceComponent = component_input;
Qt.inputMethod.show();
});
}
} else {
loader_input.sourceComponent = component_input;
loader_input.item.focus = true;
}
}
signal keyboardOpen()
onKeyboardOpen: {
if(Qt.platform.os === "android") {
try {
if(!Keyboard.visible) {
// 关闭键盘
loader_input.sourceComponent = undefined;
upAnimation.to = 0;
upAnimation.start();
}
} catch(e) {
console.log(e)
}
}
}
Component.onCompleted: {
Qt.inputMethod.visibleChanged.connect(keyboardOpen);
}
bottomBar: BottomBar {
id: bottombar
focus: true
RowLayout {
focus: true
anchors.fill: parent
spacing: 5
IconButton {
width: topBar.height - 2
height: topBar.height - 2
activeIconSource: R.R.activeIconSound
inactiveIconSource: R.R.inactiveIconSound
}
Item {
focus: true
Layout.fillWidth: true
implicitHeight: topBar.height
IconButton {
width: topBar.height * 0.9
height: topBar.height * 0.9
activeIconSource: R.R.activeIconEmoticon
inactiveIconSource: R.R.inactiveIconEmoticon
anchors.bottom: parent.bottom
anchors.right: parent.right
anchors.rightMargin: 10
}
Rectangle {
FontMetrics {
id: fontMetrics
font.family: GeneralSettings.generalfontFamily
font.pointSize: GeneralSettings.generalFontPointSize
font.weight: Font.Thin
font.bold: false
}
width: parent.width - 10
anchors.horizontalCenter: parent.horizontalCenter
height: 1
color: parent.focus? "#71d01d" : "#ccc"
anchors.bottom: parent.bottom
anchors.bottomMargin: fontMetrics.height * 0.2
}
Component {
id: component_input
// Sample
TextArea {
id: input
//readOnly: true
focus: true
font.family: GeneralSettings.generalfontFamily
font.pointSize: GeneralSettings.generalFontPointSize
wrapMode: TextEdit.Wrap
backgroundVisible: false
Component.onDestruction: {
chatContentBuffer = input.text;
}
Component.onCompleted: {
input.text = chatContentBuffer;
input.cursorPosition = input.length;
}
// textFormat: TextEdit.RichText
width: parent.width
implicitHeight: {
if(lineCount >= 2) {
(topBar.height - 2) * 2
} else {
(topBar.height- 2) * lineCount
}
}
// Tracker { }
}
}
Loader {
id: loader_input
focus: true
anchors.fill: parent
onLoaded: {
loader_input.item.focus = true;
loader_input.item.forceActiveFocus();
}
MouseArea {
anchors.fill: parent
visible: {
if(loader_input.item) {
return loader_input.item.readOnly
} else {
return true;
}
}
onClicked: inputMethodShowHelper();
// 当关闭输入框的时候
// 用来显示上次输入的文本
SampleLabel {
width: parent.width
elide: Text.ElideRight
text: chatContentBuffer
verticalAlignment: Text.AlignVCenter
anchors.verticalCenter: parent.verticalCenter
}
}
}
}
SampleButton {
id: sendButton
width: topBar.height * 0.9
height: topBar.height * 0.9
Layout.alignment: Qt.AlignRight
text: qsTr("Send")
onClicked: {
__sendHelp();
}
}
Item { width: 5; height: 5 }
}
}
/*
states: [
// State {
// name: "FixTopBar"
// PropertyChanges {
// target: chatPage.topBarArea
// anchors.topMargin: try {
// return Keyboard.keyboardRectangle.height;
// } catch(e) {
// return 0;
// }
// }
// }
State {
name: "FixBottomBar"
PropertyChanges {
target: chatPage.bottomBarArea
anchors.bottomMargin: keyboardHeight
}
}
]
transitions: [
// Transition {
// from: "FixTopBar"
// to: ""
// NumberAnimation {
// property: "anchors.topMargin"
// duration: 350
// }
// },
// Transition {
// from: ""
// to: "FixTopBar"
// NumberAnimation {
// property: "anchors.topMargin"
// duration: 350
// }
// }
Transition {
// 回落,键盘收回
from: "FixBottomBar"
to: ""
SequentialAnimation {
ScriptAction {
script: {
loader_input.sourceComponent = undefined;
console.log("from FixBottomBar to '', readOnly is true");
}
}
NumberAnimation {
property: "anchors.bottomMargin"
duration: 150
}
}
},
Transition {
from: ""
to: "FixBottomBar"
SequentialAnimation {
NumberAnimation {
property: "anchors.bottomMargin"
duration: 150
}
ScriptAction {
script: {
loader_input.sourceComponent = component_input;
console.log("from '' to FixBottomBar, readOnly is false");
}
}
}
}
]
*/
////////////////////////////////////////////////////////////////////////
property string userId: "垃圾君"
ListView {
id: view
anchors.fill: parent
model: chatModels
delegate: Rectangle {
width: view.width
height: chatText.contentHeight * 1.5
color: "transparent"
border.color: "black"
border.width: 1
SampleLabel {
id: chatText
width: parent.width * 0.8 >= chatText.contentWidth
? chatText.contentWidth
: parent.width * 0.8
anchors.right: ChatId != "JiJiZhaZha" ? parent.right : undefined
text: ChatText
verticalAlignment: Text.AlignVCenter
anchors.verticalCenter: parent.verticalCenter
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
}
}
ListModel {
id: chatModels
// ListElement {
// ChatText: "这是文本"
// ChatId: "JiJiZhaZha"
// }
// ListElement {
// ChatText: "我是垃圾君"
// ChatId: "垃圾君"
// }
}
}
property bool __dontFixBottomBar: false
PopupLayer {
id: inputYourNicoName
parent: chatPage
popupItem.width: chatPage.width * 0.8
popupItem.height: popupItem.width * 0.5
onStateChanged: {
if(inputYourNicoName.state == "Hide") {
__dontFixBottomBar = false;
} else {
__dontFixBottomBar = true;
}
}
RowLayout {
anchors.fill: parent
anchors.margins: parent.width * 0.05
SampleTextField {
id: getNicoName
Layout.fillWidth: true
}
SampleButton {
text: qsTr("OK")
onClicked: {
chatPage.userId = getNicoName.text;
inputYourNicoName.close();
Qt.inputMethod.hide();
}
}
}
function changeYourNicoName () {
getNicoName.text = chatPage.userId;
inputYourNicoName.open();
}
}
function tryToNotify(notifiString) {
try {
console.log("will send", notifiString);
BridgingAndroid.sendNotification(notifiString);
}catch(e) {
console.log(e)
}
}
onApplicationStateChanged: {
if(applicationState == Qt.ApplicationInactive
|| applicationState == Qt.ApplicationSuspended
|| applicationState == Qt.ApplicationHidden) {
Qt.inputMethod.hide();
}
}
function __sendHelp() {
if(loader_input.item.text !== "" ) {
chatModels.append({
"ChatText": loader_input.item.text,
"ChatId": userId
});
view.positionViewAtIndex(view.count-1, ListView.End );
Tuling123.sendTextToTuling123(loader_input.item.text,
userId,
function(responseText){
chatModels
.append(
{
"ChatText": responseText,
"ChatId": "JiJiZhaZha"
});
view.positionViewAtIndex(view.count-1, ListView.End );
},
Tuling123.errorCodeHandle
);
loader_input.item.text = "";
}
}
}
================================================
FILE: qml/WellChat/BussinessPage/Chat/Heartbeat.qml
================================================
import QtQuick 2.0
QtObject {
id: heartbeat
property alias source: worker.source
property alias interval: timer.interval
property alias running: timer.running
signal message(var msg)
signal beat()
property Timer timer: Timer {
id: timer
repeat: true
interval: 1500
triggeredOnStart: true
running: false
}
property WorkerScript worker: WorkerScript {
id: worker
}
function sendMessage(msg) { worker.sendMessage(msg); }
function start() { timer.start(); }
function stop() { timer.stop(); }
Component.onCompleted: {
worker.message.connect(message);
timer.triggered.connect(beat);
}
}
================================================
FILE: qml/WellChat/BussinessPage/Chat/Lazy.qml
================================================
import Resource 1.0 as R
import QtQuick 2.5
import QtQuick.Controls 1.4
import QtQuick.Window 2.0
import QtQuick.Layouts 1.1
import QtQuick.Dialogs 1.2
import Sparrow 1.0
import Sparrow.PopupLayer 1.0
import "../../Component"
Timer {
id: lazy
interval: 100
running: false
repeat: false
property var callback
onTriggered: {
try {
callback();
} catch(e) {
}
}
function startCallback(time, callback) {
time = time || 500;
callback = callback || function() { };
interval = time;
lazy.callback = callback;
lazy.start();
}
}
================================================
FILE: qml/WellChat/BussinessPage/Chat/Tuling123.js
================================================
.pragma library
// callback(responseText)
// err(errorCode)
function sendTextToTuling123(text, chatUserId, callback, err) {
// http://www.tuling123.com/openapi/api?key=b77b735b2797bc613e7623f4406fe342&info=你好
var host = "http://www.tuling123.com/openapi/api?";
// 这里填写你在图灵机器人网站申请的apiKey
// 现在图灵机器人网站是免费申请的哦。
var apiKey = "b77b735b2797bc613e7623f4406fe342";
var info = text;
var dataTemplate = {
"code": 10000, // 返回的错误码
"text": "回复的内容",
"url": "", // 返回单条链接
"list": [] // 返回多条信息
}
var xhr = new XMLHttpRequest;
xhr.onreadystatechange = function() {
if(xhr.readyState == xhr.DONE) {
console.log("xhr.responseText: ", xhr.responseText);
try {
var dataObject = JSON.parse(xhr.responseText);
if(!isErrorCode(dataObject.code)) {
callback(dataObject.text);
} } catch(e) {
console.log(e);
}
}
}
xhr.open("GET", host+ "key=" + apiKey +"&userid=" + chatUserId +"&info="+info );
xhr.send()
}
function isErrorCode(code) {
var errorCodes = [
{
"code":40001,
"description":"参数key长度错误(应该是32位)"
},
{
"code":40002,
"description":"请求内容info为空"
},
{
"code":40003,
"description":"key错误或帐号未激活"
},
{
"code":40004,
"description":"当天请求次数已使用完"
},
{
"code":40005,
"description":"暂不支持所请求的功能"
},
{
"code":40006,
"description":"图灵机器人服务器正在升级"
},
{
"code":40007,
"description":"数据格式异常"
},
];
for(var iter in errorCodes) {
if(errorCodes[iter].code === code) {
return true;
}
}
return false;
}
function errorCodeHandle(code) {
var errorCodes = [
{
"code":40001,
"description":"参数key长度错误(应该是32位)"
},
{
"code":40002,
"description":"请求内容info为空"
},
{
"code":40003,
"description":"key错误或帐号未激活"
},
{
"code":40004,
"description":"当天请求次数已使用完"
},
{
"code":40005,
"description":"暂不支持所请求的功能"
},
{
"code":40006,
"description":"图灵机器人服务器正在升级"
},
{
"code":40007,
"description":"数据格式异常"
},
];
for(var iter in errorCodes) {
if(errorCodes[iter].code === code) {
console.log(errorCodes[iter].description);
}
}
}
================================================
FILE: qml/WellChat/BussinessPage/Chat/heart.js
================================================
// .pragma library
// 心跳包
// to include static singleton mess_id
Qt.include("./storage.js")
WorkerScript.onMessage = function(message) {
var model = message.listModel;
var doc = new XMLHttpRequest;
doc.open("POST", "http://cnzxzc.tunnel.mobi/qyvlik/sendMess");
doc.onreadystatechange = function () {
if (doc.readyState === XMLHttpRequest.DONE) {
console.log("on message, model:", model);
console.log("XMLHttpRequest DONE");
console.log("====轮询结果=======,mess_id:", mess_id);
console.log(doc.responseText);
console.log("====轮询结果=======");
try {
var content = JSON.parse(doc.responseText);
if(content.hasOwnProperty("mess_id")) {
mess_id = content.mess_id;
timestamp = content.timestamp;
var item = {
"chatContext": content.content
}
model.append(item);
model.sync();
}
} catch(e) {
console.log(e);
}
}
}
var lunxun = {
"timestamp": timestamp,
"room_id":"1",
"mess_id":mess_id
}
doc.send(JSON.stringify(lunxun));
}
================================================
FILE: qml/WellChat/BussinessPage/ChatsView.qml
================================================
import BussinessPage 1.0 as BR
import QtQuick 2.0
import QtQuick.Controls 1.4
import QtQuick.Window 2.0
import QtQuick.Layouts 1.1
import "../Component"
import Sparrow 1.0
Page {
id: chatsView
title: "FriendList"
color: "white"
property int headPrtraitSize: 90
signal openNewChat(int userid, string username)
onOpenNewChat: {
if(__find(username) !== null) {
// go to the chat page
__LoadChatPage(userid, name);
} else {
chatItemsModel.append(
{
"chatTime": (new Date).toDateString(),
"chatName":username,
"chatisBool": false,
"chatContext":userid
});
// go to the chat page
__LoadChatPage(userid, username);
}
}
ListView {
id: listView
width: chatsView.width
height: chatsView.height
model: chatItemsModel
highlightMoveDuration: 1000
highlightRangeMode: ListView.ApplyRange
// 控制滚动速度
maximumFlickVelocity: 5000
/////////////////////////////////////////////////////////////////////////////////////////
/*
highlightRangeMode: ListView.StrictlyEnforceRange
readonly property alias topSideBarIsOpen: listView.__topSideBarIsOpen
property bool __topSideBarIsOpen: false
onAtYBeginningChanged: {
try {
if(listView.atYBeginning) {
console.log(-listView.contentY, listView.headerItem.height)
if( -contentY > listView.headerItem.height) {
listView.__topSideBarIsOpen = true;
}
} else {
listView.__topSideBarIsOpen = false;
}
} catch(e) { }
}
onTopSideBarIsOpenChanged: {
if(listView.topSideBarIsOpen) {
listView.highlightRangeMode = ListView.ApplyRange // 焦点Item允许停止的位置
} else {
listView.highlightRangeMode = ListView.StrictlyEnforceRange
}
}
header: Rectangle {
id: headerItem
width: listView.width;
height: listView.height
color: "black"
}
//*/
/////////////////////////////////////////////////////////////////////////////////////////
add: Transition {
NumberAnimation { property: "opacity"; from: 0; to: 1.0; duration: 400 }
NumberAnimation { property: "scale"; from: 0; to: 1.0; duration: 400 }
}
move: Transition {
NumberAnimation { properties: "x,y"; duration: 800; easing.type: Easing.OutBack }
}
displaced: Transition {
NumberAnimation { properties: "x,y"; duration: 400; easing.type: Easing.OutBounce }
}
states: [
State {
name: "ShowBar"
when: listView.movingVertically
PropertyChanges { target: verticalScrollBar; opacity: 1 }
},
State {
name: "HideBar"
when: !listView.movingVertically
PropertyChanges { target: verticalScrollBar; opacity: 0 }
}
]
transitions: [
Transition {
from: "ShowBar"
to: "HideBar"
NumberAnimation { properties: "opacity"; duration: 400 }
},
Transition {
from: "HideBar"
to: "ShowBar"
NumberAnimation { properties: "opacity"; duration: 400 }
}
]
ScrollBar {
id: verticalScrollBar
width: 10 * Screen.devicePixelRatio
height: listView.height - width
anchors.right: listView.right
orientation: Qt.Vertical
position: listView.visibleArea.yPosition
pageSize: listView.visibleArea.heightRatio
}
delegate: Rectangle {
id: chatItem
// chatItem
property int chatItemHeight: chatItemRowLayout.height
width: chatsView.width
height: chatItem.chatItemHeight
color: "transparent"
border.width: 1
border.color: "#ccc"
state: "UnSelected"
states: [
State {
name: "Selected"
PropertyChanges { target:chatItem; color: "#ccc" }
},
State {
name: "UnSelected"
PropertyChanges { target:chatItem; color: "transparent" }
}
]
transitions: [
Transition {
from: "Selected"
to: "UnSelected"
NumberAnimation { properties: "color"; duration: 400 }
},
Transition {
from: "UnSelected"
to: "Selected"
NumberAnimation { properties: "color"; duration: 400 }
}
]
RowLayout {
id: chatItemRowLayout
width: parent.width
height: (chatItemName.contentHeight+chatItemContext.contentHeight) * 1.5
anchors.margins: spacing
Image {
width: chatItem.chatItemHeight
height: chatItem.chatItemHeight
anchors.verticalCenter: parent.verticalCenter
sourceSize.width: chatItem.chatItemHeight - 2
sourceSize.height: chatItem.chatItemHeight - 2
source: "../Resource/tests/tests001.jpg"
fillMode: Image.PreserveAspectFit
}
ColumnLayout {
Layout.fillHeight: true
Layout.fillWidth: true
RowLayout {
Layout.fillHeight: true
Layout.fillWidth: true
SampleLabel { id: chatItemName; Layout.fillWidth: true; text: name }
SampleLabel { id: chatItemTime; Layout.fillWidth: true; text: chatTime }
}
RowLayout {
Layout.fillHeight: true
Layout.fillWidth: true
SampleLabel { id: chatItemContext; Layout.fillWidth: true; text: chatContext }
SampleLabel { id: chatItemisBool;Layout.fillWidth: true; text: chatisBool }
}
}
}
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.LeftButton | Qt.RightButton
onPressAndHold: {
chatItem.state = "Selected";
chatItemMenu.aboutToHide.connect(function(){
chatItemMenu.aboutToHide.disconnect(arguments.callee);
chatItem.state = "UnSelected";
});
chatItemMenu.aboutToShow.connect(function(){
chatItemMenu.aboutToShow.disconnect(arguments.callee);
chatItem.state = "Selected";
});
chatItemMenu.chatItemIndex = index;
chatItemMenu.popup();
}
onClicked: {
__LoadChatPage(1, name);
}
}
}
Menu {
id: chatItemMenu
property int chatItemIndex: 0
MenuItem {
text: qsTr("Delete conversation")
onTriggered: {
listView.model.remove(chatItemMenu.chatItemIndex);
}
}
MenuItem {
text: qsTr("Sticky on top")
onTriggered: {
listView.model.move(chatItemMenu.chatItemIndex, 0, 1);
}
}
MenuItem {
text: qsTr("Clear")
onTriggered: {
listView.model.clear();
}
}
}
ListModel {
id: chatItemsModel
// ListElement {
// username: "Apple"
// chatContext: "2333"
// chatTime: 2.45
// chatisBool: true
// }
/*
联系人名字
聊天记录
时间
是否
*/
Component.onCompleted: {
for(var i=0; i<1; i++) {
chatItemsModel
.append(
{
"chatTime": i,
"name":"忍野忍",
"chatisBool": false,
"chatContext":"233" + i
});
}
}
}
}
function __find(name) {
if(chatItemsModel.count == 0) return null;
var chatItemsCount = chatItemsModel.count;
for(var i=0; i<chatItemsCount; i++) {
// console.log("chatItemsModel.get(i).chatName: ", chatItemsModel.get(i).chatName, ", name: ",name);
if(chatItemsModel.get(i).chatName === name) {
return chatItemsModel.get(i);
}
}
return null;
}
function __LoadChatPage(userid, username){
__PushPage(BR.R.chatChatPage, {username: username} );
}
}
================================================
FILE: qml/WellChat/BussinessPage/Contacts/ContactsListView.qml
================================================
import QtQuick 2.5
import QtQuick.Window 2.0
import QtQuick.Layouts 1.1
import Sparrow 1.0 as Sparrow
Rectangle {
id: root
width: 400
height: 600
color: "transparent"
property ListView mainListView: null
property alias model: listView.model
property alias delegate: listView.delegate
property alias section: listView.section
ListView {
id: listView
anchors.fill: parent
snapMode: ListView.NoSnap
maximumFlickVelocity: 5000
highlightRangeMode: ListView.NoHighlightRange
}
function getSectionHeadIndex(sectionModel, role, sectionText) {
try {
var count = sectionModel.count;
var iter = 0;
while(iter < count) {
if(sectionModel.get(iter)[role].charAt(0) === sectionText) {
return iter;
}
++iter;
}
} catch(e) {
console.log(e);
}
return 0;
}
Rectangle {
id: bar
height: parent.height
width: Screen.pixelDensity * 5 // 2mn
anchors.right: parent.right
color: Qt.rgba(0.5, 0.5, 0.5, 0.5)
opacity: 0.2
ColumnLayout {
anchors.fill: parent
Repeater {
id: repeater
model: ["↑", "☆","a", "b", "c", "d", "e", "f"
, "g", "h", "i", "j", "k", "l", "m", "n",
"o", "p", "q", "r", "s", "t", "u", "v", "w",
"x", "y", "z"]
Text {
anchors.horizontalCenter: parent.horizontalCenter
text: repeater.model[index]
font.pointSize: Sparrow.UI.SmallFontPointSize - 1
}
}
}
MouseArea {
anchors.fill: parent
onReleased: {
listView.highlightRangeMode = ListView.NoHighlightRange;
listView.snapMode = ListView.NoSnap;
mainListView.interactive = true;
bar.opacity = 0.2;
showText.close();
}
onPositionChanged: {
bar.opacity = 0.8;
var itemHeight = parent.height / repeater.model.length;
var pos = Math.floor(mouse.y / itemHeight);
try {
mainListView.interactive = false;
showText.show(repeater.model[pos]);
listView.highlightRangeMode = ListView.StrictlyEnforceRange;
listView.snapMode = ListView.SnapOneItem;
listView.currentIndex =
getSectionHeadIndex(listView.model,
listView.section.property,
repeater.model[pos]);
} catch(e) {
listView.highlightRangeMode = ListView.NoHighlightRange;
listView.snapMode = ListView.NoSnap;
mainListView.interactive = true;
console.log(pos);
console.log(e)
}
}
}
}
Rectangle {
id: showText
width: Screen.pixelDensity * 20
height: Screen.pixelDensity * 20
color: Qt.rgba(0.8, 0.8,0.8, 0.8)
anchors.centerIn: parent
property alias text: text.text
visible: false
Sparrow.SampleLabel {
id: text
anchors.centerIn: parent
}
function show(t) {
showText.text = t;
showText.visible = true;
}
function close() {
showText.text = "";
showText.visible = false;
}
}
}
================================================
FILE: qml/WellChat/BussinessPage/ContactsView.qml
================================================
import Resource 1.0 as R
import BussinessPage 1.0 as BR
import QtQuick 2.0
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.1
import "../Component"
import "./Contacts"
import Sparrow 1.0
Page {
id: contactsView
title: qsTr("Contacts")
property int headPrtraitSize: 50
property ListView mainListView: null
ContactsListView {
mainListView: contactsView.mainListView
width: contactsView.width
height: contactsView.height
section.property: "name"
section.criteria: ViewSection.FirstCharacter
section.delegate: Rectangle {
width: contactsView.width
height: childrenRect.height
color: "transparent"
SampleLabel {
text: section
}
}
model: ListModel {
id: personModel
Component.onCompleted: {
personModel
var d = ["☆","a1","a1","a1", "a1","a1","a1","a1","a1","a1","a1","a1",
"b2","b2","b2","b2","b2","b2","b2","b2","b2","b2","b2","b2",
"b2","b2","b2","b2","b2","b2","b2","b2","b2","b2","b2","b2",
"b2","b2","b2","b2","b2","b2","b2","b2","b2","b2","b2","b2",
"b2","c3","c3","c3","c3","c3","c3","c3","c3","c3","c3","d",
"e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p",
"q", "r", "s", "t", "u", "v", "w","x24", "x24","x24","x24","x24",
"x24","x24","x24","x24","x24","x24","x24","x24","x24","x24","x24",
"x24","x24","x24","y", "z"];
for(var i=0;i<d.length; i++) {
personModel.append({"name": d[i]});
}
}
}
delegate: ColumnLayout {
width: contactsView.width
height: l.height
IconLabel {
id: l
spacing: 10
Layout.fillWidth: true;
iconSource: R.R.testPic
labelText: qsTr("哔哩哔哩")
onPressAndHold: {
menu.chatItemIndex = index;
menu.popup();
}
Separator {
color: "#999"; orientation: Qt.Horizontal ;
length: parent.width * 0.8
anchors.bottom: parent.bottom
anchors.horizontalCenter: parent.horizontalCenter
}
onClicked: {
console.log("go to the person profile");
__PushPage(BR.R.profilePage);
}
}
}
Menu {
id: menu
property int chatItemIndex: 0
MenuItem {
text: qsTr("Set Remarks and Tags")
onTriggered: {
}
}
}
}
}
================================================
FILE: qml/WellChat/BussinessPage/Discover/MomentsPage/MomentsPage.qml
================================================
import Resource 1.0 as R
import QtQuick 2.0
import QtQuick.Controls 1.4
import QtQuick.Window 2.2
import QtQuick.Layouts 1.1
import Sparrow 1.0
import "../../../Component"
Page {
id: momentsPage
title: "moments"
color: "#22292c"
focus: true
Keys.onBackPressed: {
event.accepted = true;
if(webPage.canGoBack) {
webPage.goBack();
} else {
try { stackView.pop(); }
catch(e) { console.log(e); }
}
}
Constant {
id: constant
}
topBar: TopBar {
id: topBar
// //! aviod looping binding
// Item { anchors.fill: parent }
RowLayout {
anchors.fill: parent
spacing: 10
Item { width: topBar.height - 2; height: width }
SampleIcon {
iconSize: Qt.size( topBar.height - 2, topBar.height - 2)
anchors.verticalCenter: parent.verticalCenter
iconSource: R.R.activeIconBack
onClicked: {
try { stackView.pop(); } catch(e) { }
}
Separator {
color: "black"
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
}
}
}
// such as menuBar
Row {
parent: topBar
anchors.left: parent.left
anchors.leftMargin: (topBar.height - 2) * 1.5
anchors.fill: parent
Label {
text: momentsPage.title
// Layout.alignment: Qt.AlignRight
color: "white"
anchors.verticalCenter: parent.verticalCenter
font.family: GeneralSettings.generalfontFamily
font.pointSize: constant.middleFontPointSize
}
}
}
Item {
anchors.fill: parent
Item {
id: loadProgressArea
width: momentsPage.width
height: Screen.pixelDensity
visible: webPage.loadProgress != 100
Rectangle {
height: parent.height
width: parent.width * (100/webPage.loadProgress)
color: "green"
}
}
WebPage {
id: webPage
width: momentsPage.width
anchors.top: loadProgressArea.bottom
anchors.bottom: parent.bottom
url: "https://github.com/GDPURJYFS/WellChat"
// {
// if(Qt.platform.os == "android") {
// return Qt.resolvedUrl("file:///android_asset/html/index.html");
// } else {
// return "../../../Resource/html/index.html";
// }
// }
}
}
}
================================================
FILE: qml/WellChat/BussinessPage/DiscoverPage.qml
================================================
import Resource 1.0 as R
import BussinessPage 1.0 as BR
import QtQuick 2.5
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.1
import "../Component"
import "./Personal"
import Sparrow 1.0
Page {
id: discoverPage
title: qsTr("Discover")
color: "#ebebeb"
ScrollView {
id: page
anchors.fill: parent
verticalScrollBarPolicy :Qt.ScrollBarAlwaysOff
horizontalScrollBarPolicy: Qt.ScrollBarAlwaysOff
Item {
id: content
width: page.width
height: Math.max(page.viewport.height, column.implicitHeight + 2 * column.spacing)
FontMetrics {
id: fontMetrics
font.family: GeneralSettings.generalfontFamily
font.pointSize: GeneralSettings.generalFontPointSize
}
ColumnLayout {
id: column
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
spacing: fontMetrics.height
Item { width: parent.spacing; height: parent.height }
IconLabel {
Layout.fillWidth: true
iconSource: R.R.labelIconMoments
labelText: qsTr("Moments")
onClicked: {
__PushPage(BR.R.discoverMomentsPage)
}
Image {
id: momentsCurrentActiveFriend
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
anchors.rightMargin: column.spacing
width: parent.height
height: parent.height
sourceSize: Qt.size(width, height)
source: R.R.testPic
}
} // First Group
Rectangle {
id: colmnLayout2Parent
Layout.fillWidth: true
height: columnLayout2.height
color: "white"
ColumnLayout {
id: columnLayout2
width: parent.width
spacing: 0
IconLabel {
Layout.fillWidth: true
iconSource: R.R.labelIconScanQRCode
labelText: qsTr("Scan QR Code")
}
Separator {
Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
color: "#666"; orientation: Qt.Horizontal ;
anchors.horizontalCenter: parent.horizontalCenter
}
IconLabel {
Layout.fillWidth: true
iconSource: R.R.labelIconShake
labelText: qsTr("Shake")
}
}
} // Second Group
Rectangle {
Layout.fillWidth: true
height: columnLayout3.height
color: "white"
ColumnLayout {
id: columnLayout3
width: parent.width
spacing: 0
IconLabel {
Layout.fillWidth: true
iconSource: R.R.labelIconPeopleNearby
labelText: qsTr("People Nearby")
}
Separator {
Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
color: "#666"; orientation: Qt.Horizontal ;
anchors.horizontalCenter: parent.horizontalCenter
}
IconLabel {
Layout.fillWidth: true
iconSource: R.R.labelIconDriftBottle
labelText: qsTr("Drift Bottle")
}
}
} // Thrid Group
IconLabel {
Layout.fillWidth: true
iconSource: R.R.labelIconGames
labelText: qsTr("Games")
} // First Group
} // Main ColumnLayout
} // content
} // ScrollView
}
================================================
FILE: qml/WellChat/BussinessPage/Personal/FavoritesPage.qml
================================================
import Resource 1.0 as R
import QtQuick 2.0
import QtQuick.Layouts 1.1
import "../../Component"
import "./Settings"
import Sparrow 1.0
import WellChat 1.0
Page {
id: myPostPage
title: qsTr("My Post")
color: "white"
focus: true
Keys.onBackPressed: {
event.accepted = true;
try { stackView.pop(); } catch(e) { }
}
topBar: TopBar {
id: topBar
// //! aviod looping binding
// Item { anchors.fill: parent }
RowLayout {
anchors.fill: parent
spacing: 10
Item { width: topBar.height - 2; height: width }
SampleIcon {
iconSource: R.R.activeIconBack
iconSize: Qt.size( topBar.height - 2, topBar.height - 2)
anchors.verticalCenter: parent.verticalCenter
onClicked: {
try { stackView.pop(); } catch(e) { }
// console.log(x, y)
}
//! [0] fix the bug
// 在本页面压入一个页面之后再弹出
// x 的值会变成 180
// 需要将其设置回 0
onXChanged: {
if(x != 0 ) {
x = 0
}
}
//! [0] fix the bug
Separator {
color: "black"
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
}
}
}
// such as menuBar
Row {
parent: topBar
anchors.left: parent.left
anchors.leftMargin: (topBar.height - 2) * 1.5
anchors.fill: parent
SampleLabel {
text: myPostPage.title
color: "white"
anchors.verticalCenter: parent.verticalCenter
}
}
}
ListView {
id: listView
anchors.fill: parent
clip: true
maximumFlickVelocity: 5000
model: CollectionsModel {
id: collectionsModel
// enum CollectionRole {
// Author // 作者
// CreateTime, // 创建时间
// Title, // 标题
// Source, // 来源地址:http://baidu.com
// SourceName, // 来源名字:baidu
// Summary, // 摘要
// CollectionType// 收藏的类型,例如链接,音乐,图片等
// };
Component.onCompleted: {
console.log();
}
}
spacing: 30
delegate: RowLayout {
width: myPostPage.width
SampleLabel {
text: Author
}
SampleLabel {
Layout.fillWidth: true
text: "Author " + Author + "\n"
+ "CreateTime: " + CreateTime + "\n"
+ "Title: " + Title + "\n"
+ "Source: " + Source + "\n"
+ "SourceName: " + SourceName + "\n"
+ "Summary: " + Summary + "\n"
+ "CollectionType: " + CollectionType + "\n"
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
}
}
}
}
================================================
FILE: qml/WellChat/BussinessPage/Personal/MyPostsPage.qml
================================================
import Resource 1.0 as R
import QtQuick 2.0
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.1
import "../../Component"
import "./Settings"
import Sparrow 1.0
Page {
id: myPostPage
title: qsTr("My Post")
color: "white"
focus: true
Keys.onBackPressed: {
event.accepted = true;
try { stackView.pop(); } catch(e) { }
}
topBar: TopBar {
id: topBar
// //! aviod looping binding
// Item { anchors.fill: parent }
RowLayout {
anchors.fill: parent
spacing: 10
Item { width: topBar.height - 2; height: width }
SampleIcon {
iconSource: R.R.activeIconBack
iconSize: Qt.size( topBar.height - 2, topBar.height - 2)
anchors.verticalCenter: parent.verticalCenter
onClicked: {
try { stackView.pop(); } catch(e) { }
// console.log(x, y)
}
//! [0] fix the bug
// 在本页面压入一个页面之后再弹出
// x 的值会变成 180
// 需要将其设置回 0
onXChanged: {
if(x != 0 ) {
x = 0
}
}
//! [0] fix the bug
Separator {
color: "black"
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
}
}
}
// such as menuBar
Row {
parent: topBar
anchors.left: parent.left
anchors.leftMargin: (topBar.height - 2) * 1.5
anchors.fill: parent
SampleLabel {
text: myPostPage.title
color: "white"
anchors.verticalCenter: parent.verticalCenter
}
}
}
ListView {
id: listView
anchors.fill: parent
clip: true
maximumFlickVelocity: 5000
model: 100
spacing: 30
header: Item {
width: myPostPage.width
height: fengmian.height + (touxiang.height)
Image {
id: fengmian
source: R.R.testPic
sourceSize.width: myPostPage.width
width: myPostPage.width
fillMode: Image.PreserveAspectCrop
}
Image {
id: touxiang
anchors.right: parent.right
anchors.rightMargin: touxiang.height * 0.2
anchors.bottom: parent.bottom
anchors.bottomMargin: touxiang.height / 2
source: R.R.testPic
sourceSize.width: myPostPage.width * 0.23
}
}
delegate: RowLayout {
width: myPostPage.width
SampleLabel {
text: "今天"
}
Image {
source: R.R.testPic
sourceSize.width: myPostPage.width * 0.23
fillMode: Image.PreserveAspectCrop
}
SampleLabel {
Layout.fillWidth: true
text: "正文之今天选课,炸了dddddddddddddddddddddddddddddddddddddddddddddddd炸了炸了炸了"
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
}
}
}
}
================================================
FILE: qml/WellChat/BussinessPage/Personal/Settings/AboutPage.qml
================================================
import Resource 1.0 as R
import QtQuick 2.0
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.1
import Sparrow 1.0
import "../../../Component"
Page {
id: aboutPage
title: qsTr("My Account")
color: "#ccc"
focus: true
Keys.onBackPressed: {
event.accepted = true;
try { stackView.pop(); } catch(e) { }
}
Constant { id: constant }
topBar: TopBar {
id: topBar
// //! aviod looping binding
// Item { anchors.fill: parent }
RowLayout {
anchors.fill: parent
spacing: 10
Item { width: topBar.height - 2; height: width }
SampleIcon {
iconSource: R.R.activeIconBack
iconSize: Qt.size( topBar.height - 2, topBar.height - 2)
anchors.verticalCenter: parent.verticalCenter
onClicked: {
try { stackView.pop(); } catch(e) { }
}
Separator {
color: "black"
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
}
}
}
// such as menuBar
Row {
parent: topBar
anchors.left: parent.left
anchors.leftMargin: (topBar.height - 2) * 1.5
anchors.fill: parent
SampleLabel {
text: aboutPage.title
// Layout.alignment: Qt.AlignRight
color: "white"
anchors.verticalCenter: parent.verticalCenter
}
}
}
ScrollView {
id: page
anchors.fill: parent
verticalScrollBarPolicy :Qt.ScrollBarAlwaysOff
horizontalScrollBarPolicy: Qt.ScrollBarAlwaysOff
Item {
id: content
width: page.width
height: Math.max(page.viewport.height, column.implicitHeight + 2 * column.spacing)
ColumnLayout {
id: column
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
spacing: 20
Item { width: parent.spacing; height: parent.height }
Image {
anchors.horizontalCenter: parent.horizontalCenter
width: page.width * 0.4
height: page.width * 0.4
sourceSize: Qt.size(page.width * 0.4, page.width * 0.4)
source: R.R.testPic
}
SettingsGroup {
Layout.fillWidth: true
IconLabel {
Layout.fillWidth: true
labelText: qsTr("Rete WellChat")
}
Separator {
Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
color: "#666"; orientation: Qt.Horizontal ;
anchors.horizontalCenter: parent.horizontalCenter
}
IconLabel {
Layout.fillWidth: true
labelText: qsTr("Features")
}
Separator {
Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
color: "#666"; orientation: Qt.Horizontal ;
anchors.horizontalCenter: parent.horizontalCenter
}
IconLabel {
Layout.fillWidth: true
labelText: qsTr("Help & Feedback")
}
Separator {
Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
color: "#666"; orientation: Qt.Horizontal ;
anchors.horizontalCenter: parent.horizontalCenter
}
IconLabel {
Layout.fillWidth: true
labelText: qsTr("Version Update")
Label {
text: qsTr("1.0.0")
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
anchors.rightMargin: column.spacing
color: "#666"
font.family: GeneralSettings.generalfontFamily
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
font.pointSize: constant.smallFontPointSize + 2
}
}
}
Label {
Layout.fillWidth: true
text: qsTr("Terms and Privacy")
color: "blue"
font.family: GeneralSettings.generalfontFamily
horizontalAlignment: Text.AlignHCenter
font.pointSize: constant.smallFontPointSize + 2
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
}
Label {
Layout.fillWidth: true
text: qsTr("Copyright © 2015 qyvlik\n All Rights Reserved.")
color: "#666"
font.family: GeneralSettings.generalfontFamily
font.pointSize: constant.smallFontPointSize + 2
horizontalAlignment: Text.AlignHCenter
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
}
} // Main ColumnLayout
} // content
} // ScrollView
}
================================================
FILE: qml/WellChat/BussinessPage/Personal/Settings/ChatSettingsPage.qml
================================================
import Resource 1.0 as R
import QtQuick 2.0
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.1
import Sparrow 1.0
import Sparrow.PopupLayer 1.0
import "../../../Component"
Page {
id: chatSettnigsPage
title: qsTr("Chat")
color: "#ccc"
focus: true
Keys.onBackPressed: {
event.accepted = true;
try { stackView.pop(); } catch(e) { }
}
topBar: TopBar {
id: topBar
// //! aviod looping binding
// Item { anchors.fill: parent }
RowLayout {
anchors.fill: parent
spacing: 10
Item { width: topBar.height - 2; height: width }
SampleIcon {
iconSource: R.R.activeIconBack
iconSize: Qt.size( topBar.height - 2, topBar.height - 2)
anchors.verticalCenter: parent.verticalCenter
onClicked: {
try { stackView.pop(); } catch(e) { }
}
Separator {
color: "black"
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
}
}
}
// such as menuBar
Row {
parent: topBar
anchors.left: parent.left
anchors.leftMargin: (topBar.height - 2) * 1.5
anchors.fill: parent
SampleLabel {
text: chatSettnigsPage.title
// Layout.alignment: Qt.AlignRight
color: "white"
anchors.verticalCenter: parent.verticalCenter
}
}
}
ScrollView {
id: page
anchors.fill: parent
verticalScrollBarPolicy :Qt.ScrollBarAlwaysOff
horizontalScrollBarPolicy: Qt.ScrollBarAlwaysOff
Item {
id: content
width: page.width
height: Math.max(page.viewport.height, column.implicitHeight + 2 * column.spacing)
ColumnLayout {
id: column
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
spacing: 20
Item { width: parent.spacing; height: parent.height }
SettingsGroup {
Layout.fillWidth: true
IconLabel {
Layout.fillWidth: true
labelText: qsTr("Turn Off Speaker")
Switch {
checked: false
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
anchors.rightMargin: column.spacing
}
}
Separator {
Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
color: "#666"; orientation: Qt.Horizontal ;
anchors.horizontalCenter: parent.horizontalCenter
}
IconLabel {
Layout.fillWidth: true
labelText: qsTr("Press Enter to Send")
Switch {
checked: false
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
anchors.rightMargin: column.spacing
}
}
Separator {
Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
color: "#666"; orientation: Qt.Horizontal ;
anchors.horizontalCenter: parent.horizontalCenter
}
IconLabel {
Layout.fillWidth: true
labelText: qsTr("Background")
}
Separator {
Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
color: "#666"; orientation: Qt.Horizontal ;
anchors.horizontalCenter: parent.horizontalCenter
}
IconLabel {
Layout.fillWidth: true
labelText: qsTr("My Stickers")
}
} // First Settings Ground
SettingsGroup {
Layout.fillWidth: true
IconLabel {
Layout.fillWidth: true
labelText: qsTr("Backup/Restore Chat History")
}
Separator {
Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
color: "#666"; orientation: Qt.Horizontal ;
anchors.horizontalCenter: parent.horizontalCenter
}
IconLabel {
Layout.fillWidth: true
labelText: qsTr("Clear Chat History")
onClicked: dialog.open()
}
} // Second Settings Ground
} // Main ColumnLayout
} // content
} // ScrollView
PopupLayer {
id: dialog
popupItem.radius: chatSettnigsPage.width * 0.05
SampleButton {
anchors.centerIn: parent
text: qsTr("Clear?")
}
}
}
================================================
FILE: qml/WellChat/BussinessPage/Personal/Settings/DoNotDisturbSettingsPage.qml
================================================
import Resource 1.0 as R
import QtQuick 2.0
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.1
import Sparrow 1.0
import "../../../Component"
Page {
id: notificationsPage
title: qsTr("Do Not Disturb")
color: "#ccc"
focus: true
Keys.onBackPressed: {
event.accepted = true;
try { stackView.pop(); } catch(e) { }
}
Constant { id: constant }
topBar: TopBar {
id: topBar
// //! aviod looping binding
// Item { anchors.fill: parent }
RowLayout {
anchors.fill: parent
spacing: 10
Item { width: topBar.height - 2; height: width }
SampleIcon {
iconSource: R.R.activeIconBack
iconSize: Qt.size( topBar.height - 2, topBar.height - 2)
anchors.verticalCenter: parent.verticalCenter
onClicked: {
try { stackView.pop(); } catch(e) { }
}
Separator {
color: "black"
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
}
}
}
// such as menuBar
Row {
parent: topBar
anchors.left: parent.left
anchors.leftMargin: (topBar.height - 2) * 1.5
anchors.fill: parent
SampleLabel {
text: notificationsPage.title
color: "white"
anchors.verticalCenter: parent.verticalCenter
}
}
}
ScrollView {
id: page
anchors.fill: parent
verticalScrollBarPolicy :Qt.ScrollBarAlwaysOff
horizontalScrollBarPolicy: Qt.ScrollBarAlwaysOff
Item {
id: content
width: page.width
height: Math.max(page.viewport.height, column.implicitHeight + 2 * column.spacing)
ColumnLayout {
id: column
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
spacing: 20
Item { width: parent.spacing; height: parent.height }
SettingsGroup {
Layout.fillWidth: true
IconLabel {
Layout.fillWidth: true
labelText: qsTr("Notificatons")
Switch {
id: switch1
checked: false
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
anchors.rightMargin: column.spacing
}
}
Item {
width: notificationsPage.width
height: label.height
Label {
id: label
anchors.right: parent.right
anchors.left: parent.left
anchors.margins: 10
color: "#666"
font.family: GeneralSettings.generalfontFamily
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
font.pointSize: constant.smallFontPointSize + 2
text: qsTr("If enabled, you won't be notified about new messages during the hours set.")
}
}
Separator {
visible: switch1.checked
Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
color: "#666"; orientation: Qt.Horizontal ;
anchors.horizontalCenter: parent.horizontalCenter
}
IconLabel {
visible: switch1.checked
Layout.fillWidth: true
labelText: qsTr("Start")
Label {
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
anchors.rightMargin: column.spacing
color: "#666"
font.family: GeneralSettings.generalfontFamily
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
font.pointSize: constant.smallFontPointSize + 2
text: qsTr("11:00 PM")
}
}
Separator {
visible: switch1.checked
Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
color: "#666"; orientation: Qt.Horizontal ;
anchors.horizontalCenter: parent.horizontalCenter
}
IconLabel {
visible: switch1.checked
Layout.fillWidth: true
labelText: qsTr("End")
Label {
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
anchors.rightMargin: column.spacing
color: "#666"
font.family: GeneralSettings.generalfontFamily
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
font.pointSize: constant.smallFontPointSize + 2
text: qsTr("8:00 AM")
}
}
}
} // Main ColumnLayout
} // content
} // ScorllView
}
================================================
FILE: qml/WellChat/BussinessPage/Personal/Settings/GeneralSettingsPage.qml
================================================
import Resource 1.0 as R
import QtQuick 2.0
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.1
import Sparrow 1.0
import "../../../Component"
Page {
id: generalSettingsPage
title: qsTr("General")
color: "#ccc"
focus: true
Keys.onBackPressed: {
event.accepted = true;
try { stackView.pop(); } catch(e) { }
}
Constant { id: constant }
topBar: TopBar {
id: topBar
// //! aviod looping binding
// Item { anchors.fill: parent }
RowLayout {
anchors.fill: parent
spacing: 10
Item { width: topBar.height - 2; height: width }
SampleIcon {
iconSource: R.R.activeIconBack
iconSize: Qt.size( topBar.height - 2, topBar.height - 2)
anchors.verticalCenter: parent.verticalCenter
onClicked: {
try { stackView.pop(); } catch(e) { }
}
Separator {
color: "black"
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
}
}
}
// such as menuBar
Row {
parent: topBar
anchors.left: parent.left
anchors.leftMargin: (topBar.height - 2) * 1.5
anchors.fill: parent
Label {
text: generalSettingsPage.title
// Layout.alignment: Qt.AlignRight
color: "white"
anchors.verticalCenter: parent.verticalCenter
font.family: GeneralSettings.generalfontFamily
font.pointSize: constant.middleFontPointSize
}
}
}
ScrollView {
id: page
anchors.fill: parent
verticalScrollBarPolicy :Qt.ScrollBarAlwaysOff
horizontalScrollBarPolicy: Qt.ScrollBarAlwaysOff
Item {
id: content
width: page.width
height: Math.max(page.viewport.height, column.implicitHeight + 2 * column.spacing)
ColumnLayout {
id: column
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
spacing: 20
Item { width: parent.spacing; height: parent.height }
SettingsGroup {
Layout.fillWidth: true
IconLabel {
Layout.fillWidth: true
labelText: qsTr("Landscape Display")
Switch {
checked: true
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
anchors.rightMargin: column.spacing
}
}
Separator {
Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
color: "#666"; orientation: Qt.Horizontal ;
anchors.horizontalCenter: parent.horizontalCenter
}
IconLabel {
Layout.fillWidth: true
labelText: qsTr("Low-bitrate Recording")
Switch {
checked: true
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
anchors.rightMargin: column.spacing
}
}
Separator {
Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
color: "#666"; orientation: Qt.Horizontal ;
anchors.horizontalCenter: parent.horizontalCenter
}
IconLabel {
Layout.fillWidth: true
labelText: qsTr("Low-bitrate Recording")
Label {
text: qsTr("3G / 4G and Wi-Fi")
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
anchors.rightMargin: column.spacing
color: "#666"
font.family: GeneralSettings.generalfontFamily
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
font.pointSize: constant.smallFontPointSize + 2
}
}
Separator {
Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
color: "#666"; orientation: Qt.Horizontal ;
anchors.horizontalCenter: parent.horizontalCenter
}
IconLabel {
Layout.fillWidth: true
labelText: qsTr("Auto-Update WellChat")
Label {
text: qsTr("Never")
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
anchors.rightMargin: column.spacing
color: "#666"
font.family: GeneralSettings.generalfontFamily
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
font.pointSize: constant.smallFontPointSize + 2
}
}
Separator {
Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
color: "#666"; orientation: Qt.Horizontal ;
anchors.horizontalCenter: parent.horizontalCenter
}
IconLabel {
Layout.fillWidth: true
labelText: qsTr("Language")
Label {
text: qsTr("English")
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
anchors.rightMargin: column.spacing
color: "#666"
font.family: GeneralSettings.generalfontFamily
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
font.pointSize: constant.smallFontPointSize + 2
}
}
Separator {
Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
color: "#666"; orientation: Qt.Horizontal ;
anchors.horizontalCenter: parent.horizontalCenter
}
IconLabel {
Layout.fillWidth: true
labelText: qsTr("Font Size")
Label {
text: qsTr("Standard")
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
anchors.rightMargin: column.spacing
color: "#666"
font.family: GeneralSettings.generalfontFamily
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
font.pointSize: constant.smallFontPointSize + 2
}
}
Separator {
Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
color: "#666"; orientation: Qt.Horizontal ;
anchors.horizontalCenter: parent.horizontalCenter
}
IconLabel {
Layout.fillWidth: true
labelText: qsTr("Features")
}
Separator {
Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
color: "#666"; orientation: Qt.Horizontal ;
anchors.horizontalCenter: parent.horizontalCenter
}
IconLabel {
Layout.fillWidth: true
labelText: qsTr("Data Usage")
}
Separator {
Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
color: "#666"; orientation: Qt.Horizontal ;
anchors.horizontalCenter: parent.horizontalCenter
}
IconLabel {
Layout.fillWidth: true
labelText: qsTr("Web WellChat")
}
Separator {
Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
color: "#666"; orientation: Qt.Horizontal ;
anchors.horizontalCenter: parent.horizontalCenter
}
IconLabel {
Layout.fillWidth: true
labelText: qsTr("Manage Storage")
}
} // First Settings Group
} // Main ColumnLayout
} // content
} // ScrollView
}
================================================
FILE: qml/WellChat/BussinessPage/Personal/Settings/MyAccountSettingsPage.qml
================================================
import Resource 1.0 as R
import QtQuick 2.0
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.1
import Sparrow 1.0
import "../../../Component"
Page {
id: myAccountSettingsPage
title: qsTr("My Account")
color: "#ccc"
focus: true
Keys.onBackPressed: {
event.accepted = true;
try { stackView.pop(); } catch(e) { }
}
Constant { id: constant }
topBar: TopBar {
id: topBar
// //! aviod looping binding
// Item { anchors.fill: parent }
RowLayout {
anchors.fill: parent
spacing: 10
Item { width: topBar.height - 2; height: width }
SampleIcon {
iconSource: R.R.activeIconBack
iconSize: Qt.size( topBar.height - 2, topBar.height - 2)
anchors.verticalCenter: parent.verticalCenter
onClicked: {
try { stackView.pop(); } catch(e) { }
}
Separator {
color: "black"
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
}
}
}
// such as menuBar
Row {
parent: topBar
anchors.left: parent.left
anchors.leftMargin: (topBar.height - 2) * 1.5
anchors.fill: parent
Label {
text: myAccountSettingsPage.title
// Layout.alignment: Qt.AlignRight
color: "white"
anchors.verticalCenter: parent.verticalCenter
font.family: GeneralSettings.generalfontFamily
font.pointSize: constant.middleFontPointSize
}
}
}
ScrollView {
id: page
anchors.fill: parent
verticalScrollBarPolicy :Qt.ScrollBarAlwaysOff
horizontalScrollBarPolicy: Qt.ScrollBarAlwaysOff
Item {
id: content
width: page.width
height: Math.max(page.viewport.height, column.implicitHeight + 2 * column.spacing)
ColumnLayout {
id: column
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
spacing: 20
Item { width: parent.spacing; height: parent.height }
SettingsGroup {
Layout.fillWidth: true
title: qsTr("Account")
IconLabel {
Layout.fillWidth: true
labelText: qsTr("Well Chat ID")
Label {
text: "qyvlik"
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
anchors.rightMargin: column.spacing
color: "#666"
font.family: GeneralSettings.generalfontFamily
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
font.pointSize: constant.smallFontPointSize + 2
}
}
Separator {
Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
color: "#666"; orientation: Qt.Horizontal ;
anchors.horizontalCenter: parent.horizontalCenter
}
IconLabel {
Layout.fillWidth: true
labelText: qsTr("QQ ID")
Label {
text: "1234567890"
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
anchors.rightMargin: column.spacing
color: "#666"
font.family: GeneralSettings.generalfontFamily
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
font.pointSize: constant.smallFontPointSize + 2
}
}
Separator {
Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
color: "#666"; orientation: Qt.Horizontal ;
anchors.horizontalCenter: parent.horizontalCenter
}
IconLabel {
Layout.fillWidth: true
labelText: qsTr("Phone")
Label {
text: "13588880000"
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
anchors.rightMargin: column.spacing
color: "#666"
font.family: GeneralSettings.generalfontFamily
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
font.pointSize: constant.smallFontPointSize + 2
}
}
Separator {
Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
color: "#666"; orientation: Qt.Horizontal ;
anchors.horizontalCenter: parent.horizontalCenter
}
IconLabel {
Layout.fillWidth: true
labelText: qsTr("Email")
Label {
text: qsTr("Verified")
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
anchors.rightMargin: column.spacing
color: "#666"
font.family: GeneralSettings.generalfontFamily
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
font.pointSize: constant.smallFontPointSize + 2
}
}
} // First Settings Group
Item { width: parent.spacing; height: parent.height }
SettingsGroup {
Layout.fillWidth: true
title: qsTr("Security")
IconLabel {
Layout.fillWidth: true
labelText: qsTr("Voiceprint")
}
Separator {
Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
color: "#666"; orientation: Qt.Horizontal ;
anchors.horizontalCenter: parent.horizontalCenter
}
IconLabel {
Layout.fillWidth: true
labelText: qsTr("Password")
}
Separator {
Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
color: "#666"; orientation: Qt.Horizontal ;
anchors.horizontalCenter: parent.horizontalCenter
}
IconLabel {
Layout.fillWidth: true
labelText: qsTr("Account Protection")
}
Separator {
Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
color: "#666"; orientation: Qt.Horizontal ;
anchors.horizontalCenter: parent.horizontalCenter
}
IconLabel {
Layout.fillWidth: true
labelText: qsTr("Mobile Security")
}
Item {
width: myAccountSettingsPage.width
height: label.height
Label {
id: label
anchors.right: parent.right
anchors.left: parent.left
anchors.margins: 10
color: "#666"
font.family: GeneralSettings.generalfontFamily
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
font.pointSize: constant.smallFontPointSize + 2
text: qsTr("Go to the Well Chat Security Center for account security issues.")
}
}
} // Second Settings Group
} // Main ColumnLayout
} // content
} // ScrollView
}
================================================
FILE: qml/WellChat/BussinessPage/Personal/Settings/NotificationsSettingsPage.qml
================================================
import Resource 1.0 as R
import QtQuick 2.0
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.1
import Sparrow 1.0
import "../../../Component"
Page {
id: notificationsPage
title: qsTr("Notifications")
color: "#ccc"
focus: true
Keys.onBackPressed: {
event.accepted = true;
try { stackView.pop(); } catch(e) { }
}
Constant { id: constant }
topBar: TopBar {
id: topBar
// //! aviod looping binding
// Item { anchors.fill: parent }
RowLayout {
anchors.fill: parent
spacing: 10
Item { width: topBar.height - 2; height: width }
SampleIcon {
iconSource: R.R.activeIconBack
iconSize: Qt.size( topBar.height - 2, topBar.height - 2)
anchors.verticalCenter: parent.verticalCenter
onClicked: {
try { stackView.pop(); } catch(e) { }
}
Separator {
color: "black"
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
}
}
}
// such as menuBar
Row {
parent: topBar
anchors.left: parent.left
anchors.leftMargin: (topBar.height - 2) * 1.5
anchors.fill: parent
SampleLabel {
text: notificationsPage.title
color: "white"
anchors.verticalCenter: parent.verticalCenter
}
}
}
ScrollView {
id: page
anchors.fill: parent
verticalScrollBarPolicy :Qt.ScrollBarAlwaysOff
horizontalScrollBarPolicy: Qt.ScrollBarAlwaysOff
Item {
id: content
width: page.width
height: Math.max(page.viewport.height, column.implicitHeight + 2 * column.spacing)
ColumnLayout {
id: column
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
spacing: 20
Item { width: parent.spacing; height: parent.height }
SettingsGroup {
Layout.fillWidth: true
IconLabel {
Layout.fillWidth: true
labelText: qsTr("New Message Alerts")
Switch {
checked: true
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
anchors.rightMargin: column.spacing
}
}
Separator {
Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
color: "#666"; orientation: Qt.Horizontal ;
anchors.horizontalCenter: parent.horizontalCenter
}
IconLabel {
Layout.fillWidth: true
labelText: qsTr("Notificatons")
Switch {
checked: true
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
anchors.rightMargin: column.spacing
}
}
Item {
width: notificationsPage.width
height: label.height
Label {
id: label
anchors.right: parent.right
anchors.left: parent.left
anchors.margins: 10
color: "#666"
font.family: GeneralSettings.generalfontFamily
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
font.pointSize: constant.smallFontPointSize + 2
text: qsTr("If turn off, notifications for WellChat messages will not contain the sender and summary.")
}
}
}
SettingsGroup {
Layout.fillWidth: true
IconLabel {
Layout.fillWidth: true
labelText: qsTr("Sound")
Switch {
checked: true
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
anchors.rightMargin: column.spacing
}
}
Separator {
Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
color: "#666"; orientation: Qt.Horizontal ;
anchors.horizontalCenter: parent.horizontalCenter
}
IconLabel {
Layout.fillWidth: true
labelText: qsTr("Alert Sound")
Label {
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
anchors.rightMargin: column.spacing
color: "#666"
font.family: GeneralSettings.generalfontFamily
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
font.pointSize: constant.smallFontPointSize + 2
text: qsTr("auto")
}
}
Separator {
Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
color: "#666"; orientation: Qt.Horizontal ;
anchors.horizontalCenter: parent.horizontalCenter
}
IconLabel {
Layout.fillWidth: true
labelText: qsTr("In-App Vibrate") // 震动
Switch {
checked: true
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
anchors.rightMargin: column.spacing
}
}
}
SettingsGroup {
Layout.fillWidth: true
IconLabel {
Layout.fillWidth: true
labelText: qsTr("Moments Upadates")
Switch {
checked: true
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
anchors.rightMargin: column.spacing
}
}
Item {
width: notificationsPage.width
height: labe2.height
Label {
id: labe2
anchors.right: parent.right
anchors.left: parent.left
anchors.margins: 10
color: "#666"
font.family: GeneralSettings.generalfontFamily
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
font.pointSize: constant.smallFontPointSize + 2
text: qsTr("if turned off, you will not see a red dot for friends' new messages.")
}
}
}
}
}
}
}
================================================
FILE: qml/WellChat/BussinessPage/Personal/Settings/PrivacySettingsPage.qml
================================================
import Resource 1.0 as R
import QtQuick 2.0
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.1
import Sparrow 1.0
import "../../../Component"
Page {
id: privacySettingsPage
title: qsTr("Privacy")
color: "#ccc"
focus: true
Keys.onBackPressed: {
event.accepted = true;
try { stackView.pop(); } catch(e) { }
}
Constant { id: constant }
topBar: TopBar {
id: topBar
// //! aviod looping binding
// Item { anchors.fill: parent }
RowLayout {
anchors.fill: parent
spacing: 10
Item { width: topBar.height - 2; height: width }
SampleIcon {
iconSource: R.R.activeIconBack
iconSize: Qt.size( topBar.height - 2, topBar.height - 2)
anchors.verticalCenter: parent.verticalCenter
onClicked: {
try { stackView.pop(); } catch(e) { }
}
Separator {
color: "black"
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
}
}
}
// such as menuBar
Row {
parent: topBar
anchors.left: parent.left
anchors.leftMargin: (topBar.height - 2) * 1.5
anchors.fill: parent
Label {
text: privacySettingsPage.title
// Layout.alignment: Qt.AlignRight
color: "white"
anchors.verticalCenter: parent.verticalCenter
font.family: GeneralSettings.generalfontFamily
font.pointSize: constant.middleFontPointSize
}
}
}
ScrollView {
id: page
anchors.fill: parent
verticalScrollBarPolicy :Qt.ScrollBarAlwaysOff
horizontalScrollBarPolicy: Qt.ScrollBarAlwaysOff
Item {
id: content
//width: Math.max(page.viewport.width, column.implicitWidth + 2 * column.spacing)
width: page.width
height: Math.max(page.viewport.height, column.implicitHeight + 2 * column.spacing)
ColumnLayout {
id: column
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
spacing: 20
Item { width: parent.spacing; height: parent.height }
SettingsGroup {
Layout.fillWidth: true
IconLabel {
Layout.fillWidth: true
labelText: qsTr("Friend Confirmation")
Switch {
checked: true
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
anchors.rightMargin: column.spacing
}
}
Separator {
Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
color: "#666"; orientation: Qt.Horizontal ;
anchors.horizontalCenter: parent.horizontalCenter
}
IconLabel {
Layout.fillWidth: true
labelText: qsTr("Find QQ Contacts")
Switch {
checked: true
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
anchors.rightMargin: column.spacing
}
}
Separator {
Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
color: "#666"; orientation: Qt.Horizontal ;
anchors.horizontalCenter: parent.horizontalCenter
}
IconLabel {
Layout.fillWidth: true
labelText: qsTr("Find Mobile Contacts")
Switch {
checked: true
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
anchors.rightMargin: column.spacing
}
}
Separator {
Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
color: "#666"; orientation: Qt.Horizontal ;
anchors.horizontalCenter: parent.horizontalCenter
}
IconLabel {
Layout.fillWidth: true
labelText: qsTr("Blocked List")
}
} // First Setting Group
SettingsGroup {
Layout.fillWidth: true
IconLabel {
Layout.fillWidth: true
labelText: qsTr("Find Me by WeChat ID")
Switch {
checked: true
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
anchors.rightMargin: column.spacing
}
}
Separator {
Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
color: "#666"; orientation: Qt.Horizontal ;
anchors.horizontalCenter: parent.horizontalCenter
}
IconLabel {
Layout.fillWidth: true
labelText: qsTr("Find Me by Phone No.")
Switch {
checked: true
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
anchors.rightMargin: column.spacing
}
}
Separator {
Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
color: "#666"; orientation: Qt.Horizontal ;
anchors.horizontalCenter: parent.horizontalCenter
}
IconLabel {
Layout.fillWidth: true
labelText: qsTr("Find Me By QQ ID") // 震动
Switch {
checked: true
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
anchors.rightMargin: column.spacing
}
}
} // Second Setting Group
SettingsGroup {
Layout.fillWidth: true
IconLabel {
Layout.fillWidth: true
labelText: qsTr("Don't Share My Moments")
}
Separator {
Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
color: "#666"; orientation: Qt.Horizontal ;
anchors.horizontalCenter: parent.horizontalCenter
}
IconLabel {
Layout.fillWidth: true
labelText: qsTr("Hide User's Moments")
}
Separator {
Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
color: "#666"; orientation: Qt.Horizontal ;
anchors.horizontalCenter: parent.horizontalCenter
}
IconLabel {
Layout.fillWidth: true
labelText: qsTr("Moments Groups")
}
Separator {
Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
color: "#666"; orientation: Qt.Horizontal ;
anchors.horizontalCenter: parent.horizontalCenter
}
IconLabel {
Layout.fillWidth: true
labelText: qsTr("Public Moments")
Switch {
checked: true
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
anchors.rightMargin: column.spacing
}
}
} // Third Setting Group
} // Main ColumnLayout
} // content
} // ScollView
}
================================================
FILE: qml/WellChat/BussinessPage/Personal/Settings/SettingsGroup.qml
================================================
import QtQuick 2.0
import QtQuick.Layouts 1.1
import QtQuick.Controls 1.4
import "../../../Component"
import Sparrow 1.0
Item {
id: settingsGroup
property alias title: title.text
property alias backgroundColor: background.color
property alias spacing: columnLayout.spacing
default property alias data: columnLayout.data
height: columnLayout.implicitHeight + titleArea.height
Rectangle {
id: titleArea
color: "transparent"
anchors.right: parent.right
anchors.left: parent.left
anchors.top: parent.top
height: title.text != "" ? title.height : 1
SampleLabel {
id: title
color: "#666"
anchors.left: parent.left
anchors.leftMargin: 20
anchors.verticalCenter: parent.verticalCenter
}
}
Rectangle {
id: background
color: "white"
anchors.right: parent.right
anchors.left: parent.left
anchors.top: parent.top
anchors.topMargin: titleArea.height
height: parent.height
}
ColumnLayout {
id: columnLayout
anchors.right: parent.right
anchors.left: parent.left
anchors.top: parent.top
anchors.topMargin: titleArea.height
spacing: 0
}
}
================================================
FILE: qml/WellChat/BussinessPage/Personal/SettingsPage.qml
================================================
import Resource 1.0 as R
import BussinessPage 1.0 as BR
import QtQuick 2.0
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.1
import "../../Component"
import "./Settings"
import Sparrow 1.0
import Sparrow.PopupLayer 1.0
import Sparrow.PopupLayer.Delegate 1.0
Page {
id: personalPage
title: qsTr("Personal")
focus: true
Keys.onBackPressed: {
event.accepted = true;
try { stackView.pop(); } catch(e) { }
}
topBar: TopBar {
id: topBar
// //! aviod looping binding
// Item { anchors.fill: parent }
RowLayout {
anchors.fill: parent
spacing: 10
Item { width: topBar.height - 2; height: width }
SampleIcon {
iconSource: R.R.activeIconBack
iconSize: Qt.size( topBar.height - 2, topBar.height - 2)
anchors.verticalCenter: parent.verticalCenter
onClicked: {
try { stackView.pop(); } catch(e) { }
// console.log(x, y)
}
//! [0] fix the bug
// 在本页面压入一个页面之后再弹出
// x 的值会变成 180
// 需要将其设置回 0
onXChanged: {
if(x != 0 ) {
x = 0
}
}
//! [0] fix the bug
Separator {
color: "black"
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
}
}
}
// such as menuBar
Row {
parent: topBar
anchors.left: parent.left
anchors.leftMargin: (topBar.height - 2) * 1.5
anchors.fill: parent
SampleLabel {
text: personalPage.title
color: "white"
anchors.verticalCenter: parent.verticalCenter
}
}
}
ScrollView {
id: page
anchors.fill: parent
verticalScrollBarPolicy :Qt.ScrollBarAlwaysOff
horizontalScrollBarPolicy: Qt.ScrollBarAlwaysOff
Item {
id: content
width: page.width
height: Math.max(page.viewport.height, column.implicitHeight + 2 * column.spacing)
ColumnLayout {
id: column
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
spacing: 20
Item { width: parent.spacing; height: parent.height }
SettingsGroup {
Layout.fillWidth: true
IconLabel {
Layout.fillWidth: true
labelText: qsTr("Notificatons")
onClicked: {
__PushPage(BR.R.personalSettingsNotificationsSettingsPage)
}
}
Separator {
Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
color: "#666"; orientation: Qt.Horizontal ;
anchors.horizontalCenter: parent.horizontalCenter
}
IconLabel {
Layout.fillWidth: true
labelText: qsTr("Do Not Disturb")
onClicked: {
__PushPage(BR.R.personalSettingsDoNotDisturbSettingsPage);
}
}
Separator {
Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
color: "#666"; orientation: Qt.Horizontal ;
anchors.horizontalCenter: parent.horizontalCenter
}
IconLabel {
Layout.fillWidth: true
labelText: qsTr("Chat")
onClicked: {
__PushPage(BR.R.personalSettingsChatSettingsPage)
}
}
Separator {
Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
color: "#666"; orientation: Qt.Horizontal ;
anchors.horizontalCenter: parent.horizontalCenter
}
IconLabel {
Layout.fillWidth: true
labelText: qsTr("Privacy")
onClicked: {
__PushPage(BR.R.personalSettingsPrivacySettingsPage)
}
}
Separator {
Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
color: "#666"; orientation: Qt.Horizontal ;
anchors.horizontalCenter: parent.horizontalCenter
}
IconLabel {
Layout.fillWidth: true
labelText: qsTr("General")
onClicked: {
__PushPage(BR.R.personalSettingsGeneralSettingsPage)
}
}
Separator {
Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
color: "#666"; orientation: Qt.Horizontal ;
anchors.horizontalCenter: parent.horizontalCenter
}
IconLabel {
Layout.fillWidth: true
labelText: qsTr("My Account")
onClicked: {
__PushPage(BR.R.personalSettingsMyAccountSettingsPage)
}
}
} // First Settings Group
SettingsGroup {
Layout.fillWidth: true
IconLabel {
Layout.fillWidth: true
labelText: qsTr("About")
onClicked: {
__PushPage(BR.R.personalSettingsAboutPage)
}
}
Separator {
Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
color: "#666"; orientation: Qt.Horizontal ;
anchors.horizontalCenter: parent.horizontalCenter
}
IconLabel {
Layout.fillWidth: true
labelText: qsTr("Log Out")
onClicked: dialog.open()
}
}
}// First Settings Group
} // content
} // ScrollView
PopupLayer {
id: dialog
popupItem.color: "white"
popupItem.radius: personalPage.width * 0.05
SampleButton {
anchors.centerIn: parent
text:qsTr("Log Out?")
onClicked: {
dialog.close()
}
}
}
}
================================================
FILE: qml/WellChat/BussinessPage/PersonalPage.qml
================================================
import BussinessPage 1.0 as BR
import QtQuick 2.5
import QtQuick.Controls 1.4
import QtQuick.Window 2.0
import QtQuick.Layouts 1.1
import Sparrow 1.0
import "../Component"
Page {
id: personalPage
title: qsTr("Personal")
color: "#ebebeb"
Constant { id: constant }
ScrollView {
id: page
anchors.fill: parent
verticalScrollBarPolicy :Qt.ScrollBarAlwaysOff
horizontalScrollBarPolicy: Qt.ScrollBarAlwaysOff
Item {
id: content
width: page.width
height: Math.max(page.viewport.height, column.implicitHeight + 2 * column.spacing)
FontMetrics {
id: fontMetrics
font.family: GeneralSettings.generalfontFamily
font.pointSize: GeneralSettings.generalFontPointSize
}
ColumnLayout {
id: column
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
spacing: fontMetrics.height
Item { width: parent.spacing; height: parent.height }
Rectangle {
Layout.fillWidth: true
height: rowLayout1.height + 10
RowLayout {
id: rowLayout1
width: parent.width
anchors.verticalCenter: parent.verticalCenter
spacing: Screen.pixelDensity * 1.5 // 1.5mn
Item { width: parent.spacing; height: parent.height }
Image {
height: column1.height * 1.8
width: column1.height * 1.8
sourceSize: Qt.size(width, height)
source: constant.testPic
}
ColumnLayout {
id: column1
Layout.fillHeight: true
Row {
spacing: 10
SampleLabel {
id: personName
text: "小屁孩"
}
Image {
height: personName.height
width: personName.height
sourceSize: Qt.size(width, height)
source: constant.maleSampleIcon
}
}
SampleLabel {
id: showId
text: qsTr("ID: qyvlik")
color: "#888"
}
// SampleLabel {
// id: showNick
// text: "昵称: " + "qyvlik"
// color: "#888"
// }
}
Item { Layout.fillWidth: true }
} // rowLayout1
}
Rectangle {
id: colmnLayout2Parent
Layout.fillWidth: true
height: columnLayout2.height
color: "white"
ColumnLayout {
id: columnLayout2
width: parent.width
spacing: 0
IconLabel {
Layout.fillWidth: true
iconSource: constant.myPostsLabelIcon
labelText: qsTr("My Posts")
onClicked: {
__PushPage(BR.R.personalMyPostsPage);
// __PushPage(Qt.resolvedUrl("./Personal/MyPostsPage.qml"), {} );
}
}
Separator {
Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
color: "#666"; orientation: Qt.Horizontal ;
anchors.horizontalCenter: parent.horizontalCenter
}
IconLabel {
Layout.fillWidth: true
iconSource: constant.favoritesLabelIcon
labelText: qsTr("Favorites")
onClicked: {
__PushPage(BR.R.personalFavoritesPage, {} );
// __PushPage(Qt.resolvedUrl("./Personal/FavoritesPage.qml"), {} );
}
}
}
}
IconLabel {
Layout.fillWidth: true
iconSource: constant.walletLabelIcon
labelText: qsTr("Wallet")
}
IconLabel {
Layout.fillWidth: true
iconSource: constant.faceLabelIcon
labelText: qsTr("Face")
}
IconLabel {
Layout.fillWidth: true
iconSource: constant.settingsLabelIcon
labelText: qsTr("Settings")
onClicked: {
__PushPage(BR.R.personalSettingsPage, {} );
// __PushPage(Qt.resolvedUrl("./Personal/SettingsPage.qml"), {} );
}
}
}
}
}
}
================================================
FILE: qml/WellChat/BussinessPage/ProfilePage.qml
================================================
import QtQuick 2.0
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.1
import Sparrow 1.0
import "../Component"
Page {
id: profilePage
title: qsTr("Profile") // 个人简介页面
color: "#ebebeb"
Constant { id: constant }
focus: true
Keys.onBackPressed: {
event.accepted = true;
try { stackView.pop(); } catch(e) { }
}
topBar: TopBar {
id: topBar
// //! aviod looping binding
// Item { anchors.fill: parent }
RowLayout {
anchors.fill: parent
spacing: 10
Item { width: topBar.height - 2; height: width }
SampleIcon {
iconSource: constant.backActiveIcon
height: topBar.height - 2
width: topBar.height - 2
anchors.verticalCenter: parent.verticalCenter
onClicked: {
try { stackView.pop(); } catch(e) { }
}
Separator {
color: "black"
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
}
//! [0] fix the bug
// 在本页面压入一个页面之后再弹出
// x 的值会变成 180
// 需要将其设置回 0
onXChanged: {
if(x != 0 ) {
x = 0
}
}
//! [0] fix the bug
}
}
// such as menuBar
Row {
parent: topBar
anchors.left: parent.left
anchors.leftMargin: (topBar.height - 2) * 1.5
anchors.fill: parent
SampleLabel {
text: profilePage.title
// Layout.alignment: Qt.AlignRight
color: "white"
anchors.verticalCenter: parent.verticalCenter
}
}
}
ScrollView {
id: page
anchors.fill: parent
verticalScrollBarPolicy :Qt.ScrollBarAlwaysOff
horizontalScrollBarPolicy: Qt.ScrollBarAlwaysOff
Item {
id: content
width: page.width
//width: Math.max(page.viewport.width, column.implicitWidth + 2 * column.spacing)
height: Math.max(page.viewport.height, column.implicitHeight + 2 * column.spacing)
ColumnLayout {
id: column
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
spacing: 20
Item { width: parent.spacing; height: parent.height }
Rectangle {
Layout.fillWidth: true
height: rowLayout1.height + 10
RowLayout {
id: rowLayout1
width: parent.width
anchors.verticalCenter: parent.verticalCenter
spacing: 10
Item { width: parent.spacing; height: parent.height }
Image {
height: column1.height * 1.2
width: column1.height * 1.2
sourceSize: Qt.size(width, height)
source: constant.testPic
}
ColumnLayout {
id: column1
Layout.fillHeight: true
Row {
spacing: 10
SampleLabel {
id: personName
text: "小屁孩"
}
Image {
height: personName.height
width: personName.height
sourceSize: Qt.size(width, height)
source: constant.maleSampleIcon
}
}
SampleLabel {
id: showId
text: qsTr("ID: qyvlik")
color: "#888"
}
SampleLabel {
id: showNick
text: "昵称: qyvlik"
color: "#888"
}
}
Item { Layout.fillWidth: true }
} // rowLayout1
} // colmnLayout1Parent
Rectangle {
Layout.fillWidth: true
height: columnLayout2.height
color: "white"
ColumnLayout {
id: columnLayout2
width: parent.width
spacing: 0
IconLabel {
Layout.fillWidth: true
labelText: qsTr("Region")
Label {
text: qsTr("Guangdong Shantou")
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
anchors.rightMargin: column.spacing
color: "#666"
font.family: GeneralSettings.generalfontFamily
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
}
}
Separator {
Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
color: "#666"; orientation: Qt.Horizontal ;
anchors.horizontalCenter: parent.horizontalCenter
}
IconLabel {
Layout.fillWidth: true
labelText: qsTr("What's Up")
Label {
text: "逝水流年"
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
anchors.rightMargin: column.spacing
color: "#666"
font.family: GeneralSettings.generalfontFamily
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
}
}
Separator {
Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
color: "#666"; orientation: Qt.Horizontal ;
anchors.horizontalCenter: parent.horizontalCenter
}
IconLabel {
// 相册
Layout.fillWidth: true
labelText: qsTr("Album")
Row {
id: row1
anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right
anchors.rightMargin: 10
height: parent.height
spacing: 5
Image {
anchors.verticalCenter: parent.verticalCenter
width: parent.height * 0.8
height: parent.height * 0.8
sourceSize: Qt.size(width, height)
source: constant.testPic
}
Image {
anchors.verticalCenter: parent.verticalCenter
width: parent.height * 0.8
height: parent.height * 0.8
sourceSize: Qt.size(width, height)
source: constant.testPic
}
Image {
anchors.verticalCenter: parent.verticalCenter
width: parent.height * 0.8
height: parent.height * 0.8
sourceSize: Qt.size(width, height)
source: constant.testPic
}
}
}
Separator {
Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
color: "#666"; orientation: Qt.Horizontal ;
anchors.horizontalCenter: parent.horizontalCenter
}
IconLabel {
Layout.fillWidth: true
labelText: qsTr("From")
SampleLabel {
text: qsTr("Group Chat")
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
anchors.rightMargin: column.spacing
color: "#666"
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
}
}
} // columnLayout2
} // colmnLayout2Parent
SampleButton {
text: "Message"
Layout.fillWidth: true
Layout.rightMargin: 50
Layout.leftMargin: 50
onClicked: {
// stackView.pop();
__PushPage(Qt.resolvedUrl("./Chat/ChatPage.qml"), {username: "小屁孩"});
}
}
SampleButton {
text: "Free Call"
Layout.fillWidth: true
Layout.rightMargin: 50
Layout.leftMargin: 50
onClicked: {
}
}
} // column
} // content
}// scrollview
}
================================================
FILE: qml/WellChat/BussinessPage/R.qml
================================================
// ~R
pragma Singleton
import QtQuick 2.0
// WellChat BussinessPage Resource
QtObject {
id: resource
objectName: "WellChatBussinessPageResource"
readonly property
url chatChatPage:
Qt.resolvedUrl("./Chat/ChatPage.qml")
readonly property
url discoverMomentsPage:
Qt.resolvedUrl("./Discover/MomentsPage/MomentsPage.qml")
readonly property
url personalSettingsAboutPage:
Qt.resolvedUrl("./Personal/Settings/AboutPage.qml")
readonly property
url personalSettingsChatSettingsPage:
Qt.resolvedUrl("./Personal/Settings/ChatSettingsPage.qml")
readonly property
url personalSettingsDoNotDisturbSettingsPage:
Qt.resolvedUrl("./Personal/Settings/DoNotDisturbSettingsPage.qml")
readonly property
url personalSettingsGeneralSettingsPage:
Qt.resolvedUrl("./Personal/Settings/GeneralSettingsPage.qml")
readonly property
url personalSettingsMyAccountSettingsPage:
Qt.resolvedUrl("./Personal/Settings/MyAccountSettingsPage.qml")
readonly property
url personalSettingsNotificationsSettingsPage:
Qt.resolvedUrl("./Personal/Settings/NotificationsSettingsPage.qml")
readonly property
url personalSettingsPrivacySettingsPage:
Qt.resolvedUrl("./Personal/Settings/PrivacySettingsPage.qml")
readonly property
url personalFavoritesPage:
Qt.resolvedUrl("./Personal/FavoritesPage.qml")
readonly property
url personalMyPostsPage:
Qt.resolvedUrl("./Personal/MyPostsPage.qml")
readonly property
url personalSettingsPage:
Qt.resolvedUrl("./Personal/SettingsPage.qml")
readonly property
url chatsView:
Qt.resolvedUrl("./ChatsView.qml")
readonly property
url constactsView:
Qt.resolvedUrl("./ContactsView.qml")
readonly property
url discoverPage:
Qt.resolvedUrl("./DiscoverPage.qml")
readonly property
url profilePage:
Qt.resolvedUrl("./ProfilePage.qml")
}
================================================
FILE: qml/WellChat/BussinessPage/qmldir
================================================
# this module is for this application
# don't use the other application
module BussinessPage
singleton R 1.0 ./R.qml
================================================
FILE: qml/WellChat/Component/+android/UI.js
================================================
// 这个文件用来适配UI 控件的
// 本文件是 安卓
.pragma library
// console.log("UI font point size", "android")
var smallFontPointSize = 12 // 主页面下的icon的文本例如chat等
var middleFontPointSize = 13
var normalFontPointSize = 20 // 文本编辑框,按钮中的字体大小
var bigFontPointSize = 36 // 软件标题
================================================
FILE: qml/WellChat/Component/Constant.qml
================================================
import QtQuick 2.0
import QtQuick.Window 2.2
import "./UI.js" as UI
import Sparrow 1.0
QtObject {
id: constant
// "#71d01d":"#ccc"
// 微信 深灰 #22292c
// 微信绿 #71d01d
// 普通灰 #ccc
readonly property string fontFamily: GeneralSettings.generalfontFamily
readonly property int smallFontPointSize : UI.smallFontPointSize // 主页面下的icon的文本例如chat等
readonly property int middleFontPointSize : UI.middleFontPointSize
readonly property int normalFontPointSize : UI.normalFontPointSize // 文本编辑框,按钮中的字体大小
readonly property int bigFontPointSize : UI.bigFontPointSize // 软件标题
readonly property url testPic: Qt.resolvedUrl( "../Resource/tests/tests001.jpg")
readonly property alias icons: __icons
readonly property url iconsPath: "../Resource/icons/"
readonly property url femaleSampleIcon: icons.sampleIcon("female") // 女性
readonly property url maleSampleIcon: icons.sampleIcon("male") // 男性
readonly property url soundActiveIcon: icons.activeIcon("sound")
readonly property url soundInactiveIcon: icons.inactiveIcon("sound")
readonly property url emoticonActiveIcon: icons.activeIcon("emoticon")
readonly property url emoticonInactiveIcon: icons.inactiveIcon("emoticon")
readonly property url backActiveIcon: icons.activeIcon("back")
readonly property url backInactiveIcon: icons.inactiveIcon("back")
readonly property url magnifierActiveIcon: icons.activeIcon("magnifier")
readonly property url magnifierInactiveIcon: icons.inactiveIcon("magnifier")
readonly property url plusActiveIcon: icons.activeIcon("plus")
readonly property url plusInactiveIcon: icons.inactiveIcon("plus")
readonly property url addActiveIcon: icons.activeIcon("a6c")
readonly property url addInactiveIcon: icons.inactiveIcon("a6b")
readonly property url momentsLabelIcon: icons.labelIcon("moments") // 朋友圈
readonly property url scanQRCodeLabelIcon: icons.labelIcon("scan-qr-code") // 二维码
readonly property url shakeLabelIcon: icons.labelIcon("shake") // 摇一摇
readonly property url peopleNearbyLabelIcon: icons.labelIcon("people-nearby") // 附近的人
readonly property url driftBottleLabelIcon: icons.labelIcon("drift-bottle") // 漂流瓶
readonly property url gamesLabelIcon: icons.labelIcon("games") // 游戏中心
readonly property url favoritesLabelIcon: icons.labelIcon("favorites") // 收藏
readonly property url myPostsLabelIcon: icons.labelIcon("my-posts") // 相册
readonly property url settingsLabelIcon: icons.labelIcon("settings") // 设置
readonly property url faceLabelIcon: icons.labelIcon("face") // 表情
readonly property url walletLabelIcon: icons.labelIcon("wallet") // 钱包
readonly property url shareExcelIcon: icons.share("share-excel")
readonly property url shareFileIcon: icons.share("share-file")
readonly property url shareMusicIcon: icons.share("share-music")
readonly property url sharePdfIcon: icons.share("share-pdf")
readonly property url sharePictureIcon: icons.share("share-picture")
readonly property url sharePositionIcon: icons.share("share-position")
readonly property url shareSoundIcon: icons.share("share-sound")
readonly property url shareTextIcon: icons.share("share-text")
readonly property url shareUrlIcon: icons.share("share-url")
readonly property url shareVideoIcon: icons.share("share-video")
readonly property url shareWordIcon: icons.share("share-word")
readonly property url shareZipIcon: icons.share("share-zip")
property var _icons: QtObject {
id: __icons
function share(name) {
return Qt.resolvedUrl(iconsPath + "label-icons/" + name + ".png");
}
function labelIcon(name) {
return Qt.resolvedUrl(iconsPath + "label-icons/" + name + ".png");
}
function activeIcon(name) {
return Qt.resolvedUrl(iconsPath + "bar-icons/active/" + name +".png")
}
function inactiveIcon(name) {
return Qt.resolvedUrl(iconsPath + "bar-icons/inactive/" + name +".png")
}
function sampleIcon(name) {
return Qt.resolvedUrl(iconsPath + "icons/" + name +".png")
}
}
// property var _length: QtObject {
// id: __length
// readonly property int screenWidth: Screen.width
// readonly property int screenHeight: Screen.height
// readonly property real devicePixelRatio: Screen.devicePixelRatio
// readonly property real pixelDensity: Screen.pixelDensity
// function controlLength(l) {
// }
// /*!
// \internal
// This holds the pixel density used for converting millimeters into pixels. This is the exact
// value from \l Screen:pixelDensity, but that property only works from within a \l Window type,
// so this is hardcoded here and we update it from within \l ApplicationWindow
// */
// // property real pixelDensity: 4.46
// property real multiplier: 1.4 //default multiplier, but can be changed by user
// /*!
// This is the standard function to use for accessing device-independent pixels. You should use
// this anywhere you need to refer to distances on the screen.
// */
// function dp(number) {
// return Math.round(number*((pixelDensity*25.4)/160)*multiplier);
// }
// function gu(number) {
// return number * gridUnit
// }
// property int gridUnit: dp(64)
// }
}
================================================
FILE: qml/WellChat/Component/Icon.qml
================================================
import QtQuick 2.5
import QtQuick.Layouts 1.1
import "./UI.js" as UI
import Sparrow 1.0
Rectangle {
id: icon
width: columnLayout.width
height: columnLayout.height
color: "transparent"
signal clicked()
property alias iconTextVisible: iconText.visible
property size iconSize: Qt.size(33, 33)
property alias iconText: iconText.text
property alias activeIconOpacity: activeIconImage.opacity
property alias activeIconSource: activeIconImage.source
property alias inactiveIconSource: inactiveIconImage.source
ColumnLayout {
id: columnLayout
anchors.centerIn: parent
spacing: 0
Item {
width: iconSize.width - iconText.height
height: iconSize.height - iconText.height
anchors.horizontalCenter: parent.horizontalCenter
Image {
id: activeIconImage
anchors.fill: parent
fillMode: Image.PreserveAspectFit
opacity: 1
Behavior on opacity {
NumberAnimation { duration: 300 }
}
}
Image {
id: inactiveIconImage
anchors.centerIn: parent
anchors.fill: parent
fillMode: Image.PreserveAspectFit
opacity: 1 - activeIconImage.opacity
}
}
SampleLabel {
id: iconText
anchors.horizontalCenter: parent.horizontalCenter
Layout.fillWidth: true
verticalAlignment: Text.AlignBottom
horizontalAlignment: Text.AlignHCenter
font.pointSize: UI.smallFontPointSize
color: activeIconImage.opacity == 0? "#999999": "#45c01a"
}
Item {
height: iconText.contentHeight * 0.3
width: iconText.contentHeight
}
}
MouseArea {
anchors.fill: parent
onClicked: {
icon.clicked();
}
}
}
================================================
FILE: qml/WellChat/Component/IconButton.qml
================================================
import QtQuick 2.0
import QtQuick.Controls 1.4
// import "../"
Item {
id: iconButton
// Constant { id: constant }
height: 40
width: 40
signal clicked()
property bool active: false
property url activeIconSource: ""
property url inactiveIconSource: ""
Accessible.role: Accessible.Button
Accessible.name: "iconButton"
Accessible.description: "shows the icon"
Accessible.onPressAction: {
// do a button click
clicked()
}
Image {
id: icon
height: iconButton.height * 0.65
width: iconButton.width * 0.65
anchors.centerIn: parent
fillMode: Image.PreserveAspectFit
sourceSize: Qt.size(width, height)
source: active ? activeIconSource : inactiveIconSource
}
MouseArea {
anchors.fill: parent
onClicked: iconButton.clicked()
onPressed: {
active = true;
}
onReleased: {
active = false;
}
}
}
================================================
FILE: qml/WellChat/Component/IconLabel.qml
================================================
import QtQuick 2.0
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.1
import Sparrow 1.0
Rectangle {
id: iconLabel
color: "white"
clip: true
height: label.contentHeight * 3
signal clicked()
signal pressAndHold()
property alias iconSource: icon.source
property alias labelText: label.text
property alias fontPointSize: label.font.pointSize
property alias spacing: rowLayout.spacing
RowLayout {
id: rowLayout
width: parent.width
anchors.verticalCenter: parent.verticalCenter
spacing: 20
Item { width: parent.spacing; height: parent.spacing }
Image {
id: icon
height: label.contentHeight * 1.5
width: label.contentHeight * 1.5
sourceSize: Qt.size(width, height)
visible: icon.status == Image.Ready
}
SampleLabel {
id: label
}
Item { Layout.fillWidth: true }
}
MouseArea {
anchors.fill: parent
onClicked: iconLabel.clicked();
onPressed: iconLabel.color = "#555";
onReleased: iconLabel.color = "white";
onPressAndHold: iconLabel.pressAndHold();
onPositionChanged: iconLabel.color = "white";
}
}
================================================
FILE: qml/WellChat/Component/MainListView.qml
================================================
import QtQuick 2.2
ListView {
clip: true
preferredHighlightBegin: 0
preferredHighlightEnd: 0
highlightMoveDuration: 250
highlightRangeMode: ListView.StrictlyEnforceRange
snapMode: ListView.SnapOneItem
orientation: ListView.Horizontal
maximumFlickVelocity: 3000
boundsBehavior: ListView.StopAtBounds
onCurrentIndexChanged: forceActiveFocus()
}
================================================
FILE: qml/WellChat/Component/SampleTextArea.qml
================================================
/*
* author qyvlik
* email qyvlik@qq.com
* time 2015/4/10
* FLatUI element FlatTextField
*
*/
import QtQuick 2.5
import QtQuick.Controls 1.3
import QtQuick.Controls.Styles 1.4
import Sparrow 1.0
TextArea {
id:textArea
font.family: GeneralSettings.generalfontFamily
font.pointSize: GeneralSettings.generalFontPointSize
wrapMode: TextEdit.Wrap
backgroundVisible: false
// 微信绿 #71d01d
// 普通灰 #ccc
// style: TextAreaStyle {
// renderType: Text.NativeRendering
// }
FontMetrics {
id: fontMetrics
font.family: GeneralSettings.generalfontFamily
font.pointSize: GeneralSettings.generalFontPointSize
font.weight: Font.Thin
font.bold: false
}
Rectangle {
width: parent.width - 10
anchors.horizontalCenter: parent.horizontalCenter
height: 1
color: parent.focus? "#71d01d" : "#ccc"
anchors.bottom: parent.bottom
anchors.bottomMargin: fontMetrics.height * 0.2
}
}
================================================
FILE: qml/WellChat/Component/ScrollBar.qml
================================================
import QtQuick 2.0
Item {
id: scrollBar
// The properties that define the scrollbar's state.
// position and pageSize are in the range 0.0 - 1.0. They are relative to the
// height of the page, i.e. a pageSize of 0.5 means that you can see 50%
// of the height of the view.
// orientation can be either Qt.Vertical or Qt.Horizontal
property real position
property real pageSize
property int orientation : Qt.Vertical
// A light, semi-transparent background
Rectangle {
id: background
anchors.fill: parent
radius: orientation == Qt.Vertical ? (width/2 - 1) : (height/2 - 1)
color: "white"
opacity: 0.3
}
// Size the bar to the required size, depending upon the orientation.
Rectangle {
x: orientation == Qt.Vertical ? 1 : (scrollBar.position * (scrollBar.width-2) + 1)
y: orientation == Qt.Vertical ? (scrollBar.position * (scrollBar.height-2) + 1) : 1
width: orientation == Qt.Vertical ? (parent.width-2) : (scrollBar.pageSize * (scrollBar.width-2))
height: orientation == Qt.Vertical ? (scrollBar.pageSize * (scrollBar.height-2)) : (parent.height-2)
//radius: orientation == Qt.Vertical ? (width/2 - 1) : (height/2 - 1)
color: "black"
opacity: 0.7
}
}
================================================
FILE: qml/WellChat/Component/Separator.qml
================================================
/*
* author qyvlik
* email qyvlik@qq.com
* time 2015/4/10
* FlatUI.Private element
*
* this qml file (element type) just for build module
* not allow used by user
*
*
* such as drow a line
*/
import QtQuick 2.0
Rectangle {
id:separator
property int orientation : Qt.Vertical // Qt.Horizontal
property int length:orientation == Qt.Vertical ? parent.height*0.6 : parent.width*0.6
property int separatorWidth : 1
onOrientationChanged: __fix();
onLengthChanged: __fix()
onSeparatorWidthChanged: __fix()
// private function
function __fix(){
switch(orientation){
case Qt.Vertical: // 垂直的
height = length;
width = separatorWidth;
break;
case Qt.Horizontal: // 水平的
width = length;
height = separatorWidth;
break;
default:
height = length;
width = separatorWidth;
break;
}
}
Component.onCompleted: __fix();
}
================================================
FILE: qml/WellChat/Component/UI.js
================================================
// 这个文件用来适配UI 控件的
// 本文件是win7
.pragma library
// console.log("UI font point size", "win7")
var smallFontPointSize = 8 // 主页面下的icon的文本例如chat等
var middleFontPointSize = 11
var normalFontPointSize = 14 // 文本编辑框,按钮中的字体大小
var bigFontPointSize = 18 // 软件标题
================================================
FILE: qml/WellChat/MainView.qml
================================================
import Resource 1.0 as Resource
import QtQuick 2.0
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.1
import QtQuick.Controls.Styles 1.4
import QtQml.Models 2.2
import Sparrow 1.0
import "./BussinessPage" // has R.qml
import "./Component"
Page {
id: mainView
title: "WellChat"
// Constant { }
topBar: TopBar {
id: topBar
RowLayout {
anchors.fill: parent
// spacing: 20
SampleLabel {
Layout.leftMargin: 20
text: title
color: "white"
}
Item { Layout.fillWidth: true }
}
// such as menuBar
Row {
//! [0]
parent: topBar
anchors.right: parent.right
anchors.rightMargin: 10
//! [0]
SampleIcon {
iconSource: Resource.R.activeIconMagnifier
id: iconButton2
iconSize: Qt.size( topBar.height - 2, topBar.height - 2)
onClicked: {
tryToNotify("我操!");
}
}
SampleIcon {
iconSource: Resource.R.activeIconPlus
id: iconButton1
iconSize: Qt.size( topBar.height - 2, topBar.height - 2)
onClicked: {
try {
console.log("try to setStatusBarColor",
topBar.backgroundColor)
BridgingAndroid.setStatusBarColor(topBar.backgroundColor);
} catch(e){
console.log(e);
}
}
}
}
}
bottomBar: BottomBar {
id: bottomBar
property int iconHeight: topBar.height
property int iconWidth: topBar.width
RowLayout {
id: iconBar
spacing: 0
anchors.fill: parent
readonly property var iconNames: ["Chat","Contacts","Discover", "Me"]
function getActiveIconUrl(index) {
return "./Resource/icons/bar-icons/active/"+iconNames[index].toLowerCase()+".png";
}
function getInctiveIconUrl(index) {
return "./Resource/icons/bar-icons/inactive/"+iconNames[index].toLowerCase()+".png";
}
// Item { Layout.fillWidth: true }
Repeater {
id: repeater
model:iconBar.iconNames
Icon {
Layout.fillWidth: true
iconSize: Qt.size(topBar.height, topBar.height)
iconText: iconBar.iconNames[index]
activeIconSource: iconBar.getActiveIconUrl(index)
inactiveIconSource: iconBar.getInctiveIconUrl(index)
activeIconOpacity: (mainListView.currentIndex == index)
onClicked: {
mainListView.currentIndex = index;
mainListView.currentItem.focus = true;
}
}
}
}
}
MainListView {
id: mainListView
focus: mainView.focus
anchors.fill: parent
model: itemsModel
}
ObjectModel {
id: itemsModel
ChatsView {
id: chatsView
pageStackWindow: mainView.pageStackWindow
stackView: mainView.stackView
width: mainListView.width
height: mainListView.height
}
ContactsView {
id: contactsView
mainListView: mainListView
pageStackWindow: ma
gitextract_f1fzdbi7/
├── .gitignore
├── LICENSE
├── README.md
├── Sparrow/
│ ├── Sparrow.pri
│ ├── keyboard.cpp
│ ├── keyboard.h
│ ├── qmlnetworkaccessmanagerfactory.cpp
│ ├── qmlnetworkaccessmanagerfactory.h
│ ├── qtbridgingandroid.cpp
│ ├── qtbridgingandroid.h
│ └── sparrow_global.h
├── WellChat.pro
├── android/
│ ├── AndroidManifest.xml
│ ├── assets/
│ │ └── font/
│ │ └── NotoSansHans-DemiLight.otf
│ ├── build.gradle
│ ├── gradle/
│ │ └── wrapper/
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradlew
│ ├── gradlew.bat
│ ├── res/
│ │ └── values/
│ │ └── libs.xml
│ └── src/
│ └── org/
│ └── gdpurjyfs/
│ ├── sparrow/
│ │ └── QtBridgingAndroid.java
│ └── wellchat/
│ └── WellChatActivity.java
├── deployment.pri
├── desktop.qrc
├── doc/
│ └── weixin-ui-analyse.md
├── main.cpp
├── qml/
│ └── WellChat/
│ ├── BussinessPage/
│ │ ├── Chat/
│ │ │ ├── ChatPage.qml
│ │ │ ├── Heartbeat.qml
│ │ │ ├── Lazy.qml
│ │ │ ├── Tuling123.js
│ │ │ └── heart.js
│ │ ├── ChatsView.qml
│ │ ├── Contacts/
│ │ │ └── ContactsListView.qml
│ │ ├── ContactsView.qml
│ │ ├── Discover/
│ │ │ └── MomentsPage/
│ │ │ └── MomentsPage.qml
│ │ ├── DiscoverPage.qml
│ │ ├── Personal/
│ │ │ ├── FavoritesPage.qml
│ │ │ ├── MyPostsPage.qml
│ │ │ ├── Settings/
│ │ │ │ ├── AboutPage.qml
│ │ │ │ ├── ChatSettingsPage.qml
│ │ │ │ ├── DoNotDisturbSettingsPage.qml
│ │ │ │ ├── GeneralSettingsPage.qml
│ │ │ │ ├── MyAccountSettingsPage.qml
│ │ │ │ ├── NotificationsSettingsPage.qml
│ │ │ │ ├── PrivacySettingsPage.qml
│ │ │ │ └── SettingsGroup.qml
│ │ │ └── SettingsPage.qml
│ │ ├── PersonalPage.qml
│ │ ├── ProfilePage.qml
│ │ ├── R.qml
│ │ └── qmldir
│ ├── Component/
│ │ ├── +android/
│ │ │ └── UI.js
│ │ ├── Constant.qml
│ │ ├── Icon.qml
│ │ ├── IconButton.qml
│ │ ├── IconLabel.qml
│ │ ├── MainListView.qml
│ │ ├── SampleTextArea.qml
│ │ ├── ScrollBar.qml
│ │ ├── Separator.qml
│ │ └── UI.js
│ ├── MainView.qml
│ ├── Sparrow/
│ │ ├── +android/
│ │ │ ├── UI.js
│ │ │ └── WebPage.qml
│ │ ├── BottomBar.qml
│ │ ├── ClickedShaderEffect.qml
│ │ ├── GeneralSettings.qml
│ │ ├── Page.qml
│ │ ├── PageStackWindow.qml
│ │ ├── PopupLayer/
│ │ │ ├── Delegate/
│ │ │ │ ├── PopupLayerBottomMenuDelegate.qml
│ │ │ │ ├── PopupLayerDialogDelegate.qml
│ │ │ │ ├── PopupLayerSideMenuDelegate.qml
│ │ │ │ └── qmldir
│ │ │ ├── PopupLayer.qml
│ │ │ ├── PopupLayerDelegate.qml
│ │ │ ├── PopupLayerTransition.qml
│ │ │ ├── qmldir
│ │ │ └── readme.md
│ │ ├── QObject.qml
│ │ ├── SampleButton.qml
│ │ ├── SampleIcon.qml
│ │ ├── SampleLabel.qml
│ │ ├── SampleTextField.qml
│ │ ├── TopBar.qml
│ │ ├── Tracker.qml
│ │ ├── UI.js
│ │ ├── WebPage.qml
│ │ ├── qmldir
│ │ └── resources/
│ │ ├── NotoSansHans-DemiLight.otf
│ │ └── readme.md
│ ├── WellChat.qmlproject
│ ├── main.qml
│ └── resource/
│ ├── R.qml
│ └── qmldir
├── qml.qrc
└── src/
└── wellchat/
├── collectionsmodel.cpp
└── collectionsmodel.h
SYMBOL INDEX (26 symbols across 11 files)
FILE: Sparrow/keyboard.cpp
function QRectF (line 33) | QRectF Keyboard::keyboardRectangle() const
function Keyboard (line 38) | Keyboard *Keyboard::singleton()
FILE: Sparrow/keyboard.h
function class (line 11) | class Keyboard : public QObject
FILE: Sparrow/qmlnetworkaccessmanagerfactory.cpp
function QNetworkAccessManager (line 23) | QNetworkAccessManager *QmlNetworkAccessManagerFactory::create(QObject *p...
FILE: Sparrow/qmlnetworkaccessmanagerfactory.h
function class (line 6) | class QmlNetworkAccessManagerFactory : public QQmlNetworkAccessManagerFa...
FILE: Sparrow/qtbridgingandroid.h
function class (line 8) | class QtBridgingAndroid : public QObject
FILE: android/src/org/gdpurjyfs/sparrow/QtBridgingAndroid.java
class SetStatusBarColorRunnable (line 51) | class SetStatusBarColorRunnable implements Runnable
method SetStatusBarColorRunnable (line 55) | public SetStatusBarColorRunnable(Activity activity, int color) {
method run (line 60) | @Override
class QtBridgingAndroid (line 66) | public class QtBridgingAndroid
method setStatusBarColor (line 80) | public static void setStatusBarColor(String colorString) {
method notify (line 97) | public static void notify(String notifyText)
method getRootView (line 111) | private static View getRootView(Activity context)
method listenKeyboardHeight (line 118) | public static void listenKeyboardHeight() {
method notifiedKeyboardRectangle (line 160) | public static native void notifiedKeyboardRectangle(int x, int y,
method Init (line 164) | public static void Init(Activity instanceActivity) {
FILE: android/src/org/gdpurjyfs/wellchat/WellChatActivity.java
class WellChatActivity (line 53) | public class WellChatActivity extends org.qtproject.qt5.android.bindings...
method WellChatActivity (line 62) | public WellChatActivity()
FILE: main.cpp
function main (line 18) | int main(int argc, char *argv[])
FILE: qml/WellChat/BussinessPage/Chat/Tuling123.js
function sendTextToTuling123 (line 5) | function sendTextToTuling123(text, chatUserId, callback, err) {
function isErrorCode (line 40) | function isErrorCode(code) {
function errorCodeHandle (line 79) | function errorCodeHandle(code) {
FILE: src/wellchat/collectionsmodel.cpp
function QString (line 85) | QString CollectionsModel::roleName(int role) {
function QVariant (line 138) | QVariant CollectionsModel::data(const QModelIndex &index, int role) const
function QObject (line 196) | QObject *CollectionsModel::singleton(QQmlEngine *qmlEngine, QJSEngine *j...
FILE: src/wellchat/collectionsmodel.h
function Q_OBJECT (line 12) | Q_OBJECT
Condensed preview — 97 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (276K chars).
[
{
"path": ".gitignore",
"chars": 24,
"preview": "WellChat.pro.user\n*.user"
},
{
"path": "LICENSE",
"chars": 1077,
"preview": "The MIT License (MIT)\n\nCopyright (c) 2015 GDPURJYFS\n\nPermission is hereby granted, free of charge, to any person obtaini"
},
{
"path": "README.md",
"chars": 1240,
"preview": "# WellChat\n\nWellChat is a Application that is a WeChat-like APP by qml.\n\n> best tool vesion:\n\n> Qt version >= 5.5.0\n\n> A"
},
{
"path": "Sparrow/Sparrow.pri",
"chars": 635,
"preview": "QT += core network sql qml\n\nandroid {\n QT += androidextras\n\n}\n\nHEADERS += \\\n #$$PWD/qmlnetworkaccessmanagerfactory"
},
{
"path": "Sparrow/keyboard.cpp",
"chars": 1246,
"preview": "#include \"keyboard.h\"\n#include <QGuiApplication>\n#include <QInputMethod>\n\n#include \"sparrow_global.h\"\n\nKeyboard::Keyboar"
},
{
"path": "Sparrow/keyboard.h",
"chars": 987,
"preview": "#ifndef VIRTUALKEYBOARD_H\n#define VIRTUALKEYBOARD_H\n\n#include <QObject>\n#include <QRectF>\n\nclass QtBridgingAndroid;\nclas"
},
{
"path": "Sparrow/qmlnetworkaccessmanagerfactory.cpp",
"chars": 1007,
"preview": "#include \"qmlnetworkaccessmanagerfactory.h\"\n\n#include <QDir>\n#include <QDebug>\n#include <QNetworkAccessManager>\n#include"
},
{
"path": "Sparrow/qmlnetworkaccessmanagerfactory.h",
"chars": 391,
"preview": "#ifndef QMLNETWORKACCESSMANAGERFACTORY_H\n#define QMLNETWORKACCESSMANAGERFACTORY_H\n\n#include <QQmlNetworkAccessManagerFac"
},
{
"path": "Sparrow/qtbridgingandroid.cpp",
"chars": 4146,
"preview": "#include \"qtbridgingandroid.h\"\n#include \"keyboard.h\"\n#include <QRect>\n#include <QRectF>\n#include <QGuiApplication>\n\nQtBr"
},
{
"path": "Sparrow/qtbridgingandroid.h",
"chars": 700,
"preview": "#ifndef QTBRIDGINGANDROID_H\n#define QTBRIDGINGANDROID_H\n\n#include <QObject>\n#include <QColor>\n#include \"sparrow_global.h"
},
{
"path": "Sparrow/sparrow_global.h",
"chars": 475,
"preview": "#ifndef GLOBAL\n#define GLOBAL\n\n#include <QDebug>\n\n#ifdef Q_OS_ANDROID\n\n#include <QtAndroidExtras/QAndroidJniObject>\n#inc"
},
{
"path": "WellChat.pro",
"chars": 804,
"preview": "TEMPLATE = app\n\nQT += qml quick widgets\n\nSOURCES += main.cpp \\\n src/wellchat/collectionsmodel.cpp\n\nRESOURCES += \\\n "
},
{
"path": "android/AndroidManifest.xml",
"chars": 4328,
"preview": "<?xml version=\"1.0\"?>\n<manifest package=\"org.gdpurjyfs.wellchat\" xmlns:android=\"http://schemas.android.com/apk/res/andro"
},
{
"path": "android/build.gradle",
"chars": 1502,
"preview": "buildscript {\n repositories {\n jcenter()\n }\n\n dependencies {\n classpath 'com.android.tools.build:"
},
{
"path": "android/gradle/wrapper/gradle-wrapper.properties",
"chars": 230,
"preview": "#Wed Apr 10 15:27:10 PDT 2013\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\nzipStoreBase=GRADLE_USER_"
},
{
"path": "android/gradlew",
"chars": 5080,
"preview": "#!/usr/bin/env bash\n\n##############################################################################\n##\n## Gradle start "
},
{
"path": "android/gradlew.bat",
"chars": 2314,
"preview": "@if \"%DEBUG%\" == \"\" @echo off\n@rem ##########################################################################\n@rem\n@rem "
},
{
"path": "android/res/values/libs.xml",
"chars": 661,
"preview": "<?xml version='1.0' encoding='utf-8'?>\n<resources>\n <array name=\"qt_sources\">\n <item>https://download.qt-proje"
},
{
"path": "android/src/org/gdpurjyfs/sparrow/QtBridgingAndroid.java",
"chars": 6575,
"preview": "/*\n * Copyright (c) <2015> <copyright qyvlik>\n *\n * Permission is hereby granted, free of charge, to any person obtainin"
},
{
"path": "android/src/org/gdpurjyfs/wellchat/WellChatActivity.java",
"chars": 2490,
"preview": "/****************************************************************************\n**\n** Copyright (C) 2015 The Qt Company Lt"
},
{
"path": "deployment.pri",
"chars": 648,
"preview": "android-no-sdk {\n target.path = /data/user/qt\n export(target.path)\n INSTALLS += target\n} else:android {\n QT "
},
{
"path": "desktop.qrc",
"chars": 136,
"preview": "<RCC>\n <qresource prefix=\"/\">\n <file>qml/WellChat/Sparrow/resources/NotoSansHans-DemiLight.otf</file>\n </qr"
},
{
"path": "doc/weixin-ui-analyse.md",
"chars": 1577,
"preview": "# 微信界面剖析\n\n微信界面剖析分为:首界面,单个界面,字体大小,素材等。\n\n## 首界面\n\n可以先查看[简单易用的页面栈框架](readme.md)。\n\n先看看微信的首界面。有四个分页,`BottomBar` 可以显示当前页面的以及进行切"
},
{
"path": "main.cpp",
"chars": 1984,
"preview": "/*!\n * Activity 先于 Qt 加载\n * 1. 在 Activity OnCreate 中调用 QtBridgingAndroid::Init,然后进入Qt::main\n * 2. 在 Qt::main 中注册 Java 的 "
},
{
"path": "qml/WellChat/BussinessPage/Chat/ChatPage.qml",
"chars": 16101,
"preview": "import Resource 1.0 as R\n\nimport QtQuick 2.5\nimport QtQuick.Controls 1.4\nimport QtQuick.Window 2.0\nimport QtQuick.Layout"
},
{
"path": "qml/WellChat/BussinessPage/Chat/Heartbeat.qml",
"chars": 713,
"preview": "import QtQuick 2.0\n\nQtObject {\n id: heartbeat\n\n property alias source: worker.source\n property alias interval: "
},
{
"path": "qml/WellChat/BussinessPage/Chat/Lazy.qml",
"chars": 648,
"preview": "import Resource 1.0 as R\n\nimport QtQuick 2.5\nimport QtQuick.Controls 1.4\nimport QtQuick.Window 2.0\nimport QtQuick.Layout"
},
{
"path": "qml/WellChat/BussinessPage/Chat/Tuling123.js",
"chars": 3252,
"preview": ".pragma library\n\n// callback(responseText)\n// err(errorCode)\nfunction sendTextToTuling123(text, chatUserId, callback, er"
},
{
"path": "qml/WellChat/BussinessPage/Chat/heart.js",
"chars": 1294,
"preview": "// .pragma library\n\n// 心跳包\n\n// to include static singleton mess_id\nQt.include(\"./storage.js\")\n\nWorkerScript.onMessage = "
},
{
"path": "qml/WellChat/BussinessPage/ChatsView.qml",
"chars": 9745,
"preview": "\nimport BussinessPage 1.0 as BR\n\nimport QtQuick 2.0\nimport QtQuick.Controls 1.4\nimport QtQuick.Window 2.0\nimport QtQuick"
},
{
"path": "qml/WellChat/BussinessPage/Contacts/ContactsListView.qml",
"chars": 3791,
"preview": "import QtQuick 2.5\nimport QtQuick.Window 2.0\nimport QtQuick.Layouts 1.1\nimport Sparrow 1.0 as Sparrow\n\nRectangle {\n i"
},
{
"path": "qml/WellChat/BussinessPage/ContactsView.qml",
"chars": 2933,
"preview": "import Resource 1.0 as R\nimport BussinessPage 1.0 as BR\n\nimport QtQuick 2.0\nimport QtQuick.Controls 1.4\nimport QtQuick.L"
},
{
"path": "qml/WellChat/BussinessPage/Discover/MomentsPage/MomentsPage.qml",
"chars": 2813,
"preview": "import Resource 1.0 as R\n\nimport QtQuick 2.0\nimport QtQuick.Controls 1.4\nimport QtQuick.Window 2.2\nimport QtQuick.Layout"
},
{
"path": "qml/WellChat/BussinessPage/DiscoverPage.qml",
"chars": 4550,
"preview": "import Resource 1.0 as R\nimport BussinessPage 1.0 as BR\n\nimport QtQuick 2.5\nimport QtQuick.Controls 1.4\nimport QtQuick.L"
},
{
"path": "qml/WellChat/BussinessPage/Personal/FavoritesPage.qml",
"chars": 3333,
"preview": "import Resource 1.0 as R\n\nimport QtQuick 2.0\nimport QtQuick.Layouts 1.1\n\nimport \"../../Component\"\nimport \"./Settings\"\n\ni"
},
{
"path": "qml/WellChat/BussinessPage/Personal/MyPostsPage.qml",
"chars": 3336,
"preview": "import Resource 1.0 as R\n\nimport QtQuick 2.0\nimport QtQuick.Controls 1.4\nimport QtQuick.Layouts 1.1\n\nimport \"../../Compo"
},
{
"path": "qml/WellChat/BussinessPage/Personal/Settings/AboutPage.qml",
"chars": 5690,
"preview": "import Resource 1.0 as R\n\nimport QtQuick 2.0\nimport QtQuick.Controls 1.4\nimport QtQuick.Layouts 1.1\n\nimport Sparrow 1.0\n"
},
{
"path": "qml/WellChat/BussinessPage/Personal/Settings/ChatSettingsPage.qml",
"chars": 5548,
"preview": "import Resource 1.0 as R\n\nimport QtQuick 2.0\nimport QtQuick.Controls 1.4\nimport QtQuick.Layouts 1.1\n\nimport Sparrow 1.0\n"
},
{
"path": "qml/WellChat/BussinessPage/Personal/Settings/DoNotDisturbSettingsPage.qml",
"chars": 5880,
"preview": "import Resource 1.0 as R\n\nimport QtQuick 2.0\nimport QtQuick.Controls 1.4\nimport QtQuick.Layouts 1.1\n\nimport Sparrow 1.0\n"
},
{
"path": "qml/WellChat/BussinessPage/Personal/Settings/GeneralSettingsPage.qml",
"chars": 10201,
"preview": "import Resource 1.0 as R\n\nimport QtQuick 2.0\nimport QtQuick.Controls 1.4\nimport QtQuick.Layouts 1.1\n\nimport Sparrow 1.0\n"
},
{
"path": "qml/WellChat/BussinessPage/Personal/Settings/MyAccountSettingsPage.qml",
"chars": 8885,
"preview": "import Resource 1.0 as R\n\nimport QtQuick 2.0\nimport QtQuick.Controls 1.4\nimport QtQuick.Layouts 1.1\n\nimport Sparrow 1.0\n"
},
{
"path": "qml/WellChat/BussinessPage/Personal/Settings/NotificationsSettingsPage.qml",
"chars": 7994,
"preview": "import Resource 1.0 as R\n\nimport QtQuick 2.0\nimport QtQuick.Controls 1.4\nimport QtQuick.Layouts 1.1\n\nimport Sparrow 1.0\n"
},
{
"path": "qml/WellChat/BussinessPage/Personal/Settings/PrivacySettingsPage.qml",
"chars": 9122,
"preview": "import Resource 1.0 as R\n\nimport QtQuick 2.0\nimport QtQuick.Controls 1.4\nimport QtQuick.Layouts 1.1\n\nimport Sparrow 1.0\n"
},
{
"path": "qml/WellChat/BussinessPage/Personal/Settings/SettingsGroup.qml",
"chars": 1306,
"preview": "import QtQuick 2.0\nimport QtQuick.Layouts 1.1\nimport QtQuick.Controls 1.4\nimport \"../../../Component\"\nimport Sparrow 1.0"
},
{
"path": "qml/WellChat/BussinessPage/Personal/SettingsPage.qml",
"chars": 7239,
"preview": "import Resource 1.0 as R\nimport BussinessPage 1.0 as BR\n\nimport QtQuick 2.0\nimport QtQuick.Controls 1.4\nimport QtQuick.L"
},
{
"path": "qml/WellChat/BussinessPage/PersonalPage.qml",
"chars": 5895,
"preview": "import BussinessPage 1.0 as BR\n\nimport QtQuick 2.5\nimport QtQuick.Controls 1.4\nimport QtQuick.Window 2.0\nimport QtQuick."
},
{
"path": "qml/WellChat/BussinessPage/ProfilePage.qml",
"chars": 10621,
"preview": "import QtQuick 2.0\nimport QtQuick.Controls 1.4\nimport QtQuick.Layouts 1.1\n\nimport Sparrow 1.0\n\nimport \"../Component\"\n\nPa"
},
{
"path": "qml/WellChat/BussinessPage/R.qml",
"chars": 1944,
"preview": "// ~R\n\npragma Singleton\nimport QtQuick 2.0\n\n// WellChat BussinessPage Resource\nQtObject {\n id: resource\n\n objectNa"
},
{
"path": "qml/WellChat/BussinessPage/qmldir",
"chars": 119,
"preview": "# this module is for this application\n# don't use the other application\n\nmodule BussinessPage\n\nsingleton R 1.0 ./R.qml\n"
},
{
"path": "qml/WellChat/Component/+android/UI.js",
"chars": 287,
"preview": "// 这个文件用来适配UI 控件的\n// 本文件是 安卓\n.pragma library\n\n// console.log(\"UI font point size\", \"android\")\n\nvar smallFontPointSize = "
},
{
"path": "qml/WellChat/Component/Constant.qml",
"chars": 5919,
"preview": "import QtQuick 2.0\nimport QtQuick.Window 2.2\nimport \"./UI.js\" as UI\nimport Sparrow 1.0\n\nQtObject {\n id: constant\n// \""
},
{
"path": "qml/WellChat/Component/Icon.qml",
"chars": 2000,
"preview": "import QtQuick 2.5\nimport QtQuick.Layouts 1.1\nimport \"./UI.js\" as UI\nimport Sparrow 1.0\n\nRectangle {\n id: icon\n wi"
},
{
"path": "qml/WellChat/Component/IconButton.qml",
"chars": 1000,
"preview": "import QtQuick 2.0\nimport QtQuick.Controls 1.4\n// import \"../\"\n\nItem {\n id: iconButton\n // Constant { id: constant"
},
{
"path": "qml/WellChat/Component/IconLabel.qml",
"chars": 1258,
"preview": "import QtQuick 2.0\nimport QtQuick.Controls 1.4\nimport QtQuick.Layouts 1.1\nimport Sparrow 1.0\n\nRectangle {\n id: iconLa"
},
{
"path": "qml/WellChat/Component/MainListView.qml",
"chars": 385,
"preview": "import QtQuick 2.2\n\nListView {\n clip: true\n preferredHighlightBegin: 0\n preferredHighlightEnd: 0\n highlightM"
},
{
"path": "qml/WellChat/Component/SampleTextArea.qml",
"chars": 1005,
"preview": "/*\n * author qyvlik\n * email qyvlik@qq.com\n * time 2015/4/10\n * FLatUI element FlatTextField\n *\n*/\nimport QtQuick 2.5\nim"
},
{
"path": "qml/WellChat/Component/ScrollBar.qml",
"chars": 1314,
"preview": "import QtQuick 2.0\n\nItem {\n id: scrollBar\n\n // The properties that define the scrollbar's state.\n // position a"
},
{
"path": "qml/WellChat/Component/Separator.qml",
"chars": 1009,
"preview": "/*\n * author qyvlik\n * email qyvlik@qq.com\n * time 2015/4/10\n * FlatUI.Private element\n *\n * this qml file (element type"
},
{
"path": "qml/WellChat/Component/UI.js",
"chars": 279,
"preview": "// 这个文件用来适配UI 控件的\n// 本文件是win7\n.pragma library\n\n// console.log(\"UI font point size\", \"win7\")\n\nvar smallFontPointSize = 8 "
},
{
"path": "qml/WellChat/MainView.qml",
"chars": 4531,
"preview": "import Resource 1.0 as Resource\n\nimport QtQuick 2.0\nimport QtQuick.Controls 1.4\nimport QtQuick.Layouts 1.1\nimport QtQuic"
},
{
"path": "qml/WellChat/Sparrow/+android/UI.js",
"chars": 1798,
"preview": ".pragma library\n\n// console.log(\"Android UI Config\");\n\nvar defaultFontFamily = \"Noto Sans Hanunoo\";\n//var defaultNormalF"
},
{
"path": "qml/WellChat/Sparrow/+android/WebPage.qml",
"chars": 1096,
"preview": "// just for android\nimport QtWebView 1.0\n\nimport QtQuick 2.0\nimport Sparrow 1.0\n\n/*\ncanGoBack : bool\ncanGoForward : bool"
},
{
"path": "qml/WellChat/Sparrow/BottomBar.qml",
"chars": 504,
"preview": "import QtQuick 2.0\nimport QtQuick.Controls 1.2\nimport QtQuick.Controls.Styles 1.2\n\nStatusBar {\n id: statusBar\n\n pr"
},
{
"path": "qml/WellChat/Sparrow/ClickedShaderEffect.qml",
"chars": 3232,
"preview": "import QtQuick 2.5\nimport QtGraphicalEffects 1.0\n\nShaderEffect {\n id: shaderEffect\n\n // signal clicked();\n \n "
},
{
"path": "qml/WellChat/Sparrow/GeneralSettings.qml",
"chars": 1947,
"preview": "pragma Singleton\n\nimport QtQuick 2.0\n// import Qt.labs.settings 1.0\nimport \"UI.js\" as UI\n\nQObject {\n id: generalSetti"
},
{
"path": "qml/WellChat/Sparrow/Page.qml",
"chars": 8834,
"preview": "import QtQuick 2.4\nimport QtQuick.Controls 1.2\nimport Sparrow 1.0\n\nRectangle {\n id: page\n\n width: 360\n height: "
},
{
"path": "qml/WellChat/Sparrow/PageStackWindow.qml",
"chars": 1165,
"preview": "import QtQuick 2.0\nimport QtQuick.Layouts 1.1\nimport QtQuick.Controls 1.2\nimport QtQuick.Controls.Styles 1.3\n\nApplicatio"
},
{
"path": "qml/WellChat/Sparrow/PopupLayer/Delegate/PopupLayerBottomMenuDelegate.qml",
"chars": 1398,
"preview": "//~ PopupLayerDialogDelegate\n\n// internal import\n// don't use the module import\nimport \"../\"\nimport QtQuick 2.0\n\nPopupLa"
},
{
"path": "qml/WellChat/Sparrow/PopupLayer/Delegate/PopupLayerDialogDelegate.qml",
"chars": 2226,
"preview": "//~ PopupLayerDialogDelegate\n\n// internal import\n// don't use the module import\nimport \"../\"\nimport QtQuick 2.0\n\nPopupLa"
},
{
"path": "qml/WellChat/Sparrow/PopupLayer/Delegate/PopupLayerSideMenuDelegate.qml",
"chars": 1397,
"preview": "//~ PopupLayerSideMenuDelegate\n\n// internal import\n// don't use the module import\nimport \"../\"\nimport QtQuick 2.0\n\nPopup"
},
{
"path": "qml/WellChat/Sparrow/PopupLayer/Delegate/qmldir",
"chars": 220,
"preview": "module PopupLayer.Delegate\n\nPopupLayerDialogDelegate 1.0 ./PopupLayerDialogDelegate.qml\nPopupLayerSideMenuDelegate 1.0 ."
},
{
"path": "qml/WellChat/Sparrow/PopupLayer/PopupLayer.qml",
"chars": 2029,
"preview": "//! Qt 5.0 or new\n\n// internal import\n// don't use the module import\nimport \"./Delegate\" as Delegate\nimport QtQuick 2.0\n"
},
{
"path": "qml/WellChat/Sparrow/PopupLayer/PopupLayerDelegate.qml",
"chars": 348,
"preview": "//~ PopupLayerDelegate\nimport QtQuick 2.0\n\nQtObject {\n id: popupLayerDelegate\n\n property PopupLayerTransition show"
},
{
"path": "qml/WellChat/Sparrow/PopupLayer/PopupLayerTransition.qml",
"chars": 259,
"preview": "import QtQuick 2.0\n\nQtObject {\n id: popupLayerTransition\n default property alias animaitons: popupLayerTransition."
},
{
"path": "qml/WellChat/Sparrow/PopupLayer/qmldir",
"chars": 151,
"preview": "module PopupLayer\n\nPopupLayer 1.0 ./PopupLayer.qml\nPopupLayerDelegate 1.0 ./PopupLayerDelegate.qml\nPopupLayerTransition "
},
{
"path": "qml/WellChat/Sparrow/PopupLayer/readme.md",
"chars": 3581,
"preview": "# PopupLayer\n\n使用 QML 实现的弹出层。\n\n使用注意事项。\n\n1. `PopupLayer` 内部有个 `popupItem`,是作为这个控件内部孩子的默认父指针。\n\n2. `PopupLayer` 默认覆盖他的 `pare"
},
{
"path": "qml/WellChat/Sparrow/QObject.qml",
"chars": 132,
"preview": "import QtQuick 2.0\n\nQtObject {\n id: qObject\n default property alias data: qObject.__data\n property list<QtObjec"
},
{
"path": "qml/WellChat/Sparrow/SampleButton.qml",
"chars": 1646,
"preview": "import QtQuick 2.5\nimport QtQuick.Controls 1.4\nimport QtQuick.Controls.Styles 1.4\nimport QtGraphicalEffects 1.0\nimport S"
},
{
"path": "qml/WellChat/Sparrow/SampleIcon.qml",
"chars": 969,
"preview": "import QtQuick 2.5\nimport QtQuick.Layouts 1.1\nimport Sparrow 1.0\n\nItem {\n id: icon\n\n property alias backgroundColo"
},
{
"path": "qml/WellChat/Sparrow/SampleLabel.qml",
"chars": 185,
"preview": "import QtQuick 2.0\nimport QtQuick.Controls 1.2\nimport Sparrow 1.0\n\nLabel {\n font.family: GeneralSettings.generalfontF"
},
{
"path": "qml/WellChat/Sparrow/SampleTextField.qml",
"chars": 982,
"preview": "import Sparrow 1.0\nimport QtQuick 2.5\nimport QtQuick.Controls 1.4\nimport QtQuick.Controls.Styles 1.4\n\nTextField {\n id"
},
{
"path": "qml/WellChat/Sparrow/TopBar.qml",
"chars": 1608,
"preview": "import QtQuick 2.5\nimport QtQuick.Controls 1.4\nimport QtQuick.Controls.Styles 1.4\nimport QtQuick.Layouts 1.1\n\nToolBar {\n"
},
{
"path": "qml/WellChat/Sparrow/Tracker.qml",
"chars": 173,
"preview": "import QtQuick 2.0\n\nRectangle {\n anchors.fill: parent\n color: \"green\"\n opacity: 0.5\n// color: \"transparent\"\n"
},
{
"path": "qml/WellChat/Sparrow/UI.js",
"chars": 352,
"preview": ".pragma library\n\n// console.log(\"Window UI Config\");\n\nvar defaultFontFamily = \"Microsoft YaHei UI\"; // 微软雅黑\n//var defaul"
},
{
"path": "qml/WellChat/Sparrow/WebPage.qml",
"chars": 1167,
"preview": "import QtQuick 2.0\nimport QtQuick.Controls 1.2\nimport QtWebKit 3.0\nimport Sparrow 1.0\n\n/*\ncanGoBack : bool\ncanGoForward "
},
{
"path": "qml/WellChat/Sparrow/qmldir",
"chars": 525,
"preview": "# version 1.0\nmodule Sparrow\n\nUI 1.0 ./UI.js\nsingleton GeneralSettings 1.0 ./GeneralSettings.qml\n\nQObject 1.0 ./QObject."
},
{
"path": "qml/WellChat/Sparrow/resources/readme.md",
"chars": 80,
"preview": "在安卓中,推荐字体需要大家来进行测试了。。。\n\n[有哪些值得推荐的中文字体?](https://www.zhihu.com/question/20727176)"
},
{
"path": "qml/WellChat/WellChat.qmlproject",
"chars": 707,
"preview": "import QmlProject 1.0\n\nProject {\n /* Include .qml, .js, and image files from current directory and subdirectories */\n"
},
{
"path": "qml/WellChat/main.qml",
"chars": 1031,
"preview": "import QtQuick 2.0\nimport QtQuick.Controls 1.4\nimport Sparrow 1.0\n\nPageStackWindow {\n id: mainWindow\n\n title: qsTr"
},
{
"path": "qml/WellChat/resource/R.qml",
"chars": 4680,
"preview": "pragma Singleton\n\nimport QtQuick 2.0\n\n// R\n// Applicaton icon html ... resource\n\nQtObject {\n id: resource\n\n object"
},
{
"path": "qml/WellChat/resource/qmldir",
"chars": 41,
"preview": "module Resource\n\nsingleton R 1.0 ./R.qml\n"
},
{
"path": "qml.qrc",
"chars": 10426,
"preview": "<RCC>\n <qresource prefix=\"/\">\n <file>qml/WellChat/BussinessPage/Chat/ChatPage.qml</file>\n <file>qml/Wel"
},
{
"path": "src/wellchat/collectionsmodel.cpp",
"chars": 6589,
"preview": "#include \"collectionsmodel.h\"\n#include <QSqlQuery>\n#include <QDebug>\n#include <QSqlError>\n#include <QStandardPaths>\n#inc"
},
{
"path": "src/wellchat/collectionsmodel.h",
"chars": 1055,
"preview": "#ifndef COLLECTIONSMODEL_H\n#define COLLECTIONSMODEL_H\n\n#include <QAbstractListModel>\n#include <QSqlDatabase>\n\nclass QQml"
}
]
// ... and 3 more files (download for full content)
About this extraction
This page contains the full source code of the GDPURJYFS/WellChat GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 97 files (248.8 KB), approximately 57.0k tokens, and a symbol index with 26 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.