Fix text color on white background.

Fix text color on white background.

${
import math

def my_floor(num):
    return int(math.floor(num))

def my_ceil(num):
    return int(math.ceil(num))

# Should we set the line width in the engine to 2.25, and draw non pixel aligned lines?
# Are these already the correct sizes for the XO?

# These sizes need to be sanity checked ...
if theme == "sugar-xo":
    xo = True
    line_width = 2.0        # 2.25px, rounded down
    thick_line_width = 3.5  # 3.5
    subcell_size = 15
    icon_base = 11
    bullet_size = 9.5
    font_height = 24
    default_padding = 6
    toolbutton_padding = 9
else: # About 72% of the XO size, adjusted so that eg. toolbuttons work
    xo = False
    line_width = 2.0            # 1.62 rounded up
    thick_line_width = 3.0      # 2.52
    subcell_size = 11           # 10.8
    icon_base = 8               # 7.92
    bullet_size = 6.5           # 6.84
    # This is a guess on the font size (Sans 10 at 96 DPI)
    font_height = 17
    default_padding = 4         # 4.32
    toolbutton_padding = 6      # 7.68

radio_size = my_floor(subcell_size + bullet_size + line_width)
scale_slider_width = my_floor(2 * subcell_size + line_width)
thickness = my_ceil(line_width)

# Colors:

black = '"#000000"'
toolbar_grey = '"#282828"'
button_grey = '"#808080"'
selection_grey = '"#A6A6A6"'
panel_grey = '"#C0C0C0"'
text_field_grey = '"#E5E5E5"'
white = '"#FFFFFF"'

}
${
icon_small = icon_base * 3
icon_large = icon_base * 5

small_icons = [ "gtk-menu", "gtk-dnd", "gtk-small-toolbar", "gtk-button" ]
large_icons = [ "gtk-large-toolbar" ]

icon_sizes = []
for icon in small_icons:
    icon_sizes += [icon + "=" + str(icon_small) + ',' + str(icon_small)]
for icon in large_icons:
    icon_sizes += [icon + "=" + str(icon_large) + ',' + str(icon_large)]

icon_sizes = ":".join(icon_sizes)

}
gtk-icon-sizes="$icon_sizes"

style "default"
{
    # Will be overriden in some widgets
    color["focus_line"] = $white

    bg[NORMAL] = $button_grey
    bg[PRELIGHT] = $button_grey
    bg[ACTIVE] = $white
    bg[SELECTED] = $text_field_grey

    fg[NORMAL]        = $black
    fg[ACTIVE]        = $black
    fg[SELECTED]      = $white
    fg[PRELIGHT]      = $white

    text[NORMAL] = $black # button_grey? 1. need to patch GTK+ to use ACTIVE when focused, 2. what color should this really be?
    text[ACTIVE] = $black
    text[SELECTED] = $black
    text[PRELIGHT] = $black

    base[NORMAL] = $text_field_grey
    base[ACTIVE] = $white
    base[SELECTED] = $selection_grey
    base[PRELIGHT] = $white

    fg[INSENSITIVE] = $button_grey
    text[INSENSITIVE] = $button_grey

    xthickness = $thickness
    ythickness = $thickness

    # A lot of these will probably need to be changed, but this has to
    # be done when the exact sizes are known
    GtkWidget::interior-focus = 0
    GtkWidget::focus-line-width = 1   # Prevents some drawing glitches
    GtkWidget::focus-padding = 0
    # 0.05 works good for both the sugar and sugar-xo themes
    GtkWidget::cursor-aspect-ratio = 0.05

    GtkWidget::wide-separators = 0
    GtkWidget::separator-height = $thickness
    GtkWidget::separator-width = $thickness

    GtkWidget::scroll-arrow-hlength = $subcell_size
    GtkWidget::scroll-arrow-vlength = $subcell_size

    GtkRange::activate-slider = 1

    # We fake the default border in the theme
    GtkButton::default-border = { 0, 0, 0, 0 }
    GtkButton::default-outside-border = { 0, 0, 0, 0 }
    GtkButton::image-spacing = $subcell_size

    GtkScrolledWindow::scrollbar-spacing = 0

    GtkExpander::expander-size = 24
    GtkExpander::expander-spacing = 2     # XXX

    GtkTreeView::expander-size = 24

    GtkArrow::arrow-size = 1.0

    GtkToolbar::shadow-type = GTK_SHADOW_NONE
    GtkToolbar::space-size = $(2*subcell_size)

    GtkProgressBar::min-horizontal-bar-height = $subcell_size
    GtkProgressBar::min-vertical-bar-width = $subcell_size

    GtkButtonBox::child-min-height = $(3*subcell_size)
    GtkButtonBox::child-min-width = $(3*subcell_size)
    GtkButtonBox::child-internal-pad-x = 0
    GtkButtonBox::child-internal-pad-y = 0

    engine "sugar" {
        line_width = $line_width
        thick_line_width = $thick_line_width
        subcell_size = $subcell_size

        max_radius = $( 2*subcell_size )
    }
}

#############################################################
# Styles that set default background/foreground colors
#
#  We almost always need two styles because of the X windows.
#  For example bg[NORMAL] of a window (or eventbox) needs to
#  be set to be the correct window color so that X fills the
#  window correctly from the beginning, and it does not
#  flash in the wrong color.
#############################################################

style "window"
{
    bg[NORMAL] = $panel_grey
}

style "window-child"
{
    bg[INSENSITIVE] = $panel_grey
    base[INSENSITIVE] = $panel_grey

    fg[NORMAL] = $black

    engine "sugar" {
        parent_fg_color = $black
        parent_bg_color = $panel_grey
    }
}

style "white-bg"
{
    bg[NORMAL] = $white
}

style "white-bg-child"
{
    bg[INSENSITIVE] = $white
    base[INSENSITIVE] = $white

    fg[NORMAL] = $black

    engine "sugar" {
        parent_fg_color = $black
        parent_bg_color = $white
    }
}

style "black-bg"
{
    bg[NORMAL] = $black
}

style "black-bg-child"
{
    bg[INSENSITIVE] = $black
    base[INSENSITIVE] = $black

    fg[NORMAL] = $white

    engine "sugar" {
        parent_fg_color = $white
        parent_bg_color = $black
    }
}

style "groupbox-panel"
{
    bg[NORMAL] = $selection_grey
}

style "groupbox-panel-child"
{
    bg[INSENSITIVE] = $selection_grey
    base[INSENSITIVE] = $selection_grey

    fg[NORMAL] = $black

    engine "sugar" {
        parent_fg_color = $black
        parent_bg_color = $selection_grey
    }
}

style "groupbox-palette"
{
    bg[NORMAL] = $toolbar_grey
}

style "groupbox-palette-child"
{
    bg[INSENSITIVE] = $toolbar_grey
    base[INSENSITIVE] = $toolbar_grey

    fg[NORMAL] = $white

    engine "sugar" {
        parent_fg_color = $white
        parent_bg_color = $toolbar_grey
    }
}

