<commit_before>package imgui.imgui.widgets

import glm_.*
import glm_.vec2.Vec2
import imgui.Col
import imgui.ColumnsFlags
import imgui.ID
import imgui.ImGui.buttonBehavior
import imgui.ImGui.contentRegionAvail
import imgui.ImGui.currentWindow
import imgui.ImGui.currentWindowRead
import imgui.ImGui.getColumnOffset
import imgui.ImGui.getOffsetFrom
import imgui.ImGui.io
import imgui.ImGui.isClippedEx
import imgui.ImGui.keepAliveID
import imgui.ImGui.popClipRect
import imgui.ImGui.popId
import imgui.ImGui.popItemWidth
import imgui.ImGui.pushClipRect
import imgui.ImGui.pushId
import imgui.ImGui.pushItemWidth
import imgui.ImGui.style
import imgui.MouseCursor
import imgui.imgui.g
import imgui.internal.*
import kotlin.math.max
import kotlin.math.min
import imgui.internal.ColumnsFlag as Cf

//-------------------------------------------------------------------------
// [SECTION] Widgets: Columns, BeginColumns, EndColumns, etc.
// In the current version, Columns are very weak. Needs to be replaced with a more full-featured system.
//-------------------------------------------------------------------------
interface imgui_widgets_columns {

    /** get current column index
     *  ~GetColumnIndex */
    val columnIndex: Int
        get() = currentWindowRead!!.dc.currentColumns?.current ?: 0

    /** number of columns (what was passed to Columns())
     *  ~GetColumnsCount */
    val columnsCount: Int
        get() = currentWindowRead!!.dc.currentColumns?.count ?: 1

    /** ~GetColumnOffsetFromNorm    */
    infix fun Columns.getOffsetFrom(offsetNorm: Float): Float = offsetNorm * (offMaxX - offMinX)

    /** ~GetColumnNormFromOffset    */
    fun Columns.getNormFrom(offset: Float): Float = offset / (offMaxX - offMinX)

    /** get position of column line (in pixels, from the left side of the contents region). pass -1 to use current
     *  column, otherwise 0..GetColumnsCount() inclusive. column 0 is typically 0.0f    */
    fun getColumnOffset(columnIndex_: Int = -1): Float {

        val window = currentWindowRead!!
        val columns = window.dc.currentColumns ?: return 0f

        val columnIndex = if (columnIndex_ < 0) columns.current else columnIndex_

        val t = columns.columns[columnIndex].offsetNorm
        return lerp(columns.offMinX, columns.offMaxX, t) // xOffset
    }

    /** get column width (in pixels). pass -1 to use current column   */
    fun getColumnWidth(columnIndex_: Int = -1): Float {

        val window = g.currentWindow!!
        val columns = window.dc.currentColumns ?: return contentRegionAvail.x
        val columnIndex = if (columnIndex_ < 0) columns.current else columnIndex_
        return columns.getOffsetFrom(columns.columns[columnIndex + 1].offsetNorm - columns.columns[columnIndex].offsetNorm)
    }

    /** set position of column line (in pixels, from the left side of the contents region). pass -1 to use current column  */
    fun setColumnOffset(columnIndex_: Int, offset_: Float) {
        val window = g.currentWindow!!
        val columns = window.dc.currentColumns!!

        val columnIndex = if (columnIndex_ < 0) columns.current else columnIndex_
        assert(columnIndex < columns.columns.size)

        val preserveWidth = columns.flags hasnt Cf.NoPreserveWidths && columnIndex < columns.count - 1
        val width = if (preserveWidth) getColumnWidthEx(columns, columnIndex, columns.isBeingResized) else 0f

        val offset = if (columns.flags has Cf.NoForceWithinWindow) offset_
        else min(offset_, columns.offMaxX - style.columnsMinSpacing * (columns.count - columnIndex))
        columns.columns[columnIndex].offsetNorm = columns.getNormFrom(offset - columns.offMinX)

        if (preserveWidth)
            setColumnOffset(columnIndex + 1, offset + glm.max(style.columnsMinSpacing, width))
    }

    /** set column width (in pixels). pass -1 to use current column */
    fun setColumnWidth(columnIndex_: Int, width: Float) {
        val window = currentWindowRead!!
        val columns = window.dc.currentColumns!!
        val columnIndex = if (columnIndex_ < 0) columns.current else columnIndex_

        setColumnOffset(columnIndex + 1, getColumnOffset(columnIndex) + width)
    }

