import React from "react"; import ReactDOM from "react-dom"; import { action, observable, makeObservable } from "mobx"; import { observer } from "mobx-react"; import { closest } from "eez-studio-shared/dom"; import { SearchInput } from "eez-studio-ui/search-input"; import { ProjectContext } from "project-editor/project/context"; import { IEezObject, PropertyInfo } from "project-editor/core/object"; import { findBitmap } from "project-editor/project/project"; import { SortDirectionType } from "project-editor/core/objectAdapter"; import { getEnumItems } from "./utils"; //////////////////////////////////////////////////////////////////////////////// export const ObjectReferenceInput = observer( class ObjectReferenceInput extends React.Component<{ objects: IEezObject[]; propertyInfo: PropertyInfo; value: any; onChange: (newValue: any) => void; readOnly: boolean; }> { static contextType = ProjectContext; declare context: React.ContextType; buttonRef = React.createRef(); dropDownRef = React.createRef(); dropDownOpen: boolean | undefined = false; dropDownLeft = 0; dropDownTop = 0; dropDownWidth = 0; sortDirection: SortDirectionType = "none"; searchText: string = ""; constructor(props: any) { super(props); makeObservable(this, { dropDownOpen: observable, dropDownLeft: observable, dropDownTop: observable, dropDownWidth: observable, sortDirection: observable, searchText: observable, onSearchChange: action.bound, setDropDownOpen: action }); } getObjectNames() { const { propertyInfo } = this.props; if (!propertyInfo.referencedObjectCollectionPath) { if (propertyInfo.enumItems) { return getEnumItems(this.props.objects, propertyInfo) .filter( enumItem => (enumItem.label || enumItem.id.toString()) .toLowerCase() .indexOf( this.searchText.trim().toLowerCase() ) != -1 ) .map(enumItem => enumItem.id); } return []; } let assets = this.context.project._assets.maps[ "name" ].getAllObjectsOfType(propertyInfo.referencedObjectCollectionPath!); return assets .slice() .filter(asset => propertyInfo.filterReferencedObjectCollection ? propertyInfo.filterReferencedObjectCollection( this.props.objects, asset.object ) : true ) .map(asset => asset.name) .filter( objectName => !this.searchText || objectName .toLowerCase() .indexOf(this.searchText.trim().toLowerCase()) != -1 ) .sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase())); } onChange = (event: React.ChangeEvent) => { this.props.onChange(event.target.value); }; onSearchChange(event: any) { this.searchText = $(event.target).val() as string; } setDropDownOpen(open: boolean) { if (this.dropDownOpen === false) { document.removeEventListener( "pointerdown", this.onDocumentPointerDown, true ); } this.dropDownOpen = open; if (this.dropDownOpen) { document.addEventListener( "pointerdown", this.onDocumentPointerDown, true ); } } openDropdown = action(() => { const buttonEl = this.buttonRef.current; if (!buttonEl) { return; } const dropDownEl = this.dropDownRef.current; if (!dropDownEl) { return; } this.setDropDownOpen(!this.dropDownOpen); if (this.dropDownOpen) { const rectInputGroup = buttonEl.parentElement!.getBoundingClientRect(); this.dropDownLeft = rectInputGroup.left; this.dropDownTop = rectInputGroup.bottom; this.dropDownWidth = rectInputGroup.width; if ( this.dropDownLeft + this.dropDownWidth > window.innerWidth ) { this.dropDownLeft = window.innerWidth - this.dropDownWidth; } const DROP_DOWN_HEIGHT = 270; if ( this.dropDownTop + DROP_DOWN_HEIGHT + 20 > window.innerHeight ) { this.dropDownTop = window.innerHeight - (DROP_DOWN_HEIGHT + 20); } } }); onDocumentPointerDown = action((event: MouseEvent) => { if (this.dropDownOpen) { if ( !closest( event.target, el => this.buttonRef.current == el || this.dropDownRef.current == el ) ) { event.preventDefault(); event.stopPropagation(); this.setDropDownOpen(false); } } }); render() { const { value, readOnly } = this.props; const objectNames = this.getObjectNames(); const portal = ReactDOM.createPortal(
{ this.searchText = ""; })} onChange={this.onSearchChange} onKeyDown={this.onSearchChange} />
    {objectNames.map(objectName => (
  • { this.props.onChange(objectName); this.setDropDownOpen(false); })} > {objectName}
  • ))}
, document.body ); let bitmap; if ( !this.props.propertyInfo.disableBitmapPreview && this.props.propertyInfo.referencedObjectCollectionPath === "bitmaps" ) { bitmap = findBitmap(this.context.project, this.props.value); } const placeholder = this.props.propertyInfo.inputPlaceholder && this.props.objects.length == 1 ? this.props.propertyInfo.inputPlaceholder( this.props.objects[0] ) : ""; return (
{!readOnly && ( <>
{bitmap && bitmap.imageSrc && bitmap.imageElement && (
Dimension: {bitmap.imageElement.width} x{" "} {bitmap.imageElement.height} px
)}
); } } );