Browse Source

Shop images process mode (crop/resize)

Vova Tkach 5 years ago
parent
commit
6c3cbb17ef

+ 1 - 1
assets/template/shop_product_html_file.go

@@ -36,7 +36,7 @@ var VarShopProductHtmlFile = []byte(`{{template "header.html" .}}
 							<div class="card mt-1">
 								<div id="product_thumbnails" class="thumbnails d-flex flex-wrap">
 									{{range $index, $img := $.Data.Shop.Product.Images}}
-										<a class="thumbnail{{if gt $index 5}} thumbnail-hidden{{end}}" href="{{.FullImage}}" data-src="{{.FullImage}}">
+										<a class="thumbnail{{if gt $index 5}} thumbnail-hidden{{end}}" href="{{.ThumbnailFull}}" data-src="{{.ThumbnailFull}}">
 											<img class="img-responsive" alt="" src="{{.Thumbnail1}}" />
 										</a>
 									{{end}}

+ 30 - 4
engine/fetdata/shop_product_image.go

@@ -63,18 +63,44 @@ func (this *ShopProductImage) Thumbnail3() string {
 	return "/api/product-image/thumb-3/" + utils.IntToStr(this.object.A_product_id) + "/" + this.object.A_filename
 }
 
+func (this *ShopProductImage) ThumbnailFull() string {
+	if this == nil {
+		return ""
+	}
+	return "/api/product-image/thumb-full/" + utils.IntToStr(this.object.A_product_id) + "/" + this.object.A_filename
+}
+
 func (this *ShopProductImage) ThumbnailSize0() [2]int {
-	return (*this.wrap.Config).Shop.Thumbnails.Thumbnail0
+	return [2]int{
+		(*this.wrap.Config).Shop.Thumbnails.Thumbnail0[0],
+		(*this.wrap.Config).Shop.Thumbnails.Thumbnail0[1],
+	}
 }
 
 func (this *ShopProductImage) ThumbnailSize1() [2]int {
-	return (*this.wrap.Config).Shop.Thumbnails.Thumbnail1
+	return [2]int{
+		(*this.wrap.Config).Shop.Thumbnails.Thumbnail1[0],
+		(*this.wrap.Config).Shop.Thumbnails.Thumbnail1[1],
+	}
 }
 
 func (this *ShopProductImage) ThumbnailSize2() [2]int {
-	return (*this.wrap.Config).Shop.Thumbnails.Thumbnail2
+	return [2]int{
+		(*this.wrap.Config).Shop.Thumbnails.Thumbnail2[0],
+		(*this.wrap.Config).Shop.Thumbnails.Thumbnail2[1],
+	}
 }
 
 func (this *ShopProductImage) ThumbnailSize3() [2]int {
-	return (*this.wrap.Config).Shop.Thumbnails.Thumbnail3
+	return [2]int{
+		(*this.wrap.Config).Shop.Thumbnails.Thumbnail3[0],
+		(*this.wrap.Config).Shop.Thumbnails.Thumbnail3[1],
+	}
+}
+
+func (this *ShopProductImage) ThumbnailSizeFull() [2]int {
+	return [2]int{
+		(*this.wrap.Config).Shop.Thumbnails.ThumbnailFull[0],
+		(*this.wrap.Config).Shop.Thumbnails.ThumbnailFull[1],
+	}
 }

+ 16 - 4
engine/wrapper/config.go

@@ -18,10 +18,11 @@ type Config struct {
 			Category int
 		}
 		Thumbnails struct {
-			Thumbnail0 [2]int
-			Thumbnail1 [2]int
-			Thumbnail2 [2]int
-			Thumbnail3 [2]int
+			Thumbnail0    [3]int
+			Thumbnail1    [3]int
+			Thumbnail2    [3]int
+			Thumbnail3    [3]int
+			ThumbnailFull [3]int
 		}
 	}
 	API struct {
@@ -49,12 +50,23 @@ func (this *Config) configDefault() {
 
 	this.Shop.Thumbnails.Thumbnail0[0] = 100
 	this.Shop.Thumbnails.Thumbnail0[1] = 100
+	this.Shop.Thumbnails.Thumbnail0[2] = 0
+
 	this.Shop.Thumbnails.Thumbnail1[0] = 200
 	this.Shop.Thumbnails.Thumbnail1[1] = 200
+	this.Shop.Thumbnails.Thumbnail1[2] = 0
+
 	this.Shop.Thumbnails.Thumbnail2[0] = 250
 	this.Shop.Thumbnails.Thumbnail2[1] = 250
+	this.Shop.Thumbnails.Thumbnail2[2] = 0
+
 	this.Shop.Thumbnails.Thumbnail3[0] = 450
 	this.Shop.Thumbnails.Thumbnail3[1] = 450
+	this.Shop.Thumbnails.Thumbnail3[2] = 0
+
+	this.Shop.Thumbnails.ThumbnailFull[0] = 1000
+	this.Shop.Thumbnails.ThumbnailFull[1] = 800
+	this.Shop.Thumbnails.ThumbnailFull[2] = 1
 
 	this.API.XML.Enabled = 0
 	this.API.XML.Name = ""

+ 3 - 3
hosts/localhost/template/shop-product.html

@@ -25,7 +25,7 @@
 					<div class="col-md-6">
 						<div class="card" id="product_image">
 							{{if $.Data.Shop.Product.HaveImages }}
-								<img class="card-img-top" src="{{$.Data.Shop.Product.Image.Thumbnail1}}" alt="{{$.Data.EscapeString $.Data.Shop.Product.Name}}">
+								<img class="card-img-top" src="{{$.Data.Shop.Product.Image.Thumbnail3}}" alt="{{$.Data.EscapeString $.Data.Shop.Product.Name}}">
 							{{else}}
 								<img class="card-img-top" src="data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D%22286%22%20height%3D%22180%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20286%20180%22%20preserveAspectRatio%3D%22none%22%3E%3Cdefs%3E%3Cstyle%20type%3D%22text%2Fcss%22%3E%23holder_16c7e5ac360%20text%20%7B%20fill%3Argba(255%2C255%2C255%2C.75)%3Bfont-weight%3Anormal%3Bfont-family%3AHelvetica%2C%20monospace%3Bfont-size%3A14pt%20%7D%20%3C%2Fstyle%3E%3C%2Fdefs%3E%3Cg%20id%3D%22holder_16c7e5ac360%22%3E%3Crect%20width%3D%22286%22%20height%3D%22180%22%20fill%3D%22%23777%22%3E%3C%2Frect%3E%3Cg%3E%3Ctext%20x%3D%22107.0078125%22%20y%3D%2296.234375%22%3E286x180%3C%2Ftext%3E%3C%2Fg%3E%3C%2Fg%3E%3C%2Fsvg%3E" alt="{{$.Data.EscapeString $.Data.Shop.Product.Name}}">
 							{{end}}
@@ -34,8 +34,8 @@
 							<div class="card mt-1">
 								<div id="product_thumbnails" class="thumbnails d-flex flex-wrap">
 									{{range $index, $img := $.Data.Shop.Product.Images}}
-										<a class="thumbnail{{if gt $index 5}} thumbnail-hidden{{end}}" href="{{.FullImage}}" data-src="{{.FullImage}}">
-											<img class="img-responsive" alt="" src="{{.Thumbnail1}}" />
+										<a class="thumbnail{{if gt $index 5}} thumbnail-hidden{{end}}" href="{{.ThumbnailFull}}" data-src="{{.ThumbnailFull}}">
+											<img class="img-responsive" alt="" src="{{.Thumbnail0}}" />
 										</a>
 									{{end}}
 								</div>

+ 24 - 5
modules/module_api.go

@@ -18,7 +18,7 @@ import (
 	"github.com/disintegration/imaging"
 )
 
-func (this *Modules) api_GenerateImage(wrap *wrapper.Wrapper, width, height, color int, filename string) ([]byte, bool, string, error) {
+func (this *Modules) api_GenerateImage(wrap *wrapper.Wrapper, width, height int, resize bool, filename string) ([]byte, bool, string, error) {
 	file_ext := ""
 	if strings.ToLower(filepath.Ext(filename)) == ".png" {
 		file_ext = "image/png"
@@ -33,8 +33,11 @@ func (this *Modules) api_GenerateImage(wrap *wrapper.Wrapper, width, height, col
 		return []byte(""), false, file_ext, err
 	}
 
-	src = imaging.Fill(src, width, height, imaging.Center, imaging.Lanczos)
-	// src = imaging.Fit(src, width, height, imaging.Lanczos)
+	if !resize {
+		src = imaging.Fill(src, width, height, imaging.Center, imaging.Lanczos)
+	} else {
+		src = imaging.Fit(src, width, height, imaging.Lanczos)
+	}
 
 	var out_bytes bytes.Buffer
 	out := bufio.NewWriter(&out_bytes)
@@ -290,7 +293,7 @@ func (this *Modules) RegisterModule_Api() *Module {
 		Icon:   assets.SysSvgIconPage,
 		Sub:    &[]MISub{},
 	}, func(wrap *wrapper.Wrapper) {
-		if len(wrap.UrlArgs) == 5 && wrap.UrlArgs[0] == "api" && wrap.UrlArgs[1] == "product-image" && (wrap.UrlArgs[2] == "thumb-0" || wrap.UrlArgs[2] == "thumb-1" || wrap.UrlArgs[2] == "thumb-2" || wrap.UrlArgs[2] == "thumb-3") {
+		if len(wrap.UrlArgs) == 5 && wrap.UrlArgs[0] == "api" && wrap.UrlArgs[1] == "product-image" && (wrap.UrlArgs[2] == "thumb-0" || wrap.UrlArgs[2] == "thumb-1" || wrap.UrlArgs[2] == "thumb-2" || wrap.UrlArgs[2] == "thumb-3" || wrap.UrlArgs[2] == "thumb-full") {
 			thumb_type := wrap.UrlArgs[2]
 			product_id := wrap.UrlArgs[3]
 			file_name := wrap.UrlArgs[4]
@@ -304,21 +307,37 @@ func (this *Modules) RegisterModule_Api() *Module {
 
 			width := (*wrap.Config).Shop.Thumbnails.Thumbnail0[0]
 			height := (*wrap.Config).Shop.Thumbnails.Thumbnail0[1]
+			resize := false
 
 			if thumb_type == "thumb-1" {
 				width = (*wrap.Config).Shop.Thumbnails.Thumbnail1[0]
 				height = (*wrap.Config).Shop.Thumbnails.Thumbnail1[1]
+				if (*wrap.Config).Shop.Thumbnails.Thumbnail1[2] == 1 {
+					resize = true
+				}
 			} else if thumb_type == "thumb-2" {
 				width = (*wrap.Config).Shop.Thumbnails.Thumbnail2[0]
 				height = (*wrap.Config).Shop.Thumbnails.Thumbnail2[1]
+				if (*wrap.Config).Shop.Thumbnails.Thumbnail2[2] == 1 {
+					resize = true
+				}
 			} else if thumb_type == "thumb-3" {
 				width = (*wrap.Config).Shop.Thumbnails.Thumbnail3[0]
 				height = (*wrap.Config).Shop.Thumbnails.Thumbnail3[1]
+				if (*wrap.Config).Shop.Thumbnails.Thumbnail3[2] == 1 {
+					resize = true
+				}
+			} else if thumb_type == "thumb-full" {
+				width = (*wrap.Config).Shop.Thumbnails.ThumbnailFull[0]
+				height = (*wrap.Config).Shop.Thumbnails.ThumbnailFull[1]
+				if (*wrap.Config).Shop.Thumbnails.ThumbnailFull[2] == 1 {
+					resize = true
+				}
 			}
 
 			target_file := wrap.DHtdocs + string(os.PathSeparator) + "products" + string(os.PathSeparator) + "images" + string(os.PathSeparator) + product_id + string(os.PathSeparator) + thumb_type + "-" + file_name
 			if !utils.IsFileExists(target_file) {
-				data, ok, ext, err := this.api_GenerateImage(wrap, width, height, 0, original_file)
+				data, ok, ext, err := this.api_GenerateImage(wrap, width, height, resize, original_file)
 				if err != nil {
 					// System error 500
 					utils.SystemErrorPageEngine(wrap.W, err)

+ 156 - 62
modules/module_settings.go

@@ -128,8 +128,6 @@ func (this *Modules) RegisterModule_Settings() *Module {
 				{Name: "Thumbnails"},
 			})
 
-			// TODO: two fields in one line
-
 			content += builder.DataForm(wrap, []builder.DataFormField{
 				{
 					Kind:  builder.DFKHidden,
@@ -137,76 +135,172 @@ func (this *Modules) RegisterModule_Settings() *Module {
 					Value: "settings-thumbnails",
 				},
 				{
-					Kind:     builder.DFKNumber,
-					Caption:  "Shop thumbnail 1 width",
-					Name:     "shop-thumbnail-w-1",
-					Min:      "10",
-					Max:      "1000",
-					Required: true,
-					Value:    utils.IntToStr((*wrap.Config).Shop.Thumbnails.Thumbnail1[0]),
-				},
-				{
-					Kind:     builder.DFKNumber,
-					Caption:  "Shop thumbnail 1 height",
-					Name:     "shop-thumbnail-h-1",
-					Min:      "10",
-					Max:      "1000",
-					Required: true,
-					Value:    utils.IntToStr((*wrap.Config).Shop.Thumbnails.Thumbnail1[1]),
-				},
-				{
-					Kind:    builder.DFKText,
-					Caption: "",
-					Name:    "",
-					Value:   "",
+					Kind: builder.DFKText,
 					CallBack: func(field *builder.DataFormField) string {
-						return `<hr>`
+						resize_list := ``
+						resize_list += `<select class="form-control" name="shop-thumbnail-r-1">`
+						resize_list += `<option value="0"`
+						if (*wrap.Config).Shop.Thumbnails.Thumbnail1[2] == 0 {
+							resize_list += ` selected`
+						}
+						resize_list += `>Crop</option>`
+						resize_list += `<option value="1"`
+						if (*wrap.Config).Shop.Thumbnails.Thumbnail1[2] == 1 {
+							resize_list += ` selected`
+						}
+						resize_list += `>Resize</option>`
+						resize_list += `</select>`
+						return `<div class="form-group n3">` +
+							`<div class="row">` +
+							`<div class="col-md-3">` +
+							`<label for="lbl_price">Shop thumbnail 1</label>` +
+							`</div>` +
+							`<div class="col-md-9">` +
+							`<div>` +
+							`<div class="row">` +
+							`<div class="col-md-3">` +
+							`<div><input class="form-control" type="number" name="shop-thumbnail-w-1" value="` + utils.IntToStr((*wrap.Config).Shop.Thumbnails.Thumbnail1[0]) + `" min="100" max="1000" placeholder="" autocomplete="off" required></div>` +
+							`<div class="d-md-none mb-3"></div>` +
+							`</div>` +
+							`<div class="col-md-3">` +
+							`<div><input class="form-control" type="number" name="shop-thumbnail-h-1" value="` + utils.IntToStr((*wrap.Config).Shop.Thumbnails.Thumbnail1[1]) + `" min="100" max="1000" placeholder="" autocomplete="off" required></div>` +
+							`<div class="d-md-none mb-3"></div>` +
+							`</div>` +
+							`<div class="col-md-6">` +
+							resize_list +
+							`</div>` +
+							`</div>` +
+							`</div>` +
+							`</div>` +
+							`</div>` +
+							`</div>`
 					},
 				},
 				{
-					Kind:     builder.DFKNumber,
-					Caption:  "Shop thumbnail 2 width",
-					Name:     "shop-thumbnail-w-2",
-					Min:      "10",
-					Max:      "1000",
-					Required: true,
-					Value:    utils.IntToStr((*wrap.Config).Shop.Thumbnails.Thumbnail2[0]),
-				},
-				{
-					Kind:     builder.DFKNumber,
-					Caption:  "Shop thumbnail 2 height",
-					Name:     "shop-thumbnail-h-2",
-					Min:      "10",
-					Max:      "1000",
-					Required: true,
-					Value:    utils.IntToStr((*wrap.Config).Shop.Thumbnails.Thumbnail2[1]),
-				},
-				{
-					Kind:    builder.DFKText,
-					Caption: "",
-					Name:    "",
-					Value:   "",
+					Kind: builder.DFKText,
 					CallBack: func(field *builder.DataFormField) string {
-						return `<hr>`
+						resize_list := ``
+						resize_list += `<select class="form-control" name="shop-thumbnail-r-2">`
+						resize_list += `<option value="0"`
+						if (*wrap.Config).Shop.Thumbnails.Thumbnail2[2] == 0 {
+							resize_list += ` selected`
+						}
+						resize_list += `>Crop</option>`
+						resize_list += `<option value="1"`
+						if (*wrap.Config).Shop.Thumbnails.Thumbnail2[2] == 1 {
+							resize_list += ` selected`
+						}
+						resize_list += `>Resize</option>`
+						resize_list += `</select>`
+						return `<div class="form-group n3">` +
+							`<div class="row">` +
+							`<div class="col-md-3">` +
+							`<label for="lbl_price">Shop thumbnail 2</label>` +
+							`</div>` +
+							`<div class="col-md-9">` +
+							`<div>` +
+							`<div class="row">` +
+							`<div class="col-md-3">` +
+							`<div><input class="form-control" type="number" name="shop-thumbnail-w-2" value="` + utils.IntToStr((*wrap.Config).Shop.Thumbnails.Thumbnail2[0]) + `" min="100" max="1000" placeholder="" autocomplete="off" required></div>` +
+							`<div class="d-md-none mb-3"></div>` +
+							`</div>` +
+							`<div class="col-md-3">` +
+							`<div><input class="form-control" type="number" name="shop-thumbnail-h-2" value="` + utils.IntToStr((*wrap.Config).Shop.Thumbnails.Thumbnail2[1]) + `" min="100" max="1000" placeholder="" autocomplete="off" required></div>` +
+							`<div class="d-md-none mb-3"></div>` +
+							`</div>` +
+							`<div class="col-md-6">` +
+							resize_list +
+							`</div>` +
+							`</div>` +
+							`</div>` +
+							`</div>` +
+							`</div>` +
+							`</div>`
 					},
 				},
 				{
-					Kind:     builder.DFKNumber,
-					Caption:  "Shop thumbnail 3 width",
-					Name:     "shop-thumbnail-w-3",
-					Min:      "10",
-					Max:      "1000",
-					Required: true,
-					Value:    utils.IntToStr((*wrap.Config).Shop.Thumbnails.Thumbnail3[0]),
+					Kind: builder.DFKText,
+					CallBack: func(field *builder.DataFormField) string {
+						resize_list := ``
+						resize_list += `<select class="form-control" name="shop-thumbnail-r-3">`
+						resize_list += `<option value="0"`
+						if (*wrap.Config).Shop.Thumbnails.Thumbnail3[2] == 0 {
+							resize_list += ` selected`
+						}
+						resize_list += `>Crop</option>`
+						resize_list += `<option value="1"`
+						if (*wrap.Config).Shop.Thumbnails.Thumbnail3[2] == 1 {
+							resize_list += ` selected`
+						}
+						resize_list += `>Resize</option>`
+						resize_list += `</select>`
+						return `<div class="form-group n3">` +
+							`<div class="row">` +
+							`<div class="col-md-3">` +
+							`<label for="lbl_price">Shop thumbnail 3</label>` +
+							`</div>` +
+							`<div class="col-md-9">` +
+							`<div>` +
+							`<div class="row">` +
+							`<div class="col-md-3">` +
+							`<div><input class="form-control" type="number" name="shop-thumbnail-w-3" value="` + utils.IntToStr((*wrap.Config).Shop.Thumbnails.Thumbnail3[0]) + `" min="100" max="1000" placeholder="" autocomplete="off" required></div>` +
+							`<div class="d-md-none mb-3"></div>` +
+							`</div>` +
+							`<div class="col-md-3">` +
+							`<div><input class="form-control" type="number" name="shop-thumbnail-h-3" value="` + utils.IntToStr((*wrap.Config).Shop.Thumbnails.Thumbnail3[1]) + `" min="100" max="1000" placeholder="" autocomplete="off" required></div>` +
+							`<div class="d-md-none mb-3"></div>` +
+							`</div>` +
+							`<div class="col-md-6">` +
+							resize_list +
+							`</div>` +
+							`</div>` +
+							`</div>` +
+							`</div>` +
+							`</div>` +
+							`</div>`
+					},
 				},
 				{
-					Kind:     builder.DFKNumber,
-					Caption:  "Shop thumbnail 3 height",
-					Name:     "shop-thumbnail-h-3",
-					Min:      "10",
-					Max:      "1000",
-					Required: true,
-					Value:    utils.IntToStr((*wrap.Config).Shop.Thumbnails.Thumbnail3[1]),
+					Kind: builder.DFKText,
+					CallBack: func(field *builder.DataFormField) string {
+						resize_list := ``
+						resize_list += `<select class="form-control" name="shop-thumbnail-r-full">`
+						resize_list += `<option value="0"`
+						if (*wrap.Config).Shop.Thumbnails.ThumbnailFull[2] == 0 {
+							resize_list += ` selected`
+						}
+						resize_list += `>Crop</option>`
+						resize_list += `<option value="1"`
+						if (*wrap.Config).Shop.Thumbnails.ThumbnailFull[2] == 1 {
+							resize_list += ` selected`
+						}
+						resize_list += `>Resize</option>`
+						resize_list += `</select>`
+						return `<div class="form-group n3">` +
+							`<div class="row">` +
+							`<div class="col-md-3">` +
+							`<label for="lbl_price">Shop thumbnail full</label>` +
+							`</div>` +
+							`<div class="col-md-9">` +
+							`<div>` +
+							`<div class="row">` +
+							`<div class="col-md-3">` +
+							`<div><input class="form-control" type="number" name="shop-thumbnail-w-full" value="` + utils.IntToStr((*wrap.Config).Shop.Thumbnails.ThumbnailFull[0]) + `" min="100" max="1000" placeholder="" autocomplete="off" required></div>` +
+							`<div class="d-md-none mb-3"></div>` +
+							`</div>` +
+							`<div class="col-md-3">` +
+							`<div><input class="form-control" type="number" name="shop-thumbnail-h-full" value="` + utils.IntToStr((*wrap.Config).Shop.Thumbnails.ThumbnailFull[1]) + `" min="100" max="1000" placeholder="" autocomplete="off" required></div>` +
+							`<div class="d-md-none mb-3"></div>` +
+							`</div>` +
+							`<div class="col-md-6">` +
+							resize_list +
+							`</div>` +
+							`</div>` +
+							`</div>` +
+							`</div>` +
+							`</div>` +
+							`</div>`
+					},
 				},
 				{
 					Kind:   builder.DFKSubmit,

+ 77 - 0
modules/module_settings_act_thumbnails.go

@@ -17,12 +17,19 @@ func (this *Modules) RegisterAction_SettingsThumbnails() *Action {
 	}, func(wrap *wrapper.Wrapper) {
 		pf_shop_thumbnail_w_1 := wrap.R.FormValue("shop-thumbnail-w-1")
 		pf_shop_thumbnail_h_1 := wrap.R.FormValue("shop-thumbnail-h-1")
+		pf_shop_thumbnail_r_1 := wrap.R.FormValue("shop-thumbnail-r-1")
 
 		pf_shop_thumbnail_w_2 := wrap.R.FormValue("shop-thumbnail-w-2")
 		pf_shop_thumbnail_h_2 := wrap.R.FormValue("shop-thumbnail-h-2")
+		pf_shop_thumbnail_r_2 := wrap.R.FormValue("shop-thumbnail-r-2")
 
 		pf_shop_thumbnail_w_3 := wrap.R.FormValue("shop-thumbnail-w-3")
 		pf_shop_thumbnail_h_3 := wrap.R.FormValue("shop-thumbnail-h-3")
+		pf_shop_thumbnail_r_3 := wrap.R.FormValue("shop-thumbnail-r-3")
+
+		pf_shop_thumbnail_w_full := wrap.R.FormValue("shop-thumbnail-w-full")
+		pf_shop_thumbnail_h_full := wrap.R.FormValue("shop-thumbnail-h-full")
+		pf_shop_thumbnail_r_full := wrap.R.FormValue("shop-thumbnail-r-full")
 
 		if _, err := strconv.Atoi(pf_shop_thumbnail_w_1); err != nil {
 			wrap.MsgError(`Must be integer number`)
@@ -32,6 +39,10 @@ func (this *Modules) RegisterAction_SettingsThumbnails() *Action {
 			wrap.MsgError(`Must be integer number`)
 			return
 		}
+		if _, err := strconv.Atoi(pf_shop_thumbnail_r_1); err != nil {
+			wrap.MsgError(`Must be integer number`)
+			return
+		}
 
 		if _, err := strconv.Atoi(pf_shop_thumbnail_w_2); err != nil {
 			wrap.MsgError(`Must be integer number`)
@@ -41,6 +52,10 @@ func (this *Modules) RegisterAction_SettingsThumbnails() *Action {
 			wrap.MsgError(`Must be integer number`)
 			return
 		}
+		if _, err := strconv.Atoi(pf_shop_thumbnail_r_2); err != nil {
+			wrap.MsgError(`Must be integer number`)
+			return
+		}
 
 		if _, err := strconv.Atoi(pf_shop_thumbnail_w_3); err != nil {
 			wrap.MsgError(`Must be integer number`)
@@ -50,15 +65,39 @@ func (this *Modules) RegisterAction_SettingsThumbnails() *Action {
 			wrap.MsgError(`Must be integer number`)
 			return
 		}
+		if _, err := strconv.Atoi(pf_shop_thumbnail_r_3); err != nil {
+			wrap.MsgError(`Must be integer number`)
+			return
+		}
+
+		if _, err := strconv.Atoi(pf_shop_thumbnail_w_full); err != nil {
+			wrap.MsgError(`Must be integer number`)
+			return
+		}
+		if _, err := strconv.Atoi(pf_shop_thumbnail_h_full); err != nil {
+			wrap.MsgError(`Must be integer number`)
+			return
+		}
+		if _, err := strconv.Atoi(pf_shop_thumbnail_r_full); err != nil {
+			wrap.MsgError(`Must be integer number`)
+			return
+		}
 
 		pfi_shop_thumbnail_w_1 := utils.StrToInt(pf_shop_thumbnail_w_1)
 		pfi_shop_thumbnail_h_1 := utils.StrToInt(pf_shop_thumbnail_h_1)
+		pfi_shop_thumbnail_r_1 := utils.StrToInt(pf_shop_thumbnail_r_1)
 
 		pfi_shop_thumbnail_w_2 := utils.StrToInt(pf_shop_thumbnail_w_2)
 		pfi_shop_thumbnail_h_2 := utils.StrToInt(pf_shop_thumbnail_h_2)
+		pfi_shop_thumbnail_r_2 := utils.StrToInt(pf_shop_thumbnail_r_2)
 
 		pfi_shop_thumbnail_w_3 := utils.StrToInt(pf_shop_thumbnail_w_3)
 		pfi_shop_thumbnail_h_3 := utils.StrToInt(pf_shop_thumbnail_h_3)
+		pfi_shop_thumbnail_r_3 := utils.StrToInt(pf_shop_thumbnail_r_3)
+
+		pfi_shop_thumbnail_w_full := utils.StrToInt(pf_shop_thumbnail_w_full)
+		pfi_shop_thumbnail_h_full := utils.StrToInt(pf_shop_thumbnail_h_full)
+		pfi_shop_thumbnail_r_full := utils.StrToInt(pf_shop_thumbnail_r_full)
 
 		// Correct some values
 		if pfi_shop_thumbnail_w_1 < 10 {
@@ -67,6 +106,12 @@ func (this *Modules) RegisterAction_SettingsThumbnails() *Action {
 		if pfi_shop_thumbnail_h_1 > 1000 {
 			pfi_shop_thumbnail_h_1 = 1000
 		}
+		if pfi_shop_thumbnail_r_1 > 1 {
+			pfi_shop_thumbnail_r_1 = 1
+		}
+		if pfi_shop_thumbnail_r_1 < 0 {
+			pfi_shop_thumbnail_r_1 = 0
+		}
 
 		if pfi_shop_thumbnail_w_2 < 10 {
 			pfi_shop_thumbnail_w_2 = 10
@@ -74,6 +119,12 @@ func (this *Modules) RegisterAction_SettingsThumbnails() *Action {
 		if pfi_shop_thumbnail_h_2 > 1000 {
 			pfi_shop_thumbnail_h_2 = 1000
 		}
+		if pfi_shop_thumbnail_r_2 > 1 {
+			pfi_shop_thumbnail_r_2 = 1
+		}
+		if pfi_shop_thumbnail_r_2 < 0 {
+			pfi_shop_thumbnail_r_2 = 0
+		}
 
 		if pfi_shop_thumbnail_w_3 < 10 {
 			pfi_shop_thumbnail_w_3 = 10
@@ -81,15 +132,41 @@ func (this *Modules) RegisterAction_SettingsThumbnails() *Action {
 		if pfi_shop_thumbnail_h_3 > 1000 {
 			pfi_shop_thumbnail_h_3 = 1000
 		}
+		if pfi_shop_thumbnail_r_3 > 1 {
+			pfi_shop_thumbnail_r_3 = 1
+		}
+		if pfi_shop_thumbnail_r_3 < 0 {
+			pfi_shop_thumbnail_r_3 = 0
+		}
+
+		if pfi_shop_thumbnail_w_full < 10 {
+			pfi_shop_thumbnail_w_full = 10
+		}
+		if pfi_shop_thumbnail_h_full > 1000 {
+			pfi_shop_thumbnail_h_full = 1000
+		}
+		if pfi_shop_thumbnail_r_full > 1 {
+			pfi_shop_thumbnail_r_full = 1
+		}
+		if pfi_shop_thumbnail_r_full < 0 {
+			pfi_shop_thumbnail_r_full = 0
+		}
 
 		(*wrap.Config).Shop.Thumbnails.Thumbnail1[0] = pfi_shop_thumbnail_w_1
 		(*wrap.Config).Shop.Thumbnails.Thumbnail1[1] = pfi_shop_thumbnail_h_1
+		(*wrap.Config).Shop.Thumbnails.Thumbnail1[2] = pfi_shop_thumbnail_r_1
 
 		(*wrap.Config).Shop.Thumbnails.Thumbnail2[0] = pfi_shop_thumbnail_w_2
 		(*wrap.Config).Shop.Thumbnails.Thumbnail2[1] = pfi_shop_thumbnail_h_2
+		(*wrap.Config).Shop.Thumbnails.Thumbnail2[2] = pfi_shop_thumbnail_r_2
 
 		(*wrap.Config).Shop.Thumbnails.Thumbnail3[0] = pfi_shop_thumbnail_w_3
 		(*wrap.Config).Shop.Thumbnails.Thumbnail3[1] = pfi_shop_thumbnail_h_3
+		(*wrap.Config).Shop.Thumbnails.Thumbnail3[2] = pfi_shop_thumbnail_r_3
+
+		(*wrap.Config).Shop.Thumbnails.ThumbnailFull[0] = pfi_shop_thumbnail_w_full
+		(*wrap.Config).Shop.Thumbnails.ThumbnailFull[1] = pfi_shop_thumbnail_h_full
+		(*wrap.Config).Shop.Thumbnails.ThumbnailFull[2] = pfi_shop_thumbnail_r_full
 
 		if err := wrap.ConfigSave(); err != nil {
 			wrap.MsgError(err.Error())