コード例 #1
0
ファイル: events.py プロジェクト: snegovick/map_editor
 def screen_left_press(self, args):
     offset = state.get_offset()
     scale = state.get_scale()
     cx = (args[0][0]-offset[0])/scale[0]
     cy = (args[0][1]-offset[1])/scale[1]
     state.set_left_press_start((cx, cy))
     grid_step = state.get_grid_step()
     layer = state.get_active_layer()
コード例 #2
0
 def layer_set_child_button_click(self, args):
     layer = state.get_active_layer()
     if layer != None:
         selected_proxys = layer.get_selected_proxys()
         if len(selected_proxys) == 2:
             if layer.get_layer_type() == LayerType.meta:
                 layer.link_proxys()
                 self.mw.widget.update()
コード例 #3
0
 def update_layer_objects_list(self, args):
     layer = state.get_active_layer()
     if layer != None:
         proxys = layer.get_proxy_lst()
         if proxys != None:
             self.mw.clear_list(self.mw.lo_gtklist)
             for p in proxys:
                 self.mw.add_item_to_list(self.mw.lo_gtklist, p.name, None)
コード例 #4
0
ファイル: events.py プロジェクト: snegovick/map_editor
 def update_layer_objects_list(self, args):
     layer = state.get_active_layer()
     if layer!=None:
         proxys = layer.get_proxy_lst()
         if proxys != None:
             self.mw.clear_list(self.mw.lo_gtklist)
             for p in proxys:
                 self.mw.add_item_to_list(self.mw.lo_gtklist, p.name, None)
コード例 #5
0
ファイル: events.py プロジェクト: snegovick/map_editor
 def layer_set_child_button_click(self, args):
     layer = state.get_active_layer()
     if layer != None:
         selected_proxys = layer.get_selected_proxys()
         if len(selected_proxys) == 2:
             if layer.get_layer_type() == LayerType.meta:
                 layer.link_proxys()
                 self.mw.widget.update()
コード例 #6
0
 def screen_left_press(self, args):
     offset = state.get_offset()
     scale = state.get_scale()
     cx = (args[0][0] - offset[0]) / scale[0]
     cy = (args[0][1] - offset[1]) / scale[1]
     state.set_left_press_start((cx, cy))
     grid_step = state.get_grid_step()
     layer = state.get_active_layer()
コード例 #7
0
 def layer_delete_object_button_click(self, args):
     layer = state.get_active_layer()
     if layer != None:
         selected_proxys = layer.get_selected_proxys()
         layer.unselect_all_proxys()
         for p in selected_proxys:
             layer.remove_proxy_by_id(p.id)
         self.update_layer_objects_list(None)
         self.mw.widget.update()
コード例 #8
0
ファイル: events.py プロジェクト: snegovick/map_editor
 def layer_delete_object_button_click(self, args):
     layer = state.get_active_layer()
     if layer != None:
         selected_proxys = layer.get_selected_proxys()
         layer.unselect_all_proxys()
         for p in selected_proxys:
             layer.remove_proxy_by_id(p.id)
         self.update_layer_objects_list(None)
         self.mw.widget.update()
コード例 #9
0
 def deselect_all(self, args, noupdate=False):
     layer = state.get_active_layer()
     if layer != None:
         selected_proxys = layer.get_selected_proxys()
         layer.unselect_all_proxys()
         state.unset_put_layer_object()
         if not noupdate:
             self.mw.widget.update()
             self.update_layer_objects_list(None)
         self.update_sprites_list(None)
         self.update_layers_list(None)
コード例 #10
0
ファイル: events.py プロジェクト: snegovick/map_editor
 def deselect_all(self, args, noupdate=False):
     layer = state.get_active_layer()
     if layer != None:
         selected_proxys = layer.get_selected_proxys()
         layer.unselect_all_proxys()
         state.unset_put_layer_object()
         if not noupdate:
             self.mw.widget.update()
             self.update_layer_objects_list(None)
         self.update_sprites_list(None)
         self.update_layers_list(None)