style "menu"
{
    bg[NORMAL] = $black
    # Used for the arrow colour
    fg[NORMAL]   = $white
    fg[PRELIGHT] = $white
    bg[ACTIVE] = $button_grey

    ${# This is just the exact reverse of what is going on inside GTK+ ...}
    GtkMenu::scroll-arrow-vlength = $(my_floor(subcell_size/0.7 + 2*thickness))
    GtkMenu::horizontal-padding = 0
    GtkMenu::vertical-padding   = 0
    # This means the outline of the submenu overlaps with a palette.
    # However in the case of two normal menus, they are next to each other.
    # It is not possible to be smarter about this, because the style comes from
    # the submenu.
    GtkMenu::horizontal-offset  = 0
    GtkMenu::vertical-offset    = 0

    xthickness = $thickness
    ythickness = $thickness
}

style "palette-menu" = "menu"
{
    xthickness = 0
    ythickness = $subcell_size
}

# Can this all be moved in the menuitem style?
style "menu-child"
{
    color["bg_color"] = $black

    fg[NORMAL]   = $white
    fg[PRELIGHT] = $white

    bg[NORMAL] = $button_grey

    bg[INSENSITIVE] = $black
    base[INSENSITIVE] = $black

    engine "sugar" {
        parent_fg_color = $white
        parent_bg_color = $black
    }
}

#########################################################
#########################################################

style "textview"
{
    # We always use white here
    base[NORMAL]      = $white

    GtkTextView::interior-focus = 1
}

style "scrollbar"
{
    GtkScrollbar::slider-width = $subcell_size
    GtkScrollbar::trough-border = 0
    GtkScrollbar::stepper-spacing = 0
    GtkScrollbar::min-slider-length = $(3*subcell_size)
    GtkScrollbar::has-forward-stepper = 0
    GtkScrollbar::has-backward-stepper = 0
    GtkScrollbar::has-secondary-forward-stepper = 0
    GtkScrollbar::has-secondary-backward-stepper = 0

    # Hack for mozilla as it does not obey the above style properties ...
    # Really, mozilla should be fixed ...
    GtkScrollbar::stepper-size = 1
}

# hints for the trough padding hacks
# We cannot go trough GTK+, as we don't want a padding on all sides, but only one
# If we wanted padding on all sides, trough-border would work great.
style "hscrollbar" = "scrollbar"
{
    engine "sugar" {
        hint = "hscrollbar"
        scrollbar_border = $thickness
    }
}

style "vscrollbar" = "scrollbar"
{
    engine "sugar" {
        hint = "vscrollbar"
        scrollbar_border = $thickness
    }
}

style "hscrollbar-scrolled-window"
{
    GtkScrollbar::slider-width = $(subcell_size - thickness)
    GtkScrollbar::stepper-spacing = $thickness
    GtkScrollbar::has-forward-stepper = 1
    GtkScrollbar::has-backward-stepper = 1
    GtkScrollbar::stepper-size = 0

    engine "sugar" {
        hint = "hscrollbar-scrolled-window"
    }
}

style "vscrollbar-scrolled-window"
{
    GtkScrollbar::slider-width = $(subcell_size - thickness)
    GtkScrollbar::stepper-spacing = $thickness
    GtkScrollbar::has-forward-stepper = 1
    GtkScrollbar::has-backward-stepper = 1
    GtkScrollbar::stepper-size = 0

    engine "sugar" {
        hint = "vscrollbar-scrolled-window"
    }
}

style "scale"
{
    GtkWidget::focus-line-width = 0

    bg[NORMAL] = $button_grey

    # "square" slider (really round of course)
    # Same as indicator-size?
    GtkRange::slider-width = $scale_slider_width
    GtkScale::slider-length = $scale_slider_width
    GtkRange::trough-border = 0
    GtkRange::stepper-spacing = 0
    GtkRange::trough-side-details = 1
}

# hints for the trough sizing hacks
style "hscale" = "scale"
{
    engine "sugar" {
        hint = "hscale"
    }
}

style "vscale" = "scale"
{
    engine "sugar" {
        hint = "vscale"
    }
}

style "spinbutton"
{
    bg[NORMAL]  = $button_grey
    bg[ACTIVE]  = $white
    fg[NORMAL]  = $white
    fg[ACTIVE]  = $black

    ${ spin_ythickness = my_ceil(0.2 * (subcell_size*3.0/2.0 - thickness) + thickness) }
    ${ spin_xthickness = subcell_size }

    # small inner border and a large x/ythickness for entries
    # to reduce the number of hacks needed :-)
    xthickness = $spin_xthickness
    ythickness = $spin_ythickness
    GtkWidget::focus-line-width = 0

    # This tries to get a height of exactly 45 pixel for the entry.
    GtkEntry::inner-border = { $(max(subcell_size - spin_xthickness, 0)), $(max(subcell_size - spin_xthickness, 0)),
                               $(max(my_ceil((3*subcell_size - font_height - spin_ythickness*2)/2.0),0)), $(max(my_floor((3*subcell_size - font_height - spin_ythickness*2)/2.0), 0)) }

    engine "sugar" {
        hint = "spinbutton"
    }
}

style "frame"
{
    bg[NORMAL] = $toolbar_grey

    engine "sugar" {
        parent_bg_color = $toolbar_grey
        parent_fg_color = $white
    }
}

style "notebook-tab"
{
    bg[ACTIVE] = $button_grey
    fg[ACTIVE] = $white
}

style "notebook-panel"
{
    GtkNotebook::tab-overlap = -2
    GtkNotebook::tab-curvature = $default_padding

    xthickness = 0
    ythickness = 0

    bg[NORMAL] = $selection_grey
}

style "toolbox-notebook"
{
    GtkNotebook::tab-overlap = -2

    xthickness = 0
    ythickness = 0
}

style "toolbutton"
{
    xthickness = 0
    ythickness = 0
    GtkButton::inner-border = { $toolbutton_padding,
                                $toolbutton_padding,
                                $toolbutton_padding,
                                $toolbutton_padding }
    GtkWidget::focus-padding = 0

    bg[PRELIGHT] = $black
    bg[ACTIVE] = $button_grey
    bg[NORMAL] = $black

    fg[NORMAL] = $white
    fg[ACTIVE] = $white
    fg[PRELIGHT] = $white

    engine "sugar" {
        max_radius = 5.0
        fake_padding = $default_padding
    }
}

style "separatortoolbutton"
{
    # The sizing is handled in the engine.
    bg[NORMAL] = $button_grey
}

style "toolbar"
{
    xthickness = 0
    ythickness = 0

    bg[NORMAL] = $toolbar_grey
    bg[INSENSITIVE] = $toolbar_grey
    base[INSENSITIVE] = $toolbar_grey

    engine "sugar" {
        parent_fg_color = $white
        parent_bg_color = $toolbar_grey
    }
}

style "toolbox"
{
    fg[NORMAL] = $white
    fg[ACTIVE] = $white

    bg[NORMAL] = $toolbar_grey
    bg[INSENSITIVE] = $toolbar_grey
    base[INSENSITIVE] = $toolbar_grey

    engine "sugar" {
        parent_fg_color = $white
        parent_bg_color = $toolbar_grey
    }
}

style "panel"
{
    bg[NORMAL] = $panel_grey
    fg[NORMAL] = $black
}

style "entry"
{
    color["focus_line"] = $text_field_grey

    ${ entry_ythickness = my_ceil(0.2 * (subcell_size*3.0/2.0 - thickness) + thickness) }
    ${ entry_xthickness = my_ceil(0.32 * (subcell_size*3.0/2.0 - thickness) + thickness) }

    # small inner border and a large x/ythickness for entries
    # to reduce the number of hacks needed :-)
    xthickness = $entry_xthickness
    ythickness = $entry_ythickness
    GtkWidget::focus-line-width = 0

    # This tries to get a height of exactly 45 pixel for the entry.
    GtkEntry::inner-border = { $(max(subcell_size - entry_xthickness, 0)), $(max(subcell_size - entry_xthickness, 0)),
                               $(max(my_ceil((3*subcell_size - font_height - entry_ythickness*2)/2.0),0)), $(max(my_floor((3*subcell_size - font_height - entry_ythickness*2)/2.0), 0)) }
}

style "button"
{
    ${ border = max(0, my_ceil((3*subcell_size/2.0 - icon_small / 2.0))) }
    # It would be nicer to just set the inner-border, but that does not work
    # for combo boxes ... The combobox ignores it, so set it to 0px
    # See http://bugzilla.gnome.org/show_bug.cgi?id=485762

    GtkButton::inner-border = { 0, 0, 0, 0 }

    # So set the x/ythickness; y-padding is $subcell_size overall
    xthickness = $(border)
    ythickness = $(border)

    fg[NORMAL] = $white
    fg[ACTIVE] = $black

    bg[NORMAL] = $button_grey
}

style "combobox"
{
    # "Disable" the ACTIVE state of the button, it only creates problems :-(
    bg[ACTIVE] = $button_grey
    fg[ACTIVE] = $white

    # Work around GTK+ bug #382646
    text[NORMAL]      = $white
    text[ACTIVE]      = $white
    text[PRELIGHT]    = $white
}

style "comboboxentry"
{
    # Copied from the "default" style. Part of the workaround for bug #382646.
    text[NORMAL] = $black
    text[ACTIVE] = $black
    text[SELECTED] = $black
    text[PRELIGHT] = $black

    # It just happens that the entry xthickness works good for the button,
    # which simplefies matters a bit.
    xthickness = $entry_xthickness

    engine "sugar" {
        hint = "comboboxentry"
    }
}

style "checkbutton"
{
    base[NORMAL]      = $white
    base[PRELIGHT]    = $white
    base[ACTIVE]      = $text_field_grey

    text[PRELIGHT]    = $toolbar_grey
    text[NORMAL]      = $toolbar_grey
    text[ACTIVE]      = $toolbar_grey

    # I won't get the exact sizing, but this should be pretty close
    GtkCheckButton::indicator-size = $radio_size
    GtkCheckButton::indicator-spacing = 3
    GtkWidget::focus-padding = 3

    engine "sugar" {
        # Reset the colors to the normal color again
        # as they were overriden by the button style
        fg[NORMAL]        = parent_fg_color
        fg[PRELIGHT]      = parent_fg_color
        fg[ACTIVE]        = parent_fg_color
    }
}

style "progressbar"
{
    xthickness = 0
    ythickness = 0
}

style "menuitem"
{
    GtkMenuItem::horizontal-padding = 0
    GtkMenuItem::arrow-spacing = $subcell_size
    GtkMenuItem::toggle-spacing = $subcell_size

    bg[PRELIGHT] = $button_grey

    # Work around bug #382646
    text[PRELIGHT]    = $white
    text[NORMAL]      = $white
    text[ACTIVE]      = $white

    xthickness = $subcell_size
    ythickness = $((subcell_size * 3 - font_height) / 2)
}

style "checkmenuitem"
{
    GtkCheckMenuItem::indicator-size = $radio_size
    GtkMenuItem::toggle-spacing = $(subcell_size * 2 / 3)

    ythickness = $((subcell_size * 3 - max(font_height, subcell_size * 2 / 3)) / 2)

    # This is only there because of bug #382646 ...
    base[NORMAL]      = $white
    base[PRELIGHT]    = $white
    base[ACTIVE]      = $text_field_grey

    text[PRELIGHT]    = $toolbar_grey
    text[NORMAL]      = $toolbar_grey
    text[ACTIVE]      = $toolbar_grey
}

style "imagemenuitem"
{
    # Assume a $(icon_small)px image and height of $(4*subcell_size)
    ythickness = $(max(0, (3*subcell_size - icon_small) / 2))
}

style "separatormenuitem"
{
    GtkWidget::wide-separators = 1
    GtkWidget::separator-height = $(2*subcell_size)

    ythickness = 0
    xthickness = 0
}

style "trayicon"
{
    bg[PRELIGHT] = $black
    bg[ACTIVE] = $button_grey
}

style "parent-bg"
{
    engine "sugar" {
        bg[NORMAL] = parent_bg_color
        bg[INSENSITIVE] = parent_bg_color
    }
}

####################################################################
# Default style, setting some generic options and style properties
####################################################################
class "GtkWidget" style "default"

####################################################################
# Styles that apply the different background (and foreground) colors
####################################################################

# This one should probably be the default (ie. no window-child style)
widget_class "<GtkWindow>"               style "window"
widget_class "<GtkWindow>*"              style "window-child"

widget_class "*<SugarAlert>"               style "black-bg"
widget_class "*<SugarAlert>*"              style "black-bg-child"

widget_class "*<SugarSectionView>"       style "white-bg"
widget_class "*<SugarSectionView>*"      style "white-bg-child"

# The notebook is very high, so that everything is overriden
# Only the color of the tab labels needs to be modified inside the
# notebooks in this style (and the widget itself).
# Assume that there is either just a normal label in the notebook tab, or
# it is inside a GtkBox (H- or VBox) together with eg. a close button.
widget_class "*<GtkNotebook>"                        style "notebook-tab"
widget_class "*<GtkNotebook>.<GtkLabel>"             style "notebook-tab"
widget_class "*<GtkNotebook>.<GtkBox>.<GtkLabel>"    style "notebook-tab"

# SugarPalette and Menu
widget_class "*<GtkMenu>"               style "menu"
widget_class "<SugarPalette>"           style "menu"
widget_class "<SugarPalette>.*"         style "menu-child"
widget_class "<SugarPalette>*<GtkMenu>" style "palette-menu"
widget_class "*<GtkMenuShell>.*"        style "menu-child"

# SugarFrameWindow
widget_class "*<SugarFrameWindow>*"    style "frame"

# SugarPanel
widget_class "*<SugarPanel>*"          style "panel"

# GroupBoxes (don't set bg[NORMAL] on the widget itself)
widget_class "<GtkWindow>*<SugarGroupBox>*"   style "groupbox-panel-child"

widget_class "<GtkWindow>*<GtkNotebook>*"   style "groupbox-panel-child"
widget_class "<GtkWindow>*<GtkNotebook>"    style "notebook-panel"

widget_class "<SugarPalette>*<SugarGroupBox>*"   style "groupbox-palette-child"

# SugarToolbox
#widget_class "*<SugarToolbox>" style "toolbox"
#widget_class "*<SugarToolbox>*" style "toolbox-child"
#widget_class "*<SugarToolbox>*<GtkEventBox>" style "toolbox"
#widget_class "*<SugarToolbox>*<GtkLayout>"   style "toolbox"
widget_class "*<SugarToolbox>*"        style "toolbox"
widget_class "*<GtkToolbar>*"          style "toolbox"
widget_class "*<SugarToolbox>.<GtkNotebook>" style "toolbox-notebook"

####################################################################
# Normal widget styles, using the above things
####################################################################
# The following only uses widget_class matches to get the priority
# right. An alternative would be to lower the priority of the
# background matches (which need widget_class) to eg. "application"

widget_class "*<GtkMenuItem>*"            style "menuitem"
widget_class "*<GtkCheckMenuItem>"        style "checkmenuitem"
widget_class "*<GtkImageMenuItem>"        style "imagemenuitem"
widget_class "*<GtkSeparatorMenuItem>*"   style "separatormenuitem"

# Buttons and Combos
widget_class "*<GtkButton>*"           style "button"
widget_class "*<GtkCheckButton>*"      style "checkbutton"
widget_class "*<GtkComboBox>*"         style "combobox"
widget_class "*<GtkComboBoxEntry>*"    style "comboboxentry"
widget_class "*<GtkCombo>*"            style "comboboxentry"

# Entries
widget_class "*<GtkEntry>"       style "entry"
widget_class "*<GtkSpinButton>"  style "spinbutton"
widget_class "*<GtkTextView>"    style "textview"

# Misc widgets
widget_class "*<GtkHScrollbar>"  style "hscrollbar"
widget_class "*<GtkVScrollbar>"  style "vscrollbar"
widget_class "*<GtkHScale>"      style "hscale"
widget_class "*<GtkVScale>"      style "vscale"
widget_class "*<GtkProgressBar>" style "progressbar"

# Scrolled window scrollbars
widget_class "*<GtkScrolledWindow>.<GtkVScrollbar>" style "vscrollbar-scrolled-window"
widget_class "*<GtkScrolledWindow>.<GtkHScrollbar>" style "hscrollbar-scrolled-window"

# Toolbar
widget_class "*<GtkToolButton>*"          style "toolbutton"
widget_class "*<GtkSeparatorToolItem>*"   style "separatortoolbutton"
widget_class "*<GtkToolbar>"              style "toolbar"

# Tray
widget_class "*<SugarTrayIcon>*" style "trayicon"

# Widgets that should get the background color from the parent
widget_class "*<GtkEventBox>"        style "parent-bg"
widget_class "*<GtkLayout>"          style "parent-bg"
widget_class "*<GtkViewport>"        style "parent-bg"
widget_class "*<GtkDrawingArea>"     style "parent-bg"
widget_class "*<GtkScrolledWindow>"  style "parent-bg"

${
import math

def my_floor(num):
    return int(math.floor(num))

def my_ceil(num):
    return int(math.ceil(num))

# Should we set the line width in the engine to 2.25, and draw non pixel aligned lines?
# Are these already the correct sizes for the XO?

# These sizes need to be sanity checked ...
if theme == "sugar-xo":
    xo = True
    line_width = 2.0        # 2.25px, rounded down
    thick_line_width = 3.5  # 3.5
    subcell_size = 15
    icon_base = 11
    bullet_size = 9.5
    font_height = 24
    default_padding = 6
    toolbutton_padding = 9
else: # About 72% of the XO size, adjusted so that eg. toolbuttons work
    xo = False
    line_width = 2.0            # 1.62 rounded up
    thick_line_width = 3.0      # 2.52
    subcell_size = 11           # 10.8
    icon_base = 8               # 7.92
    bullet_size = 6.5           # 6.84
    # This is a guess on the font size (Sans 10 at 96 DPI)
    font_height = 17
    default_padding = 4         # 4.32
    toolbutton_padding = 6      # 7.68

radio_size = my_floor(subcell_size + bullet_size + line_width)
scale_slider_width = my_floor(2 * subcell_size + line_width)
thickness = my_ceil(line_width)

# Colors:

black = '"#000000"'
toolbar_grey = '"#282828"'
button_grey = '"#808080"'
selection_grey = '"#A6A6A6"'
panel_grey = '"#C0C0C0"'
text_field_grey = '"#E5E5E5"'
white = '"#FFFFFF"'

}
${
icon_small = icon_base * 3
icon_large = icon_base * 5

small_icons = [ "gtk-menu", "gtk-dnd", "gtk-small-toolbar", "gtk-button" ]
large_icons = [ "gtk-large-toolbar" ]

icon_sizes = []
for icon in small_icons:
    icon_sizes += [icon + "=" + str(icon_small) + ',' + str(icon_small)]
for icon in large_icons:
    icon_sizes += [icon + "=" + str(icon_large) + ',' + str(icon_large)]

icon_sizes = ":".join(icon_sizes)

}
gtk-icon-sizes="$icon_sizes"

style "default"
{
    # Will be overriden in some widgets
    color["focus_line"] = $white

    bg[NORMAL] = $button_grey
    bg[PRELIGHT] = $button_grey
    bg[ACTIVE] = $white
    bg[SELECTED] = $text_field_grey

    fg[NORMAL]        = $black
    fg[ACTIVE]        = $black
    fg[SELECTED]      = $white
    fg[PRELIGHT]      = $white

    text[NORMAL] = $black # button_grey? 1. need to patch GTK+ to use ACTIVE when focused, 2. what color should this really be?
    text[ACTIVE] = $black
    text[SELECTED] = $black
    text[PRELIGHT] = $black

    base[NORMAL] = $text_field_grey
    base[ACTIVE] = $white
    base[SELECTED] = $selection_grey
    base[PRELIGHT] = $white

    fg[INSENSITIVE] = $button_grey
    text[INSENSITIVE] = $button_grey

    xthickness = $thickness
    ythickness = $thickness

    # A lot of these will probably need to be changed, but this has to
    # be done when the exact sizes are known
    GtkWidget::interior-focus = 0
    GtkWidget::focus-line-width = 1   # Prevents some drawing glitches
    GtkWidget::focus-padding = 0
    # 0.05 works good for both the sugar and sugar-xo themes
    GtkWidget::cursor-aspect-ratio = 0.05

    GtkWidget::wide-separators = 0
    GtkWidget::separator-height = $thickness
    GtkWidget::separator-width = $thickness

    GtkWidget::scroll-arrow-hlength = $subcell_size
    GtkWidget::scroll-arrow-vlength = $subcell_size

    GtkRange::activate-slider = 1

    # We fake the default border in the theme
    GtkButton::default-border = { 0, 0, 0, 0 }
    GtkButton::default-outside-border = { 0, 0, 0, 0 }
    GtkButton::image-spacing = $subcell_size

    GtkScrolledWindow::scrollbar-spacing = 0

    GtkExpander::expander-size = 24
    GtkExpander::expander-spacing = 2     # XXX

    GtkTreeView::expander-size = 24

    GtkArrow::arrow-size = 1.0

    GtkToolbar::shadow-type = GTK_SHADOW_NONE
    GtkToolbar::space-size = $(2*subcell_size)

    GtkProgressBar::min-horizontal-bar-height = $subcell_size
    GtkProgressBar::min-vertical-bar-width = $subcell_size

    GtkButtonBox::child-min-height = $(3*subcell_size)
    GtkButtonBox::child-min-width = $(3*subcell_size)
    GtkButtonBox::child-internal-pad-x = 0
    GtkButtonBox::child-internal-pad-y = 0

    engine "sugar" {
        line_width = $line_width
        thick_line_width = $thick_line_width
        subcell_size = $subcell_size

        max_radius = $( 2*subcell_size )
    }
}

#############################################################
# Styles that set default background/foreground colors
#
#  We almost always need two styles because of the X windows.
#  For example bg[NORMAL] of a window (or eventbox) needs to
#  be set to be the correct window color so that X fills the
#  window correctly from the beginning, and it does not
#  flash in the wrong color.
#############################################################

style "window"
{
    bg[NORMAL] = $panel_grey
}

style "window-child"
{
    bg[INSENSITIVE] = $panel_grey
    base[INSENSITIVE] = $panel_grey

    fg[NORMAL] = $black

    engine "sugar" {
        parent_fg_color = $black
        parent_bg_color = $panel_grey
    }
}

style "white-bg"
{
    bg[NORMAL] = $white
}

style "white-bg-child"
{
    bg[INSENSITIVE] = $white
    base[INSENSITIVE] = $white

    fg[NORMAL] = $white

    engine "sugar" {
        parent_fg_color = $black
        parent_bg_color = $white
    }
}

style "black-bg"
{
    bg[NORMAL] = $black
}

style "black-bg-child"
{
    bg[INSENSITIVE] = $black
    base[INSENSITIVE] = $black

    fg[NORMAL] = $white

    engine "sugar" {
        parent_fg_color = $white
        parent_bg_color = $black
    }
}

style "groupbox-panel"
{
    bg[NORMAL] = $selection_grey
}

style "groupbox-panel-child"
{
    bg[INSENSITIVE] = $selection_grey
    base[INSENSITIVE] = $selection_grey

    fg[NORMAL] = $black

    engine "sugar" {
        parent_fg_color = $black
        parent_bg_color = $selection_grey
    }
}

style "groupbox-palette"
{
    bg[NORMAL] = $toolbar_grey
}

style "groupbox-palette-child"
{
    bg[INSENSITIVE] = $toolbar_grey
    base[INSENSITIVE] = $toolbar_grey

    fg[NORMAL] = $white

    engine "sugar" {
        parent_fg_color = $white
        parent_bg_color = $toolbar_grey
    }
}

style "menu"
{
    bg[NORMAL] = $black
    # Used for the arrow colour
    fg[NORMAL]   = $white
    fg[PRELIGHT] = $white
    bg[ACTIVE] = $button_grey

    ${# This is just the exact reverse of what is going on inside GTK+ ...}
    GtkMenu::scroll-arrow-vlength = $(my_floor(subcell_size/0.7 + 2*thickness))
    GtkMenu::horizontal-padding = 0
    GtkMenu::vertical-padding   = 0
    # This means the outline of the submenu overlaps with a palette.
    # However in the case of two normal menus, they are next to each other.
    # It is not possible to be smarter about this, because the style comes from
    # the submenu.
    GtkMenu::horizontal-offset  = 0
    GtkMenu::vertical-offset    = 0

    xthickness = $thickness
    ythickness = $thickness
}

style "palette-menu" = "menu"
{
    xthickness = 0
    ythickness = $subcell_size
}

# Can this all be moved in the menuitem style?
style "menu-child"
{
    color["bg_color"] = $black

    fg[NORMAL]   = $white
    fg[PRELIGHT] = $white

    bg[NORMAL] = $button_grey

    bg[INSENSITIVE] = $black
    base[INSENSITIVE] = $black

    engine "sugar" {
        parent_fg_color = $white
        parent_bg_color = $black
    }
}

#########################################################
#########################################################

style "textview"
{
    # We always use white here
    base[NORMAL]      = $white

    GtkTextView::interior-focus = 1
}

style "scrollbar"
{
    GtkScrollbar::slider-width = $subcell_size
    GtkScrollbar::trough-border = 0
    GtkScrollbar::stepper-spacing = 0
    GtkScrollbar::min-slider-length = $(3*subcell_size)
    GtkScrollbar::has-forward-stepper = 0
    GtkScrollbar::has-backward-stepper = 0
    GtkScrollbar::has-secondary-forward-stepper = 0
    GtkScrollbar::has-secondary-backward-stepper = 0

    # Hack for mozilla as it does not obey the above style properties ...
    # Really, mozilla should be fixed ...
    GtkScrollbar::stepper-size = 1
}

# hints for the trough padding hacks
# We cannot go trough GTK+, as we don't want a padding on all sides, but only one
# If we wanted padding on all sides, trough-border would work great.
style "hscrollbar" = "scrollbar"
{
    engine "sugar" {
        hint = "hscrollbar"
        scrollbar_border = $thickness
    }
}

style "vscrollbar" = "scrollbar"
{
    engine "sugar" {
        hint = "vscrollbar"
        scrollbar_border = $thickness
    }
}

style "hscrollbar-scrolled-window"
{
    GtkScrollbar::slider-width = $(subcell_size - thickness)
    GtkScrollbar::stepper-spacing = $thickness
    GtkScrollbar::has-forward-stepper = 1
    GtkScrollbar::has-backward-stepper = 1
    GtkScrollbar::stepper-size = 0

    engine "sugar" {
        hint = "hscrollbar-scrolled-window"
    }
}

style "vscrollbar-scrolled-window"
{
    GtkScrollbar::slider-width = $(subcell_size - thickness)
    GtkScrollbar::stepper-spacing = $thickness
    GtkScrollbar::has-forward-stepper = 1
    GtkScrollbar::has-backward-stepper = 1
    GtkScrollbar::stepper-size = 0

    engine "sugar" {
        hint = "vscrollbar-scrolled-window"
    }
}

style "scale"
{
    GtkWidget::focus-line-width = 0

    bg[NORMAL] = $button_grey

    # "square" slider (really round of course)
    # Same as indicator-size?
    GtkRange::slider-width = $scale_slider_width
    GtkScale::slider-length = $scale_slider_width
    GtkRange::trough-border = 0
    GtkRange::stepper-spacing = 0
    GtkRange::trough-side-details = 1
}

# hints for the trough sizing hacks
style "hscale" = "scale"
{
    engine "sugar" {
        hint = "hscale"
    }
}

style "vscale" = "scale"
{
    engine "sugar" {
        hint = "vscale"
    }
}

style "spinbutton"
{
    bg[NORMAL]  = $button_grey
    bg[ACTIVE]  = $white
    fg[NORMAL]  = $white
    fg[ACTIVE]  = $black

    ${ spin_ythickness = my_ceil(0.2 * (subcell_size*3.0/2.0 - thickness) + thickness) }
    ${ spin_xthickness = subcell_size }

    # small inner border and a large x/ythickness for entries
    # to reduce the number of hacks needed :-)
    xthickness = $spin_xthickness
    ythickness = $spin_ythickness
    GtkWidget::focus-line-width = 0

    # This tries to get a height of exactly 45 pixel for the entry.
    GtkEntry::inner-border = { $(max(subcell_size - spin_xthickness, 0)), $(max(subcell_size - spin_xthickness, 0)),
                               $(max(my_ceil((3*subcell_size - font_height - spin_ythickness*2)/2.0),0)), $(max(my_floor((3*subcell_size - font_height - spin_ythickness*2)/2.0), 0)) }

    engine "sugar" {
        hint = "spinbutton"
    }
}

style "frame"
{
    bg[NORMAL] = $toolbar_grey

    engine "sugar" {
        parent_bg_color = $toolbar_grey
        parent_fg_color = $white
    }
}

style "notebook-tab"
{
    bg[ACTIVE] = $button_grey
    fg[ACTIVE] = $white
}

style "notebook-panel"
{
    GtkNotebook::tab-overlap = -2
    GtkNotebook::tab-curvature = $default_padding

    xthickness = 0
    ythickness = 0

    bg[NORMAL] = $selection_grey
}

style "toolbox-notebook"
{
    GtkNotebook::tab-overlap = -2

    xthickness = 0
    ythickness = 0
}

style "toolbutton"
{
    xthickness = 0
    ythickness = 0
    GtkButton::inner-border = { $toolbutton_padding,
                                $toolbutton_padding,
                                $toolbutton_padding,
                                $toolbutton_padding }
    GtkWidget::focus-padding = 0

    bg[PRELIGHT] = $black
    bg[ACTIVE] = $button_grey
    bg[NORMAL] = $black

    fg[NORMAL] = $white
    fg[ACTIVE] = $white
    fg[PRELIGHT] = $white

    engine "sugar" {
        max_radius = 5.0
        fake_padding = $default_padding
    }
}

style "separatortoolbutton"
{
    # The sizing is handled in the engine.
    bg[NORMAL] = $button_grey
}

style "toolbar"
{
    xthickness = 0
    ythickness = 0

    bg[NORMAL] = $toolbar_grey
    bg[INSENSITIVE] = $toolbar_grey
    base[INSENSITIVE] = $toolbar_grey

    engine "sugar" {
        parent_fg_color = $white
        parent_bg_color = $toolbar_grey
    }
}

style "toolbox"
{
    fg[NORMAL] = $white
    fg[ACTIVE] = $white

    bg[NORMAL] = $toolbar_grey
    bg[INSENSITIVE] = $toolbar_grey
    base[INSENSITIVE] = $toolbar_grey

    engine "sugar" {
        parent_fg_color = $white
        parent_bg_color = $toolbar_grey
    }
}

style "panel"
{
    bg[NORMAL] = $panel_grey
    fg[NORMAL] = $black
}

style "entry"
{
    color["focus_line"] = $text_field_grey

    ${ entry_ythickness = my_ceil(0.2 * (subcell_size*3.0/2.0 - thickness) + thickness) }
    ${ entry_xthickness = my_ceil(0.32 * (subcell_size*3.0/2.0 - thickness) + thickness) }

    # small inner border and a large x/ythickness for entries
    # to reduce the number of hacks needed :-)
    xthickness = $entry_xthickness
    ythickness = $entry_ythickness
    GtkWidget::focus-line-width = 0

    # This tries to get a height of exactly 45 pixel for the entry.
    GtkEntry::inner-border = { $(max(subcell_size - entry_xthickness, 0)), $(max(subcell_size - entry_xthickness, 0)),
                               $(max(my_ceil((3*subcell_size - font_height - entry_ythickness*2)/2.0),0)), $(max(my_floor((3*subcell_size - font_height - entry_ythickness*2)/2.0), 0)) }
}

style "button"
{
    ${ border = max(0, my_ceil((3*subcell_size/2.0 - icon_small / 2.0))) }
    # It would be nicer to just set the inner-border, but that does not work
    # for combo boxes ... The combobox ignores it, so set it to 0px
    # See http://bugzilla.gnome.org/show_bug.cgi?id=485762

    GtkButton::inner-border = { 0, 0, 0, 0 }

    # So set the x/ythickness; y-padding is $subcell_size overall
    xthickness = $(border)
    ythickness = $(border)

    fg[NORMAL] = $white
    fg[ACTIVE] = $black

    bg[NORMAL] = $button_grey
}

style "combobox"
{
    # "Disable" the ACTIVE state of the button, it only creates problems :-(
    bg[ACTIVE] = $button_grey
    fg[ACTIVE] = $white

    # Work around GTK+ bug #382646
    text[NORMAL]      = $white
    text[ACTIVE]      = $white
    text[PRELIGHT]    = $white
}

style "comboboxentry"
{
    # Copied from the "default" style. Part of the workaround for bug #382646.
    text[NORMAL] = $black
    text[ACTIVE] = $black
    text[SELECTED] = $black
    text[PRELIGHT] = $black

    # It just happens that the entry xthickness works good for the button,
    # which simplefies matters a bit.
    xthickness = $entry_xthickness

    engine "sugar" {
        hint = "comboboxentry"
    }
}

style "checkbutton"
{
    base[NORMAL]      = $white
    base[PRELIGHT]    = $white
    base[ACTIVE]      = $text_field_grey

    text[PRELIGHT]    = $toolbar_grey
    text[NORMAL]      = $toolbar_grey
    text[ACTIVE]      = $toolbar_grey

    # I won't get the exact sizing, but this should be pretty close
    GtkCheckButton::indicator-size = $radio_size
    GtkCheckButton::indicator-spacing = 3
    GtkWidget::focus-padding = 3

    engine "sugar" {
        # Reset the colors to the normal color again
        # as they were overriden by the button style
        fg[NORMAL]        = parent_fg_color
        fg[PRELIGHT]      = parent_fg_color
        fg[ACTIVE]        = parent_fg_color
    }
}

style "progressbar"
{
    xthickness = 0
    ythickness = 0
}

style "menuitem"
{
    GtkMenuItem::horizontal-padding = 0
    GtkMenuItem::arrow-spacing = $subcell_size
    GtkMenuItem::toggle-spacing = $subcell_size

    bg[PRELIGHT] = $button_grey

    # Work around bug #382646
    text[PRELIGHT]    = $white
    text[NORMAL]      = $white
    text[ACTIVE]      = $white

    xthickness = $subcell_size
    ythickness = $((subcell_size * 3 - font_height) / 2)
}

style "checkmenuitem"
{
    GtkCheckMenuItem::indicator-size = $radio_size
    GtkMenuItem::toggle-spacing = $(subcell_size * 2 / 3)

    ythickness = $((subcell_size * 3 - max(font_height, subcell_size * 2 / 3)) / 2)

    # This is only there because of bug #382646 ...
    base[NORMAL]      = $white
    base[PRELIGHT]    = $white
    base[ACTIVE]      = $text_field_grey

    text[PRELIGHT]    = $toolbar_grey
    text[NORMAL]      = $toolbar_grey
    text[ACTIVE]      = $toolbar_grey
}

style "imagemenuitem"
{
    # Assume a $(icon_small)px image and height of $(4*subcell_size)
    ythickness = $(max(0, (3*subcell_size - icon_small) / 2))
}

style "separatormenuitem"
{
    GtkWidget::wide-separators = 1
    GtkWidget::separator-height = $(2*subcell_size)

    ythickness = 0
    xthickness = 0
}

style "trayicon"
{
    bg[PRELIGHT] = $black
    bg[ACTIVE] = $button_grey
}

style "parent-bg"
{
    engine "sugar" {
        bg[NORMAL] = parent_bg_color
        bg[INSENSITIVE] = parent_bg_color
    }
}

####################################################################
# Default style, setting some generic options and style properties
####################################################################
class "GtkWidget" style "default"

####################################################################
# Styles that apply the different background (and foreground) colors
####################################################################

# This one should probably be the default (ie. no window-child style)
widget_class "<GtkWindow>"               style "window"
widget_class "<GtkWindow>*"              style "window-child"

widget_class "*<SugarAlert>"               style "black-bg"
widget_class "*<SugarAlert>*"              style "black-bg-child"

widget_class "*<SugarSectionView>"       style "white-bg"
widget_class "*<SugarSectionView>*"      style "white-bg-child"

# The notebook is very high, so that everything is overriden
# Only the color of the tab labels needs to be modified inside the
# notebooks in this style (and the widget itself).
# Assume that there is either just a normal label in the notebook tab, or
# it is inside a GtkBox (H- or VBox) together with eg. a close button.
widget_class "*<GtkNotebook>"                        style "notebook-tab"
widget_class "*<GtkNotebook>.<GtkLabel>"             style "notebook-tab"
widget_class "*<GtkNotebook>.<GtkBox>.<GtkLabel>"    style "notebook-tab"

# SugarPalette and Menu
widget_class "*<GtkMenu>"               style "menu"
widget_class "<SugarPalette>"           style "menu"
widget_class "<SugarPalette>.*"         style "menu-child"
widget_class "<SugarPalette>*<GtkMenu>" style "palette-menu"
widget_class "*<GtkMenuShell>.*"        style "menu-child"

# SugarFrameWindow
widget_class "*<SugarFrameWindow>*"    style "frame"

# SugarPanel
widget_class "*<SugarPanel>*"          style "panel"

# GroupBoxes (don't set bg[NORMAL] on the widget itself)
widget_class "<GtkWindow>*<SugarGroupBox>*"   style "groupbox-panel-child"

widget_class "<GtkWindow>*<GtkNotebook>*"   style "groupbox-panel-child"
widget_class "<GtkWindow>*<GtkNotebook>"    style "notebook-panel"

widget_class "<SugarPalette>*<SugarGroupBox>*"   style "groupbox-palette-child"

# SugarToolbox
#widget_class "*<SugarToolbox>" style "toolbox"
#widget_class "*<SugarToolbox>*" style "toolbox-child"
#widget_class "*<SugarToolbox>*<GtkEventBox>" style "toolbox"
#widget_class "*<SugarToolbox>*<GtkLayout>"   style "toolbox"
widget_class "*<SugarToolbox>*"        style "toolbox"
widget_class "*<GtkToolbar>*"          style "toolbox"
widget_class "*<SugarToolbox>.<GtkNotebook>" style "toolbox-notebook"

####################################################################
# Normal widget styles, using the above things
####################################################################
# The following only uses widget_class matches to get the priority
# right. An alternative would be to lower the priority of the
# background matches (which need widget_class) to eg. "application"

widget_class "*<GtkMenuItem>*"            style "menuitem"
widget_class "*<GtkCheckMenuItem>"        style "checkmenuitem"
widget_class "*<GtkImageMenuItem>"        style "imagemenuitem"
widget_class "*<GtkSeparatorMenuItem>*"   style "separatormenuitem"

# Buttons and Combos
widget_class "*<GtkButton>*"           style "button"
widget_class "*<GtkCheckButton>*"      style "checkbutton"
widget_class "*<GtkComboBox>*"         style "combobox"
widget_class "*<GtkComboBoxEntry>*"    style "comboboxentry"
widget_class "*<GtkCombo>*"            style "comboboxentry"

# Entries
widget_class "*<GtkEntry>"       style "entry"
widget_class "*<GtkSpinButton>"  style "spinbutton"
widget_class "*<GtkTextView>"    style "textview"

# Misc widgets
widget_class "*<GtkHScrollbar>"  style "hscrollbar"
widget_class "*<GtkVScrollbar>"  style "vscrollbar"
widget_class "*<GtkHScale>"      style "hscale"
widget_class "*<GtkVScale>"      style "vscale"
widget_class "*<GtkProgressBar>" style "progressbar"

# Scrolled window scrollbars
widget_class "*<GtkScrolledWindow>.<GtkVScrollbar>" style "vscrollbar-scrolled-window"
widget_class "*<GtkScrolledWindow>.<GtkHScrollbar>" style "hscrollbar-scrolled-window"

# Toolbar
widget_class "*<GtkToolButton>*"          style "toolbutton"
widget_class "*<GtkSeparatorToolItem>*"   style "separatortoolbutton"
widget_class "*<GtkToolbar>"              style "toolbar"

# Tray
widget_class "*<SugarTrayIcon>*" style "trayicon"

# Widgets that should get the background color from the parent
widget_class "*<GtkEventBox>"        style "parent-bg"
widget_class "*<GtkLayout>"          style "parent-bg"
widget_class "*<GtkViewport>"        style "parent-bg"
widget_class "*<GtkDrawingArea>"     style "parent-bg"
widget_class "*<GtkScrolledWindow>"  style "parent-bg"


removing extra quote mark from environment hooks file

@[if DEVELSPACE]@
. "@(CMAKE_CURRENT_SOURCE_DIR)/scripts/rosman.bash"
@[else]@
if [ -z "$CATKIN_ENV_HOOK_WORKSPACE" ]; then
  CATKIN_ENV_HOOK_WORKSPACE="@(CMAKE_INSTALL_PREFIX)"
fi
. "$CATKIN_ENV_HOOK_WORKSPACE/share/rosman/scripts/rosman.bash"
@[end if]@

@[if DEVELSPACE]@
. "@(CMAKE_CURRENT_SOURCE_DIR)/scripts/rosman.bash"
@[else]@
if [ -z "$CATKIN_ENV_HOOK_WORKSPACE" ]; then
  CATKIN_ENV_HOOK_WORKSPACE="@(CMAKE_INSTALL_PREFIX)"
fi
. "$CATKIN_ENV_HOOK_WORKSPACE"/share/rosman/scripts/rosman.bash"
@[end if]@


seaparate checkboxes for fastrtps and opensplice in packaging job (#99)

<?xml version='1.0' encoding='UTF-8'?>
<project>
  <actions/>
  <description></description>
  <keepDependencies>false</keepDependencies>
  <properties>
    <com.coravy.hudson.plugins.github.GithubProjectProperty plugin="github@@1.25.1">
      <projectUrl>@(ci_scripts_repository)/</projectUrl>
      <displayName />
    </com.coravy.hudson.plugins.github.GithubProjectProperty>
    <com.sonyericsson.rebuild.RebuildSettings plugin="rebuild@@1.25">
      <autoRebuild>false</autoRebuild>
      <rebuildDisabled>false</rebuildDisabled>
    </com.sonyericsson.rebuild.RebuildSettings>
    <org.jenkinsci.plugins.requeuejob.RequeueJobProperty plugin="jobrequeue@@1.1">
      <requeueJob>true</requeueJob>
    </org.jenkinsci.plugins.requeuejob.RequeueJobProperty>
    <hudson.model.ParametersDefinitionProperty>
      <parameterDefinitions>
@(SNIPPET(
    'property_parameter-definition_common',
    ci_scripts_default_branch=ci_scripts_default_branch,
    default_repos_url=default_repos_url,
    supplemental_repos_url=supplemental_repos_url,
    cmake_build_type=cmake_build_type,
    ament_build_args_default=ament_build_args_default,
))@
        <hudson.model.BooleanParameterDefinition>
          <name>CI_USE_FASTRTPS</name>
          <description>By setting this to True, the build will attempt to use eProsima's FastRTPS.</description>
          <defaultValue>@(use_fastrtps_default)</defaultValue>
        </hudson.model.BooleanParameterDefinition>
        <hudson.model.BooleanParameterDefinition>
          <name>CI_USE_OPENSPLICE</name>
          <description>By setting this to True, the build will attempt to use PrismTech's OpenSplice.</description>
          <defaultValue>@(use_opensplice_default)</defaultValue>
        </hudson.model.BooleanParameterDefinition>
        <hudson.model.BooleanParameterDefinition>
          <name>CI_TEST_BRIDGE</name>
          <description>By setting this to True, the tests for the ros1_bridge will be run.</description>
          <defaultValue>@(test_bridge_default)</defaultValue>
        </hudson.model.BooleanParameterDefinition>
        <hudson.model.StringParameterDefinition>
          <name>CI_AMENT_TEST_ARGS</name>
          <description>Additional arguments passed to 'ament test' if testing the bridge.</description>
          <defaultValue>@(ament_test_args_default)</defaultValue>
        </hudson.model.StringParameterDefinition>
      </parameterDefinitions>
    </hudson.model.ParametersDefinitionProperty>
  </properties>
  <scm class="hudson.plugins.git.GitSCM" plugin="git@@3.0.1">
    <configVersion>2</configVersion>
    <userRemoteConfigs>
      <hudson.plugins.git.UserRemoteConfig>
        <url>@(ci_scripts_repository)</url>
        <credentialsId>1c2004f6-2e00-425d-a421-2e1ba62ca7a7</credentialsId>
      </hudson.plugins.git.UserRemoteConfig>
    </userRemoteConfigs>
    <branches>
      <hudson.plugins.git.BranchSpec>
        <name>refs/heads/${CI_SCRIPTS_BRANCH}</name>
      </hudson.plugins.git.BranchSpec>
    </branches>
    <doGenerateSubmoduleConfigurations>false</doGenerateSubmoduleConfigurations>
    <browser class="hudson.plugins.git.browser.GithubWeb">
      <url></url>
    </browser>
    <submoduleCfg class="list"/>
    <extensions>@
@[if os_name != 'windows']
      <hudson.plugins.git.extensions.impl.SubmoduleOption>
        <disableSubmodules>false</disableSubmodules>
        <recursiveSubmodules>true</recursiveSubmodules>
        <trackingSubmodules>false</trackingSubmodules>
        <reference/>
        <parentCredentials>false</parentCredentials>
      </hudson.plugins.git.extensions.impl.SubmoduleOption>
    @
@[end if]</extensions>
  </scm>
  <assignedNode>@(label_expression)</assignedNode>
  <canRoam>false</canRoam>
  <disabled>false</disabled>
  <blockBuildWhenDownstreamBuilding>false</blockBuildWhenDownstreamBuilding>
  <blockBuildWhenUpstreamBuilding>false</blockBuildWhenUpstreamBuilding>
  <triggers>@
@[if time_trigger_spec]
    <hudson.triggers.TimerTrigger>
      <spec>@(time_trigger_spec)</spec>
    </hudson.triggers.TimerTrigger>
  @
@[end if]</triggers>
  <concurrentBuild>false</concurrentBuild>
  <builders>
    <hudson.plugins.groovy.SystemGroovy plugin="groovy@@2.0">
      <source class="hudson.plugins.groovy.StringSystemScriptSource">

          <sandbox>false</sandbox>
        </script>
      </source>
    </hudson.plugins.groovy.SystemGroovy>
    <hudson.tasks.@(shell_type)>
      <command>@
@[if os_name in ['linux', 'linux-aarch64', 'osx']]@
rm -rf ws workspace

echo "# BEGIN SECTION: Determine arguments"
export CI_ARGS="--packaging --do-venv --force-ansi-color"
if [ -n "${CI_BRANCH_TO_TEST+x}" ]; then
  export CI_ARGS="$CI_ARGS --test-branch $CI_BRANCH_TO_TEST"
fi
if [ "$CI_USE_FASTRTPS" = "true" ]; then
  export CI_ARGS="$CI_ARGS --fastrtps"
fi
if [ "$CI_USE_OPENSPLICE" = "true" ]; then
  export CI_ARGS="$CI_ARGS --opensplice"
fi
if [ -z "${CI_ROS2_REPOS_URL+x}" ]; then
  CI_ROS2_REPOS_URL="@default_repos_url"
fi
export CI_ARGS="$CI_ARGS --repo-file-url $CI_ROS2_REPOS_URL"
if [ "$CI_TEST_BRIDGE" = "true" ]; then
  export CI_ARGS="$CI_ARGS --test-bridge"
fi
if [ "${CI_CMAKE_BUILD_TYPE}" != "None" ]; then
  export CI_ARGS="$CI_ARGS --cmake-build-type $CI_CMAKE_BUILD_TYPE"
fi
if [ -n "${CI_AMENT_BUILD_ARGS+x}" ]; then
  case $CI_AMENT_BUILD_ARGS in
    *-- )
      # delimiter is already appended
      ;;
    * )
      CI_AMENT_BUILD_ARGS="$CI_AMENT_BUILD_ARGS --"
      ;;
  esac
  export CI_ARGS="$CI_ARGS --ament-build-args $CI_AMENT_BUILD_ARGS"
fi
if [ -n "${CI_AMENT_TEST_ARGS+x}" ]; then
  case $CI_AMENT_TEST_ARGS in
    *-- )
      # delimiter is already appended
      ;;
    * )
      CI_AMENT_TEST_ARGS="$CI_AMENT_TEST_ARGS --"
      ;;
  esac
  export CI_ARGS="$CI_ARGS --ament-test-args $CI_AMENT_TEST_ARGS"
