aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbob <bcz@cs.brown.edu>2019-09-16 17:13:16 -0400
committerbob <bcz@cs.brown.edu>2019-09-16 17:13:16 -0400
commit999cd7deb87ce5c6430a5f8e0e1721033736bbab (patch)
tree5e78a64c44f3e12c6595ca6b41e58549df6fbc81
parent2f1741cf291c69ce55b87116bd24edd2f940141d (diff)
cleaned up titling of icons and summaries.
-rw-r--r--src/client/views/DocumentDecorations.tsx6
-rw-r--r--src/client/views/collections/collectionFreeForm/MarqueeView.tsx10
-rw-r--r--src/client/views/nodes/DocumentView.tsx22
-rw-r--r--src/client/views/nodes/IconBox.tsx53
4 files changed, 43 insertions, 48 deletions
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index ac1f51688..240abaf6b 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -32,6 +32,8 @@ import { CurrentUserUtils } from '../../server/authentication/models/current_use
import { Pulls, Pushes } from '../apis/google_docs/GoogleApiClientUtils';
import { ObjectField } from '../../new_fields/ObjectField';
import { DocServer } from '../DocServer';
+import { CompileScript } from '../util/Scripting';
+import { ComputedField } from '../../new_fields/ScriptField';
const higflyout = require("@hig/flyout");
export const { anchorPoints } = higflyout;
export const Flyout = higflyout.default;
@@ -378,8 +380,8 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
let doc = selected[0].props.Document;
let iconDoc = Docs.Create.IconDocument(layoutString);
iconDoc.isButton = true;
- iconDoc.proto!.title = selected.length > 1 ? "-multiple-.icon" : StrCast(doc.title) + ".icon";
- iconDoc.labelField = selected.length > 1 ? undefined : this._fieldKey;
+
+ IconBox.AutomaticTitle(iconDoc);
//iconDoc.proto![this._fieldKey] = selected.length > 1 ? "collection" : undefined;
iconDoc.proto!.isMinimized = false;
iconDoc.width = Number(MINIMIZED_ICON_SIZE);
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
index 5cab6f8e0..d74fbafb3 100644
--- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
+++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
@@ -23,6 +23,8 @@ import { SchemaHeaderField, RandomPastel } from "../../../../new_fields/SchemaHe
import { string } from "prop-types";
import { listSpec } from "../../../../new_fields/Schema";
import { CurrentUserUtils } from "../../../../server/authentication/models/current_user_utils";
+import { CompileScript } from "../../../util/Scripting";
+import { ComputedField } from "../../../../new_fields/ScriptField";
interface MarqueeViewProps {
getContainerTransform: () => Transform;
@@ -309,7 +311,7 @@ export class MarqueeView extends React.Component<MarqueeViewProps>
defaultBackgroundColor: this.props.container.isAnnotationOverlay ? undefined : chosenColor,
width: bounds.width,
height: bounds.height,
- title: e.key === "s" || e.key === "S" ? "-summary-" : "a nested collection",
+ title: "a nested collection",
});
let dataExtensionField = Doc.CreateDocumentExtensionForField(newCollection, "data");
dataExtensionField.ink = inkData ? new InkField(this.marqueeInkSelect(inkData)) : undefined;
@@ -325,9 +327,11 @@ export class MarqueeView extends React.Component<MarqueeViewProps>
});
newCollection.chromeStatus = "disabled";
let summary = Docs.Create.TextDocument({ x: bounds.left, y: bounds.top, width: 300, height: 100, autoHeight: true, backgroundColor: "#e2ad32" /* yellow */, title: "-summary-" });
- summary.proto!.maximizeLocation = "inTab"; // or "inPlace", or "onRight"
- newCollection.proto!.summaryDoc = summary;
+ Doc.GetProto(summary).maximizeLocation = "inTab"; // or "inPlace", or "onRight"
+ Doc.GetProto(newCollection).summaryDoc = summary;
newCollection.x = bounds.left + bounds.width;
+ let computed = CompileScript(`return summaryTitle(this);`, { params: { this: "Doc" }, typecheck: false });
+ computed.compiled && (Doc.GetProto(newCollection).title = new ComputedField(computed));
if (e.key === "s") { // summary is wrapped in an expand/collapse container that also contains the summarized documents in a free form view.
let container = Docs.Create.FreeformDocument([summary, newCollection], { x: bounds.left, y: bounds.top, width: 300, height: 200, chromeStatus: "disabled", title: "-summary-" });
container.viewType = CollectionViewType.Stacking;
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 760f4d584..50a9aa326 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -141,13 +141,11 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
private _hitTemplateDrag = false;
private _mainCont = React.createRef<HTMLDivElement>();
private _dropDisposer?: DragManager.DragDropDisposer;
- _animateToIconDisposer?: IReactionDisposer;
- _reactionDisposer?: IReactionDisposer;
+ private _animateToIconDisposer?: IReactionDisposer;
public get ContentDiv() { return this._mainCont.current; }
@computed get active(): boolean { return SelectionManager.IsSelected(this) || this.props.parentActive(); }
@computed get topMost(): boolean { return this.props.renderDepth === 0; }
- screenRect = (): ClientRect | DOMRect => this._mainCont.current ? this._mainCont.current.getBoundingClientRect() : new DOMRect();
@action
componentDidMount() {
@@ -156,19 +154,6 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
handlers: { drop: this.drop.bind(this) }
});
}
- // bcz: kind of ugly .. setup a reaction to update the title of a summary document's target (maximizedDocs) whenver the summary doc's title changes
- this._reactionDisposer = reaction(() => [DocListCast(this.props.Document.maximizedDocs).map(md => md.title),
- this.props.Document.summaryDoc, this.props.Document.summaryDoc instanceof Doc ? this.props.Document.summaryDoc.title : ""],
- () => {
- let maxDoc = DocListCast(this.props.Document.maximizedDocs);
- if (maxDoc.length === 1 && StrCast(this.props.Document.title).startsWith("-") && StrCast(this.props.Document.layout).indexOf("IconBox") !== -1) {
- this.props.Document.proto!.title = "-" + maxDoc[0].title + ".icon";
- }
- let sumDoc = Cast(this.props.Document.summaryDoc, Doc);
- if (sumDoc instanceof Doc && StrCast(this.props.Document.title).startsWith("-")) {
- this.props.Document.proto!.title = "-" + sumDoc.title + ".expanded";
- }
- }, { fireImmediately: true });
this._animateToIconDisposer = reaction(() => this.props.Document.isIconAnimating, (values) =>
(values instanceof List) && this.animateBetweenIcon(values, values[2], values[3] ? true : false)
, { fireImmediately: true });
@@ -209,16 +194,11 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
}
@action
componentWillUnmount() {
- this._reactionDisposer && this._reactionDisposer();
this._animateToIconDisposer && this._animateToIconDisposer();
this._dropDisposer && this._dropDisposer();
DocumentManager.Instance.DocumentViews.splice(DocumentManager.Instance.DocumentViews.indexOf(this), 1);
}
- stopPropagation = (e: React.SyntheticEvent) => {
- e.stopPropagation();
- }
-
get dataDoc() {
// bcz: don't think we need this, but left it in in case strange behavior pops up. DocumentContentsView has this functionality
// if (this.props.DataDoc === undefined && (this.props.Document.layout instanceof Doc || this.props.Document instanceof Promise)) {
diff --git a/src/client/views/nodes/IconBox.tsx b/src/client/views/nodes/IconBox.tsx
index 7e78ec684..ef9885bcf 100644
--- a/src/client/views/nodes/IconBox.tsx
+++ b/src/client/views/nodes/IconBox.tsx
@@ -12,6 +12,8 @@ import { IconField } from "../../../new_fields/IconField";
import { ContextMenu } from "../ContextMenu";
import Measure from "react-measure";
import { MINIMIZED_ICON_SIZE } from "../../views/globalCssVariables.scss";
+import { Scripting, CompileScript } from "../../util/Scripting";
+import { ComputedField } from "../../../new_fields/ScriptField";
library.add(faCaretUp);
@@ -27,6 +29,26 @@ export class IconBox extends React.Component<FieldViewProps> {
@computed get layout(): string { const field = Cast(this.props.Document[this.props.fieldKey], IconField); return field ? field.icon : "<p>Error loading icon data</p>"; }
@computed get minimizedIcon() { return IconBox.DocumentIcon(this.layout); }
+ public static summaryTitleScript(inputDoc: Doc) {
+ const sumDoc = Cast(inputDoc.summaryDoc, Doc) as Doc;
+ if (sumDoc && StrCast(sumDoc.title).startsWith("-")) {
+ return sumDoc.title + ".expanded";
+ }
+ return "???";
+ }
+ public static titleScript(inputDoc: Doc) {
+ const maxDoc = DocListCast(inputDoc.maximizedDocs);
+ if (maxDoc.length === 1 && StrCast(maxDoc[0].title).startsWith("-")) {
+ return maxDoc[0].title + ".icon";
+ }
+ return maxDoc.length > 1 ? "-multiple-.icon" : "???";
+ }
+
+ public static AutomaticTitle(doc: Doc) {
+ let computed = CompileScript(`return iconTitle(this);`, { params: { this: "Doc" }, typecheck: false });
+ computed.compiled && (Doc.GetProto(doc).title = new ComputedField(computed));
+ }
+
public static DocumentIcon(layout: string) {
let button = layout.indexOf("PDFBox") !== -1 ? faFilePdf :
layout.indexOf("ImageBox") !== -1 ? faImage :
@@ -38,35 +60,20 @@ export class IconBox extends React.Component<FieldViewProps> {
}
setLabelField = (): void => {
- this.props.Document.hideLabel = !BoolCast(this.props.Document.hideLabel);
- }
- setUseOwnTitleField = (): void => {
- this.props.Document.useOwnTitle = !BoolCast(this.props.Document.useTargetTitle);
+ this.props.Document.hideLabel = !this.props.Document.hideLabel;
}
specificContextMenu = (): void => {
- ContextMenu.Instance.addItem({
- description: BoolCast(this.props.Document.hideLabel) ? "Show label with icon" : "Remove label from icon",
- event: this.setLabelField,
- icon: "tag"
- });
- let maxDocs = DocListCast(this.props.Document.maximizedDocs);
- if (maxDocs.length === 1 && !BoolCast(this.props.Document.hideLabel)) {
- ContextMenu.Instance.addItem({
- description: BoolCast(this.props.Document.useOwnTitle) ? "Use target title for label" : "Use own title label",
- event: this.setUseOwnTitleField,
- icon: "text-height"
- });
+ let cm = ContextMenu.Instance;
+ cm.addItem({ description: this.props.Document.hideLabel ? "Show label with icon" : "Remove label from icon", event: this.setLabelField, icon: "tag" });
+ if (!this.props.Document.hideLabel) {
+ cm.addItem({ description: "Use Target Title", event: () => IconBox.AutomaticTitle(this.props.Document), icon: "text-height" });
}
}
@observable _panelWidth: number = 0;
@observable _panelHeight: number = 0;
render() {
- let labelField = StrCast(this.props.Document.labelField);
- let hideLabel = BoolCast(this.props.Document.hideLabel);
- let maxDocs = DocListCast(this.props.Document.maximizedDocs);
- let firstDoc = maxDocs.length ? maxDocs[0] : undefined;
- let label = hideLabel ? "" : (firstDoc && labelField && !BoolCast(this.props.Document.useOwnTitle) ? firstDoc[labelField] : this.props.Document.title);
+ let label = this.props.Document.hideLabel ? "" : this.props.Document.title;
return (
<div className="iconBox-container" onContextMenu={this.specificContextMenu}>
{this.minimizedIcon}
@@ -82,4 +89,6 @@ export class IconBox extends React.Component<FieldViewProps> {
</Measure>
</div>);
}
-} \ No newline at end of file
+}
+Scripting.addGlobal(function iconTitle(doc: any) { return IconBox.titleScript(doc); });
+Scripting.addGlobal(function summaryTitle(doc: any) { return IconBox.summaryTitleScript(doc); }); \ No newline at end of file