コード例 #11
0
    def pointer_motion(self, args):
        offset = state.get_offset()
        scale = state.get_scale()
        cx = (args[0][0] - offset[0]) / scale[0]
        cy = (args[0][1] - offset[1]) / scale[1]
        pointer_position = (cx, cy)
        grid_step = state.get_grid_step()
        nx = int(pointer_position[0] / grid_step[0]) * grid_step[0]
        ny = int(pointer_position[1] / grid_step[1]) * grid_step[1]
        pointer_position = [nx, ny]

        layer = state.get_active_layer()
        if layer != None:
            if state.get_put_layer_object():
                self.mw.widget.update()

            if state.get_left_press_start() != None:
                prev_position = state.get_pointer_position()

                proxys = layer.get_selected_proxys()

                for p in proxys:
                    if not p in self.relative_coords:
                        self.relative_coords[p] = utils.mk_vect(
                            (cx, cy), p.get_position())
                    nx = cx + self.relative_coords[p][0]
                    ny = cy + self.relative_coords[p][1]
                    p.set_position((int(nx / grid_step[0]) * grid_step[0],
                                    int(ny / grid_step[1]) * grid_step[1]))
                    layer.resort_all_proxys()

            if state.is_selection_mode():
                if state.get_update_selection_box_selection():
                    state.update_selection_box(nx, ny)
                    sb = state.get_selection_box()
                    select_aabb = utils.AABB(sb[0], sb[1], sb[2], sb[3])
                    self.deselect_all(None, noupdate=True)
                    for p in layer.get_proxy_lst():
                        p_aabb = p.get_aabb()
                        if (p_aabb != None):
                            #print "proxy_aabb:", p_aabb
                            #print "select:", select_aabb

                            overlap = select_aabb.aabb_in_aabb(p_aabb)
                            #print "overlap",overlap
                            if (overlap != utils.OverlapEnum.no_overlap) and (
                                    overlap !=
                                    utils.OverlapEnum.fully_lays_inside):
                                p.set_selected()
                                layer.add_proxy_to_selected_fast(p)
            self.mw.widget.update()
        state.set_pointer_position(pointer_position)
        self.mw.cursor_pos_label.set_text("Pos: %.3f:%.3f" % (cx, cy))
コード例 #12
0
ファイル: events.py プロジェクト: snegovick/map_editor
    def pointer_motion(self, args):
        offset = state.get_offset()
        scale = state.get_scale()
        cx = (args[0][0]-offset[0])/scale[0]
        cy = (args[0][1]-offset[1])/scale[1]
        pointer_position = (cx, cy)
        grid_step = state.get_grid_step()
        nx = int(pointer_position[0]/grid_step[0])*grid_step[0]
        ny = int(pointer_position[1]/grid_step[1])*grid_step[1]
        pointer_position = [nx, ny]


        layer = state.get_active_layer()
        if layer != None:
            if state.get_put_layer_object():
                self.mw.widget.update()

            if state.get_left_press_start() != None:
                prev_position = state.get_pointer_position()

                proxys = layer.get_selected_proxys()

                for p in proxys:
                    if not p in self.relative_coords:
                        self.relative_coords[p] = utils.mk_vect((cx, cy), p.get_position())
                    nx = cx + self.relative_coords[p][0]
                    ny = cy + self.relative_coords[p][1]
                    p.set_position((int(nx/grid_step[0])*grid_step[0], int(ny/grid_step[1])*grid_step[1]))
                    layer.resort_all_proxys()
                
            if state.is_selection_mode():
                if state.get_update_selection_box_selection():
                    state.update_selection_box(nx, ny)
                    sb = state.get_selection_box()
                    select_aabb = utils.AABB(sb[0], sb[1], sb[2], sb[3])
                    self.deselect_all(None, noupdate=True)
                    for p in layer.get_proxy_lst():
                        p_aabb = p.get_aabb()
                        if (p_aabb != None):
                            #print "proxy_aabb:", p_aabb
                            #print "select:", select_aabb

                            overlap = select_aabb.aabb_in_aabb(p_aabb)
                            #print "overlap",overlap
                            if (overlap != utils.OverlapEnum.no_overlap) and (overlap != utils.OverlapEnum.fully_lays_inside):
                                p.set_selected()
                                layer.add_proxy_to_selected_fast(p)
            self.mw.widget.update()
        state.set_pointer_position(pointer_position)
        self.mw.cursor_pos_label.set_text("Pos: %.3f:%.3f"%(cx, cy))