    fun pushColumnClipRect(columnIndex_: Int) {

        val window = currentWindowRead!!
        val columns = window.dc.currentColumns!!
        val columnIndex = if (columnIndex_ < 0) columns.current else columnIndex_

        pushClipRect(columns.columns[columnIndex].clipRect.min, columns.columns[columnIndex].clipRect.max, false)
    }

    /** Get into the columns background draw command (which is generally the same draw command as before we called BeginColumns) */
    fun pushColumnsBackground() {
        val window = currentWindowRead!!
        val columns = window.dc.currentColumns!!
        if (columns.count == 1) return
        window.drawList.channelsSetCurrent(0)
        val cmdSize = window.drawList.cmdBuffer.size
        pushClipRect(columns.hostClipRect.min, columns.hostClipRect.max, false)
        assert(cmdSize == window.drawList.cmdBuffer.size) { "Being in channel 0 this should not have created an ImDrawCmd" }
    }

    fun popColumnsBackground() {
        val window = currentWindowRead!!
        val columns = window.dc.currentColumns!!
        if (columns.count == 1) return
        window.drawList.channelsSetCurrent(columns.current + 1)
        popClipRect()
    }

    // findOrCreateColumns is in Window class

    fun getColumnsID(strId: String, columnsCount: Int): ID {

        val window = g.currentWindow!!

        // Differentiate column ID with an arbitrary prefix for cases where users name their columns set the same as another widget.
        // In addition, when an identifier isn't explicitly provided we include the number of columns in the hash to make it uniquer.
        pushId(0x11223347 + if (strId.isNotEmpty()) 0 else columnsCount)
        return window.getId(if (strId.isNotEmpty()) strId else "columns")
                .also { popId() }
    }

