void navigate(int dx, int dy) {
    if (myCurrentItemIndex < 0) return;
    int x = (myCurrentItemIndex % myItemsPerRow + dx + myItemsPerRow) % myItemsPerRow;
    int y = myCurrentItemIndex / myItemsPerRow + dy;
    int newIndex = myItemsPerRow * y + x;
    if (newIndex >= 0 && newIndex < myCurrentItemCategory.myCategory.getEmoji().size()) {
      setCurrentItem(myCurrentItemCategory, newIndex);
    }
    else {
      int cat = myCategoriesPanel.findCategoryIndex(myCurrentItemCategory);
      if (cat == -1) return;
      boolean up = newIndex < 0;
      cat += up ? -1 : 1;
      if (cat < 0 || cat >= myCategoriesPanel.myCategories.size()) return;
      Category c = myCategoriesPanel.myCategories.get(cat);
      int rows = (c.myCategory.getEmoji().size() + myItemsPerRow - 1) / myItemsPerRow;
      y = up ? rows - 1 : 0;
      if (y < 0 || myItemsPerRow * y + x >= c.myCategory.getEmoji().size()) {
        y--;
        if (y < 0) return;
      }
      setCurrentItem(c, myItemsPerRow * y + x);
    }
    int overscroll = (myCellSize.height + myCellGaps.height) * dy;
    int overscrollUp = Math.max(-overscroll, 0);
    int overscrollDown = Math.max(overscroll, 0);
    myCurrentItemCategory.scrollRectToVisible(new Rectangle(
      myCurrentItemCategory.xGridToVisible(x),
      myCurrentItemCategory.yGridToVisible(y) - JBUIScale.scale(Category.LABEL_HEIGHT) - overscrollUp,
      myCellSize.width,
      myCellSize.height + JBUIScale.scale(Category.LABEL_HEIGHT) + overscrollUp + overscrollDown
    ));
  }
void navigate(int dx, int dy)