Skip to content

Commit 6ce505d

Browse files
committed
#50: User should be able to drag identicons inside a field content from a table in the left pane to a Component on the right pane
1 parent c925391 commit 6ce505d

5 files changed

Lines changed: 98 additions & 9 deletions

File tree

kview/src/main/java/dev/ikm/komet/kview/controls/ComponentItem.java

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package dev.ikm.komet.kview.controls;
22

3+
import dev.ikm.tinkar.common.id.PublicId;
34
import javafx.beans.property.ObjectProperty;
45
import javafx.beans.property.SimpleObjectProperty;
56
import javafx.beans.property.SimpleStringProperty;
@@ -9,11 +10,11 @@
910
public class ComponentItem {
1011

1112
public ComponentItem() {
12-
this(null, null, null);
13+
this(null, null, (Integer) null);
1314
}
1415

1516
public ComponentItem(String text, Image icon) {
16-
this(text, icon, null);
17+
this(text, icon, (Integer) null);
1718
}
1819

1920
public ComponentItem(String text, Image icon, Integer nid) {
@@ -22,6 +23,12 @@ public ComponentItem(String text, Image icon, Integer nid) {
2223
this.nid = nid;
2324
}
2425

26+
public ComponentItem(String text, Image icon, PublicId publicId) {
27+
this.text.set(text);
28+
this.icon.set(icon);
29+
this.publicId = publicId;
30+
}
31+
2532
// -- text
2633
private StringProperty text = new SimpleStringProperty();
2734
public String getText() { return text.get(); }
@@ -38,4 +45,9 @@ public ComponentItem(String text, Image icon, Integer nid) {
3845
private Integer nid;
3946
public Integer getNid() { return nid;}
4047
public void setNid(Integer nid) { this.nid = nid; }
48+
49+
// -- public id
50+
private PublicId publicId;
51+
public void setPublicId(PublicId publicId) { this.publicId = publicId; }
52+
public PublicId getPublicId() { return publicId; }
4153
}

kview/src/main/java/dev/ikm/komet/kview/controls/skin/ComponentItemNode.java

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,28 @@
22

33
import dev.ikm.komet.kview.controls.ComponentItem;
44
import dev.ikm.komet.kview.controls.KLReadOnlyMultiComponentControl;
5+
import dev.ikm.tinkar.common.id.PublicId;
56
import javafx.beans.property.BooleanProperty;
67
import javafx.beans.property.ObjectProperty;
78
import javafx.beans.property.SimpleBooleanProperty;
89
import javafx.beans.property.SimpleObjectProperty;
10+
import javafx.scene.SnapshotParameters;
911
import javafx.scene.control.ContextMenu;
1012
import javafx.scene.control.Label;
1113
import javafx.scene.image.Image;
1214
import javafx.scene.image.ImageView;
15+
import javafx.scene.image.WritableImage;
16+
import javafx.scene.input.ClipboardContent;
1317
import javafx.scene.input.ContextMenuEvent;
18+
import javafx.scene.input.Dragboard;
19+
import javafx.scene.input.TransferMode;
1420
import javafx.scene.layout.HBox;
1521
import javafx.scene.layout.Priority;
1622
import javafx.scene.layout.Region;
1723
import javafx.scene.shape.Circle;
24+
import java.util.Arrays;
25+
import java.util.UUID;
26+
import java.util.stream.Collectors;
1827

1928
/**
2029
* A Node used to render a Component (icon + text)
@@ -48,10 +57,42 @@ public ComponentItemNode() {
4857

4958
setupComponentItemUIBinding();
5059

60+
setupDragAndDrop();
61+
5162
// CSS
5263
getStyleClass().add("component-item");
5364
}
5465

66+
private void setupDragAndDrop() {
67+
setOnDragDetected(event -> {
68+
Dragboard dragboard = startDragAndDrop(TransferMode.COPY);
69+
70+
PublicId publicId = componentItem.get().getPublicId();
71+
72+
// Clipboard content
73+
ClipboardContent content = new ClipboardContent();
74+
String encoded = Arrays.stream(publicId.asUuidArray())
75+
.map(UUID::toString)
76+
.collect(Collectors.joining(","));
77+
content.put(KLComponentControlSkin.COMPONENT_OUTSIDE_COMPONENT_CONTROL_DRAG_FORMAT, encoded);
78+
dragboard.setContent(content);
79+
80+
// Drag Image
81+
// — temporarily force text color for visibility
82+
String previousStyle = textLabel.getStyle();
83+
textLabel.setStyle("-fx-text-fill: #111111;");
84+
85+
SnapshotParameters p = new SnapshotParameters();
86+
WritableImage snapshot = snapshot(p, null);
87+
dragboard.setDragView(snapshot);
88+
89+
// - Restore original style
90+
textLabel.setStyle(previousStyle);
91+
92+
event.consume();
93+
});
94+
}
95+
5596
public ComponentItemNode(String text, Image icon) {
5697
this();
5798
componentItem.get().setText(text);

kview/src/main/java/dev/ikm/komet/kview/controls/skin/KLComponentControlSkin.java

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,11 @@
88
import dev.ikm.komet.kview.controls.KLComponentControl;
99
import dev.ikm.komet.kview.controls.KLComponentCollectionControl;
1010
import dev.ikm.komet.kview.mvvm.model.DragAndDropInfo;
11+
import dev.ikm.tinkar.common.id.PublicId;
12+
import dev.ikm.tinkar.common.id.PublicIds;
1113
import dev.ikm.tinkar.coordinate.stamp.calculator.LatestVersionSearchResult;
1214
import dev.ikm.tinkar.entity.Entity;
15+
import dev.ikm.tinkar.entity.EntityHandle;
1316
import dev.ikm.tinkar.entity.EntityService;
1417
import dev.ikm.tinkar.terms.EntityFacade;
1518
import dev.ikm.tinkar.terms.EntityProxy;
@@ -53,11 +56,24 @@ public class KLComponentControlSkin extends SkinBase<KLComponentControl> {
5356

5457
private static final Logger LOG = LoggerFactory.getLogger(KLComponentControl.class);
5558
private static final String SEARCH_TEXT_VALUE = "search.text.value";
59+
60+
/**
61+
* Drag format for component drag and drop operations coming from outside of KLComponentControl.
62+
*/
63+
public static final DataFormat COMPONENT_OUTSIDE_COMPONENT_CONTROL_DRAG_FORMAT;
64+
static {
65+
DataFormat dataFormat = DataFormat.lookupMimeType("application/x-komet-outside-component-control-format");
66+
COMPONENT_OUTSIDE_COMPONENT_CONTROL_DRAG_FORMAT = dataFormat == null ? new DataFormat("application/x-komet-outside-component-control-format") : dataFormat;
67+
}
68+
69+
/**
70+
* Drag format for component control drag and drop operations from KLComponentControl to KLComponentControl.
71+
*/
5672
public static final DataFormat COMPONENT_CONTROL_DRAG_FORMAT;
5773

5874
static {
59-
DataFormat dataFormat = DataFormat.lookupMimeType("text/concept-control-format");
60-
COMPONENT_CONTROL_DRAG_FORMAT = dataFormat == null ? new DataFormat("text/concept-control-format") : dataFormat;
75+
DataFormat dataFormat = DataFormat.lookupMimeType("application/x-komet-component-control-format");
76+
COMPONENT_CONTROL_DRAG_FORMAT = dataFormat == null ? new DataFormat("application/x-komet-component-control-format") : dataFormat;
6177
}
6278

6379
private final Label titleLabel;
@@ -162,6 +178,8 @@ private void setupDragNDrop() {
162178
control.setOnDragOver(event -> {
163179
if (event.getDragboard().hasContent(COMPONENT_CONTROL_DRAG_FORMAT)) {
164180
event.acceptTransferModes(TransferMode.MOVE);
181+
} else if(event.getDragboard().hasContent(COMPONENT_OUTSIDE_COMPONENT_CONTROL_DRAG_FORMAT)) {
182+
event.acceptTransferModes(TransferMode.COPY);
165183
} else if (event.getGestureSource() != control && event.getDragboard().hasString()) {
166184
if (isFilterAllowedWhileDragAndDropping(event)) {
167185
event.acceptTransferModes(TransferMode.COPY_OR_MOVE);
@@ -176,7 +194,8 @@ private void setupDragNDrop() {
176194
});
177195

178196
control.setOnDragEntered(event -> {
179-
if (event.getGestureSource() != control && event.getDragboard().hasString()) {
197+
if (event.getGestureSource() != control &&
198+
(event.getDragboard().hasString() || event.getDragboard().hasContent(COMPONENT_OUTSIDE_COMPONENT_CONTROL_DRAG_FORMAT))) {
180199
conceptContainer.setOpacity(.90);
181200
if (event.getDragboard().hasContent(COMPONENT_CONTROL_DRAG_FORMAT)) {
182201
if (hasAllowedDND(control)) {
@@ -205,7 +224,7 @@ private void setupDragNDrop() {
205224
if (hasAllowedDND(control)) {
206225
Dragboard dragboard = control.startDragAndDrop(TransferMode.MOVE);
207226
ClipboardContent clipboardContent = new ClipboardContent();
208-
clipboardContent.put(COMPONENT_CONTROL_DRAG_FORMAT, "concept-control");
227+
clipboardContent.put(COMPONENT_CONTROL_DRAG_FORMAT, "component-control");
209228
control.setUserData(control.getEntity().publicId());
210229
clipboardContent.putString(control.getEntity().toString());
211230
dragboard.setContent(clipboardContent);
@@ -231,6 +250,20 @@ private void setupDragNDrop() {
231250
}
232251
}
233252

253+
if (event.getDragboard().hasContent(COMPONENT_OUTSIDE_COMPONENT_CONTROL_DRAG_FORMAT)) {
254+
String encoded = (String) event.getDragboard().getContent(COMPONENT_OUTSIDE_COMPONENT_CONTROL_DRAG_FORMAT);
255+
PublicId publicId = PublicIds.of(encoded.split(","));
256+
257+
EntityHandle.get(publicId).ifPresent(entity -> {
258+
control.setEntity(entity.toProxy());
259+
addConceptNode(entity.toProxy(), control.getComponentNameRenderer());
260+
261+
event.setDropCompleted(true);
262+
event.consume();
263+
return;
264+
});
265+
}
266+
234267
if (event.getDragboard().hasContent(CONCEPT_NAVIGATOR_DRAG_FORMAT) ) {
235268
List list = (List) event.getDragboard().getContent(CONCEPT_NAVIGATOR_DRAG_FORMAT);
236269
if (!list.isEmpty() && list.get(0) instanceof List) {
@@ -270,6 +303,8 @@ private void setupDragNDrop() {
270303
* @return Returns true if the user is allowed to drag and drop an item (source) to this control (destination).
271304
*/
272305
private boolean isFilterAllowedWhileDragAndDropping(DragEvent dragEvent) {
306+
boolean isFromOutsideControl = dragEvent.getDragboard().hasContent(COMPONENT_OUTSIDE_COMPONENT_CONTROL_DRAG_FORMAT);
307+
273308
// Detect classic concept navigator to drag and drop concepts
274309
boolean classicConceptNavigatorDnD = isFromClassicConceptNav(dragEvent); // and the allowed filter returns true
275310

@@ -282,7 +317,7 @@ private boolean isFilterAllowedWhileDragAndDropping(DragEvent dragEvent) {
282317
// Existing checks for next gen search navigator items to drag.
283318
boolean nextGenSearchDnD = isADragAndDropInfo(dragEvent);
284319

285-
return classicConceptNavigatorDnD || classicSearchDnD || nextGenConceptNavigatorDnD || nextGenSearchDnD;
320+
return classicConceptNavigatorDnD || classicSearchDnD || nextGenConceptNavigatorDnD || nextGenSearchDnD || isFromOutsideControl;
286321
}
287322

288323
/**

kview/src/main/java/dev/ikm/komet/kview/mvvm/view/genpurpose/control/table/PatternSemanticsTablePresenter.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ private PatternSemanticsTableControl createTableControl(ViewProperties viewPrope
6161
String description = viewCalculator.languageCalculator()
6262
.getFullyQualifiedDescriptionTextWithFallbackOrNid(entityProxy.nid());
6363
Image identicon = Identicon.generateIdenticonImage(entityProxy.publicId());
64-
ComponentItem componentItem = new ComponentItem(description, identicon);
64+
ComponentItem componentItem = new ComponentItem(description, identicon, entityProxy.publicId());
6565
return componentItem;
6666
});
6767
patternSemanticsControl.setNidToComponentItem(nid -> {
@@ -71,7 +71,7 @@ private PatternSemanticsTableControl createTableControl(ViewProperties viewPrope
7171
String description = viewCalculator.languageCalculator()
7272
.getFullyQualifiedDescriptionTextWithFallbackOrNid(entityProxy.nid());
7373

74-
return new ComponentItem(description, icon);
74+
return new ComponentItem(description, icon, entityProxy.publicId());
7575
});
7676

7777
return patternSemanticsControl;

kview/src/main/java/module-info.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
requires dev.ikm.tinkar.events;
5151
requires dev.ikm.komet.preferences;
5252
requires dev.ikm.komet.rules;
53+
requires dev.ikm.tinkar.schema;
5354

5455
exports dev.ikm.komet.kview.state;
5556
exports dev.ikm.komet.kview.state.pattern;

0 commit comments

Comments
 (0)