コード例 #13
0
 def sprites_selection_changed(self, args):
     selection = args[0][0].get_selection()
     if len(selection) > 0:
         layer = state.get_active_layer()
         if layer == None:
             args[0][0].unselect_child(selection[0])
             return
         if layer.get_layer_type() == LayerType.meta:
             args[0][0].unselect_child(selection[0])
             return
         layer.unselect_layer_object()
         name = selection[0].children()[0].children()[1].get_text()
         for s in state.get_sprites():
             if s.name == name:
                 layer.set_selected_layer_object(s)
                 break
コード例 #14
0
ファイル: events.py プロジェクト: snegovick/map_editor
 def sprites_selection_changed(self, args):
     selection = args[0][0].get_selection()
     if len(selection)>0:
         layer = state.get_active_layer()
         if layer == None:
             args[0][0].unselect_child(selection[0])
             return
         if layer.get_layer_type() == LayerType.meta:
             args[0][0].unselect_child(selection[0])
             return
         layer.unselect_layer_object()
         name = selection[0].children()[0].children()[1].get_text()
         for s in state.get_sprites():
             if s.name == name:
                 layer.set_selected_layer_object(s)
                 break
コード例 #15
0
ファイル: events.py プロジェクト: snegovick/map_editor
 def layer_objects_selection_changed(self, args):
     layer = state.get_active_layer()
     if layer != None:
         if args != None:
             self.mw.new_settings_vbox(args.get_settings_list(), "Object "+args.name+" settings")
             
             if not state.get_shift_pressed():
                 layer.unselect_all_proxys()
             layer.add_proxy_to_selected(args)
             layer.set_ignore_next_selection_change()
         else:
             if layer.get_ignore_next_selection_change():
                 layer.unset_ignore_next_selection_change()
                 return
             layer.unselect_all_proxys()
     self.mw.widget.update()
コード例 #16
0
    def layer_objects_selection_changed(self, args):
        layer = state.get_active_layer()
        if layer != None:
            if args != None:
                self.mw.new_settings_vbox(args.get_settings_list(),
                                          "Object " + args.name + " settings")

                if not state.get_shift_pressed():
                    layer.unselect_all_proxys()
                layer.add_proxy_to_selected(args)
                layer.set_ignore_next_selection_change()
            else:
                if layer.get_ignore_next_selection_change():
                    layer.unset_ignore_next_selection_change()
                    return
                layer.unselect_all_proxys()
        self.mw.widget.update()
