<commit_before>package com.mntnorv.wrdl.views;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.View;

import java.util.ArrayList;

public class TileGridView extends View {

    private Paint mTextNormalPaint;
    private Paint mTextSelectedPaint;

    private float[] mTextXOffsets;
    private float[] mTextYOffsets;
    private String[] mTileStrings;
    private boolean[] mTilesSelected;

    private int sizeInTiles;
    private float tileSize;

    public TileGridView(Context context) {
        super(context);
        init();
    }

    public TileGridView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public TileGridView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        mTextNormalPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.SUBPIXEL_TEXT_FLAG);
        mTextNormalPaint.setColor(0xFF000000);
        mTextNormalPaint.setTextSize(12);

        mTextSelectedPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.SUBPIXEL_TEXT_FLAG);
        mTextSelectedPaint.setColor(0xFFFF0000);
        mTextSelectedPaint.setTextSize(12);

        mTileStrings = new String[] {"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P"};
        sizeInTiles = (int) Math.sqrt(mTileStrings.length);

        setOnTouchListener(touchListener);
    }

    private GridSequenceTouchListener touchListener = new GridSequenceTouchListener() {
        @Override
        protected void sequenceChanged(ArrayList<Integer> sequence, byte changeType, int elemChanged) {
            switch (changeType) {
                case GridSequenceTouchListener.ELEMENT_ADDED:
                    selectTile(elemChanged);
                    break;
                case GridSequenceTouchListener.ELEMENT_REMOVED:
                    deselectTile(elemChanged);
                    break;
                case GridSequenceTouchListener.SEQUENCE_CLEARED:
                    deselectAllTiles();
                    break;
            }
        }
    };

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        int newSize = w > h ? h : w;
        super.onSizeChanged(newSize, newSize, oldw, oldh);

        tileSize = newSize / (sizeInTiles * 1.0f);
        updateDrawableProperties();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int width = MeasureSpec.getSize(widthMeasureSpec);
        int height = MeasureSpec.getSize(heightMeasureSpec);
        int measureSpec = width > height ? heightMeasureSpec : widthMeasureSpec;
        super.onMeasure(measureSpec, measureSpec);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        for (int i = 0; i < mTileStrings.length; i++) {
            if (!mTilesSelected[i]) {
                canvas.drawText(mTileStrings[i], mTextXOffsets[i], mTextYOffsets[i], mTextNormalPaint);
            } else {
                canvas.drawText(mTileStrings[i], mTextXOffsets[i], mTextYOffsets[i], mTextSelectedPaint);
            }
        }
    }

    private void updateDrawableProperties() {
        touchListener.initialize(getWidth(), getHeight(), sizeInTiles, sizeInTiles);

        mTextNormalPaint.setTextSize(tileSize * 0.3f);
        mTextSelectedPaint.setTextSize(tileSize * 0.3f);

        mTextXOffsets = new float[mTileStrings.length];
        mTextYOffsets = new float[mTileStrings.length];
        mTilesSelected = new boolean[mTileStrings.length];

        Rect textBounds = new Rect();
        for (int i = 0; i < mTileStrings.length; i++) {
            mTilesSelected[i] = false;
            mTextNormalPaint.getTextBounds(mTileStrings[i], 0, mTileStrings[i].length(), textBounds);
            mTextXOffsets[i] = tileSize * (i % sizeInTiles) + (tileSize - textBounds.right) / 2;
            mTextYOffsets[i] = tileSize * (i / sizeInTiles) + (tileSize / 2);
        }
    }

    private void selectTile(int position) {
        mTilesSelected[position] = true;
        invalidate();
    }

    private void deselectTile(int position) {
        mTilesSelected[position] = false;
        invalidate();
    }<commit_msg>Added selection circles in TileGridView<commit_after>package com.mntnorv.wrdl.views;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.View;

import java.util.ArrayList;

public class TileGridView extends View {

    private Paint mTextPaint;
    private Paint mCirclePaint;

    private float[] mTextXOffsets;
    private float[] mTextYOffsets;
    private String[] mTileStrings;
    private boolean[] mTilesSelected;