fi
@[if os_name in ['linux', 'linux-aarch64']]@
export CI_ARGS="$CI_ARGS --ros1-path /opt/ros/kinetic"
@[else]@
export CI_ARGS="$CI_ARGS --ros1-path /Users/osrf/kinetic/install_isolated"
@[end if]@
echo "Using args: $CI_ARGS"
echo "# END SECTION"

@[if os_name in ['linux', 'linux-aarch64']]@
mkdir -p $HOME/.ccache
echo "# BEGIN SECTION: docker version"
docker version
echo "# END SECTION"
echo "# BEGIN SECTION: docker info"
docker info
echo "# END SECTION"
echo "# BEGIN SECTION: Build Dockerfile"
@[if os_name == 'linux-aarch64']@
sed -i 's+^FROM.*$+FROM aarch64/ubuntu:xenial+' linux_docker_resources/Dockerfile
sed -i 's+apt-get update+(apt-get update || true)+' linux_docker_resources/Dockerfile
docker build --build-arg PLATFORM=arm --build-arg BRIDGE=true -t ros2_packaging_aarch64 linux_docker_resources
@[elif os_name == 'linux']@
docker build --build-arg BRIDGE=true -t ros2_packaging linux_docker_resources
@[else]@
@{ assert 'Unknown os_name: ' + os_name }@
@[end if]@
echo "# END SECTION"
echo "# BEGIN SECTION: Run Dockerfile"
@[if os_name == 'linux']@
export CONTAINER_NAME=ros2_packaging
@[elif os_name == 'linux-aarch64']@
export CONTAINER_NAME=ros2_packaging_aarch64
@[else]@
@{ assert 'Unknown os_name: ' + os_name }@
@[end if]@
docker run --privileged -e UID=`id -u` -e GID=`id -g` -e CI_ARGS="$CI_ARGS" -e CCACHE_DIR=/home/rosbuild/.ccache -i -v `pwd`:/home/rosbuild/ci_scripts -v $HOME/.ccache:/home/rosbuild/.ccache $CONTAINER_NAME
echo "# END SECTION"
@[else]@
echo "# BEGIN SECTION: Run packaging script"
/usr/local/bin/python3 -u run_ros2_batch.py $CI_ARGS
echo "# END SECTION"
@[end if]@
@[elif os_name == 'windows']@
rmdir /S /Q ws workspace