コード例 #17
0
ファイル: map_editor.py プロジェクト: snegovick/map_editor
    def do_expose_event(self, event):
        # Create the cairo context
        #state.offset = (self.allocation.width/2,self.allocation.height/2)
        #state.set_screen_offset((self.allocation.width/2, self.allocation.height/2))
        state.set_screen_offset((0, 0))
        scale = state.get_scale()
        
        offset = state.get_offset()

        cr_gdk = self.window.cairo_create()
        surface = cr_gdk.get_target()
        size = state.get_map_size_px()
        cr_surf = cairo.ImageSurface(cairo.FORMAT_ARGB32, event.area.width, event.area.height)
        cr = cairo.Context(cr_surf)
        
        # Restrict Cairo to the exposed area; avoid extra work
        cr.rectangle(event.area.x, event.area.y, event.area.width, event.area.height)
        cr.clip()

        cr.set_source_rgb(1.0, 1.0, 1.0)
        cr.rectangle(0, 0, int(size[0]*scale[0]), int(size[1]*scale[1]))
        cr.fill()

        layers = state.get_layers()
        pointer = state.get_pointer_position()
        
        if len(layers) == 0:
            cr.set_source_rgb(0.1, 0.1, 0.1)
            f_size = 13
            cr.set_font_size(f_size)
            text = "There is no layer yet, add one please"
            (x, y, width, height, dx, dy) = cr.text_extents(text)
            cr.move_to(self.allocation.width/2-width/2, self.allocation.height/2)
            cr.show_text(text);
        else:
            layer = state.get_active_layer()
            if state.get_put_layer_object():
                lo = layer.get_selected_layer_object()
                cr.translate(offset[0]+pointer[0], offset[1]+pointer[1])
                cr.scale(scale[0], scale[1])
                lo.draw_preview(cr)
                cr.identity_matrix()

            for l in layers:
                cr.translate(offset[0], offset[1])
                cr.scale(scale[0], scale[1])
                if l == layer:
                    l.draw(cr, 1.0)
                else:
                    l.draw(cr, 0.8)
                cr.identity_matrix()


            cr.set_source_rgb(0, 0, 0)
            cr.set_line_width(0.1)
            cr.translate(offset[0], offset[1])
            cr.scale(scale[0], scale[1])
            grid_step = state.get_grid_step()
            for y in range(0, int(size[1]), grid_step[1]):
                cr.move_to(0, y)
                cr.line_to(size[0], y)

            for x in range(0, int(size[0]), grid_step[0]):
                cr.move_to(x, 0)
                cr.line_to(x, size[1])
            cr.stroke()
            cr.identity_matrix()

        screen_size = state.get_screen_size()
        cr.set_source_rgba(0.5, 0.5, 0.5, 0.5)
        cr.rectangle(int(screen_size[0]*scale[0]), 0, event.area.width, event.area.height)
        cr.fill()

        cr.set_source_rgba(0.5, 0.5, 0.5, 0.5)
        cr.rectangle(0, int(screen_size[1]*scale[1]), event.area.width, event.area.height)
        cr.fill()


        sel_box = state.get_selection_box()
        if state.is_selection_mode():
            sx = min(sel_box[0], sel_box[2])
            ex = max(sel_box[0], sel_box[2])
            sy = min(sel_box[1], sel_box[3])
            ey = max(sel_box[1], sel_box[3])

            w = ex - sx
            h = ey - sy
            sel_box = [sx, sy, w, h]

            #print "sel_box:", sel_box
            #print "offset:", offset, "scale:", scale
            cr.set_source_rgba(0.7, 0.7, 0.9, 0.5)
            cr.rectangle(int(sel_box[0]*scale[0]), int(sel_box[1]*scale[1]), int(sel_box[2]*scale[0]), int(sel_box[3]*scale[1]))
            cr.fill()
        
        cr_gdk.set_source_surface(cr_surf)
        cr_gdk.paint()
コード例 #18
0
ファイル: main_window.py プロジェクト: snegovick/map_editor
    def __mk_right_vbox(self):
        self.right_vbox = gtk.VBox(homogeneous=False, spacing=0)


        self.general_settings_vb = gtk.VBox(homogeneous=False, spacing=0)
        self.update_general_settings()

        self.right_vbox.pack_start(self.general_settings_vb, expand=False, fill=False, padding=0)

        self.settings_vb = gtk.VBox(homogeneous=False, spacing=0)
        self.right_vbox.pack_start(self.settings_vb, expand=False, fill=False, padding=0)

        self.layer_objects_label = gtk.Label("Layer objects")
        self.lo_scrolled_window = gtk.ScrolledWindow()
        self.lo_gtklist = gtk.List()
        self.lo_gtklist.connect("selection_changed", lambda *args: ep.push_event(EVEnum.general_selection_changed, {"lst": args, "callback": ep.layer_objects_selection_changed, "enumerable": state.get_active_layer().get_proxy_lst()}))
        self.lo_scrolled_window.add_with_viewport(self.lo_gtklist)
        self.right_vbox.pack_start(self.layer_objects_label, expand=False, fill=False, padding=0)
        self.right_vbox.pack_start(self.lo_scrolled_window, expand=True, fill=True, padding=0)

        self.layer_object_add_button = gtk.Button("Add meta")
        self.layer_object_add_button.connect("clicked", lambda *args: ep.push_event(EVEnum.layer_object_add_meta_button_click, None))
        self.layer_object_add_button.set_sensitive(False)
        self.right_vbox.pack_start(self.layer_object_add_button, expand=False, fill=False, padding=0)

        self.layer_set_child_button = gtk.Button("Set child")
        self.layer_set_child_button.connect("clicked", lambda *args: ep.push_event(EVEnum.layer_set_child_button_click, None))
        self.layer_set_child_button.set_sensitive(False)
        self.right_vbox.pack_start(self.layer_set_child_button, expand=False, fill=False, padding=0)

        self.layer_delete_object_button = gtk.Button("Delete object")
        self.layer_delete_object_button.connect("clicked", lambda *args: ep.push_event(EVEnum.layer_delete_object_button_click, None))
        self.right_vbox.pack_start(self.layer_delete_object_button, expand=False, fill=False, padding=0)
