אפשר לגרור

אובייקט שניתן לגרירה הוא אובייקט שעבר רינדור, ונמצא בסביבת העבודה שאפשר לגרור ולשחרר. הן מטמיעות את הממשק IDraggable.

יש מעט מאוד מקרים שבהם רוצים להוסיף ל-Blockly חדש אפשרות גרירה חדשה (למשל, הפלאגין 'בחירה מרובה' או שינוי האופן שבו אובייקט קיים מטפל בגרירה), כי אי אפשר להוסיף ל-Blockly אובייקטים חדשים שעברו עיבוד. האובייקטים היחידים שעברו עיבוד שיכולים להתקיים בסביבת העבודה הם בלוקים, בועות ותגובות בסביבת העבודה.

תחומי אחריות

לנתונים לגרירה יש כמה תחומי אחריות כשמבצעים גרירה:

הטמעה

כדי ליצור ממשק גרירה חדש, צריך להטמיע את הממשק IRenderedElement ו-IDraggable. כך אפשר לדעת שהאובייקט גלוי ושניתן לגרור אותו.

class MyDraggable extends IRenderedElement, IDraggable {}

החזרת רכיב SVG ברמה הבסיסית

השיטה getRootSvg מחזירה את רכיב svg ברמה הבסיסית (בדרך כלל קבוצה) שמכיל את כל הרכיבים האחרים שמרכיבים את התצוגה של הפריט שגורר.

getSvgRoot() {
  return this.rootSvg;
}

החזרות תנועה

השיטה isMovable מחזירה את התוצאה אם אפשר לגרור את האובייקט כרגע כדי שניתן יהיה להזיז אותו (כי כדאי להשבית באופן זמני את הגרירה של אובייקט). במקרה שהפונקציה isMovable מחזירה false, המערכת תגרור את סביבת העבודה במקום זאת.

isMovable() {
  return true;
}

מצב החזרה

השיטה getRelativeToSurfaceXY מחזירה Coordinate שמציין את המיקום של פינת ההתחלה העליונה של הקואורדינטות של סביבת העבודה שניתנת לגרירה.

המקור של קואורדינטות של סביבת עבודה הוא בצד ימין למעלה ובחלק העליון ביותר של סביבת העבודה. בנוסף, הם לא משתנים כשמשנים את גודל סביבת העבודה או משנים אותה.

getRelativeToSurfaceXY() {
  return this.loc;
}

התחלת גרירה

השיטה startDrag מפעילה גרירה באזור שניתן לגרירה. השיטה הזו לא מאפשרת להעביר את הממשק לגרירה. אבל כדאי לאחסן נתונים או לבנות אובייקטים הדרושים להשלמת הגרירה. היא כוללת את כל הנתונים שצריך לבטל את הגרירה במקרה של קריאה ל-revertDrag.

הוא צריך גם לשנות את רכיבי ה-svg כך שיהיו בשכבת הגרירה של סביבת העבודה, כך שהם יהיו קיימים מעל רכיבים אחרים.

הוא גם מקבל אירוע, שאפשר להשתמש בו כדי לבדוק אם יש מקשים שנלחצו. כך אפשר (לדוגמה) לטפל בגרירה תוך כדי תזוזה באופן שונה מגרירה רגילה.

startDrag(e) {
  // Save the original location so we can revert the drag.
  this.startLoc = this.getRelativeToSurfaceXY();

  // Disable resizing the workspace for performance.
  this.workspace.setResizesEnabled(false);

  // Put the element on the drag layer.
  this.workspace.getLayerManager()?.moveToDragLayer(this);

  // Fire a drag event...

  // etc...
}

גרירה

השיטה drag למעשה מעבירה את האובייקט שניתן לגרירה. ה-newLoc נמצא בקואורדינטות של סביבת העבודה, ויש גם אירוע שהועבר שבו אפשר להשתמש כדי לבדוק אם יש מקשים לחוצים.

drag(newLoc, e) {
  this.moveTo(newLoc);
}

ביטול גרירה

השיטה revertDrag מחזירה את הגרירה למיקום שהיא הייתה בו בתחילת הגרירה. זה קורה, למשל, אם הגרירה נופלת על יעד גרירה שמונע תנועה.

revertDrag() {
  // Move back to the position that was stored in `startDrag`.
  this.moveTo(this.startLoc);
}

סיום הגרירה

השיטה endDrag מנקה גרירה, משחררת נתונים או אובייקטים מאוחסנים, ומחזירה את הפריט שגורר לשכבה המקורית שלו.

תתבצע קריאה לפונקציה endDrag אחרי revertDrag אם מתבצעת קריאה ל-revertDrag.

endDrag() {
  // Put the element back on its original layer (in this case BLOCK).
  this.workspace
    .getLayerManager()
    ?.moveOffDragLayer(this, Blockly.layers.BLOCK);

  // Allow the workspace to start resizing again.
  this.workspace.setResizesEnabled(true);
}

בחירה

הרכיב שגוררים נקבע על ידי האלמנט שנבחר כשמזוהה גרירה.

ISelectable

כדי שניתן יהיה לבחור באפשרות שניתנת לגרירה, יש להטמיע את הממשק ISelectable.

class MyDraggable implements ISelectable {
  constructor(workspace) {
    this.id = Blockly.utils.idGenerator.genUid();
    this.workspace = workspace;
  }

  select() {
    // Visually indicate this draggable is selected.
  }

  unselect() {
    // Visually indicate this draggable is not selected.
  }
}

הגדרת הבחירה

אפשר להגדיר את הרכיב שנבחר באמצעות קריאה ל-Blockly.common.setSelected(). בדרך כלל כדאי לעשות זאת בתגובה לאירוע pointerdown מהמשתמש.

  constructor() {
    this.initSvg();

    Blockly.browserEvents.conditionalBind(
      this.getSvgRoot(),
      'pointerdown',
      this,
      () => Blockly.common.setSelected(this));
  }

תאימות

באמצעות הגרירה אפשר להטמיע ממשקים נוספים כדי לתקשר עם מערכות אחרות ב-Blockly.

פריטים שניתנים למחיקה

אתם יכולים להטמיע את הממשק IDeleteable כדי לאפשר אשפה או יעדי מחיקה אחרים שאפשר להשליך אותם באמצעות גרירה.

class MyDraggable implements IDeletable {
  isDeletable() {
    return true;
  }

  dispose() {
    // Dispose of any references to data or SVG elements.
  }

  setDeleteStyle() {
    // Visually indicate that the draggable is about to be deleted.
  }
}

ניתן להעתקה

אתם יכולים להטמיע את הממשק ICopyable כדי לאפשר העתקה של הפריט שגורר אתכם ולהגדיר IPaster כדי לאפשר הדבקה שלו.

למידע נוסף על העתקת הדבקה, ראו העתקת הדבקה.