echo "# BEGIN SECTION: Determine arguments"
set "PATH=%PATH:"=%"
set "CI_ARGS=--packaging --force-ansi-color"
if "%CI_BRANCH_TO_TEST%" NEQ "" (
  set "CI_ARGS=%CI_ARGS% --test-branch %CI_BRANCH_TO_TEST%"
)
if "%CI_USE_FASTRTPS%" == "true" (
  set "CI_ARGS=%CI_ARGS% --fastrtps"
)
if "%CI_USE_OPENSPLICE%" == "true" (
  set "CI_ARGS=%CI_ARGS% --opensplice"
)
if "%CI_ROS2_REPOS_URL%" EQU "" (
  set "CI_ROS2_REPOS_URL=@default_repos_url"
)
set "CI_ARGS=%CI_ARGS% --repo-file-url %CI_ROS2_REPOS_URL%"
if "%CI_TEST_BRIDGE%" == "true" (
  set "CI_ARGS=%CI_ARGS% --test-bridge"
)
if "%CI_CMAKE_BUILD_TYPE%" NEQ "None" (
  set "CI_ARGS=%CI_ARGS% --cmake-build-type %CI_CMAKE_BUILD_TYPE%"
)
if "%CI_AMENT_BUILD_ARGS%" NEQ "" (
  if "%CI_AMENT_BUILD_ARGS:~-2%" NEQ "--" (
    set "CI_AMENT_BUILD_ARGS=%CI_AMENT_BUILD_ARGS% --"
  )
  set "CI_ARGS=%CI_ARGS% --ament-build-args %CI_AMENT_BUILD_ARGS%"
)
if "%CI_AMENT_TEST_ARGS%" NEQ "" (
  if "%CI_AMENT_TEST_ARGS:~-2%" NEQ "--" (
    set "CI_AMENT_TEST_ARGS=%CI_AMENT_TEST_ARGS% --"
  )
  set "CI_ARGS=%CI_ARGS% --ament-test-args %CI_AMENT_TEST_ARGS%"
)
echo Using args: %CI_ARGS%
echo "# END SECTION"