コード例 #19
0
    def screen_left_release(self, args):
        offset = state.get_offset()
        scale = state.get_scale()
        cx = (args[0][0] - offset[0]) / scale[0]
        cy = (args[0][1] - offset[1]) / scale[1]

        grid_step = state.get_grid_step()
        layer = state.get_active_layer()

        if layer != None:
            if state.is_selection_mode():
                pass
            else:
                if state.get_put_layer_object():
                    state.unset_put_layer_object()
                    nx = int(cx / grid_step[0]) * grid_step[0]
                    ny = int(cy / grid_step[1]) * grid_step[1]
                    pt = [nx, ny]
                    layer.add_proxy(pt)
                    self.update_layer_objects_list(None)

                proxy_lst = layer.get_proxy_lst()

                if state.get_shift_pressed():
                    for p in proxy_lst:
                        if p.point_in_aabb([cx, cy]):
                            if not p.get_selected():
                                self.general_set_selected_element({
                                    "lst":
                                    self.mw.lo_gtklist,
                                    "name":
                                    p.name,
                                    "element":
                                    p
                                })
                                layer.add_proxy_to_selected(p)
                                layer.set_ignore_next_selection_change()
                            else:
                                if p in self.relative_coords:
                                    del self.relative_coords[p]
                                self.general_unselect_element({
                                    "lst": self.mw.lo_gtklist,
                                    "name": p.name
                                })
                                layer.remove_proxy_from_selected(p)
                else:
                    selected = None
                    for p in proxy_lst:
                        if p.point_in_aabb([cx, cy]):
                            selected = p
                    if selected != None:
                        if selected.get_selected():
                            self.relative_coords = {}
                            self.general_unselect_all_elements(
                                {"lst": self.mw.lo_gtklist})
                            print "click"
                            layer.unselect_all_proxys()
                        else:
                            self.relative_coords = {}
                            self.general_set_selected_element({
                                "lst":
                                self.mw.lo_gtklist,
                                "name":
                                selected.name,
                                "element":
                                selected
                            })
                            layer.add_proxy_to_selected(p)
                            layer.set_ignore_next_selection_change()

            self.mw.widget.update()

            selected_proxys = layer.get_selected_proxys()
            if len(selected_proxys) == 2:
                if layer.get_layer_type() == LayerType.meta:
                    self.mw.layer_set_child_button.set_sensitive(True)

            self.relative_coords = {}
            for p in selected_proxys:
                self.relative_coords[p] = utils.mk_vect((cx, cy),
                                                        p.get_position())

        state.unset_left_press_start()
コード例 #20
0
 def sprite_put_button_click(self, args):
     layer = state.get_active_layer()
     if layer != None:
         if layer.get_selected_layer_object() != None:
             state.set_put_layer_object()
コード例 #21
0
ファイル: events.py プロジェクト: snegovick/map_editor
 def layer_object_add_meta_button_click(self, args):
     layer = state.get_active_layer()
     if layer != None:
         layer.set_selected_layer_object(layer.get_new_meta())
     state.set_put_layer_object()
コード例 #22
0
ファイル: events.py プロジェクト: snegovick/map_editor
 def sprite_put_button_click(self, args):
     layer = state.get_active_layer()
     if layer != None:
         if layer.get_selected_layer_object()!=None:
             state.set_put_layer_object()
