<commit_before>/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.jfoenix.skins;

import com.jfoenix.controls.JFXRippler;
import com.jfoenix.controls.JFXRippler.RipplerMask;
import com.jfoenix.controls.JFXRippler.RipplerPos;
import com.jfoenix.controls.JFXTabPane;
import com.jfoenix.effects.JFXDepthManager;
import com.jfoenix.svg.SVGGlyph;
import com.jfoenix.transitions.CachedTransition;
import com.sun.javafx.scene.control.MultiplePropertyChangeListenerHandler;
import com.sun.javafx.scene.control.behavior.TabPaneBehavior;
import com.sun.javafx.scene.control.skin.BehaviorSkinBase;
import javafx.animation.*;
import javafx.beans.InvalidationListener;
import javafx.beans.WeakInvalidationListener;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ListChangeListener.Change;
import javafx.collections.ObservableList;
import javafx.collections.WeakListChangeListener;
import javafx.css.PseudoClass;
import javafx.geometry.HPos;
import javafx.geometry.Insets;
import javafx.geometry.Side;
import javafx.geometry.VPos;
import javafx.scene.Cursor;
import javafx.scene.Node;
import javafx.scene.control.*;
import javafx.scene.input.ContextMenuEvent;
import javafx.scene.input.MouseButton;
import javafx.scene.input.ScrollEvent;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;
import javafx.scene.transform.Rotate;
import javafx.scene.transform.Scale;
import javafx.util.Duration;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * <h1>Material Design TabPane Skin</h1>
 *
 * @author <NAME>
 */
public class JFXTabPaneSkin extends BehaviorSkinBase<TabPane, TabPaneBehavior> {

    private final Color defaultColor = Color.valueOf("#00BCD4");
    private final Color ripplerColor = Color.valueOf("#FFFF8D");
    private final Color selectedTabText = Color.WHITE;
    private Color tempLabelColor = Color.WHITE;

    private HeaderContainer header;
    private ObservableList<TabContentHolder> tabContentHolders;
    private Rectangle clip;
    private Rectangle tabsClip;
    private Tab selectedTab;
    private boolean isSelectingTab = false;
    private double dragStart, offsetStart;
    private AnchorPane tabsContainer;
    private AnchorPane tabsContainerHolder;
    private static final int SPACER = 10;
    private double maxWidth = 0.0d;
    private double maxHeight = 0.0d;

    public JFXTabPaneSkin(TabPane tabPane) {
        super(tabPane, new TabPaneBehavior(tabPane));
        tabContentHolders = FXCollections.observableArrayList();
        header = new HeaderContainer();
        getChildren().add(JFXDepthManager.createMaterialNode(header, 1));

        tabsContainer = new AnchorPane();
        tabsContainerHolder = new AnchorPane();
        tabsContainerHolder.getChildren().add(tabsContainer);
        tabsClip = new Rectangle();
        tabsContainerHolder.setClip(tabsClip);
        getChildren().add(0, tabsContainerHolder);

        // add tabs
        for (Tab tab : getSkinnable().getTabs()) {
            addTabContentHolder(tab);
        }

        // clipping tabpane/header pane
        clip = new Rectangle(tabPane.getWidth(), tabPane.getHeight());
        getSkinnable().setClip(clip);
        if (getSkinnable().getTabs().size() == 0) {
            header.setVisible(false);
        }

        // select a tab
        selectedTab = getSkinnable().getSelectionModel().getSelectedItem();
        if (selectedTab == null && getSkinnable().getSelectionModel().getSelectedIndex() != -1) {
            getSkinnable().getSelectionModel().select(getSkinnable().getSelectionModel().getSelectedIndex());
            selectedTab = getSkinnable().getSelectionModel().getSelectedItem();
        }
        // if no selected tab, then select the first tab
        if (selectedTab == null) {
            getSkinnable().getSelectionModel().selectFirst();
        }
        selectedTab = getSkinnable().getSelectionModel().getSelectedItem();

        header.headersRegion.setOnMouseDragged(me -> {
            header.updateScrollOffset(offsetStart
                                      + (isHorizontal() ? me.getSceneX() : me .getSceneY())
                                      - dragStart);
            me.consume();
        });
        getSkinnable().setOnMousePressed(me -> {
            dragStart = (isHorizontal() ? me.getSceneX() : me .getSceneY());
            offsetStart = header.scrollOffset;
        });

        // add listeners on tab list
        getSkinnable().getTabs().addListener((ListChangeListener<Tab>) change -> {
            List<Tab> tabsToBeRemoved = new ArrayList<>();
            List<Tab> tabsToBeAdded = new ArrayList<>();
            int insertIndex = -1;
            while (change.next()) {
                if (change.wasPermutated()) {
                    Tab selectedTab = getSkinnable().getSelectionModel().getSelectedItem();
                    List<Tab> permutatedTabs = new ArrayList<>(change.getTo() - change.getFrom());
                    getSkinnable().getSelectionModel().clearSelection();
                    for (int i = change.getFrom(); i < change.getTo(); i++) {
                        permutatedTabs.add(getSkinnable().getTabs().get(i));<commit_msg>fixed #557 JFXTabPane doesnt react to mouse pressed events<commit_after>/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.jfoenix.skins;

import com.jfoenix.controls.JFXRippler;
import com.jfoenix.controls.JFXRippler.RipplerMask;
import com.jfoenix.controls.JFXRippler.RipplerPos;
import com.jfoenix.controls.JFXTabPane;
import com.jfoenix.effects.JFXDepthManager;
import com.jfoenix.svg.SVGGlyph;
import com.jfoenix.transitions.CachedTransition;
import com.sun.javafx.scene.control.MultiplePropertyChangeListenerHandler;
import com.sun.javafx.scene.control.behavior.TabPaneBehavior;
import com.sun.javafx.scene.control.skin.BehaviorSkinBase;
import javafx.animation.*;
import javafx.beans.InvalidationListener;
import javafx.beans.WeakInvalidationListener;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ListChangeListener.Change;
import javafx.collections.ObservableList;
import javafx.collections.WeakListChangeListener;
import javafx.css.PseudoClass;
import javafx.geometry.HPos;
import javafx.geometry.Insets;
import javafx.geometry.Side;
import javafx.geometry.VPos;
import javafx.scene.Cursor;
import javafx.scene.Node;
import javafx.scene.control.*;
import javafx.scene.input.ContextMenuEvent;
import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent;
import javafx.scene.input.ScrollEvent;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;
import javafx.scene.transform.Rotate;
import javafx.scene.transform.Scale;
import javafx.util.Duration;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * <h1>Material Design TabPane Skin</h1>
 *
 * @author <NAME>
 */
public class JFXTabPaneSkin extends BehaviorSkinBase<TabPane, TabPaneBehavior> {

    private final Color defaultColor = Color.valueOf("#00BCD4");
    private final Color ripplerColor = Color.valueOf("#FFFF8D");
    private final Color selectedTabText = Color.WHITE;
    private Color tempLabelColor = Color.WHITE;

    private HeaderContainer header;
    private ObservableList<TabContentHolder> tabContentHolders;
    private Rectangle clip;
    private Rectangle tabsClip;
    private Tab selectedTab;
    private boolean isSelectingTab = false;
    private double dragStart, offsetStart;
    private AnchorPane tabsContainer;
    private AnchorPane tabsContainerHolder;
    private static final int SPACER = 10;
    private double maxWidth = 0.0d;
    private double maxHeight = 0.0d;

    public JFXTabPaneSkin(TabPane tabPane) {
        super(tabPane, new TabPaneBehavior(tabPane));
        tabContentHolders = FXCollections.observableArrayList();
        header = new HeaderContainer();
        getChildren().add(JFXDepthManager.createMaterialNode(header, 1));

        tabsContainer = new AnchorPane();
        tabsContainerHolder = new AnchorPane();
        tabsContainerHolder.getChildren().add(tabsContainer);
        tabsClip = new Rectangle();
        tabsContainerHolder.setClip(tabsClip);
        getChildren().add(0, tabsContainerHolder);

        // add tabs
        for (Tab tab : getSkinnable().getTabs()) {
            addTabContentHolder(tab);
        }

        // clipping tabpane/header pane
        clip = new Rectangle(tabPane.getWidth(), tabPane.getHeight());
        getSkinnable().setClip(clip);
        if (getSkinnable().getTabs().size() == 0) {
            header.setVisible(false);
        }

        // select a tab
        selectedTab = getSkinnable().getSelectionModel().getSelectedItem();
        if (selectedTab == null && getSkinnable().getSelectionModel().getSelectedIndex() != -1) {
            getSkinnable().getSelectionModel().select(getSkinnable().getSelectionModel().getSelectedIndex());
            selectedTab = getSkinnable().getSelectionModel().getSelectedItem();
        }
        // if no selected tab, then select the first tab
        if (selectedTab == null) {
            getSkinnable().getSelectionModel().selectFirst();
        }
        selectedTab = getSkinnable().getSelectionModel().getSelectedItem();

        header.headersRegion.setOnMouseDragged(me -> {
            header.updateScrollOffset(offsetStart
                                      + (isHorizontal() ? me.getSceneX() : me .getSceneY())
                                      - dragStart);
            me.consume();
        });

        getSkinnable().addEventHandler(MouseEvent.MOUSE_PRESSED, me -> {
            dragStart = (isHorizontal() ? me.getSceneX() : me .getSceneY());
            offsetStart = header.scrollOffset;
        });

        // add listeners on tab list
        getSkinnable().getTabs().addListener((ListChangeListener<Tab>) change -> {
            List<Tab> tabsToBeRemoved = new ArrayList<>();
            List<Tab> tabsToBeAdded = new ArrayList<>();
            int insertIndex = -1;
            while (change.next()) {
                if (change.wasPermutated()) {
                    Tab selectedTab = getSkinnable().getSelectionModel().getSelectedItem();
                    List<Tab> permutatedTabs = new ArrayList<>(change.getTo() - change.getFrom());
                    getSkinnable().getSelectionModel().clearSelection();
                    for (int i = change.getFrom(); i < change.getTo(); i++) {
                        permutatedTabs.add(getSkinnable().getTabs().get(i));
{'fraction_non_alphanumeric': 0.10340690978886756, 'fraction_numerical': 0.003598848368522073, 'mean_word_length': 3.3800350262697023, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 33, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3953754', 'n_tokens_mistral': 3498, 'n_tokens_neox': 3386, 'n_words': 812}