echo "# BEGIN SECTION: Run packaging script"
python -u run_ros2_batch.py %CI_ARGS%
echo "# END SECTION"
@[else]@
@{ assert 'Unknown os_name: ' + os_name }@
@[end if]</command>
    </hudson.tasks.@(shell_type)>
  </builders>
  <publishers>
@(SNIPPET(
    'publisher_warnings',
    os_name=os_name,
))@
@(SNIPPET(
    'publisher_cobertura',
))@
@(SNIPPET(
    'publisher_xunit',
))@
    <hudson.tasks.ArtifactArchiver>
      <artifacts>ws/ros2-package-*.*</artifacts>
      <allowEmptyArchive>false</allowEmptyArchive>
      <onlyIfSuccessful>true</onlyIfSuccessful>
      <fingerprint>false</fingerprint>
      <defaultExcludes>true</defaultExcludes>
      <caseSensitive>true</caseSensitive>
    </hudson.tasks.ArtifactArchiver>
@[if mailer_recipients]@
    <hudson.tasks.Mailer plugin="mailer@@1.20">
      <recipients>@(mailer_recipients)</recipients>
      <dontNotifyEveryUnstableBuild>false</dontNotifyEveryUnstableBuild>
      <sendToIndividuals>false</sendToIndividuals>
    </hudson.tasks.Mailer>