コード例 #23
0
ファイル: events.py プロジェクト: snegovick/map_editor
    def screen_left_release(self, args):
        offset = state.get_offset()
        scale = state.get_scale()
        cx = (args[0][0]-offset[0])/scale[0]
        cy = (args[0][1]-offset[1])/scale[1]

        grid_step = state.get_grid_step()
        layer = state.get_active_layer()

        if layer != None:
            if state.is_selection_mode():
                pass
            else:
                if state.get_put_layer_object():
                    state.unset_put_layer_object()
                    nx = int(cx/grid_step[0])*grid_step[0]
                    ny = int(cy/grid_step[1])*grid_step[1]
                    pt = [nx, ny]
                    layer.add_proxy(pt)
                    self.update_layer_objects_list(None)

                proxy_lst = layer.get_proxy_lst()

                if state.get_shift_pressed():
                    for p in proxy_lst:
                        if p.point_in_aabb([cx, cy]):
                            if not p.get_selected():
                                self.general_set_selected_element({"lst": self.mw.lo_gtklist, "name": p.name, "element": p})
                                layer.add_proxy_to_selected(p)
                                layer.set_ignore_next_selection_change()
                            else:
                                if p in self.relative_coords:
                                    del self.relative_coords[p]
                                self.general_unselect_element({"lst": self.mw.lo_gtklist, "name": p.name})
                                layer.remove_proxy_from_selected(p)
                else:
                    selected = None
                    for p in proxy_lst:
                        if p.point_in_aabb([cx, cy]):
                            selected = p
                    if selected != None:
                        if selected.get_selected():
                            self.relative_coords = {}
                            self.general_unselect_all_elements({"lst": self.mw.lo_gtklist})
                            print "click"
                            layer.unselect_all_proxys()
                        else:
                            self.relative_coords = {}
                            self.general_set_selected_element({"lst": self.mw.lo_gtklist, "name": selected.name, "element": selected})
                            layer.add_proxy_to_selected(p)
                            layer.set_ignore_next_selection_change()

            self.mw.widget.update()

            selected_proxys = layer.get_selected_proxys()
            if len(selected_proxys) == 2:
                if layer.get_layer_type() == LayerType.meta:
                    self.mw.layer_set_child_button.set_sensitive(True)

            self.relative_coords = {}
            for p in selected_proxys:
                self.relative_coords[p] = utils.mk_vect((cx, cy), p.get_position())


        state.unset_left_press_start()
コード例 #24
0
 def layer_object_add_meta_button_click(self, args):
     layer = state.get_active_layer()
     if layer != None:
         layer.set_selected_layer_object(layer.get_new_meta())
     state.set_put_layer_object()
コード例 #25
0
ファイル: main_window.py プロジェクト: snegovick/map_editor
    def __mk_right_vbox(self):
        self.right_vbox = gtk.VBox(homogeneous=False, spacing=0)

        self.general_settings_vb = gtk.VBox(homogeneous=False, spacing=0)
        self.update_general_settings()

        self.right_vbox.pack_start(self.general_settings_vb,
                                   expand=False,
                                   fill=False,
                                   padding=0)

        self.settings_vb = gtk.VBox(homogeneous=False, spacing=0)
        self.right_vbox.pack_start(self.settings_vb,
                                   expand=False,
                                   fill=False,
                                   padding=0)

        self.layer_objects_label = gtk.Label("Layer objects")
        self.lo_scrolled_window = gtk.ScrolledWindow()
        self.lo_gtklist = gtk.List()
        self.lo_gtklist.connect(
            "selection_changed", lambda *args: ep.push_event(
                EVEnum.general_selection_changed, {
                    "lst": args,
                    "callback": ep.layer_objects_selection_changed,
                    "enumerable": state.get_active_layer().get_proxy_lst()
                }))
        self.lo_scrolled_window.add_with_viewport(self.lo_gtklist)
        self.right_vbox.pack_start(self.layer_objects_label,
                                   expand=False,
                                   fill=False,
                                   padding=0)
        self.right_vbox.pack_start(self.lo_scrolled_window,
                                   expand=True,
                                   fill=True,
                                   padding=0)

        self.layer_object_add_button = gtk.Button("Add meta")
        self.layer_object_add_button.connect(
            "clicked", lambda *args: ep.push_event(
                EVEnum.layer_object_add_meta_button_click, None))
        self.layer_object_add_button.set_sensitive(False)
        self.right_vbox.pack_start(self.layer_object_add_button,
                                   expand=False,
                                   fill=False,
                                   padding=0)

        self.layer_set_child_button = gtk.Button("Set child")
        self.layer_set_child_button.connect(
            "clicked", lambda *args: ep.push_event(
                EVEnum.layer_set_child_button_click, None))
        self.layer_set_child_button.set_sensitive(False)
        self.right_vbox.pack_start(self.layer_set_child_button,
                                   expand=False,
                                   fill=False,
                                   padding=0)

        self.layer_delete_object_button = gtk.Button("Delete object")
        self.layer_delete_object_button.connect(
            "clicked", lambda *args: ep.push_event(
                EVEnum.layer_delete_object_button_click, None))
        self.right_vbox.pack_start(self.layer_delete_object_button,
                                   expand=False,
                                   fill=False,
                                   padding=0)