    private float[] mCircleXOffsets;
    private float[] mCircleYOffsets;
    private float mCircleRadius;

    private int sizeInTiles;
    private float tileSize;

    public TileGridView(Context context) {
        super(context);
        init();
    }

    public TileGridView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public TileGridView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.SUBPIXEL_TEXT_FLAG);
        mTextPaint.setColor(0xFF000000);
        mTextPaint.setTextSize(12);

        mCirclePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mCirclePaint.setColor(0xFFFF0000);

        mTileStrings = new String[] {"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P"};
        sizeInTiles = (int) Math.sqrt(mTileStrings.length);

        setOnTouchListener(touchListener);
    }

    private GridSequenceTouchListener touchListener = new GridSequenceTouchListener() {
        @Override
        protected void sequenceChanged(ArrayList<Integer> sequence, byte changeType, int elemChanged) {
            switch (changeType) {
                case GridSequenceTouchListener.ELEMENT_ADDED:
                    selectTile(elemChanged);
                    break;
                case GridSequenceTouchListener.ELEMENT_REMOVED:
                    deselectTile(elemChanged);
                    break;
                case GridSequenceTouchListener.SEQUENCE_CLEARED:
                    deselectAllTiles();
                    break;
            }
        }
    };

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        int newSize = w > h ? h : w;
        super.onSizeChanged(newSize, newSize, oldw, oldh);

        tileSize = newSize / (sizeInTiles * 1.0f);
        updateDrawableProperties();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int width = MeasureSpec.getSize(widthMeasureSpec);
        int height = MeasureSpec.getSize(heightMeasureSpec);
        int measureSpec = width > height ? heightMeasureSpec : widthMeasureSpec;
        super.onMeasure(measureSpec, measureSpec);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        // Draw selection circles
        for (int i = 0; i < mTileStrings.length; i++) {
            if (mTilesSelected[i]) {
                canvas.drawCircle(mCircleXOffsets[i], mCircleYOffsets[i], mCircleRadius, mCirclePaint);
            }
        }

        // Draw text
        for (int i = 0; i < mTileStrings.length; i++) {
            canvas.drawText(mTileStrings[i], mTextXOffsets[i], mTextYOffsets[i], mTextPaint);
        }
    }

    private void updateDrawableProperties() {
        touchListener.initialize(getWidth(), getHeight(), sizeInTiles, sizeInTiles);

        mTextPaint.setTextSize(tileSize * 0.3f);

        mTextXOffsets = new float[mTileStrings.length];
        mTextYOffsets = new float[mTileStrings.length];
        mTilesSelected = new boolean[mTileStrings.length];

        mCircleRadius = tileSize * 0.8f / 2;
        mCircleXOffsets = new float[mTileStrings.length];
        mCircleYOffsets = new float[mTileStrings.length];

        Rect textBounds = new Rect();
        float baseXOffset;
        float baseYOffset;

        for (int i = 0; i < mTileStrings.length; i++) {
            baseXOffset = tileSize * (i % sizeInTiles);
            baseYOffset = tileSize * (i / sizeInTiles);

            // Update text properties
            mTilesSelected[i] = false;
            mTextPaint.getTextBounds(mTileStrings[i], 0, mTileStrings[i].length(), textBounds);
            mTextXOffsets[i] = baseXOffset + (tileSize - textBounds.right) / 2;
            mTextYOffsets[i] = baseYOffset + (tileSize + textBounds.bottom - textBounds.top) / 2;

            // Update circle properties
            mCircleXOffsets[i] = baseXOffset + tileSize / 2;
            mCircleYOffsets[i] = baseYOffset + tileSize / 2;
        }
    }

    private void selectTile(int position) {
        mTilesSelected[position] = true;
        invalidate();
    }

    private void deselectTile(int position) {
        mTilesSelected[position] = false;
        invalidate();
    }
{'fraction_non_alphanumeric': 0.10119811724433034, 'fraction_numerical': 0.00599058622165169, 'mean_word_length': 2.5574581430745815, 'pattern_counts': {'":': 0, '<': 10, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3137775', 'n_tokens_mistral': 2805, 'n_tokens_neox': 2679, 'n_words': 594}