@[end if]@
  </publishers>
  <buildWrappers>
    <hudson.plugins.timestamper.TimestamperBuildWrapper plugin="timestamper@@1.8.8" />
    <hudson.plugins.ansicolor.AnsiColorBuildWrapper plugin="ansicolor@@0.5.0">
      <colorMapName>xterm</colorMapName>
    </hudson.plugins.ansicolor.AnsiColorBuildWrapper>
@[if os_name != 'windows']@
    <com.cloudbees.jenkins.plugins.sshagent.SSHAgentBuildWrapper plugin="ssh-agent@@1.15">
      <credentialIds>
        <string>1c2004f6-2e00-425d-a421-2e1ba62ca7a7</string>
      </credentialIds>
      <ignoreMissing>false</ignoreMissing>
    </com.cloudbees.jenkins.plugins.sshagent.SSHAgentBuildWrapper>
@[end if]@
  </buildWrappers>
</project>

<?xml version='1.0' encoding='UTF-8'?>
<project>
  <actions/>
  <description></description>
  <keepDependencies>false</keepDependencies>
  <properties>
    <com.coravy.hudson.plugins.github.GithubProjectProperty plugin="github@@1.25.1">
      <projectUrl>@(ci_scripts_repository)/</projectUrl>
      <displayName />
    </com.coravy.hudson.plugins.github.GithubProjectProperty>
    <com.sonyericsson.rebuild.RebuildSettings plugin="rebuild@@1.25">
      <autoRebuild>false</autoRebuild>
      <rebuildDisabled>false</rebuildDisabled>
    </com.sonyericsson.rebuild.RebuildSettings>
    <org.jenkinsci.plugins.requeuejob.RequeueJobProperty plugin="jobrequeue@@1.1">
      <requeueJob>true</requeueJob>
    </org.jenkinsci.plugins.requeuejob.RequeueJobProperty>
    <hudson.model.ParametersDefinitionProperty>
      <parameterDefinitions>
@(SNIPPET(
    'property_parameter-definition_common',
    ci_scripts_default_branch=ci_scripts_default_branch,
    default_repos_url=default_repos_url,
    supplemental_repos_url=supplemental_repos_url,
    cmake_build_type=cmake_build_type,
    ament_build_args_default=ament_build_args_default,
))@
        <hudson.model.ChoiceParameterDefinition>
          <name>CI_USED_RMW_IMPL</name>
          <description/>
          <choices class="java.util.Arrays$ArrayList">

              <string>FastRTPS</string>
              <string>OpenSplice</string>

          </choices>
        </hudson.model.ChoiceParameterDefinition>
        <hudson.model.BooleanParameterDefinition>
          <name>CI_TEST_BRIDGE</name>
          <description>By setting this to True, the tests for the ros1_bridge will be run.</description>
          <defaultValue>@(test_bridge_default)</defaultValue>
        </hudson.model.BooleanParameterDefinition>
        <hudson.model.StringParameterDefinition>
          <name>CI_AMENT_TEST_ARGS</name>
          <description>Additional arguments passed to 'ament test' if testing the bridge.</description>
          <defaultValue>@(ament_test_args_default)</defaultValue>
        </hudson.model.StringParameterDefinition>
      </parameterDefinitions>
    </hudson.model.ParametersDefinitionProperty>
  </properties>
  <scm class="hudson.plugins.git.GitSCM" plugin="git@@3.0.1">
    <configVersion>2</configVersion>
    <userRemoteConfigs>
      <hudson.plugins.git.UserRemoteConfig>
        <url>@(ci_scripts_repository)</url>
        <credentialsId>1c2004f6-2e00-425d-a421-2e1ba62ca7a7</credentialsId>
      </hudson.plugins.git.UserRemoteConfig>
    </userRemoteConfigs>
    <branches>
      <hudson.plugins.git.BranchSpec>
        <name>refs/heads/${CI_SCRIPTS_BRANCH}</name>
      </hudson.plugins.git.BranchSpec>
    </branches>
    <doGenerateSubmoduleConfigurations>false</doGenerateSubmoduleConfigurations>
    <browser class="hudson.plugins.git.browser.GithubWeb">
      <url></url>
    </browser>
    <submoduleCfg class="list"/>
    <extensions>@
@[if os_name != 'windows']
      <hudson.plugins.git.extensions.impl.SubmoduleOption>
        <disableSubmodules>false</disableSubmodules>
        <recursiveSubmodules>true</recursiveSubmodules>
        <trackingSubmodules>false</trackingSubmodules>
        <reference/>
        <parentCredentials>false</parentCredentials>
      </hudson.plugins.git.extensions.impl.SubmoduleOption>
    @
@[end if]</extensions>
  </scm>
  <assignedNode>@(label_expression)</assignedNode>
  <canRoam>false</canRoam>
  <disabled>false</disabled>
  <blockBuildWhenDownstreamBuilding>false</blockBuildWhenDownstreamBuilding>
  <blockBuildWhenUpstreamBuilding>false</blockBuildWhenUpstreamBuilding>
  <triggers>@
@[if time_trigger_spec]
    <hudson.triggers.TimerTrigger>
      <spec>@(time_trigger_spec)</spec>
    </hudson.triggers.TimerTrigger>
  @
@[end if]</triggers>
  <concurrentBuild>false</concurrentBuild>
  <builders>
    <hudson.plugins.groovy.SystemGroovy plugin="groovy@@2.0">
      <source class="hudson.plugins.groovy.StringSystemScriptSource">

          <sandbox>false</sandbox>
        </script>
      </source>
    </hudson.plugins.groovy.SystemGroovy>
    <hudson.tasks.@(shell_type)>
      <command>@
@[if os_name in ['linux', 'linux-aarch64', 'osx']]@
rm -rf ws workspace

echo "# BEGIN SECTION: Determine arguments"
export CI_ARGS="--packaging --do-venv --force-ansi-color"
if [ -n "${CI_BRANCH_TO_TEST+x}" ]; then
  export CI_ARGS="$CI_ARGS --test-branch $CI_BRANCH_TO_TEST"
fi
if [ "${CI_USED_RMW_IMPL}" = "FastRTPS" ]; then
  export CI_ARGS="$CI_ARGS --fastrtps"
elif [ "${CI_USED_RMW_IMPL}" = "OpenSplice" ]; then
  export CI_ARGS="$CI_ARGS --opensplice"
fi
if [ -z "${CI_ROS2_REPOS_URL+x}" ]; then
  CI_ROS2_REPOS_URL="@default_repos_url"
fi
export CI_ARGS="$CI_ARGS --repo-file-url $CI_ROS2_REPOS_URL"
if [ "$CI_TEST_BRIDGE" = "true" ]; then
  export CI_ARGS="$CI_ARGS --test-bridge"
fi
if [ "${CI_CMAKE_BUILD_TYPE}" != "None" ]; then
  export CI_ARGS="$CI_ARGS --cmake-build-type $CI_CMAKE_BUILD_TYPE"
fi
if [ -n "${CI_AMENT_BUILD_ARGS+x}" ]; then
  case $CI_AMENT_BUILD_ARGS in
    *-- )
      # delimiter is already appended
      ;;
    * )
      CI_AMENT_BUILD_ARGS="$CI_AMENT_BUILD_ARGS --"
      ;;
  esac
  export CI_ARGS="$CI_ARGS --ament-build-args $CI_AMENT_BUILD_ARGS"
fi
if [ -n "${CI_AMENT_TEST_ARGS+x}" ]; then
  case $CI_AMENT_TEST_ARGS in
    *-- )
      # delimiter is already appended
      ;;
    * )
      CI_AMENT_TEST_ARGS="$CI_AMENT_TEST_ARGS --"
      ;;
  esac
  export CI_ARGS="$CI_ARGS --ament-test-args $CI_AMENT_TEST_ARGS"
fi
@[if os_name in ['linux', 'linux-aarch64']]@
export CI_ARGS="$CI_ARGS --ros1-path /opt/ros/kinetic"
@[else]@
export CI_ARGS="$CI_ARGS --ros1-path /Users/osrf/kinetic/install_isolated"
@[end if]@
echo "Using args: $CI_ARGS"
echo "# END SECTION"

@[if os_name in ['linux', 'linux-aarch64']]@
mkdir -p $HOME/.ccache
echo "# BEGIN SECTION: docker version"
docker version
echo "# END SECTION"
echo "# BEGIN SECTION: docker info"
docker info
echo "# END SECTION"
echo "# BEGIN SECTION: Build Dockerfile"
@[if os_name == 'linux-aarch64']@
sed -i 's+^FROM.*$+FROM aarch64/ubuntu:xenial+' linux_docker_resources/Dockerfile
sed -i 's+apt-get update+(apt-get update || true)+' linux_docker_resources/Dockerfile
docker build --build-arg PLATFORM=arm --build-arg BRIDGE=true -t ros2_packaging_aarch64 linux_docker_resources
@[elif os_name == 'linux']@
docker build --build-arg BRIDGE=true -t ros2_packaging linux_docker_resources
@[else]@
@{ assert 'Unknown os_name: ' + os_name }@
@[end if]@
echo "# END SECTION"
echo "# BEGIN SECTION: Run Dockerfile"
@[if os_name == 'linux']@
export CONTAINER_NAME=ros2_packaging
@[elif os_name == 'linux-aarch64']@
export CONTAINER_NAME=ros2_packaging_aarch64
@[else]@
@{ assert 'Unknown os_name: ' + os_name }@
@[end if]@
docker run --privileged -e UID=`id -u` -e GID=`id -g` -e CI_ARGS="$CI_ARGS" -e CCACHE_DIR=/home/rosbuild/.ccache -i -v `pwd`:/home/rosbuild/ci_scripts -v $HOME/.ccache:/home/rosbuild/.ccache $CONTAINER_NAME
echo "# END SECTION"
@[else]@
echo "# BEGIN SECTION: Run packaging script"
/usr/local/bin/python3 -u run_ros2_batch.py $CI_ARGS
echo "# END SECTION"
@[end if]@
@[elif os_name == 'windows']@
rmdir /S /Q ws workspace

