All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.qt.core.QProperty Maven / Gradle / Ivy

/****************************************************************************
**
** Copyright (C) 2009-2024 Dr. Peter Droste, Omix Visualization GmbH & Co. KG. All rights reserved.
**
** This file is part of Qt Jambi.
**
** ** $BEGIN_LICENSE$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
** 
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
** $END_LICENSE$
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
****************************************************************************/
package io.qt.core;

import java.util.Objects;

import io.qt.*;

/**
 * 

Java wrapper for Qt class QProperty

*

The QProperty class enables automatic property bindings.

*

Example:

* * QIntProperty red = new QIntProperty(255);
* QIntProperty green = new QIntProperty(0);
* QIntProperty blue = new QIntProperty(0);
* QIntProperty alpha = new QIntProperty(255);
* QProperty<QColor> color = new QProperty<>(QColor.class);
* color.setBinding(()->new QColor(red.value(), green.value(), blue.value(), alpha.value()));
* color.value(); // = red
* red.setValue(0);
* green.setValue(255);
* color.value(); // = green
*
*

For primitive-typed implementations see:

*
    *
  • {@link QBooleanProperty}
  • *
  • {@link QByteProperty}
  • *
  • {@link QShortProperty}
  • *
  • {@link QIntProperty}
  • *
  • {@link QLongProperty}
  • *
  • {@link QFloatProperty}
  • *
  • {@link QDoubleProperty}
  • *
  • {@link QCharProperty}
  • *
*/ public final class QProperty extends QPropertyData { private static class TypedPropertyBindingData extends QPropertyBindingData{ TypedPropertyBindingData(QMetaType metaType) { super(); this.metaType = metaType; } @QtUninvokable public boolean setValueBypassingBindings(QProperty property, Object val) { return QProperty.setValueBypassingBindings(QtJambi_LibraryUtilities.internal.nativeId(property), QtJambi_LibraryUtilities.internal.checkedNativeId(this.metaType), val); } final QMetaType metaType; } private static class RCTypedPropertyBindingData extends TypedPropertyBindingData{ RCTypedPropertyBindingData(QMetaType metaType, Object val) { super(metaType); __rcValue = val; } @Override public boolean setValueBypassingBindings(QProperty property, Object val) { if(super.setValueBypassingBindings(property, val)) { __rcValue = val; return true; } else return false; } @SuppressWarnings("unused") private Object __rcValue; } private static QMetaType valueMetaType(Object val) { if(val instanceof QList) { return QMetaType.fromType(QList.class, ((QList) val).elementMetaType()); }else if(val instanceof QSet) { return QMetaType.fromType(QSet.class, ((QSet) val).elementMetaType()); }else if(val instanceof QQueue) { return QMetaType.fromType(QQueue.class, ((QQueue) val).elementMetaType()); }else if(val instanceof QStack) { return QMetaType.fromType(QStack.class, ((QStack) val).elementMetaType()); }else if(val instanceof QMap) { return QMetaType.fromType(QMap.class, ((QMap) val).keyMetaType(), ((QMap) val).valueMetaType()); }else if(val instanceof QHash) { return QMetaType.fromType(QHash.class, ((QHash) val).keyMetaType(), ((QHash) val).valueMetaType()); }else if(val instanceof QMultiMap) { return QMetaType.fromType(QMultiMap.class, ((QMultiMap) val).keyMetaType(), ((QMultiMap) val).valueMetaType()); }else if(val instanceof QMultiHash) { return QMetaType.fromType(QMultiHash.class, ((QMultiHash) val).keyMetaType(), ((QMultiHash) val).valueMetaType()); }else if(val instanceof QPair) { return QMetaType.fromType(QPair.class, valueMetaType(((QPair) val).first), valueMetaType(((QPair) val).second)); }else if(val instanceof Integer) { return new QMetaType(QMetaType.Type.Int); }else if(val instanceof Long) { return new QMetaType(QMetaType.Type.LongLong); }else if(val instanceof Short) { return new QMetaType(QMetaType.Type.Short); }else if(val instanceof Byte) { return new QMetaType(QMetaType.Type.SChar); }else if(val instanceof Double) { return new QMetaType(QMetaType.Type.Double); }else if(val instanceof Float) { return new QMetaType(QMetaType.Type.Float); }else if(val instanceof Character) { return new QMetaType(QMetaType.Type.QChar); }else if(val instanceof Boolean) { return new QMetaType(QMetaType.Type.Bool); }else if(val instanceof QNativePointer) { return new QMetaType(QMetaType.Type.VoidStar); }else { return QMetaType.fromType(QtJambi_LibraryUtilities.internal.getClass(val)); } } /** * Constructs a property with the given type and initialValue. * @param initialValue * @param type class type * @param instantiations optional instantiations for container classes like {@link QList} and {@link QMap} */ public QProperty(T initialValue, @StrictNonNull Class type, @StrictNonNull QMetaType @StrictNonNull... instantiations) { super(null); QMetaType metaType = QMetaType.fromType(type, instantiations); if(metaType.flags().testFlag(QMetaType.TypeFlag.IsPointer) || metaType.name().contains("*")) { d = new RCTypedPropertyBindingData(metaType, initialValue); }else { d = new TypedPropertyBindingData(metaType); } initialize_native(this, metaType, initialValue); } /** * Constructs a property with the given type. * @param type class type * @param instantiations optional instantiations for container classes like {@link QList} and {@link QMap} */ public QProperty(@StrictNonNull Class type, @StrictNonNull QMetaType @StrictNonNull... instantiations) { this((T)null, type, instantiations); } /** * Constructs a property with the provided initialValue. The property type is extracted from initialValue. * @param initialValue initial value must not be null */ public QProperty(@StrictNonNull T initialValue) { super(null); QMetaType metaType = valueMetaType(Objects.requireNonNull(initialValue, "Argument 'initialValue': null not expected.")); if(metaType.flags().testFlag(QMetaType.TypeFlag.IsPointer) || metaType.name().contains("*")) { d = new RCTypedPropertyBindingData(metaType, initialValue); }else { d = new TypedPropertyBindingData(metaType); } initialize_native(this, metaType, initialValue); } /** * Constructs a QVariant-typed property. */ public QProperty() { super(null); QMetaType metaType = new QMetaType(QMetaType.Type.QVariant); d = new TypedPropertyBindingData(metaType); initialize_native(this, metaType, null); } /** * Constructs a property with the provided binding. The property type corresponds to the type of binding. * @param binding must not be null */ public QProperty(@StrictNonNull QPropertyBinding binding) { super(null); QMetaType metaType = binding.valueMetaType(); if(metaType.flags().testFlag(QMetaType.TypeFlag.IsPointer) || metaType.name().contains("*")) { d = new RCTypedPropertyBindingData(metaType, null); }else { d = new TypedPropertyBindingData(metaType); } initialize_native(this, metaType, null); d.setBinding(binding, this); } /** *

Constructs a property bound to the provided functor.

*

The property type corresponds to the return type of the functor's {@link java.util.function.Supplier#get()}.

* @param functor */ public QProperty(QtUtilities.@StrictNonNull Supplier functor) { this(new QPropertyBinding<>(functor)); } /** *

Constructs a property bound to the provided functor.

*

The property type corresponds to the return type of the functor's {@link java.util.function.Supplier#get()}.

* @param functor * @param type class type * @param instantiations optional instantiations for container classes like {@link QList} and {@link QMap} */ public QProperty(QtUtilities.@StrictNonNull Supplier functor, @StrictNonNull Class type, @StrictNonNull QMetaType @StrictNonNull... instantiations) { super(null); QMetaType metaType = QMetaType.fromType(type, instantiations); if(metaType.flags().testFlag(QMetaType.TypeFlag.IsPointer) || metaType.name().contains("*")) { d = new RCTypedPropertyBindingData(metaType, null); }else { d = new TypedPropertyBindingData(metaType); } initialize_native(this, metaType, null); if(functor!=null) setBinding(functor); } /** * Returns the value of the property. This may evaluate a binding expression that is tied to this property, before returning the value. * @return value */ @QtUninvokable public T value() { if (d.hasBinding()) d.evaluateIfDirty(this); d.registerWithCurrentlyEvaluatingBinding(); return this.getValueBypassingBindings(); } /** *

Assigns newValue to this property and removes the property's associated binding, if present.

* @param newValue */ @QtUninvokable public void setValue(T newValue) { d.removeBinding(); if (d.setValueBypassingBindings(this, newValue)) d.notifyObservers(this); } @QtUninvokable static boolean checkType(QMetaType myMetaType, QMetaType metaType) { if(myMetaType.sizeOf()==1 // byte && (myMetaType.id()==QMetaType.Type.Char.value() || myMetaType.id()==QMetaType.Type.SChar.value() || myMetaType.id()==QMetaType.Type.UChar.value())) { if(metaType.sizeOf()!=1 || (metaType.id()!=QMetaType.Type.SChar.value() && metaType.id()!=QMetaType.Type.Char.value() && metaType.id()!=QMetaType.Type.UChar.value())) { return false; } } else if(myMetaType.sizeOf()==2 // char && (myMetaType.id()==QMetaType.Type.QChar.value() || myMetaType.id()==QMetaType.Type.Char16.value() || myMetaType.id()==QMetaType.Type.Short.value() || myMetaType.id()==QMetaType.Type.UShort.value())) { if(metaType.sizeOf()!=2 || (metaType.id()!=QMetaType.Type.QChar.value() && metaType.id()!=QMetaType.Type.Char16.value() && metaType.id()!=QMetaType.Type.Short.value() && metaType.id()!=QMetaType.Type.UShort.value())) { return false; } } else if(myMetaType.sizeOf()==4 // int && (myMetaType.id()==QMetaType.Type.Int.value() || myMetaType.id()==QMetaType.Type.Long.value() || myMetaType.id()==QMetaType.Type.UInt.value() || myMetaType.id()==QMetaType.Type.ULong.value() || myMetaType.id()==QMetaType.Type.Char32.value())) { if(metaType.sizeOf()!=4 || (metaType.id()!=QMetaType.Type.Int.value() && metaType.id()!=QMetaType.Type.Long.value() && metaType.id()!=QMetaType.Type.ULong.value() && metaType.id()!=QMetaType.Type.UInt.value() && metaType.id()!=QMetaType.Type.Char32.value())) { return false; } } else if(myMetaType.sizeOf()==8 // long && (myMetaType.id()==QMetaType.Type.LongLong.value() || myMetaType.id()==QMetaType.Type.Long.value() || myMetaType.id()==QMetaType.Type.ULongLong.value() || myMetaType.id()==QMetaType.Type.ULong.value())) { if(metaType.sizeOf()!=8 || (metaType.id()!=QMetaType.Type.LongLong.value() && metaType.id()!=QMetaType.Type.Long.value() && metaType.id()!=QMetaType.Type.ULong.value() && metaType.id()!=QMetaType.Type.ULongLong.value())) { return false; } } else if(myMetaType.sizeOf()==4 // float && (myMetaType.id()==QMetaType.Type.Double.value() || myMetaType.id()==QMetaType.Type.Float.value())) { if(metaType.sizeOf()!=4 || (metaType.id()!=QMetaType.Type.Double.value() && metaType.id()!=QMetaType.Type.Float.value())) { return false; } } else if(myMetaType.sizeOf()==8 // double && (myMetaType.id()==QMetaType.Type.Double.value() || myMetaType.id()==QMetaType.Type.Float.value())) { if(metaType.sizeOf()!=8 || (metaType.id()!=QMetaType.Type.Double.value() && metaType.id()!=QMetaType.Type.Float.value())) { return false; } } else if(!myMetaType.equals(metaType)) { Class myType = myMetaType.javaType(); if(myType==null || metaType.javaType()==null || !myType.isAssignableFrom(metaType.javaType())) { return false; } } return true; } /** *

Associates the value of this property with the provided newBinding expression and returns the previously associated binding.

*

The binding's value type ({@link QUntypedPropertyBinding#valueMetaType()}) has to be equals to the property's value type T, * otherwise the property remains unchanged.

*

The first time the property value is read, the binding is evaluated. * Whenever a dependency of the binding changes, the binding will be re-evaluated the next time the value of this property is read.

* @param newBinding * @return oldBinding */ @SuppressWarnings("unchecked") @QtUninvokable public @NonNull QPropertyBinding setBinding(@StrictNonNull QPropertyBinding newBinding) { if(newBinding!=null && !checkType(valueMetaType(), newBinding.valueMetaType())) return new QPropertyBinding<>(); QPropertyBindingData bd = bindingData(); QUntypedPropertyBinding oldBinding = bd.setBinding(newBinding, this); d.notifyObservers(this); if(oldBinding instanceof QPropertyBinding) return (QPropertyBinding)oldBinding; else return new QPropertyBinding<>(oldBinding); } /** *

Associates the value of this property with the provided newBinding expression.

*

The binding's value type ({@link QUntypedPropertyBinding#valueMetaType()}) has to be equals to the property's value type T, * otherwise the property remains unchanged and the method returns false.

*

The first time the property value is read, the binding is evaluated. * Whenever a dependency of the binding changes, the binding will be re-evaluated the next time the value of this property is read.

*

Returns true if the type of this property is the same as the type the binding function returns; false otherwise.

* @param newBinding * @return true if types match, false otherwise. */ @QtUninvokable public boolean setBinding(@StrictNonNull QUntypedPropertyBinding newBinding) { if(newBinding!=null && !checkType(valueMetaType(), newBinding.valueMetaType())) return false; d.setBinding(newBinding, this); d.notifyObservers(this); return true; } /** *

Associates the value of this property with the provided functor and returns the previously associated binding.

*

The first time the property value is read, the binding is evaluated by invoking {@link java.util.function.Supplier#get()} of functor. * Whenever a dependency of the binding changes, the binding will be re-evaluated the next time the value of this property is read.

* @param functor * @return oldBinding */ @QtUninvokable public @NonNull QPropertyBinding setBinding(QtUtilities.@StrictNonNull Supplier functor) { try { QPropertyBinding.setPendingMetaType(this::valueMetaType); return setBinding(new QPropertyBinding<>(functor)); }finally { QPropertyBinding.setPendingMetaType(null); } } @QtUninvokable private QPropertyBinding makeBinding() { try { QPropertyBinding.setPendingMetaType(this::valueMetaType); return new QPropertyBinding<>(this::value); }finally { QPropertyBinding.setPendingMetaType(null); } } /** * Checks if the property has a binding. * @return true if the property has a binding, false otherwise. */ @QtUninvokable public boolean hasBinding() { return d.hasBinding(); } /** * Returns the binding expression that is associated with this property. * A default constructed {@link QPropertyBinding}<T> will be returned if no such association exists. * @return binding */ @QtUninvokable public @NonNull QPropertyBinding binding() { return new QPropertyBinding<>(this); } /** *

Disassociates the binding expression from this property and returns it.

*

After calling this function, the value of the property will only change if you assign a new value to it, or when a new binding is set.

* @return the removed binding */ @QtUninvokable public @NonNull QPropertyBinding takeBinding() { return new QPropertyBinding<>(d.setBinding(new QPropertyBinding<>(), this)); } /** *

Registers the given functor f as a callback that shall be called whenever the value of the property changes.

*

The returned property change handler object keeps track of the registration. * As long as the change handler is alive i.e. as long as a reference to the {@link QPropertyChangeHandler} instance exists, * the callback remains installed. When the garbage collection deletes the instance, the callback is de-registered.

* @param f * @return property change handler * @see QPropertyChangeHandler */ @QtUninvokable public @NonNull QPropertyChangeHandler onValueChanged(@StrictNonNull Runnable f) { return new QPropertyChangeHandler(d, f); } /** * Subscribes the given functor f as a callback that is called immediately and whenever the value of the property changes in the future. * @param f * @return property change handler * @see QPropertyChangeHandler * @see #onValueChanged(Runnable) */ @QtUninvokable public @NonNull QPropertyChangeHandler subscribe(@StrictNonNull Runnable f) { f.run(); return onValueChanged(f); } /** *

Registers the given functor f as a callback that shall be called whenever the value of the bindable changes.

*

The returned property notifier object keeps track of the registration. * As long as the notifier is alive i.e. as long as a reference to the {@link QPropertyNotifier} instance exists, * the callback remains installed. When the garbage collection deletes the instance, the callback is de-registered.

* @param f * @return property notifier * @see QPropertyNotifier */ @io.qt.QtUninvokable public @NonNull QPropertyNotifier addNotifier(@StrictNonNull Runnable f) { return new QPropertyNotifier(d, f); } @QtUninvokable QPropertyBindingData bindingData() { return d; } QMetaType valueMetaType() { return d.metaType; } private final TypedPropertyBindingData d; native static void initialize_native(QPropertyData instance, QMetaType metaType, Object val); /** * {@inheritDoc} */ @QtUninvokable @Override public final T getValueBypassingBindings() { return getValueBypassingBindings(QtJambi_LibraryUtilities.internal.nativeId(this), QtJambi_LibraryUtilities.internal.checkedNativeId(d.metaType)); } @QtUninvokable static native T getValueBypassingBindings(long data, long metaType); /** * {@inheritDoc} */ @QtUninvokable @Override public final boolean setValueBypassingBindings(T val) { return d.setValueBypassingBindings(this, val); } @QtUninvokable static native boolean setValueBypassingBindings(long data, long metaType, Object val); }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy