<commit_before>/*-
 * #%L
 * BigDataViewer core classes with minimal dependencies.
 * %%
 * Copyright (C) 2012 - 2022 BigDataViewer developers.
 * %%
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 * #L%
 */
package bdv.ui.sourcetable;

import static bdv.ui.sourcetable.SourceTableModel.COLOR_COLUMN;
import static bdv.ui.sourcetable.SourceTableModel.IS_ACTIVE_COLUMN;
import static bdv.ui.sourcetable.SourceTableModel.IS_CURRENT_COLUMN;

import java.awt.Color;
import java.awt.Point;
import java.awt.datatransfer.Transferable;
import java.awt.event.InputEvent;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JColorChooser;
import javax.swing.JComponent;
import javax.swing.JTable;
import javax.swing.TransferHandler;
import javax.swing.UIManager;

import org.scijava.ui.behaviour.io.InputTriggerConfig;
import org.scijava.ui.behaviour.util.Actions;
import org.scijava.ui.behaviour.util.InputActionBindings;

import bdv.tools.brightness.ConverterSetup;
import bdv.ui.SourcesTransferable;
import bdv.ui.UIUtils;
import bdv.viewer.ConverterSetups;
import bdv.viewer.SourceAndConverter;
import bdv.viewer.SourceToConverterSetupBimap;
import bdv.viewer.ViewerState;
import net.imglib2.type.numeric.ARGBType;

/**
 * A {@code JTable} that shows the sources of a {@link ViewerState} and allows
 * to modify activeness, currentness, as well as the color of the corresponding
 * {@link ConverterSetup}.
 *
 * @author <NAME>
 */
public class SourceTable extends JTable
{
	private final SourceTableModel model;

	private final ViewerState state;

	private final SourceToConverterSetupBimap converters;

	private final Color focusedSelectionBg;
	private final Color unfocusedSelectionBg;

	private final Color focusedSelectionFg;

	public SourceTable( final ViewerState state, final ConverterSetups converterSetups )
	{
		this( state, converterSetups, new InputTriggerConfig() );
	}

	public SourceTable( final ViewerState state, final ConverterSetups converterSetups, final InputTriggerConfig inputTriggerConfig )
	{
		this.state = state;
		converters = converterSetups;
		model = new SourceTableModel( state, converterSetups );
		setModel( model );
		setTransferHandler( new SourceTableTransferHandler() );

		getColumnModel().getColumn( IS_CURRENT_COLUMN ).setCellRenderer( new RadioButtonRenderer() );
		getColumnModel().getColumn( COLOR_COLUMN ).setCellRenderer( new ColorRenderer() );
		setRowHeight( ( int )Math.round( UIManager.getDefaults().getFont( "Table.font" ).getSize() * 1.5 ) );

		setShowGrid( false );

		getColumnModel().getColumn( IS_CURRENT_COLUMN ).setMinWidth( 20 );
		getColumnModel().getColumn( IS_ACTIVE_COLUMN ).setMinWidth( 20 );
		getColumnModel().getColumn( COLOR_COLUMN ).setMinWidth( 40 );

		this.installActions( inputTriggerConfig );

		focusedSelectionBg = getSelectionBackground();
		focusedSelectionFg = getSelectionForeground();
		unfocusedSelectionBg = UIUtils.mix( focusedSelectionBg, getBackground(), 0.8 );
	}

	public void setSelectionBackground( final boolean hasFocus )
	{
		setSelectionForeground( focusedSelectionFg );
		setSelectionBackground( hasFocus ? focusedSelectionBg : unfocusedSelectionBg );
	}

	public List< SourceAndConverter< ? > > getSelectedSources()
	{
		final List< SourceAndConverter< ? > > sources = new ArrayList<>();
		for ( final int row : getSelectedRows() )
			sources.add( model.getValueAt( row ).getSource() );
		return sources;
	}

	public List< ConverterSetup > getSelectedConverterSetups()
	{
		return converters.getConverterSetups( getSelectedSources() );
	}

	private void installActions( final InputTriggerConfig inputTriggerConfig )
	{
		final InputActionBindings keybindings = InputActionBindings.installNewBindings( this, JComponent.WHEN_FOCUSED, false );
		final Actions actions = new Actions( inputTriggerConfig, "bdv" );
		actions.install( keybindings, "source table" );
		actions.runnableAction( () -> toggleSelectedActive(), "toggle active", "A" );
		actions.runnableAction( () -> makeSelectedActive( true ), "set active", "not mapped" );
		actions.runnableAction( () -> makeSelectedActive( false ), "set inactive", "not mapped" );
		actions.runnableAction( () -> cycleSelectedCurrent(), "cycle current", "C" );
	}<commit_msg>WIP LAF update for SourceTable<commit_after>/*-
 * #%L
 * BigDataViewer core classes with minimal dependencies.
 * %%
 * Copyright (C) 2012 - 2022 BigDataViewer developers.
 * %%
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 * #L%
 */
package bdv.ui.sourcetable;

import static bdv.ui.sourcetable.SourceTableModel.COLOR_COLUMN;
import static bdv.ui.sourcetable.SourceTableModel.IS_ACTIVE_COLUMN;
import static bdv.ui.sourcetable.SourceTableModel.IS_CURRENT_COLUMN;

import java.awt.Color;
import java.awt.Point;
import java.awt.datatransfer.Transferable;
import java.awt.event.InputEvent;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JColorChooser;
import javax.swing.JComponent;
import javax.swing.JTable;
import javax.swing.TransferHandler;
import javax.swing.UIManager;

import org.scijava.ui.behaviour.io.InputTriggerConfig;
import org.scijava.ui.behaviour.util.Actions;
import org.scijava.ui.behaviour.util.InputActionBindings;

import bdv.tools.brightness.ConverterSetup;
import bdv.ui.SourcesTransferable;
import bdv.ui.UIUtils;
import bdv.viewer.ConverterSetups;
import bdv.viewer.SourceAndConverter;
import bdv.viewer.SourceToConverterSetupBimap;
import bdv.viewer.ViewerState;
import net.imglib2.type.numeric.ARGBType;

/**
 * A {@code JTable} that shows the sources of a {@link ViewerState} and allows
 * to modify activeness, currentness, as well as the color of the corresponding
 * {@link ConverterSetup}.
 *
 * @author <NAME>
 */
public class SourceTable extends JTable
{
	private final SourceTableModel model;

	private final ViewerState state;

	private final SourceToConverterSetupBimap converters;

	private Color focusedSelectionBg;
	private Color unfocusedSelectionBg;

	private boolean tableHasFocus;

	public SourceTable( final ViewerState state, final ConverterSetups converterSetups )
	{
		this( state, converterSetups, new InputTriggerConfig() );
	}

	public SourceTable( final ViewerState state, final ConverterSetups converterSetups, final InputTriggerConfig inputTriggerConfig )
	{
		this.state = state;
		converters = converterSetups;
		model = new SourceTableModel( state, converterSetups );
		setModel( model );
		setTransferHandler( new SourceTableTransferHandler() );

		getColumnModel().getColumn( IS_CURRENT_COLUMN ).setCellRenderer( new RadioButtonRenderer() );
		getColumnModel().getColumn( COLOR_COLUMN ).setCellRenderer( new ColorRenderer() );
		setRowHeight( ( int )Math.round( UIManager.getDefaults().getFont( "Table.font" ).getSize() * 1.5 ) );

		setShowGrid( false );

		getColumnModel().getColumn( IS_CURRENT_COLUMN ).setMinWidth( 20 );
		getColumnModel().getColumn( IS_ACTIVE_COLUMN ).setMinWidth( 20 );
		getColumnModel().getColumn( COLOR_COLUMN ).setMinWidth( 40 );

		this.installActions( inputTriggerConfig );

		updateColors();
	}

	@Override
	public void updateUI()
	{
		super.updateUI();
		updateColors();
	}

	private void updateColors()
	{
		focusedSelectionBg = UIManager.getColor( "Table.selectionBackground" );
		unfocusedSelectionBg = UIUtils.mix( focusedSelectionBg, UIManager.getColor( "Table.background" ), 0.8 );
		setSelectionBackground( tableHasFocus ? focusedSelectionBg : unfocusedSelectionBg );
	}

	public void setSelectionBackground( final boolean hasFocus )
	{
		tableHasFocus = hasFocus;
		setSelectionBackground( hasFocus ? focusedSelectionBg : unfocusedSelectionBg );
	}

	public List< SourceAndConverter< ? > > getSelectedSources()
	{
		final List< SourceAndConverter< ? > > sources = new ArrayList<>();
		for ( final int row : getSelectedRows() )
			sources.add( model.getValueAt( row ).getSource() );
		return sources;
	}

	public List< ConverterSetup > getSelectedConverterSetups()
	{
		return converters.getConverterSetups( getSelectedSources() );
	}

	private void installActions( final InputTriggerConfig inputTriggerConfig )
	{
		final InputActionBindings keybindings = InputActionBindings.installNewBindings( this, JComponent.WHEN_FOCUSED, false );
		final Actions actions = new Actions( inputTriggerConfig, "bdv" );
		actions.install( keybindings, "source table" );
		actions.runnableAction( () -> toggleSelectedActive(), "toggle active", "A" );
		actions.runnableAction( () -> makeSelectedActive( true ), "set active", "not mapped" );
		actions.runnableAction( () -> makeSelectedActive( false ), "set inactive", "not mapped" );
		actions.runnableAction( () -> cycleSelectedCurrent(), "cycle current", "C" );
	}
{'fraction_non_alphanumeric': 0.091273374888691, 'fraction_numerical': 0.0037399821905609973, 'mean_word_length': 5.295403587443946, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4223416', 'n_tokens_mistral': 3414, 'n_tokens_neox': 3147, 'n_words': 981}