echo "# BEGIN SECTION: Determine arguments"
set "PATH=%PATH:"=%"
set "CI_ARGS=--packaging --force-ansi-color"
if "%CI_BRANCH_TO_TEST%" NEQ "" (
  set "CI_ARGS=%CI_ARGS% --test-branch %CI_BRANCH_TO_TEST%"
)
if "%CI_USED_RMW_IMPL%" EQU "FastRTPS" (
  set "CI_ARGS=%CI_ARGS% --fastrtps"
) else if "%CI_USED_RMW_IMPL%" EQU "OpenSplice" (
  set "CI_ARGS=%CI_ARGS% --opensplice"
)
if "%CI_ROS2_REPOS_URL%" EQU "" (
  set "CI_ROS2_REPOS_URL=@default_repos_url"
)
set "CI_ARGS=%CI_ARGS% --repo-file-url %CI_ROS2_REPOS_URL%"
if "%CI_TEST_BRIDGE%" == "true" (
  set "CI_ARGS=%CI_ARGS% --test-bridge"
)
if "%CI_CMAKE_BUILD_TYPE%" NEQ "None" (
  set "CI_ARGS=%CI_ARGS% --cmake-build-type %CI_CMAKE_BUILD_TYPE%"
)
if "%CI_AMENT_BUILD_ARGS%" NEQ "" (
  if "%CI_AMENT_BUILD_ARGS:~-2%" NEQ "--" (
    set "CI_AMENT_BUILD_ARGS=%CI_AMENT_BUILD_ARGS% --"
  )
  set "CI_ARGS=%CI_ARGS% --ament-build-args %CI_AMENT_BUILD_ARGS%"
)
if "%CI_AMENT_TEST_ARGS%" NEQ "" (
  if "%CI_AMENT_TEST_ARGS:~-2%" NEQ "--" (
    set "CI_AMENT_TEST_ARGS=%CI_AMENT_TEST_ARGS% --"
  )
  set "CI_ARGS=%CI_ARGS% --ament-test-args %CI_AMENT_TEST_ARGS%"
)
echo Using args: %CI_ARGS%
echo "# END SECTION"

echo "# BEGIN SECTION: Run packaging script"
python -u run_ros2_batch.py %CI_ARGS%
echo "# END SECTION"
@[else]@
@{ assert 'Unknown os_name: ' + os_name }@
@[end if]</command>
    </hudson.tasks.@(shell_type)>
  </builders>
  <publishers>
@(SNIPPET(
    'publisher_warnings',
    os_name=os_name,
))@
@(SNIPPET(
    'publisher_cobertura',
))@
@(SNIPPET(
    'publisher_xunit',
))@
    <hudson.tasks.ArtifactArchiver>
      <artifacts>ws/ros2-package-*.*</artifacts>
      <allowEmptyArchive>false</allowEmptyArchive>
      <onlyIfSuccessful>true</onlyIfSuccessful>
      <fingerprint>false</fingerprint>
      <defaultExcludes>true</defaultExcludes>
      <caseSensitive>true</caseSensitive>
    </hudson.tasks.ArtifactArchiver>
@[if mailer_recipients]@
    <hudson.tasks.Mailer plugin="mailer@@1.20">
      <recipients>@(mailer_recipients)</recipients>
      <dontNotifyEveryUnstableBuild>false</dontNotifyEveryUnstableBuild>
      <sendToIndividuals>false</sendToIndividuals>
    </hudson.tasks.Mailer>
@[end if]@
  </publishers>
  <buildWrappers>
    <hudson.plugins.timestamper.TimestamperBuildWrapper plugin="timestamper@@1.8.8" />
    <hudson.plugins.ansicolor.AnsiColorBuildWrapper plugin="ansicolor@@0.5.0">
      <colorMapName>xterm</colorMapName>
    </hudson.plugins.ansicolor.AnsiColorBuildWrapper>
@[if os_name != 'windows']@
    <com.cloudbees.jenkins.plugins.sshagent.SSHAgentBuildWrapper plugin="ssh-agent@@1.15">
      <credentialIds>
        <string>1c2004f6-2e00-425d-a421-2e1ba62ca7a7</string>
      </credentialIds>
      <ignoreMissing>false</ignoreMissing>
    </com.cloudbees.jenkins.plugins.sshagent.SSHAgentBuildWrapper>
@[end if]@
  </buildWrappers>
</project>


enable access to all arrays (#366)

enable access to all arrays (#366)

Signed-off-by: Karsten Knese <511d54834ed4308f6de59a89f9d51c4bc6e103cd@openrobotics.org>

@# Included from rosidl_typesupport_introspection_cpp/resource/idl__type_support.cpp.em
@{
from rosidl_parser.definition import AbstractGenericString
from rosidl_parser.definition import AbstractNestedType
from rosidl_parser.definition import AbstractSequence
from rosidl_parser.definition import AbstractString
from rosidl_parser.definition import AbstractWString
from rosidl_parser.definition import Array
from rosidl_parser.definition import BasicType
from rosidl_parser.definition import BoundedSequence
from rosidl_parser.definition import NamespacedType
from rosidl_cmake import convert_camel_case_to_lower_case_underscore

include_parts = [package_name] + list(interface_path.parents[0].parts) + \
    [convert_camel_case_to_lower_case_underscore(interface_path.stem)]
include_base = '/'.join(include_parts)

header_files = [
    'array',
    'cstddef',  # providing offsetof()
    'string',
    'vector',
    'rosidl_generator_c/message_type_support_struct.h',
    'rosidl_typesupport_cpp/message_type_support.hpp',
    'rosidl_typesupport_interface/macros.h',
    include_base + '__struct.hpp',
    'rosidl_typesupport_introspection_cpp/field_types.hpp',
    'rosidl_typesupport_introspection_cpp/identifier.hpp',
    'rosidl_typesupport_introspection_cpp/message_introspection.hpp',
    'rosidl_typesupport_introspection_cpp/message_type_support_decl.hpp',
    'rosidl_typesupport_introspection_cpp/visibility_control.h',
]
}@
@[for header_file in header_files]@
@[    if header_file in include_directives]@
// already included above
// @
@[    else]@
@{include_directives.add(header_file)}@
@[    end if]@
#include "@(header_file)"
@[end for]@
@[for ns in message.structure.namespaced_type.namespaces]@

namespace @(ns)
{
@[end for]@

namespace rosidl_typesupport_introspection_cpp
{

@[for member in message.structure.members]@
@{
def is_vector_bool(member):
    from rosidl_parser.definition import BasicType
    from rosidl_parser.definition import AbstractSequence
    return isinstance(member.type, AbstractSequence) and isinstance(member.type.value_type, BasicType) and member.type.value_type.typename == 'boolean'
}@
@# exclude std::vector<bool> because of specialization in their API
@[  if isinstance(member.type, AbstractNestedType) and not is_vector_bool(member)]@
@{
from rosidl_generator_cpp import  MSG_TYPE_TO_CPP
if isinstance(member.type.value_type, BasicType):
    type_ = MSG_TYPE_TO_CPP[member.type.value_type.typename]
elif isinstance(member.type.value_type, AbstractString):
    type_ = 'std::string'
elif isinstance(member.type.value_type, AbstractWString):
    assert False, 'Unknown type: ' + str(member.type.value_type)
elif isinstance(member.type.value_type, NamespacedType):
    type_ = '::'.join(member.type.value_type.namespaced_name())
}@
size_t size_function__@(message.structure.namespaced_type.name)__@(member.name)(const void * untyped_member)
{
@[    if isinstance(member.type, Array)]@
  (void)untyped_member;
  return @(member.type.size);
@[    else]@
  const auto * member = reinterpret_cast<const std::vector<@(type_)> *>(untyped_member);
  return member->size();
@[    end if]@
}

const void * get_const_function__@(message.structure.namespaced_type.name)__@(member.name)(const void * untyped_member, size_t index)
{
@[    if isinstance(member.type, Array)]@
  const auto & member =
    *reinterpret_cast<const std::array<@(type_), @(member.type.size)> *>(untyped_member);
@[    else]@
  const auto & member =
    *reinterpret_cast<const std::vector<@(type_)> *>(untyped_member);
@[    end if]@
  return &member[index];
}

void * get_function__@(message.structure.namespaced_type.name)__@(member.name)(void * untyped_member, size_t index)
{
@[    if isinstance(member.type, Array)]@
  auto & member =
    *reinterpret_cast<std::array<@(type_), @(member.type.size)> *>(untyped_member);
@[    else]@
  auto & member =
    *reinterpret_cast<std::vector<@(type_)> *>(untyped_member);
@[    end if]@
  return &member[index];
}

@[    if isinstance(member.type, AbstractSequence)]@
void resize_function__@(message.structure.namespaced_type.name)__@(member.name)(void * untyped_member, size_t size)
{
  auto * member =
    reinterpret_cast<std::vector<@(type_)> *>(untyped_member);
  member->resize(size);
}

@[    end if]@
@[  end if]@
@[end for]@
static const ::rosidl_typesupport_introspection_cpp::MessageMember @(message.structure.namespaced_type.name)_message_member_array[@(len(message.structure.members))] = {
@{
for index, member in enumerate(message.structure.members):
    type_ = member.type
    if isinstance(type_, AbstractNestedType):
        type_ = type_.value_type

    print('  {')

    # const char * name_
    print('    "%s",  // name' % member.name)
    if isinstance(type_, BasicType):
        # uint8_t type_id_
        print('    ::rosidl_typesupport_introspection_cpp::ROS_TYPE_%s,  // type' % type_.typename.upper())
        # size_t string_upper_bound
        print('    0,  // upper bound of string')
        # const rosidl_generator_c::MessageTypeSupportHandle * members_
        print('    NULL,  // members of sub message')
    elif isinstance(type_, AbstractGenericString):
        # uint8_t type_id_
        if isinstance(type_, AbstractString):
            print('    ::rosidl_typesupport_introspection_cpp::ROS_TYPE_STRING,  // type')
        elif isinstance(type_, AbstractWString):
            print('    ::rosidl_typesupport_introspection_cpp::ROS_TYPE_WSTRING,  // type')
        else:
            assert False, 'Unknown type: ' + str(type_)
        # size_t string_upper_bound
        print('    %u,  // upper bound of string' % (type_.maximum_size if type_.has_maximum_size() else 0))
        # const rosidl_generator_c::MessageTypeSupportHandle * members_
        print('    NULL,  // members of sub message')
    else:
        # uint8_t type_id_
        print('    ::rosidl_typesupport_introspection_cpp::ROS_TYPE_MESSAGE,  // type')
        # size_t string_upper_bound
        print('    0,  // upper bound of string')
        # const rosidl_message_type_support_t * members_
        print('    ::rosidl_typesupport_introspection_cpp::get_message_type_support_handle<%s>(),  // members of sub message' % '::'.join(type_.namespaced_name()))
    # bool is_array_
    print('    %s,  // is array' % ('true' if isinstance(member.type, AbstractNestedType) else 'false'))
    # size_t array_size_
    print('    %u,  // array size' % (member.type.size if isinstance(member.type, Array) else (member.type.maximum_size if isinstance(member.type, BoundedSequence) else 0)))
    # bool is_upper_bound_
    print('    %s,  // is upper bound' % ('true' if isinstance(member.type, BoundedSequence) else 'false'))
    # unsigned long offset_
    print('    offsetof(%s::%s, %s),  // bytes offset in struct' % ('::'.join([package_name] + list(interface_path.parents[0].parts)), message.structure.namespaced_type.name, member.name))
    # void * default_value_
    print('    nullptr,  // default value')  # TODO default value to be set

    function_suffix = ('%s__%s' % (message.structure.namespaced_type.name, member.name)) if isinstance(member.type, AbstractNestedType) and not is_vector_bool(member) else None

    # size_t(const void *) size_function
    print('    %s,  // size() function pointer' % ('size_function__%s' % function_suffix if function_suffix else 'nullptr'))
    # const void *(const void *, size_t) get_const_function
    print('    %s,  // get_const(index) function pointer' % ('get_const_function__%s' % function_suffix if function_suffix else 'nullptr'))
    # void *(void *, size_t) get_function
    print('    %s,  // get(index) function pointer' % ('get_function__%s' % function_suffix if function_suffix else 'nullptr'))
    # void(void *, size_t) resize_function
    print('    %s  // resize(index) function pointer' % ('resize_function__%s' % function_suffix if function_suffix and isinstance(member.type.value_type, AbstractSequence) else 'NULL'))

    if index < len(message.structure.members) - 1:
        print('  },')
    else:
        print('  }')
}@
};

static const ::rosidl_typesupport_introspection_cpp::MessageMembers @(message.structure.namespaced_type.name)_message_members = {
  "@(package_name)",  // package name
  "@(message.structure.namespaced_type.name)",  // message name
  @(len(message.structure.members)),  // number of fields
  sizeof(@('::'.join([package_name] + list(interface_path.parents[0].parts) + [message.structure.namespaced_type.name]))),
  @(message.structure.namespaced_type.name)_message_member_array  // message members
};

static const rosidl_message_type_support_t @(message.structure.namespaced_type.name)_message_type_support_handle = {
  ::rosidl_typesupport_introspection_cpp::typesupport_identifier,
  &@(message.structure.namespaced_type.name)_message_members,
  get_message_typesupport_handle_function,
};

}  // namespace rosidl_typesupport_introspection_cpp
@[  for ns in reversed(message.structure.namespaced_type.namespaces)]@

}  // namespace @(ns)
@[  end for]@

namespace rosidl_typesupport_introspection_cpp
{

template<>
ROSIDL_TYPESUPPORT_INTROSPECTION_CPP_PUBLIC
const rosidl_message_type_support_t *
get_message_type_support_handle<@('::'.join([package_name] + list(interface_path.parents[0].parts) + [message.structure.namespaced_type.name]))>()
{
  return &::@('::'.join([package_name] + list(interface_path.parents[0].parts)))::rosidl_typesupport_introspection_cpp::@(message.structure.namespaced_type.name)_message_type_support_handle;
}

}  // namespace rosidl_typesupport_introspection_cpp

#ifdef __cplusplus
extern "C"
{
#endif

ROSIDL_TYPESUPPORT_INTROSPECTION_CPP_PUBLIC
const rosidl_message_type_support_t *
ROSIDL_TYPESUPPORT_INTERFACE__MESSAGE_SYMBOL_NAME(rosidl_typesupport_introspection_cpp, @(', '.join([package_name] + list(interface_path.parents[0].parts) + [message.structure.namespaced_type.name])))() {
  return &::@('::'.join([package_name] + list(interface_path.parents[0].parts)))::rosidl_typesupport_introspection_cpp::@(message.structure.namespaced_type.name)_message_type_support_handle;
}

#ifdef __cplusplus
}
#endif

@# Included from rosidl_typesupport_introspection_cpp/resource/idl__type_support.cpp.em
@{
from rosidl_parser.definition import AbstractGenericString
from rosidl_parser.definition import AbstractNestedType
from rosidl_parser.definition import AbstractSequence
from rosidl_parser.definition import AbstractString
from rosidl_parser.definition import AbstractWString
from rosidl_parser.definition import Array
from rosidl_parser.definition import BasicType
from rosidl_parser.definition import BoundedSequence
from rosidl_parser.definition import NamespacedType
from rosidl_cmake import convert_camel_case_to_lower_case_underscore

include_parts = [package_name] + list(interface_path.parents[0].parts) + \
    [convert_camel_case_to_lower_case_underscore(interface_path.stem)]
include_base = '/'.join(include_parts)

header_files = [
    'array',
    'cstddef',  # providing offsetof()
    'string',
    'vector',
    'rosidl_generator_c/message_type_support_struct.h',
    'rosidl_typesupport_cpp/message_type_support.hpp',
    'rosidl_typesupport_interface/macros.h',
    include_base + '__struct.hpp',
    'rosidl_typesupport_introspection_cpp/field_types.hpp',
    'rosidl_typesupport_introspection_cpp/identifier.hpp',
    'rosidl_typesupport_introspection_cpp/message_introspection.hpp',
    'rosidl_typesupport_introspection_cpp/message_type_support_decl.hpp',
    'rosidl_typesupport_introspection_cpp/visibility_control.h',
]
}@
@[for header_file in header_files]@
@[    if header_file in include_directives]@
// already included above
// @
@[    else]@
@{include_directives.add(header_file)}@
@[    end if]@
#include "@(header_file)"
@[end for]@
@[for ns in message.structure.namespaced_type.namespaces]@

namespace @(ns)
{
@[end for]@

namespace rosidl_typesupport_introspection_cpp
{

@[for member in message.structure.members]@
@{
def is_vector_bool(member):
    from rosidl_parser.definition import BasicType
    from rosidl_parser.definition import AbstractSequence
    return isinstance(member.type, AbstractSequence) and isinstance(member.type.value_type, BasicType) and member.type.value_type.typename == 'boolean'
}@
@# exclude std::vector<bool> because of specialization in their API
@[  if isinstance(member.type, AbstractNestedType) and not is_vector_bool(member)]@
@{
from rosidl_generator_cpp import  MSG_TYPE_TO_CPP
if isinstance(member.type.value_type, BasicType):
    type_ = MSG_TYPE_TO_CPP[member.type.value_type.typename]
elif isinstance(member.type.value_type, AbstractString):
    type_ = 'std::string'
elif isinstance(member.type.value_type, AbstractWString):
    assert False, 'Unknown type: ' + str(member.type.value_type)
elif isinstance(member.type.value_type, NamespacedType):
    type_ = '::'.join(member.type.value_type.namespaced_name())
}@
size_t size_function__@(message.structure.namespaced_type.name)__@(member.name)(const void * untyped_member)
{
@[    if isinstance(member.type, Array)]@
  (void)untyped_member;
  return @(member.type.size);
@[    else]@
  const auto * member = reinterpret_cast<const std::vector<@(type_)> *>(untyped_member);
  return member->size();
@[    end if]@
}

const void * get_const_function__@(message.structure.namespaced_type.name)__@(member.name)(const void * untyped_member, size_t index)
{
@[    if isinstance(member.type, Array)]@
  const auto & member =
    *reinterpret_cast<const std::array<@(type_), @(member.type.size)> *>(untyped_member);
@[    else]@
  const auto & member =
    *reinterpret_cast<const std::vector<@(type_)> *>(untyped_member);
@[    end if]@
  return &member[index];
}

void * get_function__@(message.structure.namespaced_type.name)__@(member.name)(void * untyped_member, size_t index)
{
@[    if isinstance(member.type, Array)]@
  auto & member =
    *reinterpret_cast<std::array<@(type_), @(member.type.size)> *>(untyped_member);
@[    else]@
  auto & member =
    *reinterpret_cast<std::vector<@(type_)> *>(untyped_member);
@[    end if]@
  return &member[index];
}

@[    if isinstance(member.type, AbstractSequence)]@
void resize_function__@(message.structure.namespaced_type.name)__@(member.name)(void * untyped_member, size_t size)
{
  auto * member =
    reinterpret_cast<std::vector<@(type_)> *>(untyped_member);
  member->resize(size);
}

@[    end if]@
@[  end if]@
@[end for]@
static const ::rosidl_typesupport_introspection_cpp::MessageMember @(message.structure.namespaced_type.name)_message_member_array[@(len(message.structure.members))] = {
@{
for index, member in enumerate(message.structure.members):
    type_ = member.type
    if isinstance(type_, AbstractNestedType):
        type_ = type_.value_type

    print('  {')

    # const char * name_
    print('    "%s",  // name' % member.name)
    if isinstance(type_, BasicType):
        # uint8_t type_id_
        print('    ::rosidl_typesupport_introspection_cpp::ROS_TYPE_%s,  // type' % type_.typename.upper())
        # size_t string_upper_bound
        print('    0,  // upper bound of string')
        # const rosidl_generator_c::MessageTypeSupportHandle * members_
        print('    NULL,  // members of sub message')
    elif isinstance(type_, AbstractGenericString):
        # uint8_t type_id_
        if isinstance(type_, AbstractString):
            print('    ::rosidl_typesupport_introspection_cpp::ROS_TYPE_STRING,  // type')
        elif isinstance(type_, AbstractWString):
            print('    ::rosidl_typesupport_introspection_cpp::ROS_TYPE_WSTRING,  // type')
        else:
            assert False, 'Unknown type: ' + str(type_)
        # size_t string_upper_bound
        print('    %u,  // upper bound of string' % (type_.maximum_size if type_.has_maximum_size() else 0))
        # const rosidl_generator_c::MessageTypeSupportHandle * members_
        print('    NULL,  // members of sub message')
    else:
        # uint8_t type_id_
        print('    ::rosidl_typesupport_introspection_cpp::ROS_TYPE_MESSAGE,  // type')
        # size_t string_upper_bound
        print('    0,  // upper bound of string')
        # const rosidl_message_type_support_t * members_
        print('    ::rosidl_typesupport_introspection_cpp::get_message_type_support_handle<%s>(),  // members of sub message' % '::'.join(type_.namespaced_name()))
    # bool is_array_
    print('    %s,  // is array' % ('true' if isinstance(member.type, AbstractNestedType) else 'false'))
    # size_t array_size_
    print('    %u,  // array size' % (member.type.size if isinstance(member.type, Array) else (member.type.maximum_size if isinstance(member.type, BoundedSequence) else 0)))
    # bool is_upper_bound_
    print('    %s,  // is upper bound' % ('true' if isinstance(member.type, BoundedSequence) else 'false'))
    # unsigned long offset_
    print('    offsetof(%s::%s, %s),  // bytes offset in struct' % ('::'.join([package_name] + list(interface_path.parents[0].parts)), message.structure.namespaced_type.name, member.name))
    # void * default_value_
    print('    nullptr,  // default value')  # TODO default value to be set

    function_suffix = ('%s__%s' % (message.structure.namespaced_type.name, member.name)) if isinstance(member.type, AbstractNestedType) and isinstance(member.type.value_type, NamespacedType) else None

    # size_t(const void *) size_function
    print('    %s,  // size() function pointer' % ('size_function__%s' % function_suffix if function_suffix else 'nullptr'))
    # const void *(const void *, size_t) get_const_function
    print('    %s,  // get_const(index) function pointer' % ('get_const_function__%s' % function_suffix if function_suffix else 'nullptr'))
    # void *(void *, size_t) get_function
    print('    %s,  // get(index) function pointer' % ('get_function__%s' % function_suffix if function_suffix else 'nullptr'))
    # void(void *, size_t) resize_function
    print('    %s  // resize(index) function pointer' % ('resize_function__%s' % function_suffix if function_suffix and isinstance(member.type.value_type, AbstractSequence) else 'NULL'))

    if index < len(message.structure.members) - 1:
        print('  },')
    else:
        print('  }')
}@
};

static const ::rosidl_typesupport_introspection_cpp::MessageMembers @(message.structure.namespaced_type.name)_message_members = {
  "@(package_name)",  // package name
  "@(message.structure.namespaced_type.name)",  // message name
  @(len(message.structure.members)),  // number of fields
  sizeof(@('::'.join([package_name] + list(interface_path.parents[0].parts) + [message.structure.namespaced_type.name]))),
  @(message.structure.namespaced_type.name)_message_member_array  // message members
};

static const rosidl_message_type_support_t @(message.structure.namespaced_type.name)_message_type_support_handle = {
  ::rosidl_typesupport_introspection_cpp::typesupport_identifier,
  &@(message.structure.namespaced_type.name)_message_members,
  get_message_typesupport_handle_function,
};

}  // namespace rosidl_typesupport_introspection_cpp
@[  for ns in reversed(message.structure.namespaced_type.namespaces)]@

}  // namespace @(ns)
@[  end for]@

namespace rosidl_typesupport_introspection_cpp
{

template<>
ROSIDL_TYPESUPPORT_INTROSPECTION_CPP_PUBLIC
const rosidl_message_type_support_t *
get_message_type_support_handle<@('::'.join([package_name] + list(interface_path.parents[0].parts) + [message.structure.namespaced_type.name]))>()
{
  return &::@('::'.join([package_name] + list(interface_path.parents[0].parts)))::rosidl_typesupport_introspection_cpp::@(message.structure.namespaced_type.name)_message_type_support_handle;
}

}  // namespace rosidl_typesupport_introspection_cpp

#ifdef __cplusplus
extern "C"
{
#endif

ROSIDL_TYPESUPPORT_INTROSPECTION_CPP_PUBLIC
const rosidl_message_type_support_t *
ROSIDL_TYPESUPPORT_INTERFACE__MESSAGE_SYMBOL_NAME(rosidl_typesupport_introspection_cpp, @(', '.join([package_name] + list(interface_path.parents[0].parts) + [message.structure.namespaced_type.name])))() {
  return &::@('::'.join([package_name] + list(interface_path.parents[0].parts)))::rosidl_typesupport_introspection_cpp::@(message.structure.namespaced_type.name)_message_type_support_handle;
}

#ifdef __cplusplus
}
#endif