    /** setup number of columns. use an identifier to distinguish multiple column sets. close with EndColumns().    */
    fun beginColumns(strId: String = "", columnsCount: Int, flags: ColumnsFlags) {

        val window = currentWindow

        assert(columnsCount >= 1)
        assert(window.dc.currentColumns == null) { "Nested columns are currently not supported" }

        // Acquire storage for the columns set
        val id = getColumnsID(strId, columnsCount)
        val columns = window.findOrCreateColumns(id)
        assert(columns.id == id)
        columns.current = 0
        columns.count = columnsCount
        columns.flags = flags
        window.dc.currentColumns = columns

        val columnPadding = style.itemSpacing.x
        val halfClipExtendX = floor((window.windowPadding.x * 0.5f) max window.windowBorderSize)
        val max1 = window.workRect.max.x + columnPadding - max(columnPadding - window.windowPadding.x, 0f)
        val max2 = window.workRect.max.x + halfClipExtendX
        columns.apply {

            hostCursorPosY = window.dc.cursorPos.y
            hostCursorMaxPosX = window.dc.cursorMaxPos.x
            hostClipRect put window.clipRect
            hostWorkRect put window.workRect

            // Set state for first column
            // We aim so that the right-most column will have the same clipping width as other after being clipped by parent ClipRect
            offMinX = window.dc.indent - columnPadding + max(columnPadding - window.windowPadding.x, 0f)
            offMaxX = max(min(max1, max2) - window.pos.x, columns.offMinX + 1f)
            lineMinY = window.dc.cursorPos.y
            lineMaxY = lineMinY
        }
        window.dc.columnsOffset = 0f
        window.dc.cursorPos.x = (window.pos.x + window.dc.indent + window.dc.columnsOffset).i.f

        // Clear data if columns count changed
        if (columns.columns.isNotEmpty() && columns.columns.size != columnsCount + 1)
            columns.columns.clear()

        // Initialize default widths
        columns.isFirstFrame = columns.columns.isEmpty()
        if (columns.columns.isEmpty())
            for (i in 0..columnsCount)
                columns.columns += ColumnData().apply { offsetNorm = i / columnsCount.f }

        for (n in 0 until columnsCount) {<commit_msg>:construction:       Columns: Made the right-most edge reaches up to the clipping rectangle (removing WindowPadding.x*0.5 worth of asymmetrical/extraneous padding). (#125, #2666)<commit_after>package imgui.imgui.widgets

import glm_.*
import glm_.vec2.Vec2
import imgui.Col
import imgui.ColumnsFlags
import imgui.ID
import imgui.ImGui.buttonBehavior
import imgui.ImGui.contentRegionAvail
import imgui.ImGui.currentWindow
import imgui.ImGui.currentWindowRead
import imgui.ImGui.getColumnOffset
import imgui.ImGui.getOffsetFrom
import imgui.ImGui.io
import imgui.ImGui.isClippedEx
import imgui.ImGui.keepAliveID
import imgui.ImGui.popClipRect
import imgui.ImGui.popId
import imgui.ImGui.popItemWidth
import imgui.ImGui.pushClipRect
import imgui.ImGui.pushId
import imgui.ImGui.pushItemWidth
import imgui.ImGui.style
import imgui.MouseCursor
import imgui.imgui.g
import imgui.internal.*
import kotlin.math.max
import kotlin.math.min
import imgui.internal.ColumnsFlag as Cf

//-------------------------------------------------------------------------
// [SECTION] Widgets: Columns, BeginColumns, EndColumns, etc.
// In the current version, Columns are very weak. Needs to be replaced with a more full-featured system.
//-------------------------------------------------------------------------
interface imgui_widgets_columns {

    /** get current column index
     *  ~GetColumnIndex */
    val columnIndex: Int
        get() = currentWindowRead!!.dc.currentColumns?.current ?: 0

    /** number of columns (what was passed to Columns())
     *  ~GetColumnsCount */
    val columnsCount: Int
        get() = currentWindowRead!!.dc.currentColumns?.count ?: 1

    /** ~GetColumnOffsetFromNorm    */
    infix fun Columns.getOffsetFrom(offsetNorm: Float): Float = offsetNorm * (offMaxX - offMinX)

    /** ~GetColumnNormFromOffset    */
    fun Columns.getNormFrom(offset: Float): Float = offset / (offMaxX - offMinX)

    /** get position of column line (in pixels, from the left side of the contents region). pass -1 to use current
     *  column, otherwise 0..GetColumnsCount() inclusive. column 0 is typically 0.0f    */
    fun getColumnOffset(columnIndex_: Int = -1): Float {

        val window = currentWindowRead!!
        val columns = window.dc.currentColumns ?: return 0f

        val columnIndex = if (columnIndex_ < 0) columns.current else columnIndex_

        val t = columns.columns[columnIndex].offsetNorm
        return lerp(columns.offMinX, columns.offMaxX, t) // xOffset
    }

    /** get column width (in pixels). pass -1 to use current column   */
    fun getColumnWidth(columnIndex_: Int = -1): Float {

        val window = g.currentWindow!!
        val columns = window.dc.currentColumns ?: return contentRegionAvail.x
        val columnIndex = if (columnIndex_ < 0) columns.current else columnIndex_
        return columns.getOffsetFrom(columns.columns[columnIndex + 1].offsetNorm - columns.columns[columnIndex].offsetNorm)
    }

    /** set position of column line (in pixels, from the left side of the contents region). pass -1 to use current column  */
    fun setColumnOffset(columnIndex_: Int, offset_: Float) {
        val window = g.currentWindow!!
        val columns = window.dc.currentColumns!!

        val columnIndex = if (columnIndex_ < 0) columns.current else columnIndex_
        assert(columnIndex < columns.columns.size)

        val preserveWidth = columns.flags hasnt Cf.NoPreserveWidths && columnIndex < columns.count - 1
        val width = if (preserveWidth) getColumnWidthEx(columns, columnIndex, columns.isBeingResized) else 0f

        val offset = if (columns.flags has Cf.NoForceWithinWindow) offset_
        else min(offset_, columns.offMaxX - style.columnsMinSpacing * (columns.count - columnIndex))
        columns.columns[columnIndex].offsetNorm = columns.getNormFrom(offset - columns.offMinX)

        if (preserveWidth)
            setColumnOffset(columnIndex + 1, offset + glm.max(style.columnsMinSpacing, width))
    }

    /** set column width (in pixels). pass -1 to use current column */
    fun setColumnWidth(columnIndex_: Int, width: Float) {
        val window = currentWindowRead!!
        val columns = window.dc.currentColumns!!
        val columnIndex = if (columnIndex_ < 0) columns.current else columnIndex_

        setColumnOffset(columnIndex + 1, getColumnOffset(columnIndex) + width)
    }

    fun pushColumnClipRect(columnIndex_: Int) {

        val window = currentWindowRead!!
        val columns = window.dc.currentColumns!!
        val columnIndex = if (columnIndex_ < 0) columns.current else columnIndex_

        pushClipRect(columns.columns[columnIndex].clipRect.min, columns.columns[columnIndex].clipRect.max, false)
    }

    /** Get into the columns background draw command (which is generally the same draw command as before we called BeginColumns) */
    fun pushColumnsBackground() {
        val window = currentWindowRead!!
        val columns = window.dc.currentColumns!!
        if (columns.count == 1) return
        window.drawList.channelsSetCurrent(0)
        val cmdSize = window.drawList.cmdBuffer.size
        pushClipRect(columns.hostClipRect.min, columns.hostClipRect.max, false)
        assert(cmdSize == window.drawList.cmdBuffer.size) { "Being in channel 0 this should not have created an ImDrawCmd" }
    }

    fun popColumnsBackground() {
        val window = currentWindowRead!!
        val columns = window.dc.currentColumns!!
        if (columns.count == 1) return
        window.drawList.channelsSetCurrent(columns.current + 1)
        popClipRect()
    }

    // findOrCreateColumns is in Window class

    fun getColumnsID(strId: String, columnsCount: Int): ID {

        val window = g.currentWindow!!

        // Differentiate column ID with an arbitrary prefix for cases where users name their columns set the same as another widget.
        // In addition, when an identifier isn't explicitly provided we include the number of columns in the hash to make it uniquer.
        pushId(0x11223347 + if (strId.isNotEmpty()) 0 else columnsCount)
        return window.getId(if (strId.isNotEmpty()) strId else "columns")
                .also { popId() }
    }

    /** setup number of columns. use an identifier to distinguish multiple column sets. close with EndColumns().    */
    fun beginColumns(strId: String = "", columnsCount: Int, flags: ColumnsFlags) {

        val window = currentWindow

        assert(columnsCount >= 1)
        assert(window.dc.currentColumns == null) { "Nested columns are currently not supported" }

        // Acquire storage for the columns set
        val id = getColumnsID(strId, columnsCount)
        val columns = window.findOrCreateColumns(id)
        assert(columns.id == id)
        columns.current = 0
        columns.count = columnsCount
        columns.flags = flags
        window.dc.currentColumns = columns

        val columnPadding = style.itemSpacing.x
        val halfClipExtendX = floor((window.windowPadding.x * 0.5f) max window.windowBorderSize)
        val max1 = window.workRect.max.x + columnPadding - max(columnPadding - window.windowPadding.x, 0f)
        val max2 = window.workRect.max.x + halfClipExtendX
        columns.apply {

            hostCursorPosY = window.dc.cursorPos.y
            hostCursorMaxPosX = window.dc.cursorMaxPos.x
            hostClipRect put window.clipRect
            hostWorkRect put window.workRect

            // Set state for first column
            // We aim so that the right-most column will have the same clipping width as other after being clipped by parent ClipRect
            offMinX = window.dc.indent - columnPadding + max(columnPadding - window.windowPadding.x, 0f)
            offMaxX = max(min(max1, max2) - window.pos.x, columns.offMinX + 1f)
            lineMinY = window.dc.cursorPos.y
            lineMaxY = lineMinY
        }

        // Clear data if columns count changed
        if (columns.columns.isNotEmpty() && columns.columns.size != columnsCount + 1)
            columns.columns.clear()

        // Initialize default widths
        columns.isFirstFrame = columns.columns.isEmpty()
        if (columns.columns.isEmpty())
            for (i in 0..columnsCount)
                columns.columns += ColumnData().apply { offsetNorm = i / columnsCount.f }

        for (n in 0 until columnsCount) {
{'fraction_non_alphanumeric': 0.10542458503728651, 'fraction_numerical': 0.007096463796006735, 'mean_word_length': 2.7452702702702703, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 5, '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': '6616113', 'n_tokens_mistral': 4656, 'n_tokens_neox': 4461, 'n_words': 1337}